Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
c1375ab
Initial draft (pseudo code)
dnerini Oct 7, 2025
9f608f2
add namelist as resource
Nov 13, 2025
e82bd94
add verif_obs.smk to Snakefile
Nov 13, 2025
c3ab651
Add rules for observation data and namelist generation (using fake data)
Nov 13, 2025
7512d96
add newline to namelist template
Nov 13, 2025
13301a5
somewhat working version of run_mec (with fake data)
Nov 13, 2025
e722e5f
correct typo and add optional script for generating namelist, in case…
Nov 24, 2025
3d9e3c1
fix: add localrule to inference_interpolator rule (#57)
frazane Oct 8, 2025
918913f
Fix for interpolator rule
OpheliaMiralles Oct 8, 2025
179eb4d
Consolidate multi packages into unique src/ dir (#58)
dnerini Oct 14, 2025
e791a30
Update configs (#63)
OpheliaMiralles Oct 15, 2025
d197712
Adopt 'steps' instead of 'lead_time' (#62)
dnerini Oct 20, 2025
9568987
Update example config for experiment with interpolators (#70)
dnerini Oct 20, 2025
128eb91
Distinguish between primary runs ('candidates') and secondary runs (#64)
dnerini Oct 20, 2025
6315afc
Adopt forecast intervals including the end point (#71)
dnerini Oct 21, 2025
e028f59
Mrb 550 inconcsistent forecast initializations in evalml (#72)
jonasbhend Oct 21, 2025
5406777
Update vega-lite spec (#69)
frazane Oct 22, 2025
8d01490
Decouple inference preparation and execution (#68)
frazane Oct 22, 2025
b7b1311
Scores by Region (#75)
jonasbhend Oct 29, 2025
04c4cf1
input data and namelist for MEC
Dec 11, 2025
b1959dc
Merge remote-tracking branch 'origin/main' into MRB-534-Implement-rul…
dnerini Dec 11, 2025
23c9599
Cleanup
dnerini Dec 11, 2025
804455a
Refactor MEC namelist generation
Dec 11, 2025
f793d85
setup MEC case
Dec 18, 2025
3839476
add use of local MEC executable and cleaning
Jan 7, 2026
5b58b7a
Support of mec in a sarus container
Jan 8, 2026
569d713
First draft of FFV2 rules
Jan 14, 2026
e6eb2cc
change some params to fix wildcard issue
Jan 14, 2026
ce90890
change name of nl file
Jan 15, 2026
29ab980
make note about ver ens member
Jan 15, 2026
292878d
target final feedback files
Jan 15, 2026
09f06da
Fix linting
Jan 19, 2026
748ced1
Merge branch 'MRB-534-Implement-rule-to-generate-namelist' into MRB-5…
Jan 21, 2026
6776572
Ensure newline at the end of MEC namelist
Jan 21, 2026
bd485d0
add quotation marks
Jan 21, 2026
e230c2b
fix small bug in arg checking
Jan 21, 2026
6fda5cf
add param for feedback file directory (without init_time wild card)
Jan 21, 2026
31cec5a
Merge branch 'MRB-534-Implement-rule-to-generate-namelist' into MRB-5…
Jan 22, 2026
e6d3f38
syntax error?
Jan 22, 2026
6b295d7
fix wildcards
Jan 22, 2026
54b4ae3
use container paths in namelist
Jan 22, 2026
872ffe6
successful run of FFV2
Jan 22, 2026
933e6f5
fix tabs/spaces issue
Jan 29, 2026
3c584f2
more tab/spaces
Jan 29, 2026
82e5138
add touch point to wait on inference to run mec, and update the ffv2 …
Jan 29, 2026
8d28a24
add FFV2 to workflow
Jan 29, 2026
5d381f1
model data preparation for MEC
Jan 29, 2026
acce2f7
Merge branch 'main' into MRB-534-Implement-rule-to-generate-namelist
Feb 2, 2026
f9a5889
fix init_times_for_mec and add touch output/input (MEC waits for all …
Feb 4, 2026
c762ada
Merge remote-tracking branch 'origin/MRB-534-Implement-rule-to-genera…
Feb 5, 2026
99753e5
Refactoring, bugfixes
Feb 12, 2026
5fa2a34
Merge branch 'main' into MRB-534-Implement-rule-to-generate-namelist
dnerini Feb 12, 2026
4d7191b
Formatting requirements
Feb 24, 2026
87a4d07
fix rule dependencies and feedback file naming
Mar 11, 2026
8e87ea2
same feedback file naming as NWP
Mar 12, 2026
f3b8fd1
move score files to subdirs as Shiny apps expect
Mar 12, 2026
644ac1f
Merge remote-tracking branch 'origin/MRB-534-Implement-rule-to-genera…
Mar 12, 2026
29ecf65
logging msg
Mar 16, 2026
7f71a34
add param for final_fdbk_file_dir
Mar 16, 2026
28c8c72
separate out (and correct) rule to set up shiny app directory
Mar 16, 2026
2e4bf99
move categ bs data to right place
Mar 18, 2026
a7353bd
Use an okfile instead of using feedback file directory as input, beca…
Mar 19, 2026
8bce709
put logs in logs dir, and use REFTIMES_MEC
Mar 19, 2026
5fa123e
use REFTIMES_MEC for the input to ffv2 generation, but not the MEC in…
Mar 23, 2026
9c7e309
Merge branch 'MRB-536-ffv2-rule' into MRB-534-Implement-rule-to-gener…
Mar 26, 2026
6ac37e7
Clean up comments
Mar 27, 2026
4845b6e
Avoid duplicating model data and update to inn env
Apr 7, 2026
ef5fb82
Merge branch 'main' into MRB-534-Implement-rule-to-generate-namelist
Apr 7, 2026
097c58f
fixes after merge with main, support for ICON
Apr 16, 2026
5532469
Merge branch 'main' into MRB-534-Implement-rule-to-generate-namelist
andreaspauling Apr 16, 2026
331e67b
wildcard fixes
andreaspauling Apr 28, 2026
bdf12f6
support precipitation differencing
andreaspauling Apr 28, 2026
a572bbe
Merge branch 'main' into MRB-534-Implement-rule-to-generate-namelist
andreaspauling May 8, 2026
634e2d7
Merge remote-tracking branch 'refs/remotes/origin/MRB-534-Implement-r…
May 15, 2026
2d66b40
Attempt to merge from MRB-534-Implement-rule-to-generate-namelist again
May 15, 2026
d3cc2a5
cleanup
May 15, 2026
f3d45c7
support ver-files as observation source
andreaspauling May 20, 2026
21d70b4
add --mec --ffv2 options, paths in config, support of date lists
andreaspauling May 20, 2026
829932c
logging, cleaning
andreaspauling May 20, 2026
8ab3393
Run MEC outside the forecast run directory
andreaspauling May 20, 2026
d5afdf2
cleanup
andreaspauling May 21, 2026
5396f20
Remove trailing whitespace
andreaspauling May 21, 2026
332bd1e
ffv2 config update
andreaspauling May 21, 2026
0d65d78
Merge branch 'main' into MRB-534-Implement-rule-to-generate-namelist
andreaspauling May 21, 2026
4595921
updates PR review
andreaspauling May 21, 2026
1f60ccf
Merge branch 'main' into MRB-534-Implement-rule-to-generate-namelist
andreaspauling May 21, 2026
93d9354
Merge branch 'main' into MRB-534-Implement-rule-to-generate-namelist
andreaspauling May 27, 2026
a3b1aba
formatting
andreaspauling May 27, 2026
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
93 changes: 93 additions & 0 deletions config/forecasters-ich1_mec_ffv2.yaml
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance we can integrate the additional mec config in the existing templates instead of having to support an additional template? Or will this break the existing templates when run without the mec / ffv2 flags?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integrating the mec/ffv2 part in to an existing config should be possible. It is a design choice I guess. I have a slight preference for a larger number but small configs but I could try integration. Which existing one would then be best suited?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are supporting three forecaster configs (I don't know why we even have these 3 and they seem all a bit outdated). So I would have suggested to integrate it with one (or all) of these. But honestly, now that I look at the config mess, I am not even sure this is the way to go...

Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# yaml-language-server: $schema=../workflow/tools/config.schema.json
description: |
Evaluate skill of Stage E with/without cutoff edges trained with and without subgrid orography.

dates:
start: 2025-07-26T00:00
end: 2025-07-27T00:00
frequency: 6h

runs:
- forecaster:
inference_resources:
slurm_partition: normal-shared
checkpoint: https://service.meteoswiss.ch/mlstore#/experiments/602/runs/c30490b6ba064e4db03b430f3a2595ad
label: stage_E_icon_1km_cutoff_edges_subgrid_horography
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
label: stage_E_icon_1km_cutoff_edges_subgrid_horography
label: stage_E_icon_1km_cutoff_edges_subgrid_orography

steps: 0/24/6
config: resources/inference/configs/sgm-multidataset-forecaster-global-ich1-oper.yaml
extra_requirements:
- git+https://github.com/ecmwf/anemoi-inference.git@e369b1a90313e9701db13f63364a467aa281cf36

baselines:
- baseline:
baseline_id: ICON-CH1-EPS
label: ICON-CH1-ctrl
root: /store_new/mch/msopr/ml/ICON-CH1-EPS
steps: 0/24/6

- baseline:
baseline_id: ICON-CH2-EPS
label: ICON-CH2-ctrl
root: /store_new/mch/msopr/ml/ICON-CH2-EPS
steps: 0/24/6


truth:
label: KENDA-CH1
root: /store_new/mch/msopr/ml/datasets/mch-ich1-1km-2024-2025-1h-pl13-v1.0.zarr

experiment:
params:
- T_2M
- TD_2M
- U_10M
- V_10M
- TOT_PREC
stratification:
regions:
- jura
root: /scratch/mch/bhendj/regions/Prognoseregionen_LV95_20220517
thresholds:
TOT_PREC:
gt: [0.0, 1, 5]
U_10M:
gt: [2.5, 5.0, 10.0]
V_10M:
gt: [2.5, 5.0, 10.0]
T_2M:
lt: [273.15]
gt: [288.15, 298.15]
dashboard:
stratification:
# - init_hour
# - region
- season

locations:
output_root: output/

mec:
ekf_root: /store_new/mch/msopr/osm/KENDA-CH1/EKF
mon_synop_root: /scratch/mch/paa/mec/MEC_ML_input/monFiles2025
ver_synop_root: /scratch/mch/paa/mec/MEC25_I-CH1

ffv2:
experiment_ids: Varda
experiment_description: Varda-Single_suboro
file_description: exp_Varda-Single_2025
domain_table: /users/paa/01_store/02_FFV2/data/8_CH_box
blacklists: /users/paa/01_store/02_FFV2/data/blacklist

profile:
executor: slurm
global_resources:
gpus: 16
default_resources:
slurm_partition: "postproc"
cpus_per_task: 1
mem_mb_per_cpu: 1800
runtime: "1h"
gpus: 0
jobs: 50
batch_rules:
plot_forecast_frame: 32
84 changes: 84 additions & 0 deletions resources/ffv2/template_SYNOP_DET.nl.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@

# variables to verify.
varnoContinuous 'T2M,TD2M,RH2M,U10M,V10M,PS,FF,DD,GUST_6h,RR_6h' #,RR_6h,N,N_L,N_M,N_H,RAD_GL_1h
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variables are hardcoded, does this work also with a subset? Should/can this be made configurable?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works also with a subset. Is there a use case for subsets? We may always want to verify all variables we have.
This list depends on the variables in MEC and thus the observation (and model) source. If we decide on the observation source (see https://meteoswiss.atlassian.net/wiki/spaces/MR/pages/1746993334/SDL-42+Observation+sources+for+MEC+in+evalml ) the variables should stay constant

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, as you say this depends on the observations AND model data. So far we don't have wind gusts for example, so this shouldn't work. If there is internal homogenization (subsettting) of the requested parameters to the intersect of params available from both forecast and ground truth, this won't break with an 'extensive' set, but I still think it would be clearer if specified accordingly.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FFV2 just ignores a variable if it is not there. But I agree it would be clearer to specify only those variables we actually have.

pecthresholds list('FF'=list('lower'=c(2),'upper'=c(7))) # hit rates (percent correct forecast) for the forecast to hit the observation within the given limits are calculated.
catthresholds list('T2M'=c(282,292),'FF'=c(2.5,5,10)) # no space allowed between variables
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance we can reuse the thresholds defined in the main config?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, this should go into the config because that will be frequently changed. I will do it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we could basically specify the most extensive list of parameters availbale from observations and then be done with it? Is this the case now?


# senseful and short description of the model versions to verify.
# example: 'D-metno,C-metno_rollout,C-cerra_rollout'
expIds '{{ experiment_ids }}'



# location of the feedback files. All feedback files per model must be stored
# in one directory and the order must correspond to expIds
# Example: '/src/ffv2/input/,'
# fdbkDirs '{{ feedback_directories }}'
# Use a path in the container, to avoid mixups between absolute/relative paths.
# TODO: Change this once we support having more than one directory.
fdbkDirs '/src/ffv2/input'

# should be however many models
# example: '-1,-1,-1' for 3 models
veri_ens_member '{{ veri_ens_member }}'


# the (existing!) output directory (absolute or relative to working directory)
#outDir '{{ output_directory }}'
# Use a path in the container, to avoid mixups between absolute/relative paths.
outDir '/src/ffv2/output'

# string used to build the filenames of the intermediate scorefiles (one valid date). Only restriction:
# no other file in the output directory contains that string in the filename
# example: 'emulator_onPL_ALL_obs_2020'
expDescr '{{ experiment_description }}'

# string used to build the filenames of the final scorefiles.
# please follow the naming convention explained on the wiki page
# This should match the output file for this from snakemake rule
# Example: 'exp_ACOSMO-2-models_C-2E-CTRL_2020'
fileDescr '{{ file_description }}'


# string to filter feedback file input. All feedback files that contain the string in their filename are used.
# regular expressions are allowed, for details see list.files() in R
filePattern 'verSYNOP'

# switch experiment/routine verification. Set to T. (F only for DWD routine verification)
experiment 'T'

# switch for testing if two model versions differ significantly (T/F). Set to T only if there are two or more model versions to verify
sigTest 'T'

# subdomains to verify
subdomains 'ALL,USER'
# Location of domain table and blacklists. This data should be mounted from balfrin into
# the container. Recommend using the same path in src/dest, for simplicity.
# Example: '/users/paa/01_store/02_FFV2/data/7_ML_inner_polygon'
domainTable '{{ domain_table }}'
# Example: '/users/paa/01_store/02_FFV2/data/blacklist'
blacklists '{{ blacklists }}'

# time binning steps for valid times (in minutes) relative to the valid time of the feedback file (timestamp in filename) read
# (time granularity of the verification)
# does not apply to data of more than one FF (because FF are read sequently)
timeSteps '0'

# range of the temporal bins in minutes
timeBreaks '30,-30'

# set forecast times for which scores should be calculated.
# useful filter for lead times with very low LEN.
#veri_forecast_time '0000,1200,2400,3600,4800,6000,7200,8400,9600,10800,12000'

# run class(es). See Table 27 in the Feedback File Definition (version of 29 Oct. 2019)
#veri_run_class '0,2'

# run type(s). See Table 26 in the Feedback File Definition (version of 29 Oct. 2019)
veri_run_type '0,4'

# state(s) of observation to be used. See Table 8 in the Feedback File Definition (version of 29 Oct. 2019)
#state '0,1,5,7,13'

# state(s) of report to be used. See Table 8 in the Feedback File Definition (version of 29 Oct. 2019)
#r_state '0,1,5,7,13'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these changes to the accumulation logic for total precipitation needed here? If not, I would remove these.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. MEC needs precip accumulated from the beginning of the run

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a global postprocessor defined that is applied to all outputs just above. So the specific postprocessors for accumulation of precipitation introduced here are redundant.

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ output:
- extract_mask: # removes global points
mask: "lam_0/cutout_mask"
as_slice: true
- accumulate_from_start_of_forecast: # accumulate tp from start of forecast
accumulations:
- tp
- grib:
path: grib/ifs-{date}{time:04}_{step:03}.grib
encoding:
Expand All @@ -41,11 +44,14 @@ output:
templates:
samples: resources/templates_index_ifs.yaml
post_processors:
- extract_mask: # removes lam points
mask: "lam_0/cutout_mask"
as_slice: true
inverse: true
- assign_mask: # fill local/global overlapping points with nan
mask: "global/cutout_mask"
- extract_mask: # removes lam points
mask: "lam_0/cutout_mask"
as_slice: true
inverse: true
- assign_mask: # fill local/global overlapping points with nan
mask: "global/cutout_mask"
- accumulate_from_start_of_forecast: # accumulate tp from start of forecast
accumulations:
- tp

patch_metadata: resources/sgm-multidataset-ich1-oper-patch.yaml
77 changes: 77 additions & 0 deletions resources/mec/namelist.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
!==============================================================================
! namelist template for MEC
!==============================================================================

!===================
! general parameters
!===================
&run
method = 'GMESTAT' ! Model Equivalent Calculator
model = 'ML' ! forecast model. One of "COSMO" "ICON" "ML"
input = './input_mod' ! input data path
data = '/oprusers/osm/opr.inn/data/' ! data path for auxiliary data
obsinput = './input_obs' ! observation input data path
output = '.' ! output data to working directory
time_ana = {{ init_time }}00 ! analysis date YYYYMMDDHHMMSS
read_fields = 'ps u t v q geof t2m td2m u_10m v_10m'
grib_edition = 2
grib_library = 2 ! GRIB-API used: 1=GRIBEX 2=GRIB2-API
cosmo_refatm = 2 ! reference atmosphere to be used for COSMO:1or2
fc_hours = 0 ! Default is 3h. Has to be set to 0 if one wants to verify +0h leadtime
grid_file = '/oprusers/osm/opr.inn/data/grid_descriptions/icon_grid_0001_R19B08_mch.nc' ! grid description file for ICON (needed for REA-L)
nproc1 = 1
nproc2 = 1
/

!===============================
! observation related parameters
!===============================
&observations
!---------------------------------------------------
! read from CDFIN files (if not set use mon/cof/ekf)
!---------------------------------------------------
read_cdfin = F ! (F): dont read COSMO CDFIN files get obs from ekf
vint_lin_t = T ! linear vertical interpolation for temperature
vint_lin_z = T ! linear vertical interpolation for geopotential
vint_lin_uv = T ! linear vertical interpolation for wind
ptop_lapse = 850.
pbot_lapse = 950.
! int_nn = T ! horizontal interpolation: nearest neighbor
/

!====================
! Ensemble parameters
!====================
&ENKF
k_enkf = 0 ! ensemble size (0 for det. run)
det_run = 1 ! set to 1 for deterministic run, 0 for ensemble
/

!================================
! Verification related parameters
!================================
&veri_obs
obstypes = "SYNOP" ! "SYNOP TEMP"
fc_times = {{ leadtimes }} ! forecast lead time at reference (hhmm) 0000,1200,2400,...
prefix_in = 'obs' ! prefix for input files. ekf or mon (or obs if a verSYNOP.nc file is used)
prefix_out = 'ver'
rm_old = 2 ! overwrite entries in verification file ?
fc_file = '_FCR_TIMEMM_.grib' ! template for forecast file name
time_range = 1
ekf_concat = F
ref_runtype = 'any' ! accept any runtype for the reference state
/

&report
time_b = -0029 ! (hhmm, inclusive)
time_e = 0030 ! (hhmm, exclusive)
/

&cosmo_obs
lcd187 = .true. ! use ground based wind lidar obs
verification_start = -29 ! (min, inclusive)
verification_end = 30 ! (min, inclusive)
/
&synop_obs
version = 1
/
Loading
Loading