Repository navigation
Conversation
jonasbhend
left a comment
There was a problem hiding this comment.
Hi @lclanzi. Thanks for implementing this. I think the 'cross-validation' with holdin/out stations is a very nice feature. Given the additional way to select stations from jretrieve, I was wondering if we really want to support bbox selection and filtering down to Switzerland? What is the use case here that is not covered by selection by measurement network (e.g. 1,2) or bbox? If we don't have a strong argument, I would rather avoid this additional complexity.
Also, I am unable to check the implementation on linard, as mlflow is still being blocked. Will try to do a short test on Wednesday to confirm everything is working as expected.
Hi @jonasbhend, thanks a lot for the feedback! |
|
I know that this doesn't work (easily), but my question is: why do you want to use only stations in Switzerland? I guess for the nudging, you wouldn't want to constrain, and for the evaluation we could argue similarly. If anything, I think for the evaluation we should implement it as a stratifiable region (in essence the hull of all forecasting regions), which would then be available for both station and analysis-based evaluations. |
|
Thanks for the suggestions @jonasbhend! |
dnerini
left a comment
There was a problem hiding this comment.
very cool feature! I left some comments
There was a problem hiding this comment.
is adding an experiment yaml really necessary for this new feature PR?
There was a problem hiding this comment.
I removed the yaml. I will make a separate PR with varda-rapid related configs
There was a problem hiding this comment.
looks like config's still there? or am I misunderstanding your comment?
| return xr.Dataset(data_vars=data_vars, coords=coords) | ||
|
|
||
|
|
||
| def _trim_stations_xr( |
There was a problem hiding this comment.
why is this necessary? can't be handled directly through the jretrieve query?
There was a problem hiding this comment.
In principle, yes. However, I have not found a way to query SwissMetNet + partner stations within Switzerland using jretrieve. What I currently do is to query stations over a rectangular domain containing Switzerland with use_limitation=40, and further trim all stations located out of the Swiss borders. @clairemerker and @jonasbhend also looked into this, and If I remember correctly, you also had issues with this operation?
There was a problem hiding this comment.
As mentioned previously, I don't see the point in doing the subsetting on the jretrieve part. For evalml it seems sufficient to use bbox selection in jretrieve together with region stratification (which now includes Switzerland only as a separate region, right)? So I still suggest to drop this to simplify and keep the loading of obs clean(ish).
There was a problem hiding this comment.
As far as I know, bbox selection only works with a rectangular domain, meaning that stations out of Switzerland will be included in the ground truth. Or am I wrong?
There was a problem hiding this comment.
No that is correct. bbox selection is what it is. But if you wanted stations only from Switzerland, there is probably ways to do that by selecting measurement networks. And in any case for verification you could just use bbox selection and then stratify by Switzerland as a region which should be equivalent to bbox selection and trimming to Switzerland on the jretrieve call. My question here is if there is a use case (for nudging I guess) where we would want to use only stations from Switzerland and not the surrounding areas (other than selecting SwissMetNet say).
There was a problem hiding this comment.
Same, I also did not manage to make it work. And sometimes I can get more stations, but it is unclear to me which stations I am effectively retrieving. It would indeed be nice to have a better documentation or a more detailed explanation about the jretrieve API
There was a problem hiding this comment.
I think
stn_group_iddoesn't provide enough options to retrieve the partner stations in Switzerland, at least I didn't manage to do so (either not implemented or not documented?). Maybe usingmeas_group_idcould work, but the list is overwhelming to me, we will need help from MD to understand what to retrieve... (You can have a look at the options further down on that page: https://service.meteoswiss.ch/jretrieve/api/v1/surface/help)
Hi @clairemerker @lclanzi, I seem to be able to retrieve all automated stations by setting jretrieve:1,2,3,4 which is ['SMN', 'SMN precipitation', 'Partner', 'Partner precipitation']. Is this what you want?
There was a problem hiding this comment.
Hm... I'll check again, it all got me so confused :D Thanks!
There was a problem hiding this comment.
I feel the key question asked above by jonas is still valid though?
is there a use case where we would want to use only stations from Switzerland and not the surrounding areas?
my understanding is that we don't have such requirements for any of our use cases, do you agree? if this is true, the code above can be simplified
There was a problem hiding this comment.
Thanks @jonasbhend, that works. However, I'm still unable to retrieve partner stations out of Switzerland. I can only do that by using the bbox selection in combination with use_limitation, which I believe gives little control to which stations are used (note that bbox and group are mutually exclusive)
| the config contains a ``forward_transform_filter: | ||
| nudge_toward_observation`` block, in which case its | ||
| ``exclude_stations``/``holdout_fraction``/``holdout_seed`` are | ||
| injected into that block — see ``_inject_nudging_station_holdout``. |
There was a problem hiding this comment.
I think I need to be convinced about this approach as it seems to me a bit too fragile...
Wouldn't be more robust to use the station_holdout_cfg to write a list of stations that is then used downstream, eg for nudging? I know the nudging filter expects a list of stations in its config, but maybe we could change that a path to a list of stations?
There was a problem hiding this comment.
The holdout set is now a fixed list of station abbreviations in config/holdout_station/holdout_station.yaml. The evalml config points to this file with experiment.station_holdout_list. Verification uses it to split the stations that are in the truth dataset into holdout and holdin groups, for every model and baseline.
The nudging filter reads the same file through its holdout_station_file parameter and leaves those stations out when it corrects the initial condition. The file is read when the config is loaded.
There was a problem hiding this comment.
I have to apologize, I realize I didn't explain myself properly above. I created a draft PR #273 and asked Claude in more detail to implement what I had in mind.
In #259, my review comment on `4658375` was about how the setting reached the nudging plugin. `inference_prepare.py` walked the inference YAML for a `nudge_toward_observation` block and wrote `exclude_stations` / `holdout_fraction` / `holdout_seed` into it. With `holdout_fraction`, verification (in `compute_holdout_stations`) and the plugin each drew their own random sample, so nothing guaranteed both used the same stations. The suggestion was: use the experiment config to **write a list of stations once**, then have the downstream steps (verification, nudging) consume that file. Commit `c83345d` read the comment differently. It moved the *source* out of the experiment config into a hand-written YAML file (`experiment.station_holdout_list: /abs/path.yaml`). The nudging config now points at that file separately with `holdout_station_file`. The workflow neither writes nor tracks the file. Remaining problems: - The same path has to be set in two places (experiment config and inference resource YAML), and nothing checks that they match. - The file isn't in the repo (`config/holdout_station/holdout_station.yaml` doesn't exist), so experiments aren't self-contained. - Snakemake doesn't know the file exists. Editing it reruns verification (through `VERIF_HASH`) but **not** inference, even though the nudged forecasts depend on it. ## Target design ``` experiment.station_holdout: [CHM, FRE, ...] (evalml config, single source) │ ▼ rule station_holdout ──► OUT_ROOT/data/station_holdout/{HOLDOUT_HASH}.csv (nat_abbr column) │ │ ▼ ▼ verification_metrics(_baseline) inference_prepare_* (only runs whose input: holdout=… inference config references holdout_stations.csv) --holdout_stations_file {input} copies → {workdir}/holdout_stations.csv │ ▼ nudge_toward_observation: holdout_station_file: holdout_stations.csv ``` The data passes through a declared rule output, so the DAG tracks it and every run gets a copy of exactly what it used. ### What changes - **Config:** `experiment.station_holdout` is an inline list of `nat_abbr`. Empty lists and duplicate stations are rejected. This replaces `station_holdout_list`. - **New rule `station_holdout`** (`data.smk`): writes `data/station_holdout/{hash}.csv` with a single `nat_abbr` column. Changing the list gives a new file, so everything that depends on it reruns. - **Verification:** `verification_metrics` and `verification_metrics_baseline` take the CSV as an input and pass it with `--holdout_stations_file`. - **Inference:** a prepare rule takes the CSV as an input only if its run's inference config mentions `holdout_stations.csv`. The prepare script copies it into the working directory under that name. Other models don't rerun when the holdout changes. - **Nudging config:** `holdout_station_file: holdout_stations.csv`, a relative path like the existing `obs_path`. - **Fail-fast:** the workflow stops at startup if an inference config references `holdout_stations.csv` but `experiment.station_holdout` is not set. ### Requires The nudging plugin's `holdout_station_file` must read a CSV with a `nat_abbr` column, relative to the working directory. I believe this is already implemented by MeteoSwiss/anemoi-plugins-meteoswiss@aeb2fcd. To be confirmed!
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This PR adds a new stratification axis, station group (
all/holdout/holdin), alongside the existing region/season/init_hour stratifications, plus supporting infrastructure to make ground-truth retrieval more flexible. Note that this is a single fixed holdout/holdin split used for stratified evaluation, not k-fold cross-validation.all/holdout/holdinstations, so skill can be evaluated separately on stations that were withheld from nudging (or other applications) vs. those that fed into it.experiment.cross_validationin the top-level config (exclude_stations, orholdout_fraction+holdout_seedfor a random split) is the single source of truth for which stations define the holdout groupverify()(src/verification/__init__.py) adds astation_groupdimension to verification outputs, alongside the existing region/season/init_hour dimensions.report_experiment_dashboard.py,template.html.jinja2,script.js) and scorecards (report_scorecard.py) are updated to expose and correctly aggregate this new dimension.verif_hash()incommon.smknow includes the station-group configuration, so changing it correctly invalidates cached verification outputs instead of silently reusing stale results.data_input.jretrieve.parse_selection()now supportsfilter_mode=switzerland(trim to stations within the real Swiss national border) andfilter_mode=domain;domain_bbox=...(trim to an arbitrary bounding box), plus an optionaluse_limitation=<N>selector for data-usage-rights filtering. This lets a truth-root retrieve over a broad domain and then restrict to a precise region before verificationThis PR depends on MeteoSwiss/anemoi-plugins-meteoswiss#40 and should be merged only afterwards.