Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 31 additions & 0 deletions docs/examples/comparison_workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,34 @@ comparison_experiment_paths:
These experiments should have matching assimilation window parameters. By default in this suite, start and end cycle points are not specified, in which case Swell will parse the two experiments to find the matching cycle times between the two. Alternatively, start and end cycle points can be set manually.

The experiment can then be created using `swell create compare_variational_marine -o override.yaml` or `swell create compare_variational_atmosphere -o override`, depending on the type of experiments being compared. Launching the experiment will run tasks analyzing the jedi log and generating plots using Eva for increments. Comparison of the log analysis will be placed under the comparison suite's directory in a file named `jedi_log_comparison.txt`, while the eva plots will be located under the cycle directory for each cycle.

## Comparing IODA observations
The task `CompareIodaObservations` compares IODA files between experiments by checking for equality in standard IODA fields for simulated variables, including:

```
EffectiveError0
EffectiveError1
EffectiveQC0
EffectiveQC1
ObsBias0
ObsBias1
ObsValue
PreQC
hofx
hofx0,
hofx1
oman
ombg
```

Which variables are compared depends on the parameter `ioda_fields_for_comparison`. By default, `hofx` will be compared for hofx experiments, and `hofx0` and `hofx1` for variational and fgat suites. If a mismatch in data field length or average is detected, this task will fail.

The `CleanCycle` task may clear observation files depending on the setting for `clean_patterns` in `experiment.yaml`. To use this task, ensure that `clean_patterns` is set correctly in the comparison experiments.

## Comparing Increment files
`CompareIncrement` compares increment values between experiments. By default, `geos_atmosphere` suites will compare `Salt, Temp, and ave_ssh`, `geos_atmosphere` will compare `ps, ts, ua, va, t, q`, and `geos_cf` suites compare `NO2`. Data fields will be checked to ensure they share the same size, and an average will be taken to check for equality


The `CleanCycle` task may clear observation files depending on the setting for `clean_patterns` in `
experiment.yaml`. To use this task, ensure that `clean_patterns` is set correctly in the comparison
experiments.
30 changes: 24 additions & 6 deletions src/swell/suites/compare/flow.cylc
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@
{% for path in comparison_experiment_paths %}
JediOopsLogParser-{{model_component}}-{{ loop.index0 }}
{% endfor %}
JediLogComparison-{{model_component}}[^]:fail? => EvaComparisonIncrement-{{model_component}} => PublishComparisons => comparison_fail
JediLogComparison-{{model_component}}[^]:fail? => EvaComparisonJediLog-{{model_component}} => PublishComparisons => comparison_fail
JediLogComparison-{{model_component}}[^]:fail? => EvaComparisonObservations-{{model_component}} => PublishComparisons => comparison_fail
CompareIodaObservations-{{model_component}}? & CompareIncrement-{{model_component}}? & JediLogComparison-{{model_component}}[^]? => Pass

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 no increments produced for hofx suites. And CompareIncrement will unconditionally run for hofx suites I think.


CompareIodaObservations-{{model_component}}:fail? => EvaComparisonObservations-{{model_component}}? => PublishComparisons?
CompareIncrement-{{model_component}}:fail? => EvaComparisonIncrement-{{model_component}} => PublishComparisons?
JediLogComparison-{{model_component}}[^]:fail? => EvaComparisonJediLog-{{model_component}} => PublishComparisons?
PublishComparisons? => comparison_fail?
{% endif %}
{% endfor %}
"""
Expand All @@ -69,12 +72,30 @@
script = "exit 1"

{% for model_component in model_components %}
[[Pass]]
script = """
cylc set $CYLC_WORKFLOW_ID//$datetime/EvaComparisonIncrement-{{model_component}} --out skip
cylc set $CYLC_WORKFLOW_ID//$datetime/EvaComparisonJediLog-{{model_component}} --out skip
cylc set $CYLC_WORKFLOW_ID//$datetime/EvaComparisonObservations-{{model_component}} --out skip
cylc set $CYLC_WORKFLOW_ID//$datetime/PublishComparisons --out skip
cylc set $CYLC_WORKFLOW_ID//$datetime/comparison_fail --out skip
"""
Comment on lines +76 to +82

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just one thing, what is the purpose of this here? I think I saw this on another PR as well.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

These tasks are triggered by a fail state in the comparison tasks

JediLogComparison:fail? => EvaComparisonJediLog?

For some reason, cylc decides to stall the workflow (causing a failure state) if JediLogComparison succeeds, as it thinks it is waiting for EvaComparisonJediLog to be triggered. This is sort of a hacky workaround to skip those tasks if it succeeds. If anyone has any suggestions on how to do this better, I'm all ears. It seems like something that shouldn't be an issue, or have a more simple solution, but this is the only way I've been able to get it to work


[[CompareIncrement-{{model_component}}]]
script = "swell task CompareIncrement $config -d $datetime -m {{model_component}}"

[[EvaComparisonIncrement-{{model_component}}]]
script = "swell task EvaComparisonIncrement $config -d $datetime -m {{model_component}}"

[[EvaComparisonJediLog-{{model_component}}]]
script = "swell task EvaComparisonJediLog $config -d $datetime -m {{model_component}}"

[[PublishComparisons]]
script = "swell task PublishComparisons $config -d $datetime -m {{model_component}}"

[[CompareIodaObservations-{{model_component}}]]
script = "swell task CompareIodaObservations $config -d $datetime -m {{model_component}}"

[[EvaComparisonObservations-{{model_component}}]]
script = "swell task EvaComparisonObservations $config -d $datetime -m {{model_component}}"
platform = {{platform}}
Expand All @@ -84,9 +105,6 @@
--{{key}} = {{value}}
{%- endfor %}

[[PublishComparisons]]
script = "swell task PublishComparisons $config -d $datetime -m {{model_component}}"

{% if comparison_experiment_paths is mapping %}
{% for path in comparison_experiment_paths.values() %}
[[JediOopsLogParser-{{model_component}}-{{ loop.index0 }}]]
Expand Down
147 changes: 147 additions & 0 deletions src/swell/suites/compare/suite_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class SuiteConfig(QuestionContainer, Enum):
qd.cycle_times(default_value=[None], widget_type=WidgetType.STRING_CHECK_LIST),
qd.model_components(),
qd.runahead_limit(),
qd.ioda_fields_for_comparison(['hofx0/{variable}',
'hofx1/{variable}']),
qd.observations([]),
]
)

Expand All @@ -41,6 +44,21 @@ class SuiteConfig(QuestionContainer, Enum):
compare,
qd.comparison_log_type('variational'),
qd.model_components(['geos_marine']),
qd.observations([
"adt_cryosat2n",
"adt_jason3",
"adt_saral",
"adt_sentinel3a",
"adt_sentinel3b",
"insitu_profile_argo",
"sst_ostia",
"sss_smos",
"sss_smapv5",
"sst_abi_g16_l3c",
"sst_gmi_l3u",
"sst_viirs_n20_l3u",
"temp_profile_xbt"
])
]
)

Expand All @@ -52,6 +70,42 @@ class SuiteConfig(QuestionContainer, Enum):
compare,
qd.comparison_log_type('variational'),
qd.model_components(['geos_atmosphere']),
qd.observations([
"aircraft_temperature",
"aircraft_wind",
"airs_aqua",
"amsr2_gcom-w1",
"amsua_aqua",
"amsua_metop-b",
"amsua_metop-c",
"amsua_n15",
"amsua_n18",
"amsua_n19",
"atms_n20",
"atms_npp",
"avhrr3_metop-b",
"avhrr3_n18",
"avhrr3_n19",
"cris-fsr_n20",
"cris-fsr_npp",
"gmi_gpm",
"gps",
"iasi_metop-b",
"iasi_metop-c",
"mhs_metop-b",
"mhs_metop-c",
"mhs_n19",
"mls55_aura",
"omi_aura",
"ompsnm_npp",
"pibal",
"satwind",
"scatwind",
"sfcship",
"sfc",
"sondes",
"ssmis_f17"
])
]
)

Expand All @@ -63,6 +117,10 @@ class SuiteConfig(QuestionContainer, Enum):
compare,
qd.comparison_log_type('variational'),
qd.model_components(['geos_cf']),
qd.observations([
"tempo_no2_tropo",
"tropomi_s5p_no2_tropo",
])
]
)

Expand All @@ -74,6 +132,95 @@ class SuiteConfig(QuestionContainer, Enum):
compare,
qd.comparison_log_type('fgat'),
qd.model_components(['geos_marine']),
qd.observations([
"adt_cryosat2n",
"adt_jason3",
"adt_jason3n",
"adt_saral",
"adt_sentinel3a",
"adt_sentinel3b",
"adt_sentinel6a",
"adt_swot_nadir",
"insitu_profile_argo",
"insitu_profile_ctd",
"insitu_profile_pirata",
"insitu_profile_rama",
"insitu_profile_tao",
"icec_amsr2_north",
"icec_amsr2_south",
"icec_nsidc_nh",
"icec_nsidc_sh",
"sst_ostia",
"sss_smos",
"sss_smapv5",
"sst_abi_g16_l3c",
"sst_avhrrf_mb_l3u",
"sst_avhrrf_mc_l3u",
"sst_viirs_n20_l3u",
"sst_viirs_npp_l3u",
"temp_profile_xbt"
])
]
)

# --------------------------------------------------------------------------------------------------

compare_hofx = QuestionList(
list_name="compare_hofx",
questions=[
compare,
qd.comparison_log_type('hofx'),
qd.model_components(['geos_atmosphere']),
qd.ioda_fields_for_comparison(['hofx/{variable}']),
qd.observations([
"aircraft_temperature",
"aircraft_wind",
"airs_aqua",
"amsr2_gcom-w1",
"amsua_aqua",
"amsua_metop-b",
"amsua_metop-c",
"amsua_n15",
"amsua_n18",
"amsua_n19",
"atms_n20",
"atms_npp",
"avhrr3_metop-b",
"avhrr3_n18",
"avhrr3_n19",
"cris-fsr_n20",
"cris-fsr_npp",
"gmi_gpm",
"gps",
"iasi_metop-b",
"iasi_metop-c",
"mhs_metop-b",
"mhs_metop-c",
"mhs_n19",
"mls55_aura",
"omi_aura",
"ompsnm_npp",
"pibal",
"satwind",
"scatwind",
"sfcship",
"sfc",
"sondes",
"ssmis_f17"
]),
qd.mock_experiment(True)
]
)

# --------------------------------------------------------------------------------------------------

compare_hofx_cf = QuestionList(
list_name="compare_hofx_cf",
questions=[
compare,
qd.comparison_log_type('hofx'),
qd.ioda_fields_for_comparison(['hofx/{variable}']),
qd.model_components(['geos_cf']),

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.

is

        qd.observations([
            "tempo_no2_tropo",
            "tropomi_s5p_no2_tropo",
        ])

missing here?

]
)

Expand Down
7 changes: 6 additions & 1 deletion src/swell/suites/hofx_cf/suite_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,21 @@ class SuiteConfig(QuestionContainer, Enum):
qd.final_cycle_point("2023-08-05T18:00:00Z"),
qd.jedi_build_method("use_existing"),
qd.model_components(['geos_cf']),
qd.check_for_obs(False) # don't check empty for empty obs
qd.check_for_obs(False), # don't check empty for empty obs
qd.clean_patterns([])
],

geos_cf=[
]
)

# --------------------------------------------------------------------------------------------------

hofx_cf_tier1 = QuestionList(
list_name="hofx_cf_tier1",
questions=[
hofx_cf
]
)

# --------------------------------------------------------------------------------------------------
Loading
Loading