-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Obs only #593
Conversation
…true of no model is found
The _make_dummy_model function is only partially annotated, since importing EvalSetup lead to a circular import |
Codecov Report
@@ Coverage Diff @@
## main-dev #593 +/- ##
============================================
- Coverage 76.98% 76.70% -0.28%
============================================
Files 97 97
Lines 17494 17589 +95
============================================
+ Hits 13467 13492 +25
- Misses 4027 4097 +70
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some minor comments about the code itself.
More importantly, I would appreciate the private functions to be collected on a private module with a descriptive name.
obs_list = self.cfg.obs_cfg.keylist(obs_name) | ||
if self.cfg.model_cfg == {}: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could use the fact that an empty dictionary "is falsy"
if not self.cfg.model_cfg:
...
this also covers the case when self.cfg.model_cfg is None
Is it possible for the model_cfg
attribute to be missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it is possible. I think aeroval will crash if no model_cfg is given
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and model_cfg = None
?
pyaerocom/helpers.py
Outdated
start = min([int(per.split("-")[0]) for per in periods]) | ||
stop = max( | ||
[int(per.split("-")[1]) if len(per.split("-")) > 1 else int(per) for per in periods] | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you do not need to pass a list to min
/max
a generator expression will work just as well
start = min(int(per.split("-")[0]) for per in periods)
stop = max(
int(per.split("-")[1]) if "-" in per 1 else int(per) for per in periods
)
I think I've made all the changes requested |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor requests regarding the use of pathlib.Path
instead of os.path.*
.
Please, feel free to ignore them if you do not see the added value
outdir = os.path.join(tmpdir, f"{model_id}/renamed") | ||
|
||
os.makedirs(outdir, exist_ok=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if GriddedData.to_netcdf
accepts pathlib.Path
objects but it might be cleaner to write this part with a Path object
outdir = Path(tmpdir) / f"{model_id}/renamed"
outdir.mkdir(parents=True, exist_ok=True)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GriddedData.to_netcdf
uses os.path.join
, so I think it must be str. If we are going to change this, then it should be its own PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
os.path.join
accepts path-like objects (see docs),
which means that it will accept pathlib.Path
objects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not using a Path
object?
outdir = Path(tmpdir) / f"{model_id}/renamed"
outdir.makedir(parents=True, exist_ok=True)
as I wrote on my previous review
GriddedData.to_netcdf
usesos.path.join
, so I think it must be str. If we are going to change this, then it should be its own PR
os.path.join
accepts path-like objects (see docs),
which means that it will acceptpathlib.Path
objects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small nitpicks
outdir = os.path.join(tmpdir, f"{model_id}/renamed") | ||
|
||
os.makedirs(outdir, exist_ok=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not using a Path
object?
outdir = Path(tmpdir) / f"{model_id}/renamed"
outdir.makedir(parents=True, exist_ok=True)
as I wrote on my previous review
GriddedData.to_netcdf
usesos.path.join
, so I think it must be str. If we are going to change this, then it should be its own PR
os.path.join
accepts path-like objects (see docs),
which means that it will acceptpathlib.Path
objects
|
||
|
||
def get_max_period_range(periods): | ||
start = min([int(per.split("-")[0]) for per in periods]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can pass the generator expression directly to min
without creating a list, e.g.
start = min(int(per.split("-")[0]) for per in periods)
|
||
def get_max_period_range(periods): | ||
start = min([int(per.split("-")[0]) for per in periods]) | ||
stop = max(int(per.split("-")[1]) if len(per.split("-")) > 1 else int(per) for per in periods) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can simplify the generator expression by processing the last element on the split,
if you are concerned about invalid periods you could add an assert
assert all(per.count("-") <= 1 for per in periods), f"invalid period in {periods=}"
stop = max(int(per.split("-")[-1]) for per in periods)
if freq not in TS_TYPE_TO_PANDAS_FREQ.keys(): | ||
raise ValueError(f"{freq} not a recognized frequency") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can test membership on a dictionary directly without calling .keys()
if freq not in TS_TYPE_TO_PANDAS_FREQ:
 raise ValueError(f"{freq} not a recognized frequency")
Way of handling dummy data to be able obs only evaluation. See #436