Skip to content
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

Pydantic ColocationSetup #1120

Merged
merged 49 commits into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
f814171
start colocation_setup.py
lewisblake Apr 14, 2024
b7c3e6a
first run through old init attrs
lewisblake Apr 14, 2024
f214498
TODO
lewisblake Apr 14, 2024
84829cf
clean up and validators
lewisblake Apr 14, 2024
5d3e362
imports are completely broken. will revisit
lewisblake Apr 14, 2024
77b8dec
back up and try basic tests on ColocationSetup
lewisblake Apr 14, 2024
6a2830f
clean up syntax errors
lewisblake Apr 14, 2024
691a978
don't import new ColocationSetup into old tests
lewisblake Apr 14, 2024
4a8e42b
start test_colocation_setup
lewisblake Apr 14, 2024
c3788c5
initial test passes
lewisblake Apr 14, 2024
4e8ec2b
Merge branch 'main-dev' into pydantic-colocationsetup
lewisblake May 13, 2024
1e1118e
ColocationSetup init and model_validator
lewisblake May 13, 2024
6a910dd
new ColocatedSetup in test_colocation_auto WIP
lewisblake May 13, 2024
cf3e4eb
maybe use obs_config in default_setup
lewisblake May 15, 2024
52fcd99
obs_config problematic. positional args working
lewisblake May 15, 2024
df2597f
Merge branch 'main-dev' into pydantic-colocationsetup
lewisblake May 16, 2024
f15c307
colocation_setup testing
lewisblake May 22, 2024
de9dea9
Pydantic ColocationSetup in EvalSetup
lewisblake May 23, 2024
058255a
WIP
lewisblake May 23, 2024
1872cb8
obs_var validator
lewisblake May 23, 2024
1c84e32
_obs_is_vertical_profile
lewisblake May 24, 2024
50119c9
WIP
lewisblake May 24, 2024
fc1ba85
spearting functionality from data containers WIP
lewisblake May 27, 2024
6e8d5b8
update test_colocation_auto WIP
lewisblake May 28, 2024
dfd644a
fixing up testing with daniel
lewisblake May 28, 2024
9caeba1
Aeroval testing fixing WIP
lewisblake May 29, 2024
9992474
WIP
lewisblake May 29, 2024
ba38e92
keep checker ing Colocator.run()
lewisblake May 29, 2024
552ebb8
obs_vars must be a tuple
lewisblake May 29, 2024
abbb98d
update configs to use tuples for obs_vars
lewisblake May 29, 2024
bc6b0ab
WIP: hacked obs_cfg keys into col.colocation_setup
lewisblake May 29, 2024
0119875
WIP
lewisblake May 30, 2024
16b8b93
do same for model cfg as obs_cfg in get_colocator
lewisblake May 30, 2024
95e1394
_init_log: self.colocation_setup.basedir_coldata
lewisblake May 30, 2024
66fc25e
almost all aeroval tests passing
lewisblake May 30, 2024
eff7244
maybe need to update add_meta dict
lewisblake May 31, 2024
9168ae7
cams2_83 tests passing
lewisblake May 31, 2024
f7bf700
don't force vars_to_retrieve and varlist_aerocom to be tuples
lewisblake May 31, 2024
ee1c648
fixing up the last of tests
lewisblake May 31, 2024
5f47157
clean up
lewisblake May 31, 2024
2773379
clean up and docstrings
lewisblake May 31, 2024
4242cfc
don't break api
lewisblake May 31, 2024
4a828ff
Merge branch 'main-dev' into pydantic-colocationsetup
lewisblake May 31, 2024
0cc2a83
Merge branch 'main-dev' into pydantic-colocationsetup
lewisblake May 31, 2024
146b710
passes locally. thanks daniel
lewisblake May 31, 2024
5e55c2a
merge
lewisblake May 31, 2024
cb65477
clean up
lewisblake May 31, 2024
fa1b79c
heiko comments / clean up
lewisblake May 31, 2024
a88fe87
more clean up
lewisblake May 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 28 additions & 11 deletions pyaerocom/aeroval/_processing_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pyaerocom.aeroval import EvalSetup
from pyaerocom.aeroval.experiment_output import ExperimentOutput
from pyaerocom.colocation_auto import Colocator
from pyaerocom.colocation_setup import ColocationSetup


class HasConfig:
Expand Down Expand Up @@ -113,21 +114,37 @@ def get_colocator(self, model_name: str = None, obs_name: str = None) -> Colocat
Colocator

"""
col_cfg = {**self.cfg.colocation_opts.model_dump()}
outdir = self.cfg.path_manager.get_coldata_dir()
col_cfg["basedir_coldata"] = outdir

if not model_name and not obs_name:
col_stp = ColocationSetup(**col_cfg)
return Colocator(col_stp)

if model_name:
mod_cfg = self.cfg.get_model_entry(model_name)
col_cfg["model_cfg"] = mod_cfg

# LB: Hack and at what lowlevel_helpers's import_from was doing
for key, val in mod_cfg.items():
if key in ColocationSetup.model_fields:
col_cfg[key] = val
if obs_name:
obs_cfg = self.cfg.get_obs_entry(obs_name)
pyaro_config = obs_cfg["obs_config"] if "obs_config" in obs_cfg else None
col_cfg = {**self.cfg.colocation_opts}
col_cfg["obs_config"] = pyaro_config
col = Colocator(**col_cfg)
col.import_from(obs_cfg)
col.add_glob_meta(diurnal_only=self._get_diurnal_only(obs_name))
else:
col = Colocator(**self.cfg.colocation_opts)
if model_name:
mod_cfg = self.cfg.get_model_entry(model_name)
col.import_from(mod_cfg)
outdir = self.cfg.path_manager.get_coldata_dir()
col.basedir_coldata = outdir

# LB: Hack and at what lowlevel_helpers's import_from was doing
for key, val in obs_cfg.items():
if key in ColocationSetup.model_fields:
col_cfg[key] = val

col_cfg["add_meta"].update(diurnal_only=self._get_diurnal_only(obs_name))

col_stp = ColocationSetup(**col_cfg)
col = Colocator(col_stp)

return col


Expand Down
5 changes: 2 additions & 3 deletions pyaerocom/aeroval/experiment_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def _run_single_entry(self, model_name, obs_name, var_list):
elif ocfg["only_json"]:
if not ocfg["coldata_dir"]:
raise Exception(
f"No coldata_dir provided for an obs network for which only_json=True. The assumption of setting only_json=True is that colocated files already exist, and so a directory for these files must be provided."
"No coldata_dir provided for an obs network for which only_json=True. The assumption of setting only_json=True is that colocated files already exist, and so a directory for these files must be provided."
)
else:
preprocessed_coldata_dir = ocfg["coldata_dir"]
Expand All @@ -70,8 +70,7 @@ def _run_single_entry(self, model_name, obs_name, var_list):
if self.cfg.processing_opts.only_json:
files_to_convert = col.get_available_coldata_files(var_list)
else:
model_read_kwargs = self.cfg.model_cfg[model_name]["kwargs"]
col.run(var_list, model_read_kwargs=model_read_kwargs)
col.run(var_list)
files_to_convert = col.files_written

if self.cfg.processing_opts.only_colocation:
Expand Down
2 changes: 0 additions & 2 deletions pyaerocom/aeroval/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
start_stop,
to_pandas_timestamp,
)
from pyaerocom.io import ReadGridded
from pyaerocom.tstype import TsType
from pyaerocom.variable import Variable

logger = logging.getLogger(__name__)
Expand Down
34 changes: 13 additions & 21 deletions pyaerocom/aeroval/setupclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
check_if_year,
)
from pyaerocom.aeroval.json_utils import read_json, set_float_serialization_precision, write_json
from pyaerocom.colocation_auto import ColocationSetup
from pyaerocom.colocation_setup import ColocationSetup

logger = logging.getLogger(__name__)

Expand All @@ -50,7 +50,7 @@ class OutputPaths(BaseModel):
project ID
exp_id : str
experiment ID
json_basedir : str
json_basedir : str, Path

"""

Expand Down Expand Up @@ -422,13 +422,6 @@ def statistics_opts(self) -> StatisticsSetup:
}
return StatisticsSetup(**model_args)

##################################
## Non-BaseModel-based attributes
##################################

# These attributes require special attention b/c they're not based on Pydantic's BaseModel class.

# TODO: Use Pydantic for ColocationSetup
@computed_field
@cached_property
def colocation_opts(self) -> ColocationSetup:
Expand All @@ -438,7 +431,7 @@ def colocation_opts(self) -> ColocationSetup:
model_args = {
key: val
for key, val in self.model_extra.items()
if key in ColocationSetup().__dict__.keys()
if key in ColocationSetup.model_fields
}
# need to pass some default values to the ColocationSetup if not provided in config
default_dict = {"save_coldata": True, "keep_data": False, "resample_how": "mean"}
Expand All @@ -448,12 +441,11 @@ def colocation_opts(self) -> ColocationSetup:

return ColocationSetup(**model_args)

@field_serializer("colocation_opts")
def serialize_colocation_opts(self, colocation_opts: ColocationSetup):
return colocation_opts.json_repr()
##################################
## Non-BaseModel-based attributes
##################################

# ObsCollection and ModelCollection
# TODO Use Pydantic for ObsCollection and ModelCollection
# These attributes require special attention b/c they're not based on Pydantic's BaseModel class.

obs_cfg: ObsCollection | dict = ObsCollection()

Expand Down Expand Up @@ -550,8 +542,8 @@ def _import_aux_funs(self) -> None:

def _check_time_config(self) -> None:
periods = self.time_cfg.periods
colstart = self.colocation_opts["start"]
colstop = self.colocation_opts["stop"]
colstart = self.colocation_opts.start
colstop = self.colocation_opts.stop

if len(periods) == 0:
if colstart is None:
Expand All @@ -576,15 +568,15 @@ def _check_time_config(self) -> None:
if stop_yr == start_yr:
stop_yr += 1
if colstart is None:
self.colocation_opts["start"] = start.strftime("%Y/%m/%d %H:%M:%S")
self.colocation_opts.start = start.strftime("%Y/%m/%d %H:%M:%S")
if colstop is None:
self.colocation_opts["stop"] = stop.strftime(
self.colocation_opts.stop = stop.strftime(
"%Y/%m/%d %H:%M:%S"
) # + 1 # add 1 year since we want to include stop year
else:
if colstart is None:
self.colocation_opts["start"] = start_yr
self.colocation_opts.start = start_yr
if colstop is None:
self.colocation_opts["stop"] = (
self.colocation_opts.stop = (
stop_yr + 1
) # add 1 year since we want to include stop year
Loading