From 582859dc0cb23fc944fbdb6e4f4a8f4ccedd505f Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Tue, 25 Nov 2025 14:39:29 -0500 Subject: [PATCH 01/51] Add task --- .../tasks/eva_comparison_observations.py | 246 ++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 src/swell/tasks/eva_comparison_observations.py diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py new file mode 100644 index 000000000..e5d9c49dd --- /dev/null +++ b/src/swell/tasks/eva_comparison_observations.py @@ -0,0 +1,246 @@ +# (C) Copyright 2021- United States Government as represented by the Administrator of the +# National Aeronautics and Space Administration. All Rights Reserved. + +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + + +# -------------------------------------------------------------------------------------------------- + + +from multiprocessing import Pool +import osq +import yaml + +from eva.eva_driver import eva + +from swell.deployment.platforms.platforms import login_or_compute +from swell.tasks.base.task_base import taskBase +from swell.utilities.dictionary import remove_matching_keys, replace_string_in_dictionary +from swell.utilities.jinja2 import template_string_jinja2 +from swell.utilities.observations import ioda_name_to_long_name +from swell.utilities.run_jedi_executables import check_obs + +# -------------------------------------------------------------------------------------------------- + + +# Pass through to avoid confusion with optional logger argument inside eva +def run_eva(eva_dict: dict) -> eva: + eva(eva_dict) + + +# -------------------------------------------------------------------------------------------------- + + +class EvaObservations(taskBase): + + def execute(self) -> None: + + # Compute window beginning time + # ----------------------------- + window_begin = self.da_window_params.window_begin(self.config.window_offset()) + background_time = self.da_window_params.background_time(self.config.window_offset(), + self.config.background_time_offset() + ) + + # Comparison log type + # ------------------- + log_type = self.config.comparison_log_type() + + # Get the experiment paths + # ------------------------ + experiment_paths = self.config.comparison_experiment_paths() + experiment_path_1 = experiment_paths[0] + experiment_path_2 = experiment_paths[1] + + with open(experiment_path_1, 'r') as f: + experiment_config_1 = yaml.safe_load(f) + + with open(experiment_path_2, 'r') as f: + experiment_config_2 = yaml.safe_load(f) + + jedi_config_file_1 = os.path.join(os.path.dirname(experiment_path_1), '..', 'run', + self.cycle_time(), self.get_model(), f'jedi_{log_type}_config.yaml') + + with open(jedi_config_file_1, 'r') as f: + jedi_config = yaml.safe_load(f) + obs_config_1 = jedi_config['cost function']['observations']['observers'] + + jedi_config_file_2 = os.path.join(os.path.dirname(experiment_path_2), '..', 'run', + self.cycle_time(), self.get_model(), f'jedi_{log_type}_config.yaml') + + with open(jedi_config_file_2, 'r') as f: + jedi_config = yaml.safe_load(f) + obs_config_2 = jedi_config['cost function']['observations']['observers'] + + # Determine if running on login or compute node and set workers + # ------------------------------------------------------------- + number_of_workers = 6 + if login_or_compute(self.platform()) == 'compute': + number_of_workers = 40 + self.logger.info(f'Running parallel plot generation with {number_of_workers} workers') + + # Read Eva template file into dictionary + # -------------------------------------- + model = self.get_model() + eva_path = os.path.join(self.experiment_path(), self.experiment_id()+'-suite', 'eva') + eva_config_file = os.path.join(eva_path, f'observations-{model}.yaml') + with open(eva_config_file, 'r') as eva_config_file_open: + eva_str_template = eva_config_file_open.read() + + # Set channels for which plots will be made + # This should be configurable once we do the eva refactoring. + # ------------------------------------------------------------- + channels_to_plot = { + 'airs_aqua': [15, 92, 128, 156, 172, 175, 190, 215, 252, 262, 310, 362, 497, 672, 914, + 1088, 1329, 1449, 1766, 1800, 1869, 1918], + 'cris-fsr_n20': [59, 69, 82, 86, 92, 102, 107, 114, 130, 141, 153, 158, 164, 167, 168, + 402, 487, 501, 626, 874, 882, 1008], + 'cris-fsr_npp': [59, 69, 82, 86, 92, 102, 107, 114, 130, 141, 153, 158, 164, 167, 168, + 402, 487, 501, 626, 874, 882, 1008], + 'iasi_metop-b': [55, 70, 106, 122, 144, 176, 185, 210, 236, 254, 299, 345, 375, 404, + 445, 552, 573, 906, 1121, 1194, 1427, 1585], + 'iasi_metop-c': [55, 70, 106, 122, 144, 176, 185, 210, 236, 254, 299, 345, 375, 404, + 445, 552, 573, 906, 1121, 1194, 1427, 1585], + } + + # Loop over observations and create dictionaries + # ---------------------------------------------- + eva_dicts = [] # Empty list of dictionaries + + # Set the observing system records path + self.jedi_rendering.set_obs_records_path(self.config.observing_system_records_path(None)) + + for observation in self.config.observations(): + + observation_dict_1 = None + for key, value in obs_config_1.items(): + if value['name'] == observation: + observation_dict_1 = value + + observation_dict_2 = None + for key, value in obs_config_2.items(): + if value['name'] == observation: + observation_dict_2 = value + + if observation_dict_1 is None or observation_dict_2 is None: + continue + + # Check if IODA observation input and output have non-zero location dimensions + use_obs_1 = check_obs(self.jedi_rendering.observing_system_records_path, observation, + observation_dict_1, self.cycle_time_dto(), input_and_output=True) + + use_obs_2 = check_obs(self.jedi_rendering.observing_system_records_path, observation, + observation_dict_1, self.cycle_time_dto(), input_and_output=True) + + use_obs = use_obs_1 and use_obs_2 + + if not use_obs: + continue + + # Split the full path into path and filename + obs_path_file_1 = observation_dict_1['obsdataout']['engine']['obsfile'] + cycle_dir_1, obs_file_1 = os.path.split(obs_path_file_1) + + # Split the full path into path and filename + obs_path_file_2 = observation_dict_2['obsdataout']['engine']['obsfile'] + cycle_dir_2, obs_file_2 = os.path.split(obs_path_file_2) + + # Check for need to add 0000 to the file + # -------------------------------------- + if not os.path.exists(obs_path_file_1): + obs_path_file_name, obs_path_file_ext = os.path.splitext(obs_path_file_1) + obs_path_file_0000 = obs_path_file_name + '_0000' + obs_path_file_ext + if not os.path.exists(obs_path_file_0000): + self.logger.abort(f'No observation file found for {obs_path_file_1} or ' + + f'{obs_path_file_0000}') + obs_path_file_1 = obs_path_file_0000 + + # Check for need to add 0000 to the file + # -------------------------------------- + if not os.path.exists(obs_path_file_2): + obs_path_file_name, obs_path_file_ext = os.path.splitext(obs_path_file_2) + obs_path_file_0000 = obs_path_file_name + '_0000' + obs_path_file_ext + if not os.path.exists(obs_path_file_0000): + self.logger.abort(f'No observation file found for {obs_path_file_2} or ' + + f'{obs_path_file_0000}') + obs_path_file_2 = obs_path_file_0000 + + # Get instrument ioda and full name + # --------------------------------- + ioda_name = observation + full_name = ioda_name_to_long_name(ioda_name, self.logger) + + # Create dictionary used to override the eva config + # ------------------------------------------------- + eva_override = {} + eva_override['cycle_dir'] = self.cycle_dir() + eva_override['obs_path_file_1'] = obs_path_file_1 + eva_override['obs_path_file_2'] = obs_path_file_2 + eva_override['instrument'] = ioda_name + eva_override['instrument_title'] = full_name + eva_override['simulated_variables'] = \ + observation_dict_1['obs space']['simulated variables'] + eva_override['map_projection'] = 'plcarr' + eva_override['domain'] = 'global' + + # If filename contains icec_ change map projection to polar stereographic + # ----------------------------------------------------------------------- + if 'icec_' in obs_file_1: + eva_override['map_projection'] = 'npstere' + eva_override['domain'] = 'north' + + # if file name has 'south" or "sh" then change to south polar stereographic + # --------------------------------------------------------------- + if 'south' in obs_file_1 or 'sh' in obs_file_1: + eva_override['map_projection'] = 'spstere' + eva_override['domain'] = 'south' + + # # Check if the "passivate" condition exists within the "obs filters" list + passivate_exists = any( + filter_item.get('action', {}).get('name') == 'passivate' + for filter_item in observation_dict_1.get('obs filters', []) + ) + + if passivate_exists: + self.logger.info("Condition 'passivate' exists in 'obs filters'") + eva_override['passivated_variables'] = True + + if 'channels' in observation_dict_1['obs space']: + need_channels = True + if observation in channels_to_plot: + eva_override['channels'] = channels_to_plot[observation] + else: + eva_override['channels'] = observation_dict_1['obs space']['channels'] + else: + need_channels = False + eva_override['channels'] = '' + eva_override['channel'] = '' + + # Override the eva dictionary + # --------------------------- + eva_str = template_string_jinja2(self.logger, eva_str_template, eva_override) + eva_dict = yaml.safe_load(eva_str) + + # Remove channel keys if not needed + # --------------------------------- + if not need_channels: + remove_matching_keys(eva_dict, 'channel') + remove_matching_keys(eva_dict, 'channels') + eva_dict = replace_string_in_dictionary(eva_dict, '${channel}', '') + + # Write eva dictionary to file + # ---------------------------- + conf_output = os.path.join(self.cycle_dir(), 'eva', ioda_name, ioda_name+'_eva.yaml') + os.makedirs(os.path.dirname(conf_output), exist_ok=True) + with open(conf_output, 'w') as outfile: + yaml.dump(eva_dict, outfile, default_flow_style=False) + + # Add eva dictionary to list + # -------------------------- + eva_dicts.append(eva_dict) + + # Call eva in parallel + # -------------------- + with Pool(processes=number_of_workers) as pool: + pool.map(run_eva, eva_dicts) From 37b668f8c4f8fbe1f8ea1f2913821cd128556e10 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 1 Dec 2025 14:14:14 -0500 Subject: [PATCH 02/51] Add obs file --- ...rvations-3dfgat_atmos_geos_atmosphere.yaml | 1244 +++++++++++++++++ 1 file changed, 1244 insertions(+) create mode 100644 src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml new file mode 100644 index 000000000..3bee03c45 --- /dev/null +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml @@ -0,0 +1,1244 @@ +datasets: + +- name: experiment_1 + type: IodaObsSpace + filenames: + - {{obs_path_file_1}} + channels: &channels {{channels}} + groups: + - name: ObsValue + variables: &variables {{simulated_variables}} + - name: GsiHofXBc + - name: GsiEffectiveQC + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: EffectiveQC0 + - name: EffectiveQC1 + - name: MetaData + - name: GsiFinalObsError + - name: EffectiveError1 + +- name: experiment_2 + type: IodaObsSpace + filenames: + - {{obs_path_file_2}} + channels: &channels {{channels}} + groups: + - name: ObsValue + variables: &variables {{simulated_variables}} + - name: GsiHofXBc + - name: GsiEffectiveQC + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: EffectiveQC0 + - name: EffectiveQC1 + - name: MetaData + - name: GsiFinalObsError + - name: EffectiveError1 + +transforms: + +# Generate hofx0 for GSI 1 +- transform: arithmetic + new name: experiment_1::ObsValueMinusGsiHofXBc::${variable} + equals: experiment_1::ObsValue::${variable}-experiment_1::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx0 for GSI 2 +- transform: arithmetic + new name: experiment_2::ObsValueMinusGsiHofXBc::${variable} + equals: experiment_2::ObsValue::${variable}-experiment_2::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx0 for JEDI 1 +- transform: arithmetic + new name: experiment_1::ObsValueMinusHofx0::${variable} + equals: experiment_1::ObsValue::${variable}-experiment_1::hofx0::${variable} + for: + variable: *variables + +# Generate hofx0 for JEDI 2 +- transform: arithmetic + new name: experiment_2::ObsValueMinusHofx0::${variable} + equals: experiment_2::ObsValue::${variable}-experiment_2::hofx0::${variable} + for: + variable: *variables + +# Generate hofx difference 1 +- transform: arithmetic + new name: experiment_1::Hofx0MinusGsiHofXBc::${variable} + equals: experiment_1::hofx0::${variable}-experiment_1::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx difference 2 +- transform: arithmetic + new name: experiment_2::Hofx0MinusGsiHofXBc::${variable} + equals: experiment_2::hofx0::${variable}-experiment_2::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::hofx0PassedQc::${variable} + starting field: experiment_1::hofx0::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::hofx0PassedQc::${variable} + starting field: experiment_2::hofx0::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate GSI hofx that passed JEDI QC 1 +- transform: accept where + new name: experiment_1::GsiHofXBcPassedQc::${variable} + starting field: experiment_1::GsiHofXBc::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate GSI hofx that passed JEDI QC 2 +- transform: accept where + new name: experiment_2::GsiHofXBcPassedQc::${variable} + starting field: experiment_2::GsiHofXBc::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ObsValueMinushofx0PassedQc::${variable} + starting field: experiment_1::ObsValueMinusHofx0::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ObsValueMinushofx0PassedQc::${variable} + starting field: experiment_2::ObsValueMinusHofx0::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx difference passed GSI QC 1 +- transform: accept where + new name: experiment_1::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} + starting field: experiment_1::Hofx0MinusGsiHofXBc::${variable} + where: + - experiment_1::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate hofx difference passed GSI QC 2 +- transform: accept where + new name: experiment_2::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} + starting field: experiment_2::Hofx0MinusGsiHofXBc::${variable} + where: + - experiment_2::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate GSI OmF passed GSI QC 1 +- transform: accept where + new name: experiment_1::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} + starting field: experiment_1::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_1::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate GSI OmF passed GSI QC 2 +- transform: accept where + new name: experiment_2::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} + starting field: experiment_2::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_2::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for GSI 1 +- transform: accept where + new name: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} + starting field: experiment_1::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for GSI 2 +- transform: accept where + new name: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} + starting field: experiment_2::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ombgPassedQc::${variable} + starting field: experiment_1::ombg::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ombgPassedQc::${variable} + starting field: experiment_2::ombg::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::omanPassedQc::${variable} + starting field: experiment_1::oman::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::omanPassedQc::${variable} + starting field: experiment_2::oman::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed JEDI QC 1 +- transform: accept where + new name: experiment_1::JediFinalObsErrorPassedQc::${variable} + starting field: experiment_1::EffectiveError1::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed JEDI QC 2 +- transform: accept where + new name: experiment_2::JediFinalObsErrorPassedQc::${variable} + starting field: experiment_2::EffectiveError1::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate GSI final obserror that passed JEDI QC 1 +- transform: accept where + new name: experiment_1::GsiFinalObsErrorPassedQc::${variable} + starting field: experiment_1::GsiFinalObsError::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate GSI final obserror that passed JEDI QC 2 +- transform: accept where + new name: experiment_2::GsiFinalObsErrorPassedQc::${variable} + starting field: experiment_2::GsiFinalObsError::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed GSI QC 1 +- transform: accept where + new name: experiment_1::JediFinalObsErrorPassedGsiQc::${variable} + starting field: experiment_1::EffectiveError1::${variable} + where: + - experiment_1::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed GSI QC 2 +- transform: accept where + new name: experiment_2::JediFinalObsErrorPassedGsiQc::${variable} + starting field: experiment_2::EffectiveError1::${variable} + where: + - experiment_2::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed GSI QC 1 +- transform: accept where + new name: experiment_1::GsiFinalObsErrorPassedGsiQc::${variable} + starting field: experiment_1::GsiFinalObsError::${variable} + where: + - experiment_1::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed GSI QC 2 +- transform: accept where + new name: experiment_2::GsiFinalObsErrorPassedGsiQc::${variable} + starting field: experiment_2::GsiFinalObsError::${variable} + where: + - experiment_2::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate obs contribution to analysis (OmA*OmA)-(OmB*OmB) 1 +- transform: arithmetic + new name: experiment_1::ResidualRMSdiff::${variable} + equals: (experiment_1::omanPassedQc::${variable})*(experiment_1::omanPassedQc::${variable})-(experiment_1::ombgPassedQc::${variable})*(experiment_1::ombgPassedQc::${variable}) + for: + variable: *variables + +# Generate obs contribution to analysis (OmA*OmA)-(OmB*OmB) 2 +- transform: arithmetic + new name: experiment_2::ResidualRMSdiff::${variable} + equals: (experiment_2::omanPassedQc::${variable})*(experiment_2::omanPassedQc::${variable})-(experiment_2::ombgPassedQc::${variable})*(experiment_2::ombgPassedQc::${variable}) + for: + variable: *variables + +graphics: + + plotting_backend: Emcpy + figure_list: + + # Correlation scatter plots + # ------------------------- + + # JEDI h(x) vs Observations + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation Value 1' + add_ylabel: 'JEDI h(x) 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI)' + + - add_xlabel: 'Observation Value 2' + add_ylabel: 'JEDI h(x) 2' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI)' + + # GSI h(x) vs Observations + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'Observations vs. GSI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation Value 1' + add_ylabel: 'GSI h(x) 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::GsiHofXBc::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::GsiHofXBcPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI h(x) versus obs (passed QC in JEDI)' + + plots: + - add_xlabel: 'Observation Value 2' + add_ylabel: 'GSI h(x) 2' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::GsiHofXBc::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::GsiHofXBcPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI h(x) versus obs (passed QC in JEDI)' + + # JEDI h(x) vs GSI h(x) + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'JEDI h(x) vs. GSI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx_vs_jedi0_hofx_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GSI h(x) 1' + add_ylabel: 'JEDI h(x) 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::GsiHofXBc::${variable} + y: + variable: experiment_1::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus GSI h(x)' + - type: Scatter + x: + variable: experiment_1::GsiHofXBcPassedQc::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' + + - add_xlabel: 'GSI h(x) 2' + add_ylabel: 'JEDI h(x) 2' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::GsiHofXBc::${variable} + y: + variable: experiment_2::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus GSI h(x)' + - type: Scatter + x: + variable: experiment_2::GsiHofXBcPassedQc::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' + + # JEDI hofx0 vs GSI hofx0 + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GSI observation minus h(x) 1' + add_ylabel: 'JEDI observation minus h(x) 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + y: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI hofx0 vs JEDI hofx0 (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} + y: + variable: experiment_1::ObsValueMinushofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' + + - add_xlabel: 'GSI observation minus h(x) 2' + add_ylabel: 'JEDI observation minus h(x) 2' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + y: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI hofx0 vs JEDI hofx0 (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} + y: + variable: experiment_2::ObsValueMinushofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' + + # JEDI-GSI hofx0 differences vs GSI Obs-hofx0 + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'hofx0 difference vs. GSI Obs-hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_diff_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GSI observation minus h(x) 1' + add_ylabel: 'JEDI h(x) minus GSI h(x) 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} + y: + variable: experiment_1::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: '(JEDI hofx0 - GSI hofx0) vs GSI Obs-hofx0 (passed GSI QC)' + + - add_xlabel: 'GSI observation minus h(x) 2' + add_ylabel: 'JEDI h(x) minus GSI h(x) 2' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} + y: + variable: experiment_2::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: '(JEDI hofx0 - GSI hofx0) vs GSI Obs-hofx0 (passed GSI QC)' + + # JEDI oma vs omb + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'OmA vs. OmB | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_oma_vs_omb_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'OmA 1' + add_ylabel: 'OmB 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::oman::${variable} + y: + variable: experiment_1::ombg::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'OmA versus OmB (all residuals) 1' + - type: Scatter + x: + variable: experiment_1::omanPassedQc::${variable} + y: + variable: experiment_1::ombgPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'OmA versus OmB (passed QC) 1' + + - add_xlabel: 'OmA 1' + add_ylabel: 'OmB 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::oman::${variable} + y: + variable: experiment_2::ombg::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'OmA versus OmB (all residuals) 2' + - type: Scatter + x: + variable: experiment_2::omanPassedQc::${variable} + y: + variable: experiment_2::ombgPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'OmA versus OmB (passed QC) 2' + + # JediFinalObsError vs GsiObsFinalObsError + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'Jedi ObsError vs. GSI ObsError | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/JediObsError_vs_GsiObsError_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GsiFinalObsError' + add_ylabel: 'JediFinalObsError' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::GsiFinalObsError::${variable} + y: + variable: experiment_1::EffectiveError1::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JediObsError versus GsiObsError (all residuals) 1' + - type: Scatter + x: + variable: experiment_1::GsiFinalObsErrorPassedQc::${variable} + y: + variable: experiment_1::JediFinalObsErrorPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JediObsError versus GsiObsError (passed Jedi QC) 1' + + - add_xlabel: 'GsiFinalObsError' + add_ylabel: 'JediFinalObsError' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::GsiFinalObsError::${variable} + y: + variable: experiment_2::EffectiveError1::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JediObsError versus GsiObsError (all residuals) 2' + - type: Scatter + x: + variable: experiment_2::GsiFinalObsErrorPassedQc::${variable} + y: + variable: experiment_2::JediFinalObsErrorPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JediObsError versus GsiObsError (passed Jedi QC) 2' + + # JediFinalObsError vs GsiObsFinalObsError (all & passed GSI QC) + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'Jedi ObsError vs. GSI ObsError | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/JediObsError_vs_GsiObsError_{{instrument}}_${variable}${channel}_b.png' + plots: + - add_xlabel: 'GsiFinalObsError' + add_ylabel: 'JediFinalObsError' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::GsiFinalObsError::${variable} + y: + variable: experiment_1::EffectiveError1::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JediObsError versus GsiObsError (all residuals) 1' + - type: Scatter + x: + variable: experiment_1::GsiFinalObsErrorPassedGsiQc::${variable} + y: + variable: experiment_1::JediFinalObsErrorPassedGsiQc::${variable} + channel: ${channel} + markersize: 5 + color: 'blue' + label: 'JediObsError versus GsiObsError (Passed GSI QC) 1' + + - add_xlabel: 'GsiFinalObsError' + add_ylabel: 'JediFinalObsError' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::GsiFinalObsError::${variable} + y: + variable: experiment_2::EffectiveError1::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JediObsError versus GsiObsError (all residuals) 2' + - type: Scatter + x: + variable: experiment_2::GsiFinalObsErrorPassedGsiQc::${variable} + y: + variable: experiment_2::JediFinalObsErrorPassedGsiQc::${variable} + channel: ${channel} + markersize: 5 + color: 'blue' + label: 'JediObsError versus GsiObsError (Passed GSI QC) 2' + +# Map plots +# --------- + + # Observations + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValue::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'Observations | {{instrument_title}} | Obs Value' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/observations_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment+1::ObsValue::${variable} + channel: ${channel} + markersize: 2 + label: ObsValue 1 + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValue::${variable} + channel: ${channel} + markersize: 2 + label: ObsValue 2 + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx0 jedi + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValueMinusHofx0::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'JEDI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_jedi_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 1' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 2' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx0 gsi + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_gsi_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 1' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 2' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx difference + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'Hofx0 Difference | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_difference_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 1' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::Hofx0MinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 2' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # RMS(oma)-RMS(omb) difference + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ResidualRMSdiff::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'RMS Residual Difference | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/rmsres_difference_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ResidualRMSdiff::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 1' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ResidualRMSdiff::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 2' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + +# Histogram plots +# --------------- + + # hofx0 vs hofx0 + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: histogram_bins + channel: ${channel} + number of bins rule: sturges + data variable: experiment_1::ObsValueMinusHofx0::${variable} + figure: + layout: [2,1] + title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation minus h(x)' + add_ylabel: 'Count' + add_legend: + loc: 'upper left' + layers: + - type: Histogram + data: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + color: 'blue' + label: 'GSI hofx0 (all obs) 1' + bins: ${dynamic_bins} + alpha: 0.5 + - type: Histogram + data: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + color: 'red' + label: 'JEDI hofx0 (all obs) 1' + bins: ${dynamic_bins} + alpha: 0.5 + + - add_xlabel: 'Observation minus h(x)' + add_ylabel: 'Count' + add_legend: + loc: 'upper left' + layers: + - type: Histogram + data: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + color: 'blue' + label: 'GSI hofx0 (all obs) 2' + bins: ${dynamic_bins} + alpha: 0.5 + - type: Histogram + data: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + color: 'red' + label: 'JEDI hofx0 (all obs) 2' + bins: ${dynamic_bins} + alpha: 0.5 + + # JEDI omb vs oma + - batch figure: + variables: *variables + dynamic options: + - type: histogram_bins + data variable: experiment::omanPassedQc::${variable} + number of bins rule: 'rice' + figure: + layout: [2,1] + title: 'OmB vs. OmA | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}/ombg_oman_{{instrument}}_${variable}.png' + plots: + - add_xlabel: 'Difference' + add_ylabel: 'Count' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_1::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_1::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_1::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background 1' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_1::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis 1' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + - add_xlabel: 'Difference' + add_ylabel: 'Count' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_2::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_2::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_2::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background 2' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_2::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis 2' + bins: ${dynamic_bins} + alpha: 0.5 + density: true \ No newline at end of file From 9e7d0216150a965136161ad74d1b281f5051bb7d Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 1 Dec 2025 14:15:11 -0500 Subject: [PATCH 03/51] fixes --- .../tasks/eva_comparison_observations.py | 20 +++++++++---------- src/swell/tasks/task_questions.py | 9 +++++++++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index e5d9c49dd..a7df58671 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -9,7 +9,7 @@ from multiprocessing import Pool -import osq +import os import yaml from eva.eva_driver import eva @@ -32,16 +32,10 @@ def run_eva(eva_dict: dict) -> eva: # -------------------------------------------------------------------------------------------------- -class EvaObservations(taskBase): +class EvaComparisonObservations(taskBase): def execute(self) -> None: - # Compute window beginning time - # ----------------------------- - window_begin = self.da_window_params.window_begin(self.config.window_offset()) - background_time = self.da_window_params.background_time(self.config.window_offset(), - self.config.background_time_offset() - ) # Comparison log type # ------------------- @@ -55,19 +49,25 @@ def execute(self) -> None: with open(experiment_path_1, 'r') as f: experiment_config_1 = yaml.safe_load(f) + window_offset = experiment_config_1['models'][self.get_model()]['window_offset'] + background_time_offset = experiment_config_1['models'][self.get_model()]['background_time_offset'] with open(experiment_path_2, 'r') as f: experiment_config_2 = yaml.safe_load(f) + window_begin = self.da_window_params.window_begin(window_offset) + background_time = self.da_window_params.background_time(window_offset, + background_time_offset) + jedi_config_file_1 = os.path.join(os.path.dirname(experiment_path_1), '..', 'run', - self.cycle_time(), self.get_model(), f'jedi_{log_type}_config.yaml') + self.__datetime__.string_directory(), self.get_model(), f'jedi_{log_type}_config.yaml') with open(jedi_config_file_1, 'r') as f: jedi_config = yaml.safe_load(f) obs_config_1 = jedi_config['cost function']['observations']['observers'] jedi_config_file_2 = os.path.join(os.path.dirname(experiment_path_2), '..', 'run', - self.cycle_time(), self.get_model(), f'jedi_{log_type}_config.yaml') + self.__datetime__.string_directory(), self.get_model(), f'jedi_{log_type}_config.yaml') with open(jedi_config_file_2, 'r') as f: jedi_config = yaml.safe_load(f) diff --git a/src/swell/tasks/task_questions.py b/src/swell/tasks/task_questions.py index da0136b5f..5205dda50 100644 --- a/src/swell/tasks/task_questions.py +++ b/src/swell/tasks/task_questions.py @@ -193,6 +193,15 @@ class TaskQuestions(QuestionContainer, Enum): # -------------------------------------------------------------------------------------------------- + EvaComparisonObservations = QuestionList( + list_name="EvaComparisonObservations", + questions=[ + qd.comparison_log_type(), + ] + ) + + # -------------------------------------------------------------------------------------------------- + EvaIncrement = QuestionList( list_name="EvaIncrement", questions=[ From 357ad7b3b2a596e712323c45c22b940ad12d24dc Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 1 Dec 2025 17:24:54 -0500 Subject: [PATCH 04/51] Fixes --- ..._observations-3dfgat_atmos_geos_atmosphere.yaml | 6 +++--- src/swell/tasks/eva_comparison_observations.py | 14 ++++++++------ src/swell/tasks/task_questions.py | 1 + 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml index 3bee03c45..8805f7ee6 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml @@ -24,10 +24,10 @@ datasets: type: IodaObsSpace filenames: - {{obs_path_file_2}} - channels: &channels {{channels}} + channels: *channels groups: - name: ObsValue - variables: &variables {{simulated_variables}} + variables: *variables - name: GsiHofXBc - name: GsiEffectiveQC - name: hofx0 @@ -1241,4 +1241,4 @@ graphics: label: 'observations minus analysis 2' bins: ${dynamic_bins} alpha: 0.5 - density: true \ No newline at end of file + density: true diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index a7df58671..257416a9f 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -85,6 +85,7 @@ def execute(self) -> None: model = self.get_model() eva_path = os.path.join(self.experiment_path(), self.experiment_id()+'-suite', 'eva') eva_config_file = os.path.join(eva_path, f'observations-{model}.yaml') + eva_config_file = '/home/manstett/swell-main/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml' with open(eva_config_file, 'r') as eva_config_file_open: eva_str_template = eva_config_file_open.read() @@ -114,13 +115,14 @@ def execute(self) -> None: for observation in self.config.observations(): observation_dict_1 = None - for key, value in obs_config_1.items(): - if value['name'] == observation: + for value in obs_config_1: + print(value.keys()) + if value['obs space']['name'] == observation: observation_dict_1 = value observation_dict_2 = None - for key, value in obs_config_2.items(): - if value['name'] == observation: + for value in obs_config_2: + if value['obs space']['name'] == observation: observation_dict_2 = value if observation_dict_1 is None or observation_dict_2 is None: @@ -139,11 +141,11 @@ def execute(self) -> None: continue # Split the full path into path and filename - obs_path_file_1 = observation_dict_1['obsdataout']['engine']['obsfile'] + obs_path_file_1 = observation_dict_1['obs space']['obsdataout']['engine']['obsfile'] cycle_dir_1, obs_file_1 = os.path.split(obs_path_file_1) # Split the full path into path and filename - obs_path_file_2 = observation_dict_2['obsdataout']['engine']['obsfile'] + obs_path_file_2 = observation_dict_2['obs space']['obsdataout']['engine']['obsfile'] cycle_dir_2, obs_file_2 = os.path.split(obs_path_file_2) # Check for need to add 0000 to the file diff --git a/src/swell/tasks/task_questions.py b/src/swell/tasks/task_questions.py index 5205dda50..29beaf963 100644 --- a/src/swell/tasks/task_questions.py +++ b/src/swell/tasks/task_questions.py @@ -197,6 +197,7 @@ class TaskQuestions(QuestionContainer, Enum): list_name="EvaComparisonObservations", questions=[ qd.comparison_log_type(), + qd.observations(), ] ) From 65ef17fe3279ae18453855269f9f3a6674776bb0 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 3 Dec 2025 12:49:57 -0500 Subject: [PATCH 05/51] add diff plot --- ...rvations-3dfgat_atmos_geos_atmosphere.yaml | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml index 8805f7ee6..e99c4fae9 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml @@ -102,6 +102,13 @@ transforms: for: variable: *variables +# Generate hofx that passed QC for JEDI diff +- transform: arithmetic + new name: experiment_2::hofx0PassedQc::${variable}_diff + equals: (experiment_1::hofx0PassedQc::${variable} - experiment_2::hofx0PassedQc::${variable}) + for: + variable: *variables + # Generate GSI hofx that passed JEDI QC 1 - transform: accept where new name: experiment_1::GsiHofXBcPassedQc::${variable} @@ -314,6 +321,13 @@ transforms: for: variable: *variables +# Arithmetic transforms for differences +- transform: arithmetic + new name: experiment_2::ObsValue::${variable}_diff + equals: (experiment_1::ObsValue::${variable} - experiment::ObsValue::${variable}) + for: + variable: *variables + graphics: plotting_backend: Emcpy @@ -327,7 +341,7 @@ graphics: variables: *variables channels: *channels figure: - layout: [2,1] + layout: [3,1] title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' plots: @@ -381,6 +395,32 @@ graphics: color: 'red' label: 'JEDI h(x) versus obs (passed QC in JEDI)' + + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x) diff (1-2)' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0::${variable}_diff + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable}_diff + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI) diff (1-2)' + # GSI h(x) vs Observations - batch figure: variables: *variables From 6b9353dc77f9b2b8902dcfce2f0f5c966a11086d Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 3 Dec 2025 12:51:56 -0500 Subject: [PATCH 06/51] Fixes --- ...servations-3dfgat_atmos_geos_atmosphere.yaml | 5 ++--- src/swell/tasks/eva_comparison_observations.py | 17 +++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml index 8805f7ee6..3c46e99ad 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml @@ -415,7 +415,6 @@ graphics: color: 'red' label: 'GSI h(x) versus obs (passed QC in JEDI)' - plots: - add_xlabel: 'Observation Value 2' add_ylabel: 'GSI h(x) 2' add_grid: @@ -808,7 +807,7 @@ graphics: latitude: variable: experiment_1::MetaData::latitude data: - variable: experiment+1::ObsValue::${variable} + variable: experiment_1::ObsValue::${variable} channel: ${channel} markersize: 2 label: ObsValue 1 @@ -1146,7 +1145,7 @@ graphics: variables: *variables dynamic options: - type: histogram_bins - data variable: experiment::omanPassedQc::${variable} + data variable: experiment_1::omanPassedQc::${variable} number of bins rule: 'rice' figure: layout: [2,1] diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index 257416a9f..7aab45ace 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -20,6 +20,7 @@ from swell.utilities.jinja2 import template_string_jinja2 from swell.utilities.observations import ioda_name_to_long_name from swell.utilities.run_jedi_executables import check_obs +from swell.utilities.observations import ioda_name_to_long_name # -------------------------------------------------------------------------------------------------- @@ -113,17 +114,17 @@ def execute(self) -> None: self.jedi_rendering.set_obs_records_path(self.config.observing_system_records_path(None)) for observation in self.config.observations(): - + obs_long_name = ioda_name_to_long_name(observation, self.logger) observation_dict_1 = None + for value in obs_config_1: - print(value.keys()) - if value['obs space']['name'] == observation: - observation_dict_1 = value + if value['obs space']['name'] == obs_long_name: + observation_dict_1 = value.copy() observation_dict_2 = None for value in obs_config_2: - if value['obs space']['name'] == observation: - observation_dict_2 = value + if value['obs space']['name'] == obs_long_name: + observation_dict_2 = value.copy() if observation_dict_1 is None or observation_dict_2 is None: continue @@ -133,8 +134,8 @@ def execute(self) -> None: observation_dict_1, self.cycle_time_dto(), input_and_output=True) use_obs_2 = check_obs(self.jedi_rendering.observing_system_records_path, observation, - observation_dict_1, self.cycle_time_dto(), input_and_output=True) - + observation_dict_2, self.cycle_time_dto(), input_and_output=True) + use_obs = use_obs_1 and use_obs_2 if not use_obs: From 53b3c3a0242e5f2a490687cee3fa4658fd41ba3b Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 3 Dec 2025 13:18:37 -0500 Subject: [PATCH 07/51] Fix yaml --- ...arison_observations-3dfgat_atmos_geos_atmosphere.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml index 299830159..33b4ac40a 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml @@ -324,7 +324,14 @@ transforms: # Arithmetic transforms for differences - transform: arithmetic new name: experiment_2::ObsValue::${variable}_diff - equals: (experiment_1::ObsValue::${variable} - experiment::ObsValue::${variable}) + equals: (experiment_1::ObsValue::${variable} - experiment_2::ObsValue::${variable}) + for: + variable: *variables + +# Arithmetic transforms for differences +- transform: arithmetic + new name: experiment_2::hofx0::${variable}_diff + equals: (experiment_1::hofx0::${variable} - experiment_2::hofx0::${variable}) for: variable: *variables From 21efed54b94327c2772e8f012be4300c5ff49294 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Thu, 4 Dec 2025 11:40:09 -0500 Subject: [PATCH 08/51] Add 3dfgat_cycle --- ...observations-3dfgat_cycle-geos_marine.yaml | 715 ++++++++++++++++++ 1 file changed, 715 insertions(+) create mode 100644 src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml new file mode 100644 index 000000000..d918fe6bc --- /dev/null +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml @@ -0,0 +1,715 @@ +datasets: + +- name: experiment_1 + type: IodaObsSpace + filenames: + - {{obs_path_file}} + groups: + - name: ObsValue + variables: &variables {{simulated_variables}} + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: MetaData + - name: EffectiveQC0 + - name: EffectiveQC1 + +- name: experiment_2 + type: IodaObsSpace + filenames: + - {{obs_path_file}} + groups: + - name: ObsValue + variables: &variables {{simulated_variables}} + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: MetaData + - name: EffectiveQC0 + - name: EffectiveQC1 + + +transforms: + +# Generate Increment for JEDI 1 +- transform: arithmetic + new name: experiment_1::increment::${variable} + equals: experiment_1::ombg::${variable}-experiment_1::oman::${variable} + for: + variable: *variables + +# Generate Increment for JEDI 2 +- transform: arithmetic + new name: experiment_2::increment::${variable} + equals: experiment_2::ombg::${variable}-experiment_2::oman::${variable} + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::hofx0PassedQc::${variable} + starting field: experiment_1::hofx0::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::hofx0PassedQc::${variable} + starting field: experiment_2::hofx0::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx1 that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::hofx1PassedQc::${variable} + starting field: experiment_1::hofx1::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate hofx1 that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::hofx1PassedQc::${variable} + starting field: experiment_2::hofx1::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ombgPassedQc::${variable} + starting field: experiment_1::ombg::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ombgPassedQc::${variable} + starting field: experiment_2::ombg::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::omanPassedQc::${variable} + starting field: experiment_1::oman::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::omanPassedQc::${variable} + starting field: experiment_2::oman::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate passivated ombg that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::PassiveombgPassedQc::${variable} + starting field: experiment_1::ombg::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 1 + for: + variable: *variables + +# Generate passivated ombg that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::PassiveombgPassedQc::${variable} + starting field: experiment_2::ombg::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 1 + for: + variable: *variables + +# Generate passivated oman that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::PassiveomanPassedQc::${variable} + starting field: experiment_1::oman::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 1 + for: + variable: *variables + +# Generate passivated oman that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::PassiveomanPassedQc::${variable} + starting field: experiment_2::oman::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 1 + for: + variable: *variables + +# Generate obs that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ObsValuePassedQc::${variable} + starting field: experiment_1::ObsValue::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate obs that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ObsValuePassedQc::${variable} + starting field: experiment_2::ObsValue::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +graphics: + + plotting_backend: Emcpy + figure_list: + + # Correlation scatter plots + # ------------------------- + + # JEDI h(x) vs Observations + - batch figure: + variables: *variables + figure: + layout: [2,1] + title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}/jedi_hofx_vs_obs_{{instrument}}_${variable}.png' + plots: + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x) 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx1::${variable} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI)' + + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x) 2' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx1::${variable} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI)' + + # Histogram plots + # --------------- + + # JEDI h(x) vs Observations + - batch figure: + variables: *variables + dynamic options: + - type: histogram_bins + data variable: experiment::omanPassedQc::${variable} + number of bins rule: 'rice' + figure: + layout: [2,1] + title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histogram/${variable}/ombg_oman_{{instrument}}_${variable}.png' + plots: + - add_xlabel: 'Difference' + add_ylabel: 'Count' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_1::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'blue' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_1::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + + layers: + - type: Histogram + data: + variable: experiment_1::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_1::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + - add_xlabel: 'Difference' + add_ylabel: 'Count' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_2::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'blue' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_2::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + + layers: + - type: Histogram + data: + variable: experiment_2::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_2::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + # Passivated OmBg and OmA + - batch figure: + variables: *variables + dynamic options: + - type: histogram_bins + data variable: experiment_1::PassiveomanPassedQc::${variable} + number of bins rule: 'rice' + figure: + layout: [2,1] + title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histogram/${variable}/pass_ombg_oman_{{instrument}}_${variable}.png' + plots: + - add_xlabel: 'Difference' + add_ylabel: 'Count 1' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_1::PassiveomanPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'blue' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_1::PassiveombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + + layers: + - type: Histogram + data: + variable: experiment_1::PassiveombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_1::PassiveomanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + - add_xlabel: 'Difference' + add_ylabel: 'Count 2' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_2::PassiveomanPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'blue' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_2::PassiveombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + + layers: + - type: Histogram + data: + variable: experiment_2::PassiveombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_2::PassiveomanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + # Map plots + # --------- + # Increment + - batch figure: + variables: *variables + dynamic options: + - type: vminvmaxcmap + data variable: experiment::ombgPassedQc::${variable} + figure: + figure size: [20,10] + layout: [4,1] + title: '{{instrument_title}} | Passed QC' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/ombg_oman_{{instrument}}_${variable}.png' + plots: + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ombgPassedQc::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::omanPassedQc::${variable} + markersize: 2 + label: OmBg + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ombgPassedQc::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::omanPassedQc::${variable} + markersize: 2 + label: OmBg + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - batch figure: + variables: *variables + dynamic options: + - type: vminvmaxcmap + data variable: experiment_1::EffectiveQC1::${variable} + figure: + figure size: [20,10] + layout: [1,1] + title: '{{instrument_title}} | Passed QC' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/effectiveQC_{{instrument}}_${variable}.png' + plots: + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: EffectiveQC1 + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::EffectiveQC1::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - batch figure: + variables: *variables + dynamic options: + - type: vminvmaxcmap + data variable: experiment_2::increment::${variable} + figure: + figure size: [20,10] + layout: [1,1] + title: '{{instrument_title}} | Passed QC' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/increment_{{instrument}}_${variable}.png' + plots: + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: Increment (OmBg - OmAn) + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::increment::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # Passivate + - batch figure: + variables: *variables + dynamic options: + - type: vminvmaxcmap + data variable: experiment_1::PassiveombgPassedQc::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: '{{instrument_title}} | Passed QC' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/passive_ombg_oman_{{instrument}}_${variable}.png' + plots: + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::PassiveombgPassedQc::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::PassiveomanPassedQc::${variable} + markersize: 2 + label: OmBg + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::PassiveombgPassedQc::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::PassiveomanPassedQc::${variable} + markersize: 2 + label: OmBg + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} \ No newline at end of file From 3e0f532530a1782f7933f9056256c70465404e77 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Fri, 5 Dec 2025 09:26:22 -0500 Subject: [PATCH 09/51] switch file --- src/swell/tasks/eva_comparison_observations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index 7aab45ace..3a1443ee5 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -86,7 +86,7 @@ def execute(self) -> None: model = self.get_model() eva_path = os.path.join(self.experiment_path(), self.experiment_id()+'-suite', 'eva') eva_config_file = os.path.join(eva_path, f'observations-{model}.yaml') - eva_config_file = '/home/manstett/swell-main/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml' + eva_config_file = '/home/manstett/swell-main/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle_geos_marine.yaml' with open(eva_config_file, 'r') as eva_config_file_open: eva_str_template = eva_config_file_open.read() From 9a09c784303ace915fa303d9db482ef53a1582fa Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Fri, 5 Dec 2025 12:53:36 -0500 Subject: [PATCH 10/51] remove window_offset --- src/swell/tasks/eva_comparison_observations.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index 3a1443ee5..c6f8b6cce 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -50,15 +50,15 @@ def execute(self) -> None: with open(experiment_path_1, 'r') as f: experiment_config_1 = yaml.safe_load(f) - window_offset = experiment_config_1['models'][self.get_model()]['window_offset'] + window_length = experiment_config_1['models'][self.get_model()]['window_length'] + window_offset = self.da_window_params.window_offset(window_length) background_time_offset = experiment_config_1['models'][self.get_model()]['background_time_offset'] with open(experiment_path_2, 'r') as f: experiment_config_2 = yaml.safe_load(f) window_begin = self.da_window_params.window_begin(window_offset) - background_time = self.da_window_params.background_time(window_offset, - background_time_offset) + background_time = self.da_window_params.background_time(background_time_offset) jedi_config_file_1 = os.path.join(os.path.dirname(experiment_path_1), '..', 'run', self.__datetime__.string_directory(), self.get_model(), f'jedi_{log_type}_config.yaml') @@ -86,7 +86,7 @@ def execute(self) -> None: model = self.get_model() eva_path = os.path.join(self.experiment_path(), self.experiment_id()+'-suite', 'eva') eva_config_file = os.path.join(eva_path, f'observations-{model}.yaml') - eva_config_file = '/home/manstett/swell-main/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle_geos_marine.yaml' + eva_config_file = '/home/manstett/swell-main/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml' with open(eva_config_file, 'r') as eva_config_file_open: eva_str_template = eva_config_file_open.read() From dcda1d14ec49bd43f3c85aed487d3d9d14adf2a9 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Fri, 5 Dec 2025 13:44:41 -0500 Subject: [PATCH 11/51] working 3dfgat_cycle --- ...rvations-3dfgat_atmos-geos_atmosphere.yaml | 1290 +++++++++++++++++ ...observations-3dfgat_cycle-geos_marine.yaml | 65 +- .../tasks/eva_comparison_observations.py | 14 +- 3 files changed, 1354 insertions(+), 15 deletions(-) create mode 100644 src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml new file mode 100644 index 000000000..33b4ac40a --- /dev/null +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml @@ -0,0 +1,1290 @@ +datasets: + +- name: experiment_1 + type: IodaObsSpace + filenames: + - {{obs_path_file_1}} + channels: &channels {{channels}} + groups: + - name: ObsValue + variables: &variables {{simulated_variables}} + - name: GsiHofXBc + - name: GsiEffectiveQC + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: EffectiveQC0 + - name: EffectiveQC1 + - name: MetaData + - name: GsiFinalObsError + - name: EffectiveError1 + +- name: experiment_2 + type: IodaObsSpace + filenames: + - {{obs_path_file_2}} + channels: *channels + groups: + - name: ObsValue + variables: *variables + - name: GsiHofXBc + - name: GsiEffectiveQC + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: EffectiveQC0 + - name: EffectiveQC1 + - name: MetaData + - name: GsiFinalObsError + - name: EffectiveError1 + +transforms: + +# Generate hofx0 for GSI 1 +- transform: arithmetic + new name: experiment_1::ObsValueMinusGsiHofXBc::${variable} + equals: experiment_1::ObsValue::${variable}-experiment_1::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx0 for GSI 2 +- transform: arithmetic + new name: experiment_2::ObsValueMinusGsiHofXBc::${variable} + equals: experiment_2::ObsValue::${variable}-experiment_2::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx0 for JEDI 1 +- transform: arithmetic + new name: experiment_1::ObsValueMinusHofx0::${variable} + equals: experiment_1::ObsValue::${variable}-experiment_1::hofx0::${variable} + for: + variable: *variables + +# Generate hofx0 for JEDI 2 +- transform: arithmetic + new name: experiment_2::ObsValueMinusHofx0::${variable} + equals: experiment_2::ObsValue::${variable}-experiment_2::hofx0::${variable} + for: + variable: *variables + +# Generate hofx difference 1 +- transform: arithmetic + new name: experiment_1::Hofx0MinusGsiHofXBc::${variable} + equals: experiment_1::hofx0::${variable}-experiment_1::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx difference 2 +- transform: arithmetic + new name: experiment_2::Hofx0MinusGsiHofXBc::${variable} + equals: experiment_2::hofx0::${variable}-experiment_2::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::hofx0PassedQc::${variable} + starting field: experiment_1::hofx0::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::hofx0PassedQc::${variable} + starting field: experiment_2::hofx0::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx that passed QC for JEDI diff +- transform: arithmetic + new name: experiment_2::hofx0PassedQc::${variable}_diff + equals: (experiment_1::hofx0PassedQc::${variable} - experiment_2::hofx0PassedQc::${variable}) + for: + variable: *variables + +# Generate GSI hofx that passed JEDI QC 1 +- transform: accept where + new name: experiment_1::GsiHofXBcPassedQc::${variable} + starting field: experiment_1::GsiHofXBc::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate GSI hofx that passed JEDI QC 2 +- transform: accept where + new name: experiment_2::GsiHofXBcPassedQc::${variable} + starting field: experiment_2::GsiHofXBc::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ObsValueMinushofx0PassedQc::${variable} + starting field: experiment_1::ObsValueMinusHofx0::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ObsValueMinushofx0PassedQc::${variable} + starting field: experiment_2::ObsValueMinusHofx0::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx difference passed GSI QC 1 +- transform: accept where + new name: experiment_1::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} + starting field: experiment_1::Hofx0MinusGsiHofXBc::${variable} + where: + - experiment_1::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate hofx difference passed GSI QC 2 +- transform: accept where + new name: experiment_2::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} + starting field: experiment_2::Hofx0MinusGsiHofXBc::${variable} + where: + - experiment_2::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate GSI OmF passed GSI QC 1 +- transform: accept where + new name: experiment_1::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} + starting field: experiment_1::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_1::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate GSI OmF passed GSI QC 2 +- transform: accept where + new name: experiment_2::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} + starting field: experiment_2::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_2::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for GSI 1 +- transform: accept where + new name: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} + starting field: experiment_1::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for GSI 2 +- transform: accept where + new name: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} + starting field: experiment_2::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ombgPassedQc::${variable} + starting field: experiment_1::ombg::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ombgPassedQc::${variable} + starting field: experiment_2::ombg::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::omanPassedQc::${variable} + starting field: experiment_1::oman::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::omanPassedQc::${variable} + starting field: experiment_2::oman::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed JEDI QC 1 +- transform: accept where + new name: experiment_1::JediFinalObsErrorPassedQc::${variable} + starting field: experiment_1::EffectiveError1::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed JEDI QC 2 +- transform: accept where + new name: experiment_2::JediFinalObsErrorPassedQc::${variable} + starting field: experiment_2::EffectiveError1::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate GSI final obserror that passed JEDI QC 1 +- transform: accept where + new name: experiment_1::GsiFinalObsErrorPassedQc::${variable} + starting field: experiment_1::GsiFinalObsError::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate GSI final obserror that passed JEDI QC 2 +- transform: accept where + new name: experiment_2::GsiFinalObsErrorPassedQc::${variable} + starting field: experiment_2::GsiFinalObsError::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed GSI QC 1 +- transform: accept where + new name: experiment_1::JediFinalObsErrorPassedGsiQc::${variable} + starting field: experiment_1::EffectiveError1::${variable} + where: + - experiment_1::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed GSI QC 2 +- transform: accept where + new name: experiment_2::JediFinalObsErrorPassedGsiQc::${variable} + starting field: experiment_2::EffectiveError1::${variable} + where: + - experiment_2::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed GSI QC 1 +- transform: accept where + new name: experiment_1::GsiFinalObsErrorPassedGsiQc::${variable} + starting field: experiment_1::GsiFinalObsError::${variable} + where: + - experiment_1::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate jedi final obserror that passed GSI QC 2 +- transform: accept where + new name: experiment_2::GsiFinalObsErrorPassedGsiQc::${variable} + starting field: experiment_2::GsiFinalObsError::${variable} + where: + - experiment_2::GsiEffectiveQC::${variable} == 0 + for: + variable: *variables + +# Generate obs contribution to analysis (OmA*OmA)-(OmB*OmB) 1 +- transform: arithmetic + new name: experiment_1::ResidualRMSdiff::${variable} + equals: (experiment_1::omanPassedQc::${variable})*(experiment_1::omanPassedQc::${variable})-(experiment_1::ombgPassedQc::${variable})*(experiment_1::ombgPassedQc::${variable}) + for: + variable: *variables + +# Generate obs contribution to analysis (OmA*OmA)-(OmB*OmB) 2 +- transform: arithmetic + new name: experiment_2::ResidualRMSdiff::${variable} + equals: (experiment_2::omanPassedQc::${variable})*(experiment_2::omanPassedQc::${variable})-(experiment_2::ombgPassedQc::${variable})*(experiment_2::ombgPassedQc::${variable}) + for: + variable: *variables + +# Arithmetic transforms for differences +- transform: arithmetic + new name: experiment_2::ObsValue::${variable}_diff + equals: (experiment_1::ObsValue::${variable} - experiment_2::ObsValue::${variable}) + for: + variable: *variables + +# Arithmetic transforms for differences +- transform: arithmetic + new name: experiment_2::hofx0::${variable}_diff + equals: (experiment_1::hofx0::${variable} - experiment_2::hofx0::${variable}) + for: + variable: *variables + +graphics: + + plotting_backend: Emcpy + figure_list: + + # Correlation scatter plots + # ------------------------- + + # JEDI h(x) vs Observations + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [3,1] + title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation Value 1' + add_ylabel: 'JEDI h(x) 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI)' + + - add_xlabel: 'Observation Value 2' + add_ylabel: 'JEDI h(x) 2' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI)' + + + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x) diff (1-2)' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0::${variable}_diff + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable}_diff + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI) diff (1-2)' + + # GSI h(x) vs Observations + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'Observations vs. GSI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation Value 1' + add_ylabel: 'GSI h(x) 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::GsiHofXBc::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::GsiHofXBcPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI h(x) versus obs (passed QC in JEDI)' + + - add_xlabel: 'Observation Value 2' + add_ylabel: 'GSI h(x) 2' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::GsiHofXBc::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::GsiHofXBcPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI h(x) versus obs (passed QC in JEDI)' + + # JEDI h(x) vs GSI h(x) + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'JEDI h(x) vs. GSI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx_vs_jedi0_hofx_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GSI h(x) 1' + add_ylabel: 'JEDI h(x) 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::GsiHofXBc::${variable} + y: + variable: experiment_1::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus GSI h(x)' + - type: Scatter + x: + variable: experiment_1::GsiHofXBcPassedQc::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' + + - add_xlabel: 'GSI h(x) 2' + add_ylabel: 'JEDI h(x) 2' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::GsiHofXBc::${variable} + y: + variable: experiment_2::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus GSI h(x)' + - type: Scatter + x: + variable: experiment_2::GsiHofXBcPassedQc::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' + + # JEDI hofx0 vs GSI hofx0 + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GSI observation minus h(x) 1' + add_ylabel: 'JEDI observation minus h(x) 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + y: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI hofx0 vs JEDI hofx0 (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} + y: + variable: experiment_1::ObsValueMinushofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' + + - add_xlabel: 'GSI observation minus h(x) 2' + add_ylabel: 'JEDI observation minus h(x) 2' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + y: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI hofx0 vs JEDI hofx0 (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} + y: + variable: experiment_2::ObsValueMinushofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' + + # JEDI-GSI hofx0 differences vs GSI Obs-hofx0 + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'hofx0 difference vs. GSI Obs-hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_diff_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GSI observation minus h(x) 1' + add_ylabel: 'JEDI h(x) minus GSI h(x) 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} + y: + variable: experiment_1::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: '(JEDI hofx0 - GSI hofx0) vs GSI Obs-hofx0 (passed GSI QC)' + + - add_xlabel: 'GSI observation minus h(x) 2' + add_ylabel: 'JEDI h(x) minus GSI h(x) 2' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} + y: + variable: experiment_2::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: '(JEDI hofx0 - GSI hofx0) vs GSI Obs-hofx0 (passed GSI QC)' + + # JEDI oma vs omb + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'OmA vs. OmB | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_oma_vs_omb_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'OmA 1' + add_ylabel: 'OmB 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::oman::${variable} + y: + variable: experiment_1::ombg::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'OmA versus OmB (all residuals) 1' + - type: Scatter + x: + variable: experiment_1::omanPassedQc::${variable} + y: + variable: experiment_1::ombgPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'OmA versus OmB (passed QC) 1' + + - add_xlabel: 'OmA 1' + add_ylabel: 'OmB 1' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::oman::${variable} + y: + variable: experiment_2::ombg::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'OmA versus OmB (all residuals) 2' + - type: Scatter + x: + variable: experiment_2::omanPassedQc::${variable} + y: + variable: experiment_2::ombgPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'OmA versus OmB (passed QC) 2' + + # JediFinalObsError vs GsiObsFinalObsError + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'Jedi ObsError vs. GSI ObsError | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/JediObsError_vs_GsiObsError_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GsiFinalObsError' + add_ylabel: 'JediFinalObsError' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::GsiFinalObsError::${variable} + y: + variable: experiment_1::EffectiveError1::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JediObsError versus GsiObsError (all residuals) 1' + - type: Scatter + x: + variable: experiment_1::GsiFinalObsErrorPassedQc::${variable} + y: + variable: experiment_1::JediFinalObsErrorPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JediObsError versus GsiObsError (passed Jedi QC) 1' + + - add_xlabel: 'GsiFinalObsError' + add_ylabel: 'JediFinalObsError' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::GsiFinalObsError::${variable} + y: + variable: experiment_2::EffectiveError1::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JediObsError versus GsiObsError (all residuals) 2' + - type: Scatter + x: + variable: experiment_2::GsiFinalObsErrorPassedQc::${variable} + y: + variable: experiment_2::JediFinalObsErrorPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JediObsError versus GsiObsError (passed Jedi QC) 2' + + # JediFinalObsError vs GsiObsFinalObsError (all & passed GSI QC) + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + title: 'Jedi ObsError vs. GSI ObsError | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/JediObsError_vs_GsiObsError_{{instrument}}_${variable}${channel}_b.png' + plots: + - add_xlabel: 'GsiFinalObsError' + add_ylabel: 'JediFinalObsError' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::GsiFinalObsError::${variable} + y: + variable: experiment_1::EffectiveError1::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JediObsError versus GsiObsError (all residuals) 1' + - type: Scatter + x: + variable: experiment_1::GsiFinalObsErrorPassedGsiQc::${variable} + y: + variable: experiment_1::JediFinalObsErrorPassedGsiQc::${variable} + channel: ${channel} + markersize: 5 + color: 'blue' + label: 'JediObsError versus GsiObsError (Passed GSI QC) 1' + + - add_xlabel: 'GsiFinalObsError' + add_ylabel: 'JediFinalObsError' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::GsiFinalObsError::${variable} + y: + variable: experiment_2::EffectiveError1::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JediObsError versus GsiObsError (all residuals) 2' + - type: Scatter + x: + variable: experiment_2::GsiFinalObsErrorPassedGsiQc::${variable} + y: + variable: experiment_2::JediFinalObsErrorPassedGsiQc::${variable} + channel: ${channel} + markersize: 5 + color: 'blue' + label: 'JediObsError versus GsiObsError (Passed GSI QC) 2' + +# Map plots +# --------- + + # Observations + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValue::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'Observations | {{instrument_title}} | Obs Value' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/observations_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ObsValue::${variable} + channel: ${channel} + markersize: 2 + label: ObsValue 1 + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValue::${variable} + channel: ${channel} + markersize: 2 + label: ObsValue 2 + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx0 jedi + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValueMinusHofx0::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'JEDI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_jedi_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 1' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 2' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx0 gsi + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_gsi_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 1' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 2' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx difference + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'Hofx0 Difference | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_difference_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 1' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::Hofx0MinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 2' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # RMS(oma)-RMS(omb) difference + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ResidualRMSdiff::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'RMS Residual Difference | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/rmsres_difference_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ResidualRMSdiff::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 1' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ResidualRMSdiff::${variable} + channel: ${channel} + markersize: 2 + label: '${variable} 2' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + +# Histogram plots +# --------------- + + # hofx0 vs hofx0 + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: histogram_bins + channel: ${channel} + number of bins rule: sturges + data variable: experiment_1::ObsValueMinusHofx0::${variable} + figure: + layout: [2,1] + title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation minus h(x)' + add_ylabel: 'Count' + add_legend: + loc: 'upper left' + layers: + - type: Histogram + data: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + color: 'blue' + label: 'GSI hofx0 (all obs) 1' + bins: ${dynamic_bins} + alpha: 0.5 + - type: Histogram + data: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + color: 'red' + label: 'JEDI hofx0 (all obs) 1' + bins: ${dynamic_bins} + alpha: 0.5 + + - add_xlabel: 'Observation minus h(x)' + add_ylabel: 'Count' + add_legend: + loc: 'upper left' + layers: + - type: Histogram + data: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + color: 'blue' + label: 'GSI hofx0 (all obs) 2' + bins: ${dynamic_bins} + alpha: 0.5 + - type: Histogram + data: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + color: 'red' + label: 'JEDI hofx0 (all obs) 2' + bins: ${dynamic_bins} + alpha: 0.5 + + # JEDI omb vs oma + - batch figure: + variables: *variables + dynamic options: + - type: histogram_bins + data variable: experiment_1::omanPassedQc::${variable} + number of bins rule: 'rice' + figure: + layout: [2,1] + title: 'OmB vs. OmA | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}/ombg_oman_{{instrument}}_${variable}.png' + plots: + - add_xlabel: 'Difference' + add_ylabel: 'Count' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_1::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_1::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_1::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background 1' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_1::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis 1' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + - add_xlabel: 'Difference' + add_ylabel: 'Count' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_2::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_2::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_2::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background 2' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_2::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis 2' + bins: ${dynamic_bins} + alpha: 0.5 + density: true diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml index d918fe6bc..98dfcce9a 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml @@ -3,7 +3,7 @@ datasets: - name: experiment_1 type: IodaObsSpace filenames: - - {{obs_path_file}} + - {{obs_path_file_1}} groups: - name: ObsValue variables: &variables {{simulated_variables}} @@ -18,10 +18,10 @@ datasets: - name: experiment_2 type: IodaObsSpace filenames: - - {{obs_path_file}} + - {{obs_path_file_2}} groups: - name: ObsValue - variables: &variables {{simulated_variables}} + variables: *variables - name: hofx0 - name: hofx1 - name: ombg @@ -243,7 +243,7 @@ graphics: variables: *variables dynamic options: - type: histogram_bins - data variable: experiment::omanPassedQc::${variable} + data variable: experiment_1::omanPassedQc::${variable} number of bins rule: 'rice' figure: layout: [2,1] @@ -453,7 +453,7 @@ graphics: variables: *variables dynamic options: - type: vminvmaxcmap - data variable: experiment::ombgPassedQc::${variable} + data variable: experiment_1::ombgPassedQc::${variable} figure: figure size: [20,10] layout: [4,1] @@ -555,7 +555,7 @@ graphics: data variable: experiment_1::EffectiveQC1::${variable} figure: figure size: [20,10] - layout: [1,1] + layout: [2,1] title: '{{instrument_title}} | Passed QC' output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/effectiveQC_{{instrument}}_${variable}.png' plots: @@ -581,17 +581,62 @@ graphics: vmin: ${dynamic_vmin} vmax: ${dynamic_vmax} + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: EffectiveQC1 + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::EffectiveQC1::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + - batch figure: variables: *variables dynamic options: - type: vminvmaxcmap - data variable: experiment_2::increment::${variable} + data variable: experiment_1::increment::${variable} figure: figure size: [20,10] - layout: [1,1] + layout: [2,1] title: '{{instrument_title}} | Passed QC' output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/increment_{{instrument}}_${variable}.png' plots: + + - mapping: + projection: {{map_projection}} + domain: {{domain}} + add_map_features: ['coastline'] + add_colorbar: + label: Increment (OmBg - OmAn) + add_grid: + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::increment::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + - mapping: projection: {{map_projection}} domain: {{domain}} @@ -622,7 +667,7 @@ graphics: data variable: experiment_1::PassiveombgPassedQc::${variable} figure: figure size: [20,10] - layout: [2,1] + layout: [4,1] title: '{{instrument_title}} | Passed QC' output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/passive_ombg_oman_{{instrument}}_${variable}.png' plots: @@ -712,4 +757,4 @@ graphics: colorbar: true cmap: ${dynamic_cmap} vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} \ No newline at end of file + vmax: ${dynamic_vmax} diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index c6f8b6cce..ddab9373e 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -112,11 +112,15 @@ def execute(self) -> None: # Set the observing system records path self.jedi_rendering.set_obs_records_path(self.config.observing_system_records_path(None)) - + print(self.config.observations()) for observation in self.config.observations(): - obs_long_name = ioda_name_to_long_name(observation, self.logger) - observation_dict_1 = None + if self.get_model() == 'geos_atmosphere': + obs_long_name = ioda_name_to_long_name(observation, self.logger) + else: + obs_long_name = observation + observation_dict_1 = None + print(obs_long_name) for value in obs_config_1: if value['obs space']['name'] == obs_long_name: observation_dict_1 = value.copy() @@ -137,14 +141,14 @@ def execute(self) -> None: observation_dict_2, self.cycle_time_dto(), input_and_output=True) use_obs = use_obs_1 and use_obs_2 - + print(observation_dict_1) if not use_obs: continue # Split the full path into path and filename obs_path_file_1 = observation_dict_1['obs space']['obsdataout']['engine']['obsfile'] cycle_dir_1, obs_file_1 = os.path.split(obs_path_file_1) - + print(obs_path_file_1) # Split the full path into path and filename obs_path_file_2 = observation_dict_2['obs space']['obsdataout']['engine']['obsfile'] cycle_dir_2, obs_file_2 = os.path.split(obs_path_file_2) From 1d70595f1e7241df2d3543598776ae69a7bcdaaf Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Fri, 5 Dec 2025 13:47:28 -0500 Subject: [PATCH 12/51] rename --- ...rvations-3dfgat_atmos_geos_atmosphere.yaml | 1290 ----------------- 1 file changed, 1290 deletions(-) delete mode 100644 src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml deleted file mode 100644 index 33b4ac40a..000000000 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos_geos_atmosphere.yaml +++ /dev/null @@ -1,1290 +0,0 @@ -datasets: - -- name: experiment_1 - type: IodaObsSpace - filenames: - - {{obs_path_file_1}} - channels: &channels {{channels}} - groups: - - name: ObsValue - variables: &variables {{simulated_variables}} - - name: GsiHofXBc - - name: GsiEffectiveQC - - name: hofx0 - - name: hofx1 - - name: ombg - - name: oman - - name: EffectiveQC0 - - name: EffectiveQC1 - - name: MetaData - - name: GsiFinalObsError - - name: EffectiveError1 - -- name: experiment_2 - type: IodaObsSpace - filenames: - - {{obs_path_file_2}} - channels: *channels - groups: - - name: ObsValue - variables: *variables - - name: GsiHofXBc - - name: GsiEffectiveQC - - name: hofx0 - - name: hofx1 - - name: ombg - - name: oman - - name: EffectiveQC0 - - name: EffectiveQC1 - - name: MetaData - - name: GsiFinalObsError - - name: EffectiveError1 - -transforms: - -# Generate hofx0 for GSI 1 -- transform: arithmetic - new name: experiment_1::ObsValueMinusGsiHofXBc::${variable} - equals: experiment_1::ObsValue::${variable}-experiment_1::GsiHofXBc::${variable} - for: - variable: *variables - -# Generate hofx0 for GSI 2 -- transform: arithmetic - new name: experiment_2::ObsValueMinusGsiHofXBc::${variable} - equals: experiment_2::ObsValue::${variable}-experiment_2::GsiHofXBc::${variable} - for: - variable: *variables - -# Generate hofx0 for JEDI 1 -- transform: arithmetic - new name: experiment_1::ObsValueMinusHofx0::${variable} - equals: experiment_1::ObsValue::${variable}-experiment_1::hofx0::${variable} - for: - variable: *variables - -# Generate hofx0 for JEDI 2 -- transform: arithmetic - new name: experiment_2::ObsValueMinusHofx0::${variable} - equals: experiment_2::ObsValue::${variable}-experiment_2::hofx0::${variable} - for: - variable: *variables - -# Generate hofx difference 1 -- transform: arithmetic - new name: experiment_1::Hofx0MinusGsiHofXBc::${variable} - equals: experiment_1::hofx0::${variable}-experiment_1::GsiHofXBc::${variable} - for: - variable: *variables - -# Generate hofx difference 2 -- transform: arithmetic - new name: experiment_2::Hofx0MinusGsiHofXBc::${variable} - equals: experiment_2::hofx0::${variable}-experiment_2::GsiHofXBc::${variable} - for: - variable: *variables - -# Generate hofx that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::hofx0PassedQc::${variable} - starting field: experiment_1::hofx0::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::hofx0PassedQc::${variable} - starting field: experiment_2::hofx0::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx that passed QC for JEDI diff -- transform: arithmetic - new name: experiment_2::hofx0PassedQc::${variable}_diff - equals: (experiment_1::hofx0PassedQc::${variable} - experiment_2::hofx0PassedQc::${variable}) - for: - variable: *variables - -# Generate GSI hofx that passed JEDI QC 1 -- transform: accept where - new name: experiment_1::GsiHofXBcPassedQc::${variable} - starting field: experiment_1::GsiHofXBc::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate GSI hofx that passed JEDI QC 2 -- transform: accept where - new name: experiment_2::GsiHofXBcPassedQc::${variable} - starting field: experiment_2::GsiHofXBc::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx0 that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::ObsValueMinushofx0PassedQc::${variable} - starting field: experiment_1::ObsValueMinusHofx0::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx0 that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::ObsValueMinushofx0PassedQc::${variable} - starting field: experiment_2::ObsValueMinusHofx0::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx difference passed GSI QC 1 -- transform: accept where - new name: experiment_1::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} - starting field: experiment_1::Hofx0MinusGsiHofXBc::${variable} - where: - - experiment_1::GsiEffectiveQC::${variable} == 0 - for: - variable: *variables - -# Generate hofx difference passed GSI QC 2 -- transform: accept where - new name: experiment_2::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} - starting field: experiment_2::Hofx0MinusGsiHofXBc::${variable} - where: - - experiment_2::GsiEffectiveQC::${variable} == 0 - for: - variable: *variables - -# Generate GSI OmF passed GSI QC 1 -- transform: accept where - new name: experiment_1::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} - starting field: experiment_1::ObsValueMinusGsiHofXBc::${variable} - where: - - experiment_1::GsiEffectiveQC::${variable} == 0 - for: - variable: *variables - -# Generate GSI OmF passed GSI QC 2 -- transform: accept where - new name: experiment_2::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} - starting field: experiment_2::ObsValueMinusGsiHofXBc::${variable} - where: - - experiment_2::GsiEffectiveQC::${variable} == 0 - for: - variable: *variables - -# Generate hofx0 that passed QC for GSI 1 -- transform: accept where - new name: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} - starting field: experiment_1::ObsValueMinusGsiHofXBc::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx0 that passed QC for GSI 2 -- transform: accept where - new name: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} - starting field: experiment_2::ObsValueMinusGsiHofXBc::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate ombg that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::ombgPassedQc::${variable} - starting field: experiment_1::ombg::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate ombg that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::ombgPassedQc::${variable} - starting field: experiment_2::ombg::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate oman that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::omanPassedQc::${variable} - starting field: experiment_1::oman::${variable} - where: - - experiment_1::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate oman that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::omanPassedQc::${variable} - starting field: experiment_2::oman::${variable} - where: - - experiment_2::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate jedi final obserror that passed JEDI QC 1 -- transform: accept where - new name: experiment_1::JediFinalObsErrorPassedQc::${variable} - starting field: experiment_1::EffectiveError1::${variable} - where: - - experiment_1::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate jedi final obserror that passed JEDI QC 2 -- transform: accept where - new name: experiment_2::JediFinalObsErrorPassedQc::${variable} - starting field: experiment_2::EffectiveError1::${variable} - where: - - experiment_2::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate GSI final obserror that passed JEDI QC 1 -- transform: accept where - new name: experiment_1::GsiFinalObsErrorPassedQc::${variable} - starting field: experiment_1::GsiFinalObsError::${variable} - where: - - experiment_1::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate GSI final obserror that passed JEDI QC 2 -- transform: accept where - new name: experiment_2::GsiFinalObsErrorPassedQc::${variable} - starting field: experiment_2::GsiFinalObsError::${variable} - where: - - experiment_2::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate jedi final obserror that passed GSI QC 1 -- transform: accept where - new name: experiment_1::JediFinalObsErrorPassedGsiQc::${variable} - starting field: experiment_1::EffectiveError1::${variable} - where: - - experiment_1::GsiEffectiveQC::${variable} == 0 - for: - variable: *variables - -# Generate jedi final obserror that passed GSI QC 2 -- transform: accept where - new name: experiment_2::JediFinalObsErrorPassedGsiQc::${variable} - starting field: experiment_2::EffectiveError1::${variable} - where: - - experiment_2::GsiEffectiveQC::${variable} == 0 - for: - variable: *variables - -# Generate jedi final obserror that passed GSI QC 1 -- transform: accept where - new name: experiment_1::GsiFinalObsErrorPassedGsiQc::${variable} - starting field: experiment_1::GsiFinalObsError::${variable} - where: - - experiment_1::GsiEffectiveQC::${variable} == 0 - for: - variable: *variables - -# Generate jedi final obserror that passed GSI QC 2 -- transform: accept where - new name: experiment_2::GsiFinalObsErrorPassedGsiQc::${variable} - starting field: experiment_2::GsiFinalObsError::${variable} - where: - - experiment_2::GsiEffectiveQC::${variable} == 0 - for: - variable: *variables - -# Generate obs contribution to analysis (OmA*OmA)-(OmB*OmB) 1 -- transform: arithmetic - new name: experiment_1::ResidualRMSdiff::${variable} - equals: (experiment_1::omanPassedQc::${variable})*(experiment_1::omanPassedQc::${variable})-(experiment_1::ombgPassedQc::${variable})*(experiment_1::ombgPassedQc::${variable}) - for: - variable: *variables - -# Generate obs contribution to analysis (OmA*OmA)-(OmB*OmB) 2 -- transform: arithmetic - new name: experiment_2::ResidualRMSdiff::${variable} - equals: (experiment_2::omanPassedQc::${variable})*(experiment_2::omanPassedQc::${variable})-(experiment_2::ombgPassedQc::${variable})*(experiment_2::ombgPassedQc::${variable}) - for: - variable: *variables - -# Arithmetic transforms for differences -- transform: arithmetic - new name: experiment_2::ObsValue::${variable}_diff - equals: (experiment_1::ObsValue::${variable} - experiment_2::ObsValue::${variable}) - for: - variable: *variables - -# Arithmetic transforms for differences -- transform: arithmetic - new name: experiment_2::hofx0::${variable}_diff - equals: (experiment_1::hofx0::${variable} - experiment_2::hofx0::${variable}) - for: - variable: *variables - -graphics: - - plotting_backend: Emcpy - figure_list: - - # Correlation scatter plots - # ------------------------- - - # JEDI h(x) vs Observations - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [3,1] - title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'Observation Value 1' - add_ylabel: 'JEDI h(x) 1' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::ObsValue::${variable} - y: - variable: experiment_1::hofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JEDI h(x) versus obs (all obs)' - - type: Scatter - x: - variable: experiment_1::ObsValue::${variable} - y: - variable: experiment_1::hofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JEDI h(x) versus obs (passed QC in JEDI)' - - - add_xlabel: 'Observation Value 2' - add_ylabel: 'JEDI h(x) 2' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::hofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JEDI h(x) versus obs (all obs)' - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::hofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JEDI h(x) versus obs (passed QC in JEDI)' - - - - add_xlabel: 'Observation Value' - add_ylabel: 'JEDI h(x) diff (1-2)' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::hofx0::${variable}_diff - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JEDI h(x) versus obs (all obs)' - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::hofx0PassedQc::${variable}_diff - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JEDI h(x) versus obs (passed QC in JEDI) diff (1-2)' - - # GSI h(x) vs Observations - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - title: 'Observations vs. GSI h(x) | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'Observation Value 1' - add_ylabel: 'GSI h(x) 1' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::ObsValue::${variable} - y: - variable: experiment_1::GsiHofXBc::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'GSI h(x) versus obs (all obs)' - - type: Scatter - x: - variable: experiment_1::ObsValue::${variable} - y: - variable: experiment_1::GsiHofXBcPassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'GSI h(x) versus obs (passed QC in JEDI)' - - - add_xlabel: 'Observation Value 2' - add_ylabel: 'GSI h(x) 2' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::GsiHofXBc::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'GSI h(x) versus obs (all obs)' - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::GsiHofXBcPassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'GSI h(x) versus obs (passed QC in JEDI)' - - # JEDI h(x) vs GSI h(x) - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - title: 'JEDI h(x) vs. GSI h(x) | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx_vs_jedi0_hofx_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'GSI h(x) 1' - add_ylabel: 'JEDI h(x) 1' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::GsiHofXBc::${variable} - y: - variable: experiment_1::hofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JEDI h(x) versus GSI h(x)' - - type: Scatter - x: - variable: experiment_1::GsiHofXBcPassedQc::${variable} - y: - variable: experiment_1::hofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' - - - add_xlabel: 'GSI h(x) 2' - add_ylabel: 'JEDI h(x) 2' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::GsiHofXBc::${variable} - y: - variable: experiment_2::hofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JEDI h(x) versus GSI h(x)' - - type: Scatter - x: - variable: experiment_2::GsiHofXBcPassedQc::${variable} - y: - variable: experiment_2::hofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' - - # JEDI hofx0 vs GSI hofx0 - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'GSI observation minus h(x) 1' - add_ylabel: 'JEDI observation minus h(x) 1' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} - y: - variable: experiment_1::ObsValueMinusHofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'GSI hofx0 vs JEDI hofx0 (all obs)' - - type: Scatter - x: - variable: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} - y: - variable: experiment_1::ObsValueMinushofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' - - - add_xlabel: 'GSI observation minus h(x) 2' - add_ylabel: 'JEDI observation minus h(x) 2' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} - y: - variable: experiment_2::ObsValueMinusHofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'GSI hofx0 vs JEDI hofx0 (all obs)' - - type: Scatter - x: - variable: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} - y: - variable: experiment_2::ObsValueMinushofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' - - # JEDI-GSI hofx0 differences vs GSI Obs-hofx0 - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - title: 'hofx0 difference vs. GSI Obs-hofx0 | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_diff_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'GSI observation minus h(x) 1' - add_ylabel: 'JEDI h(x) minus GSI h(x) 1' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} - y: - variable: experiment_1::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: '(JEDI hofx0 - GSI hofx0) vs GSI Obs-hofx0 (passed GSI QC)' - - - add_xlabel: 'GSI observation minus h(x) 2' - add_ylabel: 'JEDI h(x) minus GSI h(x) 2' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::ObsValueMinusGsiHofXBcPassedGsiQc::${variable} - y: - variable: experiment_2::Hofx0MinusGsiHofXBcPassedGsiQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: '(JEDI hofx0 - GSI hofx0) vs GSI Obs-hofx0 (passed GSI QC)' - - # JEDI oma vs omb - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - title: 'OmA vs. OmB | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_oma_vs_omb_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'OmA 1' - add_ylabel: 'OmB 1' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::oman::${variable} - y: - variable: experiment_1::ombg::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'OmA versus OmB (all residuals) 1' - - type: Scatter - x: - variable: experiment_1::omanPassedQc::${variable} - y: - variable: experiment_1::ombgPassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'OmA versus OmB (passed QC) 1' - - - add_xlabel: 'OmA 1' - add_ylabel: 'OmB 1' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::oman::${variable} - y: - variable: experiment_2::ombg::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'OmA versus OmB (all residuals) 2' - - type: Scatter - x: - variable: experiment_2::omanPassedQc::${variable} - y: - variable: experiment_2::ombgPassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'OmA versus OmB (passed QC) 2' - - # JediFinalObsError vs GsiObsFinalObsError - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - title: 'Jedi ObsError vs. GSI ObsError | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/JediObsError_vs_GsiObsError_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'GsiFinalObsError' - add_ylabel: 'JediFinalObsError' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::GsiFinalObsError::${variable} - y: - variable: experiment_1::EffectiveError1::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JediObsError versus GsiObsError (all residuals) 1' - - type: Scatter - x: - variable: experiment_1::GsiFinalObsErrorPassedQc::${variable} - y: - variable: experiment_1::JediFinalObsErrorPassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JediObsError versus GsiObsError (passed Jedi QC) 1' - - - add_xlabel: 'GsiFinalObsError' - add_ylabel: 'JediFinalObsError' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::GsiFinalObsError::${variable} - y: - variable: experiment_2::EffectiveError1::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JediObsError versus GsiObsError (all residuals) 2' - - type: Scatter - x: - variable: experiment_2::GsiFinalObsErrorPassedQc::${variable} - y: - variable: experiment_2::JediFinalObsErrorPassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JediObsError versus GsiObsError (passed Jedi QC) 2' - - # JediFinalObsError vs GsiObsFinalObsError (all & passed GSI QC) - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - title: 'Jedi ObsError vs. GSI ObsError | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/JediObsError_vs_GsiObsError_{{instrument}}_${variable}${channel}_b.png' - plots: - - add_xlabel: 'GsiFinalObsError' - add_ylabel: 'JediFinalObsError' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::GsiFinalObsError::${variable} - y: - variable: experiment_1::EffectiveError1::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JediObsError versus GsiObsError (all residuals) 1' - - type: Scatter - x: - variable: experiment_1::GsiFinalObsErrorPassedGsiQc::${variable} - y: - variable: experiment_1::JediFinalObsErrorPassedGsiQc::${variable} - channel: ${channel} - markersize: 5 - color: 'blue' - label: 'JediObsError versus GsiObsError (Passed GSI QC) 1' - - - add_xlabel: 'GsiFinalObsError' - add_ylabel: 'JediFinalObsError' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::GsiFinalObsError::${variable} - y: - variable: experiment_2::EffectiveError1::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JediObsError versus GsiObsError (all residuals) 2' - - type: Scatter - x: - variable: experiment_2::GsiFinalObsErrorPassedGsiQc::${variable} - y: - variable: experiment_2::JediFinalObsErrorPassedGsiQc::${variable} - channel: ${channel} - markersize: 5 - color: 'blue' - label: 'JediObsError versus GsiObsError (Passed GSI QC) 2' - -# Map plots -# --------- - - # Observations - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: vminvmaxcmap - channel: ${channel} - data variable: experiment_1::ObsValue::${variable} - figure: - figure size: [20,10] - layout: [2,1] - title: 'Observations | {{instrument_title}} | Obs Value' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/observations_{{instrument}}_${variable}${channel}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: ObsValue - add_grid: - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::ObsValue::${variable} - channel: ${channel} - markersize: 2 - label: ObsValue 1 - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: ObsValue - add_grid: - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::ObsValue::${variable} - channel: ${channel} - markersize: 2 - label: ObsValue 2 - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - # hofx0 jedi - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: vminvmaxcmap - channel: ${channel} - data variable: experiment_1::ObsValueMinusHofx0::${variable} - figure: - figure size: [20,10] - layout: [2,1] - title: 'JEDI hofx0 | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_jedi_{{instrument}}_${variable}${channel}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::ObsValueMinusHofx0::${variable} - channel: ${channel} - markersize: 2 - label: '${variable} 1' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::ObsValueMinusHofx0::${variable} - channel: ${channel} - markersize: 2 - label: '${variable} 2' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - # hofx0 gsi - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: vminvmaxcmap - channel: ${channel} - data variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} - figure: - figure size: [20,10] - layout: [2,1] - title: 'GSI hofx0 | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_gsi_{{instrument}}_${variable}${channel}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} - channel: ${channel} - markersize: 2 - label: '${variable} 1' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} - channel: ${channel} - markersize: 2 - label: '${variable} 2' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - # hofx difference - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: vminvmaxcmap - channel: ${channel} - data variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} - figure: - figure size: [20,10] - layout: [2,1] - title: 'Hofx0 Difference | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_difference_{{instrument}}_${variable}${channel}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} - channel: ${channel} - markersize: 2 - label: '${variable} 1' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::Hofx0MinusGsiHofXBc::${variable} - channel: ${channel} - markersize: 2 - label: '${variable} 2' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - # RMS(oma)-RMS(omb) difference - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: vminvmaxcmap - channel: ${channel} - data variable: experiment_1::ResidualRMSdiff::${variable} - figure: - figure size: [20,10] - layout: [2,1] - title: 'RMS Residual Difference | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/rmsres_difference_{{instrument}}_${variable}${channel}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::ResidualRMSdiff::${variable} - channel: ${channel} - markersize: 2 - label: '${variable} 1' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::ResidualRMSdiff::${variable} - channel: ${channel} - markersize: 2 - label: '${variable} 2' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - -# Histogram plots -# --------------- - - # hofx0 vs hofx0 - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: histogram_bins - channel: ${channel} - number of bins rule: sturges - data variable: experiment_1::ObsValueMinusHofx0::${variable} - figure: - layout: [2,1] - title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'Observation minus h(x)' - add_ylabel: 'Count' - add_legend: - loc: 'upper left' - layers: - - type: Histogram - data: - variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} - channel: ${channel} - color: 'blue' - label: 'GSI hofx0 (all obs) 1' - bins: ${dynamic_bins} - alpha: 0.5 - - type: Histogram - data: - variable: experiment_1::ObsValueMinusHofx0::${variable} - channel: ${channel} - color: 'red' - label: 'JEDI hofx0 (all obs) 1' - bins: ${dynamic_bins} - alpha: 0.5 - - - add_xlabel: 'Observation minus h(x)' - add_ylabel: 'Count' - add_legend: - loc: 'upper left' - layers: - - type: Histogram - data: - variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} - channel: ${channel} - color: 'blue' - label: 'GSI hofx0 (all obs) 2' - bins: ${dynamic_bins} - alpha: 0.5 - - type: Histogram - data: - variable: experiment_2::ObsValueMinusHofx0::${variable} - channel: ${channel} - color: 'red' - label: 'JEDI hofx0 (all obs) 2' - bins: ${dynamic_bins} - alpha: 0.5 - - # JEDI omb vs oma - - batch figure: - variables: *variables - dynamic options: - - type: histogram_bins - data variable: experiment_1::omanPassedQc::${variable} - number of bins rule: 'rice' - figure: - layout: [2,1] - title: 'OmB vs. OmA | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}/ombg_oman_{{instrument}}_${variable}.png' - plots: - - add_xlabel: 'Difference' - add_ylabel: 'Count' - set_xlim: [-3, 3] - add_legend: - loc: 'upper left' - statistics: - fields: - - field_name: experiment_1::ombgPassedQc::${variable} - xloc: 0.5 - yloc: -0.10 - kwargs: - color: 'black' - fontsize: 8 - fontfamily: monospace - - field_name: experiment_1::omanPassedQc::${variable} - xloc: 0.5 - yloc: -0.13 - kwargs: - color: 'red' - fontsize: 8 - fontfamily: monospace - statistics_variables: - - n - - min - - mean - - max - - std - layers: - - type: Histogram - data: - variable: experiment_1::ombgPassedQc::${variable} - color: 'red' - label: 'observations minus background 1' - bins: ${dynamic_bins} - alpha: 0.5 - density: true - - type: Histogram - data: - variable: experiment_1::omanPassedQc::${variable} - color: 'blue' - label: 'observations minus analysis 1' - bins: ${dynamic_bins} - alpha: 0.5 - density: true - - - add_xlabel: 'Difference' - add_ylabel: 'Count' - set_xlim: [-3, 3] - add_legend: - loc: 'upper left' - statistics: - fields: - - field_name: experiment_2::ombgPassedQc::${variable} - xloc: 0.5 - yloc: -0.10 - kwargs: - color: 'black' - fontsize: 8 - fontfamily: monospace - - field_name: experiment_2::omanPassedQc::${variable} - xloc: 0.5 - yloc: -0.13 - kwargs: - color: 'red' - fontsize: 8 - fontfamily: monospace - statistics_variables: - - n - - min - - mean - - max - - std - layers: - - type: Histogram - data: - variable: experiment_2::ombgPassedQc::${variable} - color: 'red' - label: 'observations minus background 2' - bins: ${dynamic_bins} - alpha: 0.5 - density: true - - type: Histogram - data: - variable: experiment_2::omanPassedQc::${variable} - color: 'blue' - label: 'observations minus analysis 2' - bins: ${dynamic_bins} - alpha: 0.5 - density: true From 966745b4c91115da6900849e681cbd6da740e2dd Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Fri, 5 Dec 2025 14:44:38 -0500 Subject: [PATCH 13/51] Fix title --- ...observations-3dfgat_cycle-geos_marine.yaml | 72 +++++++++++++++++-- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml index 98dfcce9a..9a01472e8 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml @@ -190,7 +190,8 @@ graphics: output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}/jedi_hofx_vs_obs_{{instrument}}_${variable}.png' plots: - add_xlabel: 'Observation Value' - add_ylabel: 'JEDI h(x) 1' + add_ylabel: 'JEDI h(x)' + add_title: '{experiment_id_1} (1)' add_grid: add_legend: loc: 'upper left' @@ -213,8 +214,9 @@ graphics: label: 'JEDI h(x) versus obs (passed QC in JEDI)' - add_xlabel: 'Observation Value' - add_ylabel: 'JEDI h(x) 2' + add_ylabel: 'JEDI h(x)' add_grid: + add_title: '{experiment_id_2} (2)' add_legend: loc: 'upper left' layers: @@ -224,7 +226,7 @@ graphics: y: variable: experiment_2::hofx0PassedQc::${variable} markersize: 5 - color: 'black' + color: 'green' label: 'JEDI h(x) versus obs (all obs)' - type: Scatter x: @@ -232,9 +234,51 @@ graphics: y: variable: experiment_2::hofx1::${variable} markersize: 5 - color: 'red' + color: 'blue' label: 'JEDI h(x) versus obs (passed QC in JEDI)' + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x)' + add_grid: + add_title: 'Combined' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + markersize: 2 + color: 'black' + label: 'JEDI h(x) versus obs (all obs) 1' + + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx1::${variable} + markersize: 2 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI) 1' + + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + markersize: 2 + color: 'green' + label: 'JEDI h(x) versus obs (all obs) 2' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx1::${variable} + markersize: 2 + color: 'blue' + label: 'JEDI h(x) versus obs (passed QC in JEDI) 2' + # Histogram plots # --------------- @@ -252,6 +296,7 @@ graphics: plots: - add_xlabel: 'Difference' add_ylabel: 'Count' + add_title: '{experiment_id_1} (1)' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -298,6 +343,7 @@ graphics: - add_xlabel: 'Difference' add_ylabel: 'Count' + add_title: '{experiment_id_2} (2)' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -355,7 +401,8 @@ graphics: output name: '{{cycle_dir}}/eva/{{instrument}}/histogram/${variable}/pass_ombg_oman_{{instrument}}_${variable}.png' plots: - add_xlabel: 'Difference' - add_ylabel: 'Count 1' + add_ylabel: 'Count' + add_title: '{experiment_id_1} (1)' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -401,7 +448,8 @@ graphics: density: true - add_xlabel: 'Difference' - add_ylabel: 'Count 2' + add_ylabel: 'Count' + add_title: '{experiment_id_2} (2)' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -467,6 +515,7 @@ graphics: add_colorbar: label: ObsValue add_grid: + add_title: '{experiment_id_1} (1)' layers: - type: MapScatter longitude: @@ -489,6 +538,7 @@ graphics: add_colorbar: label: ObsValue add_grid: + add_title: '{experiment_id_1} (1)' layers: - type: MapScatter longitude: @@ -511,6 +561,7 @@ graphics: add_colorbar: label: ObsValue add_grid: + add_title: '{experiment_id_2} (2)' layers: - type: MapScatter longitude: @@ -533,6 +584,7 @@ graphics: add_colorbar: label: ObsValue add_grid: + add_title: '{experiment_id_2} (2)' layers: - type: MapScatter longitude: @@ -566,6 +618,7 @@ graphics: add_colorbar: label: EffectiveQC1 add_grid: + add_title: '{experiment_id_1} (1)' layers: - type: MapScatter longitude: @@ -588,6 +641,7 @@ graphics: add_colorbar: label: EffectiveQC1 add_grid: + add_title: '{experiment_id_2} (2)' layers: - type: MapScatter longitude: @@ -622,6 +676,7 @@ graphics: add_colorbar: label: Increment (OmBg - OmAn) add_grid: + add_title: '{experiment_id_1} (1)' layers: - type: MapScatter longitude: @@ -644,6 +699,7 @@ graphics: add_colorbar: label: Increment (OmBg - OmAn) add_grid: + add_title: '{experiment_id_2} (2)' layers: - type: MapScatter longitude: @@ -678,6 +734,7 @@ graphics: add_colorbar: label: ObsValue add_grid: + add_title: '{experiment_id_1} (1)' layers: - type: MapScatter longitude: @@ -700,6 +757,7 @@ graphics: add_colorbar: label: ObsValue add_grid: + add_title: '{experiment_id_1} (1)' layers: - type: MapScatter longitude: @@ -722,6 +780,7 @@ graphics: add_colorbar: label: ObsValue add_grid: + add_title: '{experiment_id_2} (2)' layers: - type: MapScatter longitude: @@ -744,6 +803,7 @@ graphics: add_colorbar: label: ObsValue add_grid: + add_title: '{experiment_id_2} (2)' layers: - type: MapScatter longitude: From 637bbe4fb87c6b7db8c058d97be75c743411ff1b Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Fri, 5 Dec 2025 14:52:35 -0500 Subject: [PATCH 14/51] fix --- ...observations-3dfgat_cycle-geos_marine.yaml | 38 +++++++++---------- .../tasks/eva_comparison_observations.py | 4 ++ 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml index 9a01472e8..90978d9a2 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml @@ -185,13 +185,13 @@ graphics: - batch figure: variables: *variables figure: - layout: [2,1] + layout: [3,1] title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}/jedi_hofx_vs_obs_{{instrument}}_${variable}.png' plots: - add_xlabel: 'Observation Value' add_ylabel: 'JEDI h(x)' - add_title: '{experiment_id_1} (1)' + add_title: '{{experiment_id_1}} (1)' add_grid: add_legend: loc: 'upper left' @@ -216,7 +216,7 @@ graphics: - add_xlabel: 'Observation Value' add_ylabel: 'JEDI h(x)' add_grid: - add_title: '{experiment_id_2} (2)' + add_title: '{{experiment_id_2}} (2)' add_legend: loc: 'upper left' layers: @@ -296,7 +296,7 @@ graphics: plots: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{experiment_id_1} (1)' + add_title: '{{experiment_id_1}} (1)' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -343,7 +343,7 @@ graphics: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{experiment_id_2} (2)' + add_title: '{{experiment_id_2}} (2)' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -402,7 +402,7 @@ graphics: plots: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{experiment_id_1} (1)' + add_title: '{{experiment_id_1}} (1)' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -449,7 +449,7 @@ graphics: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{experiment_id_2} (2)' + add_title: '{{experiment_id_2}} (2)' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -515,7 +515,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{experiment_id_1} (1)' + add_title: '{{experiment_id_1}} (1)' layers: - type: MapScatter longitude: @@ -538,7 +538,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{experiment_id_1} (1)' + add_title: '{{experiment_id_1}} (1)' layers: - type: MapScatter longitude: @@ -561,7 +561,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{experiment_id_2} (2)' + add_title: '{{experiment_id_2}} (2)' layers: - type: MapScatter longitude: @@ -584,7 +584,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{experiment_id_2} (2)' + add_title: '{{experiment_id_2}} (2)' layers: - type: MapScatter longitude: @@ -618,7 +618,7 @@ graphics: add_colorbar: label: EffectiveQC1 add_grid: - add_title: '{experiment_id_1} (1)' + add_title: '{{experiment_id_1}} (1)' layers: - type: MapScatter longitude: @@ -641,7 +641,7 @@ graphics: add_colorbar: label: EffectiveQC1 add_grid: - add_title: '{experiment_id_2} (2)' + add_title: '{{experiment_id_2}} (2)' layers: - type: MapScatter longitude: @@ -676,7 +676,7 @@ graphics: add_colorbar: label: Increment (OmBg - OmAn) add_grid: - add_title: '{experiment_id_1} (1)' + add_title: '{{experiment_id_1}} (1)' layers: - type: MapScatter longitude: @@ -699,7 +699,7 @@ graphics: add_colorbar: label: Increment (OmBg - OmAn) add_grid: - add_title: '{experiment_id_2} (2)' + add_title: '{{experiment_id_2}} (2)' layers: - type: MapScatter longitude: @@ -734,7 +734,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{experiment_id_1} (1)' + add_title: '{{experiment_id_1}} (1)' layers: - type: MapScatter longitude: @@ -757,7 +757,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{experiment_id_1} (1)' + add_title: '{{experiment_id_1}} (1)' layers: - type: MapScatter longitude: @@ -780,7 +780,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{experiment_id_2} (2)' + add_title: '{{experiment_id_2}} (2)' layers: - type: MapScatter longitude: @@ -803,7 +803,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{experiment_id_2} (2)' + add_title: '{{experiment_id_2}} (2)' layers: - type: MapScatter longitude: diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index ddab9373e..dc6c6bbc3 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -53,9 +53,11 @@ def execute(self) -> None: window_length = experiment_config_1['models'][self.get_model()]['window_length'] window_offset = self.da_window_params.window_offset(window_length) background_time_offset = experiment_config_1['models'][self.get_model()]['background_time_offset'] + experiment_id_1 = experiment_config_1['experiment_id'] with open(experiment_path_2, 'r') as f: experiment_config_2 = yaml.safe_load(f) + experiment_id_2 = experiment_config_2['experiment_id'] window_begin = self.da_window_params.window_begin(window_offset) background_time = self.da_window_params.background_time(background_time_offset) @@ -190,6 +192,8 @@ def execute(self) -> None: observation_dict_1['obs space']['simulated variables'] eva_override['map_projection'] = 'plcarr' eva_override['domain'] = 'global' + eva_override['experiment_id_1'] = experiment_id_1 + eva_override['experiment_id_2'] = experiment_id_2 # If filename contains icec_ change map projection to polar stereographic # ----------------------------------------------------------------------- From c1b7c6cad978eedf6b2cc824745a897d8cbd296a Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Fri, 5 Dec 2025 15:16:22 -0500 Subject: [PATCH 15/51] Fixes --- .../comparison_observations-3dfgat_cycle-geos_marine.yaml | 1 + src/swell/tasks/eva_comparison_observations.py | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml index 90978d9a2..9a4abdef2 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml @@ -186,6 +186,7 @@ graphics: variables: *variables figure: layout: [3,1] + figure size: [10, 30] title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}/jedi_hofx_vs_obs_{{instrument}}_${variable}.png' plots: diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index dc6c6bbc3..c4724fab9 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -114,7 +114,7 @@ def execute(self) -> None: # Set the observing system records path self.jedi_rendering.set_obs_records_path(self.config.observing_system_records_path(None)) - print(self.config.observations()) + for observation in self.config.observations(): if self.get_model() == 'geos_atmosphere': obs_long_name = ioda_name_to_long_name(observation, self.logger) @@ -122,7 +122,6 @@ def execute(self) -> None: obs_long_name = observation observation_dict_1 = None - print(obs_long_name) for value in obs_config_1: if value['obs space']['name'] == obs_long_name: observation_dict_1 = value.copy() @@ -143,14 +142,14 @@ def execute(self) -> None: observation_dict_2, self.cycle_time_dto(), input_and_output=True) use_obs = use_obs_1 and use_obs_2 - print(observation_dict_1) + if not use_obs: continue # Split the full path into path and filename obs_path_file_1 = observation_dict_1['obs space']['obsdataout']['engine']['obsfile'] cycle_dir_1, obs_file_1 = os.path.split(obs_path_file_1) - print(obs_path_file_1) + # Split the full path into path and filename obs_path_file_2 = observation_dict_2['obs space']['obsdataout']['engine']['obsfile'] cycle_dir_2, obs_file_2 = os.path.split(obs_path_file_2) From d896f81930b7d7d015acd9d4a1f92bf3b4e6e2dc Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Fri, 5 Dec 2025 16:26:06 -0500 Subject: [PATCH 16/51] Refine --- ...observations-3dfgat_cycle-geos_marine.yaml | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml index 9a4abdef2..b7b197b13 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml @@ -101,6 +101,13 @@ transforms: for: variable: *variables +# Generate ombg that passed QC for JEDI diff +- transform: arithmetic + new name: experiment_2::ombgPassedQc::${variable}_diff + equals: experiment_1::ombgPassedQc::${variable} - experiment_2::ombgPassedQc::${variable} + for: + variable: *variables + # Generate oman that passed QC for JEDI 1 - transform: accept where new name: experiment_1::omanPassedQc::${variable} @@ -119,6 +126,13 @@ transforms: for: variable: *variables +# Generate oman that passed QC for JEDI diff +- transform: arithmetic + new name: experiment_2::omanPassedQc::${variable}_diff + equals: experiment_1::omanPassedQc::${variable} - experiment_2::omanPassedQc::${variable} + for: + variable: *variables + # Generate passivated ombg that passed QC for JEDI 1 - transform: accept where new name: experiment_1::PassiveombgPassedQc::${variable} @@ -504,7 +518,7 @@ graphics: - type: vminvmaxcmap data variable: experiment_1::ombgPassedQc::${variable} figure: - figure size: [20,10] + figure size: [20,40] layout: [4,1] title: '{{instrument_title}} | Passed QC' output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/ombg_oman_{{instrument}}_${variable}.png' @@ -516,7 +530,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '{{experiment_id_1}} (1) ombg' layers: - type: MapScatter longitude: @@ -539,7 +553,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '{{experiment_id_1}} (1) oman' layers: - type: MapScatter longitude: @@ -562,7 +576,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '{{experiment_id_2}} (2) ombg' layers: - type: MapScatter longitude: @@ -585,7 +599,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '{{experiment_id_2}} (2) oman' layers: - type: MapScatter longitude: @@ -723,7 +737,7 @@ graphics: - type: vminvmaxcmap data variable: experiment_1::PassiveombgPassedQc::${variable} figure: - figure size: [20,10] + figure size: [20,20] layout: [4,1] title: '{{instrument_title}} | Passed QC' output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/passive_ombg_oman_{{instrument}}_${variable}.png' From b69765c9f5d4ad85e6d94375ad94ffc8a31909d5 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Fri, 5 Dec 2025 16:45:54 -0500 Subject: [PATCH 17/51] 3dfgat_atmos --- ...rvations-3dfgat_atmos-geos_atmosphere.yaml | 181 ++++++++---------- 1 file changed, 80 insertions(+), 101 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml index 33b4ac40a..135a86ec7 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml @@ -102,13 +102,6 @@ transforms: for: variable: *variables -# Generate hofx that passed QC for JEDI diff -- transform: arithmetic - new name: experiment_2::hofx0PassedQc::${variable}_diff - equals: (experiment_1::hofx0PassedQc::${variable} - experiment_2::hofx0PassedQc::${variable}) - for: - variable: *variables - # Generate GSI hofx that passed JEDI QC 1 - transform: accept where new name: experiment_1::GsiHofXBcPassedQc::${variable} @@ -321,20 +314,6 @@ transforms: for: variable: *variables -# Arithmetic transforms for differences -- transform: arithmetic - new name: experiment_2::ObsValue::${variable}_diff - equals: (experiment_1::ObsValue::${variable} - experiment_2::ObsValue::${variable}) - for: - variable: *variables - -# Arithmetic transforms for differences -- transform: arithmetic - new name: experiment_2::hofx0::${variable}_diff - equals: (experiment_1::hofx0::${variable} - experiment_2::hofx0::${variable}) - for: - variable: *variables - graphics: plotting_backend: Emcpy @@ -352,8 +331,9 @@ graphics: title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' plots: - - add_xlabel: 'Observation Value 1' - add_ylabel: 'JEDI h(x) 1' + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x)' + add_title: '{{experiment_id_1}} (1)' add_grid: add_legend: loc: 'upper left' @@ -377,8 +357,9 @@ graphics: color: 'red' label: 'JEDI h(x) versus obs (passed QC in JEDI)' - - add_xlabel: 'Observation Value 2' - add_ylabel: 'JEDI h(x) 2' + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x)' + add_title: '{{experiment_id_2}} (2)' add_grid: add_legend: loc: 'upper left' @@ -402,32 +383,6 @@ graphics: color: 'red' label: 'JEDI h(x) versus obs (passed QC in JEDI)' - - - add_xlabel: 'Observation Value' - add_ylabel: 'JEDI h(x) diff (1-2)' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::hofx0::${variable}_diff - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JEDI h(x) versus obs (all obs)' - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::hofx0PassedQc::${variable}_diff - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JEDI h(x) versus obs (passed QC in JEDI) diff (1-2)' - # GSI h(x) vs Observations - batch figure: variables: *variables @@ -437,8 +392,9 @@ graphics: title: 'Observations vs. GSI h(x) | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' plots: - - add_xlabel: 'Observation Value 1' - add_ylabel: 'GSI h(x) 1' + - add_xlabel: 'Observation Value' + add_ylabel: 'GSI h(x)' + add_title: '{{experiment_id_1}} (1)' add_grid: add_legend: loc: 'upper left' @@ -462,8 +418,9 @@ graphics: color: 'red' label: 'GSI h(x) versus obs (passed QC in JEDI)' - - add_xlabel: 'Observation Value 2' - add_ylabel: 'GSI h(x) 2' + - add_xlabel: 'Observation Value' + add_ylabel: 'GSI h(x)' + add_title: '{{experiment_id_2}} (2)' add_grid: add_legend: loc: 'upper left' @@ -496,8 +453,9 @@ graphics: title: 'JEDI h(x) vs. GSI h(x) | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx_vs_jedi0_hofx_{{instrument}}_${variable}${channel}.png' plots: - - add_xlabel: 'GSI h(x) 1' - add_ylabel: 'JEDI h(x) 1' + - add_xlabel: 'GSI h(x)' + add_ylabel: 'JEDI h(x)' + add_title: '{{experiment_id_1}} (1)' add_grid: add_legend: loc: 'upper left' @@ -521,8 +479,9 @@ graphics: color: 'red' label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' - - add_xlabel: 'GSI h(x) 2' - add_ylabel: 'JEDI h(x) 2' + - add_xlabel: 'GSI h(x)' + add_ylabel: 'JEDI h(x)' + add_title: '{{experiment_id_2}} (2)' add_grid: add_legend: loc: 'upper left' @@ -555,8 +514,9 @@ graphics: title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' plots: - - add_xlabel: 'GSI observation minus h(x) 1' - add_ylabel: 'JEDI observation minus h(x) 1' + - add_xlabel: 'GSI observation minus h(x)' + add_ylabel: 'JEDI observation minus h(x)' + add_title: '{{experiment_id_1}} (1)' add_grid: add_legend: loc: 'upper left' @@ -580,8 +540,9 @@ graphics: color: 'red' label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' - - add_xlabel: 'GSI observation minus h(x) 2' - add_ylabel: 'JEDI observation minus h(x) 2' + - add_xlabel: 'GSI observation minus h(x)' + add_ylabel: 'JEDI observation minus h(x)' + add_title: '{{experiment_id_2}} (2)' add_grid: add_legend: loc: 'upper left' @@ -614,8 +575,9 @@ graphics: title: 'hofx0 difference vs. GSI Obs-hofx0 | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_diff_{{instrument}}_${variable}${channel}.png' plots: - - add_xlabel: 'GSI observation minus h(x) 1' - add_ylabel: 'JEDI h(x) minus GSI h(x) 1' + - add_xlabel: 'GSI observation minus h(x)' + add_ylabel: 'JEDI h(x) minus GSI h(x)' + add_title: '{{experiment_id_1}} (1)' add_grid: add_legend: loc: 'upper left' @@ -630,8 +592,9 @@ graphics: color: 'red' label: '(JEDI hofx0 - GSI hofx0) vs GSI Obs-hofx0 (passed GSI QC)' - - add_xlabel: 'GSI observation minus h(x) 2' - add_ylabel: 'JEDI h(x) minus GSI h(x) 2' + - add_xlabel: 'GSI observation minus h(x)' + add_ylabel: 'JEDI h(x) minus GSI h(x)' + add_title: '{{experiment_id_2}} (2)' add_grid: add_legend: loc: 'upper left' @@ -655,8 +618,9 @@ graphics: title: 'OmA vs. OmB | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_oma_vs_omb_{{instrument}}_${variable}${channel}.png' plots: - - add_xlabel: 'OmA 1' - add_ylabel: 'OmB 1' + - add_xlabel: 'OmA' + add_ylabel: 'OmB' + add_title: '{{experiment_id_1}} (1)' add_grid: add_legend: loc: 'upper left' @@ -669,7 +633,7 @@ graphics: channel: ${channel} markersize: 5 color: 'black' - label: 'OmA versus OmB (all residuals) 1' + label: 'OmA versus OmB (all residuals)' - type: Scatter x: variable: experiment_1::omanPassedQc::${variable} @@ -678,10 +642,11 @@ graphics: channel: ${channel} markersize: 5 color: 'red' - label: 'OmA versus OmB (passed QC) 1' + label: 'OmA versus OmB (passed QC)' - - add_xlabel: 'OmA 1' - add_ylabel: 'OmB 1' + - add_xlabel: 'OmA' + add_ylabel: 'OmB' + add_title: '{{experiment_id_2}} (2)' add_grid: add_legend: loc: 'upper left' @@ -694,7 +659,7 @@ graphics: channel: ${channel} markersize: 5 color: 'black' - label: 'OmA versus OmB (all residuals) 2' + label: 'OmA versus OmB (all residuals)' - type: Scatter x: variable: experiment_2::omanPassedQc::${variable} @@ -703,7 +668,7 @@ graphics: channel: ${channel} markersize: 5 color: 'red' - label: 'OmA versus OmB (passed QC) 2' + label: 'OmA versus OmB (passed QC)' # JediFinalObsError vs GsiObsFinalObsError - batch figure: @@ -716,6 +681,7 @@ graphics: plots: - add_xlabel: 'GsiFinalObsError' add_ylabel: 'JediFinalObsError' + add_title: '{{experiment_id_1}} (1)' add_grid: add_legend: loc: 'upper left' @@ -728,7 +694,7 @@ graphics: channel: ${channel} markersize: 5 color: 'black' - label: 'JediObsError versus GsiObsError (all residuals) 1' + label: 'JediObsError versus GsiObsError (all residuals)' - type: Scatter x: variable: experiment_1::GsiFinalObsErrorPassedQc::${variable} @@ -737,10 +703,11 @@ graphics: channel: ${channel} markersize: 5 color: 'red' - label: 'JediObsError versus GsiObsError (passed Jedi QC) 1' + label: 'JediObsError versus GsiObsError (passed Jedi QC)' - add_xlabel: 'GsiFinalObsError' add_ylabel: 'JediFinalObsError' + add_title: '{{experiment_id_2}} (2)' add_grid: add_legend: loc: 'upper left' @@ -753,7 +720,7 @@ graphics: channel: ${channel} markersize: 5 color: 'black' - label: 'JediObsError versus GsiObsError (all residuals) 2' + label: 'JediObsError versus GsiObsError (all residuals)' - type: Scatter x: variable: experiment_2::GsiFinalObsErrorPassedQc::${variable} @@ -762,7 +729,7 @@ graphics: channel: ${channel} markersize: 5 color: 'red' - label: 'JediObsError versus GsiObsError (passed Jedi QC) 2' + label: 'JediObsError versus GsiObsError (passed Jedi QC)' # JediFinalObsError vs GsiObsFinalObsError (all & passed GSI QC) - batch figure: @@ -775,6 +742,7 @@ graphics: plots: - add_xlabel: 'GsiFinalObsError' add_ylabel: 'JediFinalObsError' + add_title: '{{experiment_id_1}} (1)' add_grid: add_legend: loc: 'upper left' @@ -787,7 +755,7 @@ graphics: channel: ${channel} markersize: 5 color: 'black' - label: 'JediObsError versus GsiObsError (all residuals) 1' + label: 'JediObsError versus GsiObsError (all residuals)' - type: Scatter x: variable: experiment_1::GsiFinalObsErrorPassedGsiQc::${variable} @@ -796,10 +764,11 @@ graphics: channel: ${channel} markersize: 5 color: 'blue' - label: 'JediObsError versus GsiObsError (Passed GSI QC) 1' + label: 'JediObsError versus GsiObsError (Passed GSI QC)' - add_xlabel: 'GsiFinalObsError' add_ylabel: 'JediFinalObsError' + add_title: '{{experiment_id_2}} (2)' add_grid: add_legend: loc: 'upper left' @@ -812,7 +781,7 @@ graphics: channel: ${channel} markersize: 5 color: 'black' - label: 'JediObsError versus GsiObsError (all residuals) 2' + label: 'JediObsError versus GsiObsError (all residuals)' - type: Scatter x: variable: experiment_2::GsiFinalObsErrorPassedGsiQc::${variable} @@ -821,7 +790,7 @@ graphics: channel: ${channel} markersize: 5 color: 'blue' - label: 'JediObsError versus GsiObsError (Passed GSI QC) 2' + label: 'JediObsError versus GsiObsError (Passed GSI QC)' # Map plots # --------- @@ -847,6 +816,7 @@ graphics: add_colorbar: label: ObsValue add_grid: + add_title: '{{experiment_id_1}} (1)' layers: - type: MapScatter longitude: @@ -857,7 +827,7 @@ graphics: variable: experiment_1::ObsValue::${variable} channel: ${channel} markersize: 2 - label: ObsValue 1 + label: ObsValue colorbar: true cmap: ${dynamic_cmap} vmin: ${dynamic_vmin} @@ -870,6 +840,7 @@ graphics: add_colorbar: label: ObsValue add_grid: + add_title: '{{experiment_id_2}} (2)' layers: - type: MapScatter longitude: @@ -880,7 +851,7 @@ graphics: variable: experiment_2::ObsValue::${variable} channel: ${channel} markersize: 2 - label: ObsValue 2 + label: ObsValue colorbar: true cmap: ${dynamic_cmap} vmin: ${dynamic_vmin} @@ -907,6 +878,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: + add_title: '{{experiment_id_1}} (1)' layers: - type: MapScatter longitude: @@ -917,7 +889,7 @@ graphics: variable: experiment_1::ObsValueMinusHofx0::${variable} channel: ${channel} markersize: 2 - label: '${variable} 1' + label: '${variable}' colorbar: true cmap: ${dynamic_cmap} vmin: ${dynamic_vmin} @@ -930,6 +902,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: + add_title: '{{experiment_id_2}} (2)' layers: - type: MapScatter longitude: @@ -940,7 +913,7 @@ graphics: variable: experiment_2::ObsValueMinusHofx0::${variable} channel: ${channel} markersize: 2 - label: '${variable} 2' + label: '${variable}' colorbar: true cmap: ${dynamic_cmap} vmin: ${dynamic_vmin} @@ -967,6 +940,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: + add_title: '{{experiment_id_1}} (1)' layers: - type: MapScatter longitude: @@ -977,7 +951,7 @@ graphics: variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} channel: ${channel} markersize: 2 - label: '${variable} 1' + label: '${variable}' colorbar: true cmap: ${dynamic_cmap} vmin: ${dynamic_vmin} @@ -990,6 +964,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: + add_title: '{{experiment_id_2}} (2)' layers: - type: MapScatter longitude: @@ -1000,7 +975,7 @@ graphics: variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} channel: ${channel} markersize: 2 - label: '${variable} 2' + label: '${variable}' colorbar: true cmap: ${dynamic_cmap} vmin: ${dynamic_vmin} @@ -1027,6 +1002,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: + add_title: '{{experiment_id_1}} (1)' layers: - type: MapScatter longitude: @@ -1037,7 +1013,7 @@ graphics: variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} channel: ${channel} markersize: 2 - label: '${variable} 1' + label: '${variable}' colorbar: true cmap: ${dynamic_cmap} vmin: ${dynamic_vmin} @@ -1060,7 +1036,7 @@ graphics: variable: experiment_2::Hofx0MinusGsiHofXBc::${variable} channel: ${channel} markersize: 2 - label: '${variable} 2' + label: '${variable}' colorbar: true cmap: ${dynamic_cmap} vmin: ${dynamic_vmin} @@ -1087,6 +1063,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: + add_title: '{{experiment_id_1}} (1)' layers: - type: MapScatter longitude: @@ -1097,7 +1074,7 @@ graphics: variable: experiment_1::ResidualRMSdiff::${variable} channel: ${channel} markersize: 2 - label: '${variable} 1' + label: '${variable}' colorbar: true cmap: ${dynamic_cmap} vmin: ${dynamic_vmin} @@ -1120,7 +1097,7 @@ graphics: variable: experiment_2::ResidualRMSdiff::${variable} channel: ${channel} markersize: 2 - label: '${variable} 2' + label: '${variable}' colorbar: true cmap: ${dynamic_cmap} vmin: ${dynamic_vmin} @@ -1145,6 +1122,7 @@ graphics: plots: - add_xlabel: 'Observation minus h(x)' add_ylabel: 'Count' + add_title: '{{experiment_id_1}} (1)' add_legend: loc: 'upper left' layers: @@ -1153,7 +1131,7 @@ graphics: variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} channel: ${channel} color: 'blue' - label: 'GSI hofx0 (all obs) 1' + label: 'GSI hofx0 (all obs)' bins: ${dynamic_bins} alpha: 0.5 - type: Histogram @@ -1161,7 +1139,7 @@ graphics: variable: experiment_1::ObsValueMinusHofx0::${variable} channel: ${channel} color: 'red' - label: 'JEDI hofx0 (all obs) 1' + label: 'JEDI hofx0 (all obs)' bins: ${dynamic_bins} alpha: 0.5 @@ -1175,7 +1153,7 @@ graphics: variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} channel: ${channel} color: 'blue' - label: 'GSI hofx0 (all obs) 2' + label: 'GSI hofx0 (all obs)' bins: ${dynamic_bins} alpha: 0.5 - type: Histogram @@ -1183,7 +1161,7 @@ graphics: variable: experiment_2::ObsValueMinusHofx0::${variable} channel: ${channel} color: 'red' - label: 'JEDI hofx0 (all obs) 2' + label: 'JEDI hofx0 (all obs)' bins: ${dynamic_bins} alpha: 0.5 @@ -1201,6 +1179,7 @@ graphics: plots: - add_xlabel: 'Difference' add_ylabel: 'Count' + add_title: '{{experiment_id_1}} (1)' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -1231,7 +1210,7 @@ graphics: data: variable: experiment_1::ombgPassedQc::${variable} color: 'red' - label: 'observations minus background 1' + label: 'observations minus background' bins: ${dynamic_bins} alpha: 0.5 density: true @@ -1239,7 +1218,7 @@ graphics: data: variable: experiment_1::omanPassedQc::${variable} color: 'blue' - label: 'observations minus analysis 1' + label: 'observations minus analysis' bins: ${dynamic_bins} alpha: 0.5 density: true @@ -1276,7 +1255,7 @@ graphics: data: variable: experiment_2::ombgPassedQc::${variable} color: 'red' - label: 'observations minus background 2' + label: 'observations minus background' bins: ${dynamic_bins} alpha: 0.5 density: true @@ -1284,7 +1263,7 @@ graphics: data: variable: experiment_2::omanPassedQc::${variable} color: 'blue' - label: 'observations minus analysis 2' + label: 'observations minus analysis' bins: ${dynamic_bins} alpha: 0.5 density: true From d07ebb37e507e6915d6f55a0de7ea29a63ddd390 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Fri, 5 Dec 2025 17:04:34 -0500 Subject: [PATCH 18/51] update eva files --- src/swell/tasks/eva_comparison_observations.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index c4724fab9..caf0e6d61 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -14,6 +14,7 @@ from eva.eva_driver import eva +from swell.swell_path import get_swell_path from swell.deployment.platforms.platforms import login_or_compute from swell.tasks.base.task_base import taskBase from swell.utilities.dictionary import remove_matching_keys, replace_string_in_dictionary @@ -54,6 +55,7 @@ def execute(self) -> None: window_offset = self.da_window_params.window_offset(window_length) background_time_offset = experiment_config_1['models'][self.get_model()]['background_time_offset'] experiment_id_1 = experiment_config_1['experiment_id'] + comparison_suite = experiment_config_1['suite_to_run'] with open(experiment_path_2, 'r') as f: experiment_config_2 = yaml.safe_load(f) @@ -86,9 +88,11 @@ def execute(self) -> None: # Read Eva template file into dictionary # -------------------------------------- model = self.get_model() - eva_path = os.path.join(self.experiment_path(), self.experiment_id()+'-suite', 'eva') - eva_config_file = os.path.join(eva_path, f'observations-{model}.yaml') - eva_config_file = '/home/manstett/swell-main/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml' + # eva_path = os.path.join(self.experiment_path(), self.experiment_id()+'-suite', 'eva') + eva_path = os.path.join(get_swell_path(), 'suites', 'compare', 'eva') + eva_config_file = os.path.join(eva_path, + f'comparison_observations-{comparison_suite}-{model}.yaml') + with open(eva_config_file, 'r') as eva_config_file_open: eva_str_template = eva_config_file_open.read() From fc27b0a6c7f043bea071f8a126c0ff325b6ca41d Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 8 Dec 2025 10:18:28 -0500 Subject: [PATCH 19/51] Formatting adjustments --- ...rvations-3dfgat_atmos-geos_atmosphere.yaml | 12 +++++++++- src/swell/suites/compare/flow.cylc | 10 ++++++++ .../tasks/eva_comparison_observations.py | 23 ++++++++++--------- src/swell/tasks/task_questions.py | 1 - src/swell/utilities/slurm.py | 1 + 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml index 135a86ec7..53e213ec3 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml @@ -327,7 +327,8 @@ graphics: variables: *variables channels: *channels figure: - layout: [3,1] + layout: [2,1] + figure size: [20, 10] title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' plots: @@ -389,6 +390,7 @@ graphics: channels: *channels figure: layout: [2,1] + figure size: [20, 10] title: 'Observations vs. GSI h(x) | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' plots: @@ -450,6 +452,7 @@ graphics: channels: *channels figure: layout: [2,1] + figure size: [20, 10] title: 'JEDI h(x) vs. GSI h(x) | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx_vs_jedi0_hofx_{{instrument}}_${variable}${channel}.png' plots: @@ -511,6 +514,7 @@ graphics: channels: *channels figure: layout: [2,1] + figure size: [20, 10] title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' plots: @@ -572,6 +576,7 @@ graphics: channels: *channels figure: layout: [2,1] + figure size: [20, 10] title: 'hofx0 difference vs. GSI Obs-hofx0 | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_diff_{{instrument}}_${variable}${channel}.png' plots: @@ -615,6 +620,7 @@ graphics: channels: *channels figure: layout: [2,1] + figure size: [20, 10] title: 'OmA vs. OmB | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_oma_vs_omb_{{instrument}}_${variable}${channel}.png' plots: @@ -676,6 +682,7 @@ graphics: channels: *channels figure: layout: [2,1] + figure size: [20, 10] title: 'Jedi ObsError vs. GSI ObsError | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/JediObsError_vs_GsiObsError_{{instrument}}_${variable}${channel}.png' plots: @@ -737,6 +744,7 @@ graphics: channels: *channels figure: layout: [2,1] + figure size: [20, 10] title: 'Jedi ObsError vs. GSI ObsError | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/JediObsError_vs_GsiObsError_{{instrument}}_${variable}${channel}_b.png' plots: @@ -1116,6 +1124,7 @@ graphics: number of bins rule: sturges data variable: experiment_1::ObsValueMinusHofx0::${variable} figure: + figure size: [20, 10] layout: [2,1] title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' @@ -1173,6 +1182,7 @@ graphics: data variable: experiment_1::omanPassedQc::${variable} number of bins rule: 'rice' figure: + figure size: [20, 10] layout: [2,1] title: 'OmB vs. OmA | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}/ombg_oman_{{instrument}}_${variable}.png' diff --git a/src/swell/suites/compare/flow.cylc b/src/swell/suites/compare/flow.cylc index f90bf4716..979445d77 100644 --- a/src/swell/suites/compare/flow.cylc +++ b/src/swell/suites/compare/flow.cylc @@ -32,6 +32,7 @@ {% if cycle_time[model_component] %} EvaComparisonIncrement-{{model_component}} EvaComparisonJediLog-{{model_component}} + EvaComparisonObservations-{{model_component}} {% for path in comparison_experiment_paths %} JediOopsLogParser-{{model_component}}-{{ loop.index0 }} => JediLogComparison-{{model_component}} {% endfor %} @@ -63,6 +64,15 @@ [[EvaComparisonJediLog-{{model_component}}]] script = "swell task EvaComparisonJediLog $config -d $datetime -m {{model_component}}" + [[EvaComparisonObservations-{{model_component}}]] + script = "swell task EvaComparisonObservations $config -d $datetime -m {{model_component}}" + platform = {{platform}} + execution time limit = {{scheduling["EvaComparisonObservations"]["execution_time_limit"]}} + [[[directives]]] + {%- for key, value in scheduling["EvaComparisonObservations"]["directives"][model_component].items() %} + --{{key}} = {{value}} + {%- endfor %} + {% for path in comparison_experiment_paths %} [[JediOopsLogParser-{{model_component}}-{{ loop.index0 }}]] script = "swell task JediOopsLogParser {{path}} -d $datetime -m {{model_component}}" diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index caf0e6d61..37ce9937b 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -38,7 +38,6 @@ class EvaComparisonObservations(taskBase): def execute(self) -> None: - # Comparison log type # ------------------- log_type = self.config.comparison_log_type() @@ -49,30 +48,33 @@ def execute(self) -> None: experiment_path_1 = experiment_paths[0] experiment_path_2 = experiment_paths[1] + model = self.get_model() + + # Take parameters from first file with open(experiment_path_1, 'r') as f: experiment_config_1 = yaml.safe_load(f) - window_length = experiment_config_1['models'][self.get_model()]['window_length'] - window_offset = self.da_window_params.window_offset(window_length) - background_time_offset = experiment_config_1['models'][self.get_model()]['background_time_offset'] experiment_id_1 = experiment_config_1['experiment_id'] comparison_suite = experiment_config_1['suite_to_run'] + observations = experiment_config_1['models'][model]['observations'] + # Second file parameters with open(experiment_path_2, 'r') as f: experiment_config_2 = yaml.safe_load(f) experiment_id_2 = experiment_config_2['experiment_id'] - window_begin = self.da_window_params.window_begin(window_offset) - background_time = self.da_window_params.background_time(background_time_offset) - + # JEDI config file 1 jedi_config_file_1 = os.path.join(os.path.dirname(experiment_path_1), '..', 'run', - self.__datetime__.string_directory(), self.get_model(), f'jedi_{log_type}_config.yaml') + self.__datetime__.string_directory(), model, + f'jedi_{log_type}_config.yaml') with open(jedi_config_file_1, 'r') as f: jedi_config = yaml.safe_load(f) obs_config_1 = jedi_config['cost function']['observations']['observers'] + # JEDI config file 2 jedi_config_file_2 = os.path.join(os.path.dirname(experiment_path_2), '..', 'run', - self.__datetime__.string_directory(), self.get_model(), f'jedi_{log_type}_config.yaml') + self.__datetime__.string_directory(), model, + f'jedi_{log_type}_config.yaml') with open(jedi_config_file_2, 'r') as f: jedi_config = yaml.safe_load(f) @@ -87,7 +89,6 @@ def execute(self) -> None: # Read Eva template file into dictionary # -------------------------------------- - model = self.get_model() # eva_path = os.path.join(self.experiment_path(), self.experiment_id()+'-suite', 'eva') eva_path = os.path.join(get_swell_path(), 'suites', 'compare', 'eva') eva_config_file = os.path.join(eva_path, @@ -119,7 +120,7 @@ def execute(self) -> None: # Set the observing system records path self.jedi_rendering.set_obs_records_path(self.config.observing_system_records_path(None)) - for observation in self.config.observations(): + for observation in observations: if self.get_model() == 'geos_atmosphere': obs_long_name = ioda_name_to_long_name(observation, self.logger) else: diff --git a/src/swell/tasks/task_questions.py b/src/swell/tasks/task_questions.py index 388d3de59..f01f85159 100644 --- a/src/swell/tasks/task_questions.py +++ b/src/swell/tasks/task_questions.py @@ -196,7 +196,6 @@ class TaskQuestions(QuestionContainer, Enum): list_name="EvaComparisonObservations", questions=[ qd.comparison_log_type(), - qd.observations(), ] ) diff --git a/src/swell/utilities/slurm.py b/src/swell/utilities/slurm.py index a8ebe2720..92305a32c 100644 --- a/src/swell/utilities/slurm.py +++ b/src/swell/utilities/slurm.py @@ -74,6 +74,7 @@ def prepare_scheduling_dict( 'BuildJedi', 'BuildGeos', 'EvaObservations', + 'EvaComparisonObservations', 'EvaTimeseries', 'GenerateBClimatology', 'RunJediEnsembleMeanVariance', From 786a8399cecc2f531c2463795431584f6fcb38ff Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Thu, 11 Dec 2025 17:03:24 -0500 Subject: [PATCH 20/51] add 3dvar and 3dvar_atmos --- .../eva/observations-3dvar-geos_marine.yaml | 530 ++++++++++ ...ervations-3dvar_atmos-geos_atmosphere.yaml | 969 ++++++++++++++++++ 2 files changed, 1499 insertions(+) create mode 100644 src/swell/suites/compare/eva/observations-3dvar-geos_marine.yaml create mode 100644 src/swell/suites/compare/eva/observations-3dvar_atmos-geos_atmosphere.yaml diff --git a/src/swell/suites/compare/eva/observations-3dvar-geos_marine.yaml b/src/swell/suites/compare/eva/observations-3dvar-geos_marine.yaml new file mode 100644 index 000000000..453036e22 --- /dev/null +++ b/src/swell/suites/compare/eva/observations-3dvar-geos_marine.yaml @@ -0,0 +1,530 @@ +datasets: + +- name: experiment_1 + type: IodaObsSpace + filenames: + - {{obs_path_file_1}} + groups: + - name: ObsValue + variables: &variables {{simulated_variables}} + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: MetaData + - name: EffectiveQC0 + - name: EffectiveQC1 + +- name: experiment_2 + type: IodaObsSpace + filenames: + - {{obs_path_file_2}} + groups: + - name: ObsValue + variables: *variables + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: MetaData + - name: EffectiveQC0 + - name: EffectiveQC1 + +transforms: + +# Generate Increment for JEDI 1 +- transform: arithmetic + new name: experiment_1::increment::${variable} + equals: experiment_1::ombg::${variable}-experiment_1::oman::${variable} + for: + variable: *variables + +# Generate Increment for JEDI 2 +- transform: arithmetic + new name: experiment_2::increment::${variable} + equals: experiment_2::ombg::${variable}-experiment_2::oman::${variable} + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::hofx0PassedQc::${variable} + starting field: experiment_1::hofx0::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::hofx0PassedQc::${variable} + starting field: experiment_2::hofx0::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx1 that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::hofx1PassedQc::${variable} + starting field: experiment_1::hofx1::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate hofx1 that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::hofx1PassedQc::${variable} + starting field: experiment_2::hofx1::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ombgPassedQc::${variable} + starting field: experiment_1::ombg::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ombgPassedQc::${variable} + starting field: experiment_2::ombg::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::omanPassedQc::${variable} + starting field: experiment_1::oman::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::omanPassedQc::${variable} + starting field: experiment_2::oman::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate obs that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ObsValuePassedQc::${variable} + starting field: experiment_1::ObsValue::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate obs that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ObsValuePassedQc::${variable} + starting field: experiment_2::ObsValue::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +graphics: + + plotting_backend: Emcpy + figure_list: + + # Correlation scatter plots + # ------------------------- + + # JEDI h(x) vs Observations + - batch figure: + variables: *variables + figure: + layout: [2,1] + figure size: [20, 10] + title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}/jedi_hofx_vs_obs_{{instrument}}_${variable}.png' + plots: + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x)' + add_title: '{{experiment_id_1}} (1)' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + markersize: 5 + color: 'black' + label: 'JEDI h(x)_0 versus obs (passed QC in JEDI)' + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx1PassedQc::${variable} + markersize: 5 + color: 'red' + label: 'JEDI h(x)_1 versus obs (passed QC in JEDI)' + + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x)' + add_title: '{{experiment_id_2}} (2)' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + markersize: 5 + color: 'black' + label: 'JEDI h(x)_0 versus obs (passed QC in JEDI)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx1PassedQc::${variable} + markersize: 5 + color: 'red' + label: 'JEDI h(x)_1 versus obs (passed QC in JEDI)' + + # Histogram plots + # --------------- + + # JEDI h(x) vs Observations + - batch figure: + variables: *variables + dynamic options: + - type: histogram_bins + data variable: experiment::omanPassedQc::${variable} + number of bins rule: 'rice' + figure: + layout: [2,1] + figure size: [20, 10] + title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histogram/${variable}/ombg_oman_{{instrument}}_${variable}.png' + plots: + - add_xlabel: 'Difference' + add_ylabel: 'Count' + add_title: '{{experiment_id_1}} (1)' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_1::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_1::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_1::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_1::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + - add_xlabel: 'Difference' + add_ylabel: 'Count' + add_title: '{{experiment_id_2}} (2)' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_2::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_2::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_2::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_2::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + # Map plots + # --------- + # Increment + - batch figure: + variables: *variables + dynamic options: + - type: vminvmaxcmap + data variable: experiment_1::ombgPassedQc::${variable} + figure: + figure size: [40,10] + layout: [4,1] + title: '{{instrument_title}} | Passed QC' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/ombg_oman_{{instrument}}_${variable}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ombgPassedQc::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::omanPassedQc::${variable} + markersize: 2 + label: OmBg + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ombgPassedQc::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::omanPassedQc::${variable} + markersize: 2 + label: OmBg + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - batch figure: + variables: *variables + dynamic options: + - type: vminvmaxcmap + data variable: experiment::EffectiveQC1::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: '{{instrument_title}} | Passed QC' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/effectiveQC_{{instrument}}_${variable}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: EffectiveQC1 + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::EffectiveQC1::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: EffectiveQC1 + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::EffectiveQC1::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - batch figure: + variables: *variables + dynamic options: + - type: vminvmaxcmap + data variable: experiment_1::increment::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: '{{instrument_title}} | Passed QC' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/increment_{{instrument}}_${variable}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: Increment (OmBg - OmAn) + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::increment::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: Increment (OmBg - OmAn) + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::increment::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} \ No newline at end of file diff --git a/src/swell/suites/compare/eva/observations-3dvar_atmos-geos_atmosphere.yaml b/src/swell/suites/compare/eva/observations-3dvar_atmos-geos_atmosphere.yaml new file mode 100644 index 000000000..0a6a9bb9f --- /dev/null +++ b/src/swell/suites/compare/eva/observations-3dvar_atmos-geos_atmosphere.yaml @@ -0,0 +1,969 @@ +datasets: + +- name: experiment_1 + type: IodaObsSpace + filenames: + - {{obs_path_file_1}} + channels: &channels {{channels}} + groups: + - name: ObsValue + variables: &variables {{simulated_variables}} + - name: GsiHofXBc + #- name: GsiEffectiveQC + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: EffectiveQC0 + - name: EffectiveQC1 + - name: MetaData + +- name: experiment_2 + type: IodaObsSpace + filenames: + - {{obs_path_file_2}} + channels: *channels + groups: + - name: ObsValue + variables: *variables + - name: GsiHofXBc + #- name: GsiEffectiveQC + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: EffectiveQC0 + - name: EffectiveQC1 + - name: MetaData + +transforms: + +# Generate hofx0 for GSI 1 +- transform: arithmetic + new name: experiment_1::ObsValueMinusGsiHofXBc::${variable} + equals: experiment_1::ObsValue::${variable}-experiment_1::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx0 for GSI 2 +- transform: arithmetic + new name: experiment_2::ObsValueMinusGsiHofXBc::${variable} + equals: experiment_2::ObsValue::${variable}-experiment_2::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx0 for JEDI 1 +- transform: arithmetic + new name: experiment_1::ObsValueMinusHofx0::${variable} + equals: experiment_1::ObsValue::${variable}-experiment_1::hofx0::${variable} + for: + variable: *variables + +# Generate hofx0 for JEDI 2 +- transform: arithmetic + new name: experiment_2::ObsValueMinusHofx0::${variable} + equals: experiment_2::ObsValue::${variable}-experiment_2::hofx0::${variable} + for: + variable: *variables + +# Generate hofx difference 1 +- transform: arithmetic + new name: experiment_1::Hofx0MinusGsiHofXBc::${variable} + equals: experiment_1::hofx0::${variable}-experiment_1::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx difference 2 +- transform: arithmetic + new name: experiment_2::Hofx0MinusGsiHofXBc::${variable} + equals: experiment_2::hofx0::${variable}-experiment_2::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::hofx0PassedQc::${variable} + starting field: experiment_1::hofx0::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::hofx0PassedQc::${variable} + starting field: experiment_2::hofx0::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate GSI hofx that passed JEDI QC 1 +- transform: accept where + new name: experiment_1::GsiHofXBcPassedQc::${variable} + starting field: experiment_1::GsiHofXBc::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate GSI hofx that passed JEDI QC 2 +- transform: accept where + new name: experiment_2::GsiHofXBcPassedQc::${variable} + starting field: experiment_2::GsiHofXBc::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ObsValueMinushofx0PassedQc::${variable} + starting field: experiment_1::ObsValueMinusHofx0::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ObsValueMinushofx0PassedQc::${variable} + starting field: experiment_2::ObsValueMinusHofx0::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for GSI 1 +- transform: accept where + new name: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} + starting field: experiment_1::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for GSI 2 +- transform: accept where + new name: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} + starting field: experiment_2::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ombgPassedQc::${variable} + starting field: experiment_1::ombg::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ombgPassedQc::${variable} + starting field: experiment_2::ombg::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::omanPassedQc::${variable} + starting field: experiment_1::oman::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::omanPassedQc::${variable} + starting field: experiment_2::oman::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate obs contribution to analysis (OmA*OmA)-(OmB*OmB) 1 +- transform: arithmetic + new name: experiment_1::ResidualRMSdiff::${variable} + equals: (experiment_1::omanPassedQc::${variable})*(experiment_1::omanPassedQc::${variable})-(experiment_1::ombgPassedQc::${variable})*(experiment_1::ombgPassedQc::${variable}) + for: + variable: *variables + +graphics: + + plotting_backend: Emcpy + figure_list: + + # Correlation scatter plots + # ------------------------- + + # JEDI h(x) vs Observations + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + figure size: [20, 10] + title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x)' + add_grid: + add_title: '{{experiment_id_1}} (1)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI)' + + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x)' + add_grid: + add_title: '{{experiment_id_2}} (2)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI)' + + # GSI h(x) vs Observations + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + figure size: [20, 10] + title: 'Observations vs. GSI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation Value' + add_ylabel: 'GSI h(x)' + add_grid: + add_title: '{{experiment_1}} (1)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::GsiHofXBc::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::GsiHofXBcPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI h(x) versus obs (passed QC in JEDI)' + + # JEDI h(x) vs GSI h(x) + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + figure size: [20, 10] + title: 'JEDI h(x) vs. GSI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx_vs_jedi0_hofx_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GSI h(x)' + add_ylabel: 'JEDI h(x)' + add_grid: + add_title: '{{experiment_id_1}}' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::GsiHofXBc::${variable} + y: + variable: experiment_1::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus GSI h(x)' + - type: Scatter + x: + variable: experiment_1::GsiHofXBcPassedQc::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' + + - add_xlabel: 'GSI h(x)' + add_ylabel: 'JEDI h(x)' + add_grid: + add_title: '{{experiment_id_2}}' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::GsiHofXBc::${variable} + y: + variable: experiment_2::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus GSI h(x)' + - type: Scatter + x: + variable: experiment_2::GsiHofXBcPassedQc::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' + + # JEDI hofx0 vs GSI hofx0 + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + figure size: [20, 10] + title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GSI observation minus h(x)' + add_ylabel: 'JEDI observation minus h(x)' + add_grid: + add_title: '{{experiment_id_1}} (1)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + y: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI hofx0 vs JEDI hofx0 (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} + y: + variable: experiment_1::ObsValueMinushofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' + + - add_xlabel: 'GSI observation minus h(x)' + add_ylabel: 'JEDI observation minus h(x)' + add_grid: + add_title: '{{experiment_id_2}} (2)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + y: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI hofx0 vs JEDI hofx0 (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} + y: + variable: experiment_2::ObsValueMinushofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' + + # JEDI oma vs omb + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + figure size: [20, 10] + title: 'OmA vs. OmB | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_oma_vs_omb_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'OmA' + add_ylabel: 'OmB' + add_grid: + add_title: '{{experiment_id_1}} (1)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::oman::${variable} + y: + variable: experiment_1::ombg::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'OmA versus OmB (all residuals)' + - type: Scatter + x: + variable: experiment_1::omanPassedQc::${variable} + y: + variable: experiment_1::ombgPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'OmA versus OmB (passed QC)' + + - add_xlabel: 'OmA' + add_ylabel: 'OmB' + add_grid: + add_title: '{{experiment_id_2}} (2)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::oman::${variable} + y: + variable: experiment_2::ombg::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'OmA versus OmB (all residuals)' + - type: Scatter + x: + variable: experiment_2::omanPassedQc::${variable} + y: + variable: experiment_2::ombgPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'OmA versus OmB (passed QC)' + +# Map plots# --------- + + # Observations + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValue::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: 'Observations | {{instrument_title}} | Obs Value' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/observations_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: "{{experiment_id_1}} (1)" + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ObsValue::${variable} + channel: ${channel} + markersize: 2 + label: ObsValue + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: "{{experiment_id_2}} (2)" + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValue::${variable} + channel: ${channel} + markersize: 2 + label: ObsValue + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx0 jedi + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValueMinusHofx0::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'JEDI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_jedi_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx0 gsi + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: 'GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_gsi_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx difference + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: 'Hofx0 Difference | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_difference_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::Hofx0MinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # RMS(oma)-RMS(omb) difference + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ResidualRMSdiff::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: 'RMS Residual Difference | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/rmsres_difference_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ResidualRMSdiff::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ResidualRMSdiff::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + +# Histogram plots# --------------- + + # hofx0 vs hofx0 + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: histogram_bins + channel: ${channel} + number of bins rule: sturges + data variable: experiment_1::ObsValueMinusHofx0::${variable} + figure: + layout: [2,1] + figure size: [20, 10] + title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation minus h(x)' + add_ylabel: 'Count' + add_title: '{{experiment_id_1}} (1)' + add_legend: + loc: 'upper left' + layers: + - type: Histogram + data: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + color: 'blue' + label: 'GSI hofx0 (all obs)' + bins: ${dynamic_bins} + alpha: 0.5 + - type: Histogram + data: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + color: 'red' + label: 'JEDI hofx0 (all obs)' + bins: ${dynamic_bins} + alpha: 0.5 + + - add_xlabel: 'Observation minus h(x)' + add_ylabel: 'Count' + add_title: '{{experiment_id_2}} (2)' + add_legend: + loc: 'upper left' + layers: + - type: Histogram + data: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + color: 'blue' + label: 'GSI hofx0 (all obs)' + bins: ${dynamic_bins} + alpha: 0.5 + - type: Histogram + data: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + color: 'red' + label: 'JEDI hofx0 (all obs)' + bins: ${dynamic_bins} + alpha: 0.5 + + # JEDI omb vs oma + - batch figure: + variables: *variables + dynamic options: + - type: histogram_bins + data variable: experiment_1 ::omanPassedQc::${variable} + number of bins rule: 'rice' + figure: + layout: [2,1] + figure size: [20, 10] + title: 'OmB vs. OmA | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}/ombg_oman_{{instrument}}_${variable}.png' + plots: + - add_xlabel: 'Difference' + add_ylabel: 'Count' + add_title: '{{experiment_id_1}} (1)' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_1::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_1::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_1::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_1::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + - add_xlabel: 'Difference' + add_ylabel: 'Count' + add_title: '{{experiment_id_2}} (2)' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_2::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_2::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_2::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_2::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + \ No newline at end of file From 6cfee267fca3268af22d54e8ec04d06f83c313f2 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 15 Dec 2025 12:02:46 -0500 Subject: [PATCH 21/51] Add cost function --- .../eva/jedi_log-geos_atmosphere.yaml | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml b/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml index 4ba4d12a0..42b937dab 100644 --- a/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml +++ b/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml @@ -62,3 +62,27 @@ graphics: variable: JediLogTest::convergence::norm_reduction_log color: 'blue' label: 'Log norm reduction' + + - figure: + title: 'Cost Function Plot' + output name: '{{cycle_dir}}/eva/jedi_log/cost_function/cost_function.png' + plots: + - add_xlabel: 'Total inner iteration number' + add_ylabel: 'Quadratic Cost Function' + layers: + - type: LinePlot + x: + variable: JediLogTest::convergence::total_iteration + y: + variable: JediLogTest::convergence::Jb + color: 'red' + + - add_xlabel: 'Total inner iteration number' + add_ylabel: 'Log(norm reduction)' + layers: + - type: LinePlot + x: + variable: JediLogTest::convergence::total_iteration + y: + variable: JediLogTest::convergence::JoJc + color: 'blue' \ No newline at end of file From 51759dd405005d2669bd90ad9b4e9270c20ed28e Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 15 Dec 2025 14:42:10 -0500 Subject: [PATCH 22/51] fix --- .../eva/jedi_log-geos_atmosphere.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml b/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml index 42b937dab..6f1a6f669 100644 --- a/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml +++ b/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml @@ -69,20 +69,20 @@ graphics: plots: - add_xlabel: 'Total inner iteration number' add_ylabel: 'Quadratic Cost Function' + add_legend: layers: - type: LinePlot + label: 'jb' x: variable: JediLogTest::convergence::total_iteration y: - variable: JediLogTest::convergence::Jb - color: 'red' - - - add_xlabel: 'Total inner iteration number' - add_ylabel: 'Log(norm reduction)' - layers: + variable: JediLogTest::convergence::jb + color: 'black' + linestyle: '--' - type: LinePlot + label: 'jojc' x: variable: JediLogTest::convergence::total_iteration y: - variable: JediLogTest::convergence::JoJc - color: 'blue' \ No newline at end of file + variable: JediLogTest::convergence::jojc + color: 'black' From 711dd2ed25a716aeeb24df6c4e5089b1a2fa9fdc Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 15 Dec 2025 15:01:53 -0500 Subject: [PATCH 23/51] add other suites cost function --- .../3dvar/eva/jedi_log-geos_marine.yaml | 24 +++++++++++++++++++ .../eva/jedi_log-geos_atmosphere.yaml | 24 +++++++++++++++++++ .../3dvar_cycle/eva/jedi_log-geos_marine.yaml | 24 +++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/src/swell/suites/3dvar/eva/jedi_log-geos_marine.yaml b/src/swell/suites/3dvar/eva/jedi_log-geos_marine.yaml index d2f373128..8bf009e48 100644 --- a/src/swell/suites/3dvar/eva/jedi_log-geos_marine.yaml +++ b/src/swell/suites/3dvar/eva/jedi_log-geos_marine.yaml @@ -55,3 +55,27 @@ graphics: variable: jedi_log_test::convergence::norm_reduction_normalized color: 'blue' label: 'Normalized norm reduction' + + - figure: + title: 'Cost Function Plot' + output name: '{{cycle_dir}}/eva/jedi_log/cost_function/cost_function.png' + plots: + - add_xlabel: 'Total inner iteration number' + add_ylabel: 'Quadratic Cost Function' + add_legend: + layers: + - type: LinePlot + label: 'jb' + x: + variable: JediLogTest::convergence::total_iteration + y: + variable: JediLogTest::convergence::jb + color: 'black' + linestyle: '--' + - type: LinePlot + label: 'jojc' + x: + variable: JediLogTest::convergence::total_iteration + y: + variable: JediLogTest::convergence::jojc + color: 'black' \ No newline at end of file diff --git a/src/swell/suites/3dvar_atmos/eva/jedi_log-geos_atmosphere.yaml b/src/swell/suites/3dvar_atmos/eva/jedi_log-geos_atmosphere.yaml index 4ba4d12a0..6f1a6f669 100644 --- a/src/swell/suites/3dvar_atmos/eva/jedi_log-geos_atmosphere.yaml +++ b/src/swell/suites/3dvar_atmos/eva/jedi_log-geos_atmosphere.yaml @@ -62,3 +62,27 @@ graphics: variable: JediLogTest::convergence::norm_reduction_log color: 'blue' label: 'Log norm reduction' + + - figure: + title: 'Cost Function Plot' + output name: '{{cycle_dir}}/eva/jedi_log/cost_function/cost_function.png' + plots: + - add_xlabel: 'Total inner iteration number' + add_ylabel: 'Quadratic Cost Function' + add_legend: + layers: + - type: LinePlot + label: 'jb' + x: + variable: JediLogTest::convergence::total_iteration + y: + variable: JediLogTest::convergence::jb + color: 'black' + linestyle: '--' + - type: LinePlot + label: 'jojc' + x: + variable: JediLogTest::convergence::total_iteration + y: + variable: JediLogTest::convergence::jojc + color: 'black' diff --git a/src/swell/suites/3dvar_cycle/eva/jedi_log-geos_marine.yaml b/src/swell/suites/3dvar_cycle/eva/jedi_log-geos_marine.yaml index d2f373128..a0805cc50 100644 --- a/src/swell/suites/3dvar_cycle/eva/jedi_log-geos_marine.yaml +++ b/src/swell/suites/3dvar_cycle/eva/jedi_log-geos_marine.yaml @@ -55,3 +55,27 @@ graphics: variable: jedi_log_test::convergence::norm_reduction_normalized color: 'blue' label: 'Normalized norm reduction' + + - figure: + title: 'Cost Function Plot' + output name: '{{cycle_dir}}/eva/jedi_log/cost_function/cost_function.png' + plots: + - add_xlabel: 'Total inner iteration number' + add_ylabel: 'Quadratic Cost Function' + add_legend: + layers: + - type: LinePlot + label: 'jb' + x: + variable: JediLogTest::convergence::total_iteration + y: + variable: JediLogTest::convergence::jb + color: 'black' + linestyle: '--' + - type: LinePlot + label: 'jojc' + x: + variable: JediLogTest::convergence::total_iteration + y: + variable: JediLogTest::convergence::jojc + color: 'black' From ceec00b1ee36e8f40d02ee2f5f96b919e7212191 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Tue, 16 Dec 2025 12:53:03 -0500 Subject: [PATCH 24/51] add oman and ombg vs plots --- ...rvations-3dfgat_atmos-geos_atmosphere.yaml | 34 +- .../eva/observations-3dvar-geos_marine.yaml | 530 ---------- ...ervations-3dvar_atmos-geos_atmosphere.yaml | 969 ------------------ 3 files changed, 32 insertions(+), 1501 deletions(-) delete mode 100644 src/swell/suites/compare/eva/observations-3dvar-geos_marine.yaml delete mode 100644 src/swell/suites/compare/eva/observations-3dvar_atmos-geos_atmosphere.yaml diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml index 53e213ec3..ed914a220 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml @@ -619,8 +619,8 @@ graphics: variables: *variables channels: *channels figure: - layout: [2,1] - figure size: [20, 10] + layout: [4,1] + figure size: [40, 10] title: 'OmA vs. OmB | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_oma_vs_omb_{{instrument}}_${variable}${channel}.png' plots: @@ -676,6 +676,36 @@ graphics: color: 'red' label: 'OmA versus OmB (passed QC)' + - add_xlabel: 'OmA {{experiment_id_1}} (1)' + add_ylabel: 'OmA {{experiment_id_2}} (2)' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::oman::${variable} + y: + variable: experiment_2::oman::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + + - add_xlabel: 'OmB {{experiment_id_1}} (1)' + add_ylabel: 'OmB {{experiment_id_2}} (2)' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ombg::${variable} + y: + variable: experiment_2::ombg::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + # JediFinalObsError vs GsiObsFinalObsError - batch figure: variables: *variables diff --git a/src/swell/suites/compare/eva/observations-3dvar-geos_marine.yaml b/src/swell/suites/compare/eva/observations-3dvar-geos_marine.yaml deleted file mode 100644 index 453036e22..000000000 --- a/src/swell/suites/compare/eva/observations-3dvar-geos_marine.yaml +++ /dev/null @@ -1,530 +0,0 @@ -datasets: - -- name: experiment_1 - type: IodaObsSpace - filenames: - - {{obs_path_file_1}} - groups: - - name: ObsValue - variables: &variables {{simulated_variables}} - - name: hofx0 - - name: hofx1 - - name: ombg - - name: oman - - name: MetaData - - name: EffectiveQC0 - - name: EffectiveQC1 - -- name: experiment_2 - type: IodaObsSpace - filenames: - - {{obs_path_file_2}} - groups: - - name: ObsValue - variables: *variables - - name: hofx0 - - name: hofx1 - - name: ombg - - name: oman - - name: MetaData - - name: EffectiveQC0 - - name: EffectiveQC1 - -transforms: - -# Generate Increment for JEDI 1 -- transform: arithmetic - new name: experiment_1::increment::${variable} - equals: experiment_1::ombg::${variable}-experiment_1::oman::${variable} - for: - variable: *variables - -# Generate Increment for JEDI 2 -- transform: arithmetic - new name: experiment_2::increment::${variable} - equals: experiment_2::ombg::${variable}-experiment_2::oman::${variable} - for: - variable: *variables - -# Generate hofx0 that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::hofx0PassedQc::${variable} - starting field: experiment_1::hofx0::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx0 that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::hofx0PassedQc::${variable} - starting field: experiment_2::hofx0::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx1 that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::hofx1PassedQc::${variable} - starting field: experiment_1::hofx1::${variable} - where: - - experiment_1::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate hofx1 that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::hofx1PassedQc::${variable} - starting field: experiment_2::hofx1::${variable} - where: - - experiment_2::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate ombg that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::ombgPassedQc::${variable} - starting field: experiment_1::ombg::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate ombg that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::ombgPassedQc::${variable} - starting field: experiment_2::ombg::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate oman that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::omanPassedQc::${variable} - starting field: experiment_1::oman::${variable} - where: - - experiment_1::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate oman that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::omanPassedQc::${variable} - starting field: experiment_2::oman::${variable} - where: - - experiment_2::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate obs that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::ObsValuePassedQc::${variable} - starting field: experiment_1::ObsValue::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate obs that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::ObsValuePassedQc::${variable} - starting field: experiment_2::ObsValue::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -graphics: - - plotting_backend: Emcpy - figure_list: - - # Correlation scatter plots - # ------------------------- - - # JEDI h(x) vs Observations - - batch figure: - variables: *variables - figure: - layout: [2,1] - figure size: [20, 10] - title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}/jedi_hofx_vs_obs_{{instrument}}_${variable}.png' - plots: - - add_xlabel: 'Observation Value' - add_ylabel: 'JEDI h(x)' - add_title: '{{experiment_id_1}} (1)' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::ObsValue::${variable} - y: - variable: experiment_1::hofx0PassedQc::${variable} - markersize: 5 - color: 'black' - label: 'JEDI h(x)_0 versus obs (passed QC in JEDI)' - - type: Scatter - x: - variable: experiment_1::ObsValue::${variable} - y: - variable: experiment_1::hofx1PassedQc::${variable} - markersize: 5 - color: 'red' - label: 'JEDI h(x)_1 versus obs (passed QC in JEDI)' - - - add_xlabel: 'Observation Value' - add_ylabel: 'JEDI h(x)' - add_title: '{{experiment_id_2}} (2)' - add_grid: - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::hofx0PassedQc::${variable} - markersize: 5 - color: 'black' - label: 'JEDI h(x)_0 versus obs (passed QC in JEDI)' - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::hofx1PassedQc::${variable} - markersize: 5 - color: 'red' - label: 'JEDI h(x)_1 versus obs (passed QC in JEDI)' - - # Histogram plots - # --------------- - - # JEDI h(x) vs Observations - - batch figure: - variables: *variables - dynamic options: - - type: histogram_bins - data variable: experiment::omanPassedQc::${variable} - number of bins rule: 'rice' - figure: - layout: [2,1] - figure size: [20, 10] - title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/histogram/${variable}/ombg_oman_{{instrument}}_${variable}.png' - plots: - - add_xlabel: 'Difference' - add_ylabel: 'Count' - add_title: '{{experiment_id_1}} (1)' - set_xlim: [-3, 3] - add_legend: - loc: 'upper left' - statistics: - fields: - - field_name: experiment_1::ombgPassedQc::${variable} - xloc: 0.5 - yloc: -0.10 - kwargs: - color: 'black' - fontsize: 8 - fontfamily: monospace - - field_name: experiment_1::omanPassedQc::${variable} - xloc: 0.5 - yloc: -0.13 - kwargs: - color: 'red' - fontsize: 8 - fontfamily: monospace - statistics_variables: - - n - - min - - mean - - max - - std - layers: - - type: Histogram - data: - variable: experiment_1::ombgPassedQc::${variable} - color: 'red' - label: 'observations minus background ' - bins: ${dynamic_bins} - alpha: 0.5 - density: true - - type: Histogram - data: - variable: experiment_1::omanPassedQc::${variable} - color: 'blue' - label: 'observations minus analysis' - bins: ${dynamic_bins} - alpha: 0.5 - density: true - - - add_xlabel: 'Difference' - add_ylabel: 'Count' - add_title: '{{experiment_id_2}} (2)' - set_xlim: [-3, 3] - add_legend: - loc: 'upper left' - statistics: - fields: - - field_name: experiment_2::ombgPassedQc::${variable} - xloc: 0.5 - yloc: -0.10 - kwargs: - color: 'black' - fontsize: 8 - fontfamily: monospace - - field_name: experiment_2::omanPassedQc::${variable} - xloc: 0.5 - yloc: -0.13 - kwargs: - color: 'red' - fontsize: 8 - fontfamily: monospace - statistics_variables: - - n - - min - - mean - - max - - std - layers: - - type: Histogram - data: - variable: experiment_2::ombgPassedQc::${variable} - color: 'red' - label: 'observations minus background ' - bins: ${dynamic_bins} - alpha: 0.5 - density: true - - type: Histogram - data: - variable: experiment_2::omanPassedQc::${variable} - color: 'blue' - label: 'observations minus analysis' - bins: ${dynamic_bins} - alpha: 0.5 - density: true - - # Map plots - # --------- - # Increment - - batch figure: - variables: *variables - dynamic options: - - type: vminvmaxcmap - data variable: experiment_1::ombgPassedQc::${variable} - figure: - figure size: [40,10] - layout: [4,1] - title: '{{instrument_title}} | Passed QC' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/ombg_oman_{{instrument}}_${variable}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: ObsValue - add_grid: - add_title: '{{experiment_id_1}} (1)' - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::ombgPassedQc::${variable} - markersize: 2 - label: OmAn - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: ObsValue - add_grid: - add_title: '{{experiment_id_1}} (1)' - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::omanPassedQc::${variable} - markersize: 2 - label: OmBg - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: ObsValue - add_grid: - add_title: '{{experiment_id_2}} (2)' - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::ombgPassedQc::${variable} - markersize: 2 - label: OmAn - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: ObsValue - add_grid: - add_title: '{{experiment_id_2}} (2)' - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::omanPassedQc::${variable} - markersize: 2 - label: OmBg - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - batch figure: - variables: *variables - dynamic options: - - type: vminvmaxcmap - data variable: experiment::EffectiveQC1::${variable} - figure: - figure size: [40,10] - layout: [2,1] - title: '{{instrument_title}} | Passed QC' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/effectiveQC_{{instrument}}_${variable}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: EffectiveQC1 - add_grid: - add_title: '{{experiment_id_1}} (1)' - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::EffectiveQC1::${variable} - markersize: 2 - label: OmAn - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: EffectiveQC1 - add_grid: - add_title: '{{experiment_id_2}} (2)' - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::EffectiveQC1::${variable} - markersize: 2 - label: OmAn - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - batch figure: - variables: *variables - dynamic options: - - type: vminvmaxcmap - data variable: experiment_1::increment::${variable} - figure: - figure size: [40,10] - layout: [2,1] - title: '{{instrument_title}} | Passed QC' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/increment_{{instrument}}_${variable}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: Increment (OmBg - OmAn) - add_grid: - add_title: '{{experiment_id_1}} (1)' - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::increment::${variable} - markersize: 2 - label: OmAn - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: Increment (OmBg - OmAn) - add_grid: - add_title: '{{experiment_id_2}} (2)' - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::increment::${variable} - markersize: 2 - label: OmAn - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} \ No newline at end of file diff --git a/src/swell/suites/compare/eva/observations-3dvar_atmos-geos_atmosphere.yaml b/src/swell/suites/compare/eva/observations-3dvar_atmos-geos_atmosphere.yaml deleted file mode 100644 index 0a6a9bb9f..000000000 --- a/src/swell/suites/compare/eva/observations-3dvar_atmos-geos_atmosphere.yaml +++ /dev/null @@ -1,969 +0,0 @@ -datasets: - -- name: experiment_1 - type: IodaObsSpace - filenames: - - {{obs_path_file_1}} - channels: &channels {{channels}} - groups: - - name: ObsValue - variables: &variables {{simulated_variables}} - - name: GsiHofXBc - #- name: GsiEffectiveQC - - name: hofx0 - - name: hofx1 - - name: ombg - - name: oman - - name: EffectiveQC0 - - name: EffectiveQC1 - - name: MetaData - -- name: experiment_2 - type: IodaObsSpace - filenames: - - {{obs_path_file_2}} - channels: *channels - groups: - - name: ObsValue - variables: *variables - - name: GsiHofXBc - #- name: GsiEffectiveQC - - name: hofx0 - - name: hofx1 - - name: ombg - - name: oman - - name: EffectiveQC0 - - name: EffectiveQC1 - - name: MetaData - -transforms: - -# Generate hofx0 for GSI 1 -- transform: arithmetic - new name: experiment_1::ObsValueMinusGsiHofXBc::${variable} - equals: experiment_1::ObsValue::${variable}-experiment_1::GsiHofXBc::${variable} - for: - variable: *variables - -# Generate hofx0 for GSI 2 -- transform: arithmetic - new name: experiment_2::ObsValueMinusGsiHofXBc::${variable} - equals: experiment_2::ObsValue::${variable}-experiment_2::GsiHofXBc::${variable} - for: - variable: *variables - -# Generate hofx0 for JEDI 1 -- transform: arithmetic - new name: experiment_1::ObsValueMinusHofx0::${variable} - equals: experiment_1::ObsValue::${variable}-experiment_1::hofx0::${variable} - for: - variable: *variables - -# Generate hofx0 for JEDI 2 -- transform: arithmetic - new name: experiment_2::ObsValueMinusHofx0::${variable} - equals: experiment_2::ObsValue::${variable}-experiment_2::hofx0::${variable} - for: - variable: *variables - -# Generate hofx difference 1 -- transform: arithmetic - new name: experiment_1::Hofx0MinusGsiHofXBc::${variable} - equals: experiment_1::hofx0::${variable}-experiment_1::GsiHofXBc::${variable} - for: - variable: *variables - -# Generate hofx difference 2 -- transform: arithmetic - new name: experiment_2::Hofx0MinusGsiHofXBc::${variable} - equals: experiment_2::hofx0::${variable}-experiment_2::GsiHofXBc::${variable} - for: - variable: *variables - -# Generate hofx that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::hofx0PassedQc::${variable} - starting field: experiment_1::hofx0::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::hofx0PassedQc::${variable} - starting field: experiment_2::hofx0::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate GSI hofx that passed JEDI QC 1 -- transform: accept where - new name: experiment_1::GsiHofXBcPassedQc::${variable} - starting field: experiment_1::GsiHofXBc::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate GSI hofx that passed JEDI QC 2 -- transform: accept where - new name: experiment_2::GsiHofXBcPassedQc::${variable} - starting field: experiment_2::GsiHofXBc::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx0 that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::ObsValueMinushofx0PassedQc::${variable} - starting field: experiment_1::ObsValueMinusHofx0::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx0 that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::ObsValueMinushofx0PassedQc::${variable} - starting field: experiment_2::ObsValueMinusHofx0::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx0 that passed QC for GSI 1 -- transform: accept where - new name: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} - starting field: experiment_1::ObsValueMinusGsiHofXBc::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate hofx0 that passed QC for GSI 2 -- transform: accept where - new name: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} - starting field: experiment_2::ObsValueMinusGsiHofXBc::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate ombg that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::ombgPassedQc::${variable} - starting field: experiment_1::ombg::${variable} - where: - - experiment_1::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate ombg that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::ombgPassedQc::${variable} - starting field: experiment_2::ombg::${variable} - where: - - experiment_2::EffectiveQC0::${variable} == 0 - for: - variable: *variables - -# Generate oman that passed QC for JEDI 1 -- transform: accept where - new name: experiment_1::omanPassedQc::${variable} - starting field: experiment_1::oman::${variable} - where: - - experiment_1::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate oman that passed QC for JEDI 2 -- transform: accept where - new name: experiment_2::omanPassedQc::${variable} - starting field: experiment_2::oman::${variable} - where: - - experiment_2::EffectiveQC1::${variable} == 0 - for: - variable: *variables - -# Generate obs contribution to analysis (OmA*OmA)-(OmB*OmB) 1 -- transform: arithmetic - new name: experiment_1::ResidualRMSdiff::${variable} - equals: (experiment_1::omanPassedQc::${variable})*(experiment_1::omanPassedQc::${variable})-(experiment_1::ombgPassedQc::${variable})*(experiment_1::ombgPassedQc::${variable}) - for: - variable: *variables - -graphics: - - plotting_backend: Emcpy - figure_list: - - # Correlation scatter plots - # ------------------------- - - # JEDI h(x) vs Observations - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - figure size: [20, 10] - title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'Observation Value' - add_ylabel: 'JEDI h(x)' - add_grid: - add_title: '{{experiment_id_1}} (1)' - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::ObsValue::${variable} - y: - variable: experiment_1::hofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JEDI h(x) versus obs (all obs)' - - type: Scatter - x: - variable: experiment_1::ObsValue::${variable} - y: - variable: experiment_1::hofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JEDI h(x) versus obs (passed QC in JEDI)' - - - add_xlabel: 'Observation Value' - add_ylabel: 'JEDI h(x)' - add_grid: - add_title: '{{experiment_id_2}} (2)' - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::hofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JEDI h(x) versus obs (all obs)' - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::hofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JEDI h(x) versus obs (passed QC in JEDI)' - - # GSI h(x) vs Observations - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - figure size: [20, 10] - title: 'Observations vs. GSI h(x) | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'Observation Value' - add_ylabel: 'GSI h(x)' - add_grid: - add_title: '{{experiment_1}} (1)' - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::GsiHofXBc::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'GSI h(x) versus obs (all obs)' - - type: Scatter - x: - variable: experiment_2::ObsValue::${variable} - y: - variable: experiment_2::GsiHofXBcPassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'GSI h(x) versus obs (passed QC in JEDI)' - - # JEDI h(x) vs GSI h(x) - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - figure size: [20, 10] - title: 'JEDI h(x) vs. GSI h(x) | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx_vs_jedi0_hofx_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'GSI h(x)' - add_ylabel: 'JEDI h(x)' - add_grid: - add_title: '{{experiment_id_1}}' - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::GsiHofXBc::${variable} - y: - variable: experiment_1::hofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JEDI h(x) versus GSI h(x)' - - type: Scatter - x: - variable: experiment_1::GsiHofXBcPassedQc::${variable} - y: - variable: experiment_1::hofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' - - - add_xlabel: 'GSI h(x)' - add_ylabel: 'JEDI h(x)' - add_grid: - add_title: '{{experiment_id_2}}' - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::GsiHofXBc::${variable} - y: - variable: experiment_2::hofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'JEDI h(x) versus GSI h(x)' - - type: Scatter - x: - variable: experiment_2::GsiHofXBcPassedQc::${variable} - y: - variable: experiment_2::hofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' - - # JEDI hofx0 vs GSI hofx0 - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - figure size: [20, 10] - title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'GSI observation minus h(x)' - add_ylabel: 'JEDI observation minus h(x)' - add_grid: - add_title: '{{experiment_id_1}} (1)' - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} - y: - variable: experiment_1::ObsValueMinusHofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'GSI hofx0 vs JEDI hofx0 (all obs)' - - type: Scatter - x: - variable: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} - y: - variable: experiment_1::ObsValueMinushofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' - - - add_xlabel: 'GSI observation minus h(x)' - add_ylabel: 'JEDI observation minus h(x)' - add_grid: - add_title: '{{experiment_id_2}} (2)' - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} - y: - variable: experiment_2::ObsValueMinusHofx0::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'GSI hofx0 vs JEDI hofx0 (all obs)' - - type: Scatter - x: - variable: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} - y: - variable: experiment_2::ObsValueMinushofx0PassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' - - # JEDI oma vs omb - - batch figure: - variables: *variables - channels: *channels - figure: - layout: [2,1] - figure size: [20, 10] - title: 'OmA vs. OmB | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_oma_vs_omb_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'OmA' - add_ylabel: 'OmB' - add_grid: - add_title: '{{experiment_id_1}} (1)' - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_1::oman::${variable} - y: - variable: experiment_1::ombg::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'OmA versus OmB (all residuals)' - - type: Scatter - x: - variable: experiment_1::omanPassedQc::${variable} - y: - variable: experiment_1::ombgPassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'OmA versus OmB (passed QC)' - - - add_xlabel: 'OmA' - add_ylabel: 'OmB' - add_grid: - add_title: '{{experiment_id_2}} (2)' - add_legend: - loc: 'upper left' - layers: - - type: Scatter - x: - variable: experiment_2::oman::${variable} - y: - variable: experiment_2::ombg::${variable} - channel: ${channel} - markersize: 5 - color: 'black' - label: 'OmA versus OmB (all residuals)' - - type: Scatter - x: - variable: experiment_2::omanPassedQc::${variable} - y: - variable: experiment_2::ombgPassedQc::${variable} - channel: ${channel} - markersize: 5 - color: 'red' - label: 'OmA versus OmB (passed QC)' - -# Map plots# --------- - - # Observations - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: vminvmaxcmap - channel: ${channel} - data variable: experiment_1::ObsValue::${variable} - figure: - figure size: [40,10] - layout: [2,1] - title: 'Observations | {{instrument_title}} | Obs Value' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/observations_{{instrument}}_${variable}${channel}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: ObsValue - add_grid: - add_title: "{{experiment_id_1}} (1)" - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::ObsValue::${variable} - channel: ${channel} - markersize: 2 - label: ObsValue - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: ObsValue - add_grid: - add_title: "{{experiment_id_2}} (2)" - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::ObsValue::${variable} - channel: ${channel} - markersize: 2 - label: ObsValue - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - # hofx0 jedi - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: vminvmaxcmap - channel: ${channel} - data variable: experiment_1::ObsValueMinusHofx0::${variable} - figure: - figure size: [20,10] - layout: [2,1] - title: 'JEDI hofx0 | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_jedi_{{instrument}}_${variable}${channel}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - add_title: '{{experiment_id_1}} (1)' - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::ObsValueMinusHofx0::${variable} - channel: ${channel} - markersize: 2 - label: '${variable}' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - add_title: '{{experiment_id_2}} (2)' - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::ObsValueMinusHofx0::${variable} - channel: ${channel} - markersize: 2 - label: '${variable}' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - # hofx0 gsi - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: vminvmaxcmap - channel: ${channel} - data variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} - figure: - figure size: [40,10] - layout: [2,1] - title: 'GSI hofx0 | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_gsi_{{instrument}}_${variable}${channel}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - add_title: '{{experiment_id_1}} (1)' - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} - channel: ${channel} - markersize: 2 - label: '${variable}' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - add_title: '{{experiment_id_2}} (2)' - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} - channel: ${channel} - markersize: 2 - label: '${variable}' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - # hofx difference - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: vminvmaxcmap - channel: ${channel} - data variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} - figure: - figure size: [40,10] - layout: [2,1] - title: 'Hofx0 Difference | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_difference_{{instrument}}_${variable}${channel}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - add_title: '{{experiment_id_1}} (1)' - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} - channel: ${channel} - markersize: 2 - label: '${variable}' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - add_title: '{{experiment_id_2}} (2)' - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::Hofx0MinusGsiHofXBc::${variable} - channel: ${channel} - markersize: 2 - label: '${variable}' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - # RMS(oma)-RMS(omb) difference - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: vminvmaxcmap - channel: ${channel} - data variable: experiment_1::ResidualRMSdiff::${variable} - figure: - figure size: [40,10] - layout: [2,1] - title: 'RMS Residual Difference | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/rmsres_difference_{{instrument}}_${variable}${channel}.png' - plots: - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - add_title: '{{experiment_id_1}} (1)' - layers: - - type: MapScatter - longitude: - variable: experiment_1::MetaData::longitude - latitude: - variable: experiment_1::MetaData::latitude - data: - variable: experiment_1::ResidualRMSdiff::${variable} - channel: ${channel} - markersize: 2 - label: '${variable}' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - - - mapping: - projection: plcarr - domain: global - add_map_features: ['coastline'] - add_colorbar: - label: '${variable}' - add_grid: - add_title: '{{experiment_id_2}} (2)' - layers: - - type: MapScatter - longitude: - variable: experiment_2::MetaData::longitude - latitude: - variable: experiment_2::MetaData::latitude - data: - variable: experiment_2::ResidualRMSdiff::${variable} - channel: ${channel} - markersize: 2 - label: '${variable}' - colorbar: true - cmap: ${dynamic_cmap} - vmin: ${dynamic_vmin} - vmax: ${dynamic_vmax} - -# Histogram plots# --------------- - - # hofx0 vs hofx0 - - batch figure: - variables: *variables - channels: *channels - dynamic options: - - type: histogram_bins - channel: ${channel} - number of bins rule: sturges - data variable: experiment_1::ObsValueMinusHofx0::${variable} - figure: - layout: [2,1] - figure size: [20, 10] - title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' - plots: - - add_xlabel: 'Observation minus h(x)' - add_ylabel: 'Count' - add_title: '{{experiment_id_1}} (1)' - add_legend: - loc: 'upper left' - layers: - - type: Histogram - data: - variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} - channel: ${channel} - color: 'blue' - label: 'GSI hofx0 (all obs)' - bins: ${dynamic_bins} - alpha: 0.5 - - type: Histogram - data: - variable: experiment_1::ObsValueMinusHofx0::${variable} - channel: ${channel} - color: 'red' - label: 'JEDI hofx0 (all obs)' - bins: ${dynamic_bins} - alpha: 0.5 - - - add_xlabel: 'Observation minus h(x)' - add_ylabel: 'Count' - add_title: '{{experiment_id_2}} (2)' - add_legend: - loc: 'upper left' - layers: - - type: Histogram - data: - variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} - channel: ${channel} - color: 'blue' - label: 'GSI hofx0 (all obs)' - bins: ${dynamic_bins} - alpha: 0.5 - - type: Histogram - data: - variable: experiment_2::ObsValueMinusHofx0::${variable} - channel: ${channel} - color: 'red' - label: 'JEDI hofx0 (all obs)' - bins: ${dynamic_bins} - alpha: 0.5 - - # JEDI omb vs oma - - batch figure: - variables: *variables - dynamic options: - - type: histogram_bins - data variable: experiment_1 ::omanPassedQc::${variable} - number of bins rule: 'rice' - figure: - layout: [2,1] - figure size: [20, 10] - title: 'OmB vs. OmA | {{instrument_title}} | ${variable_title}' - output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}/ombg_oman_{{instrument}}_${variable}.png' - plots: - - add_xlabel: 'Difference' - add_ylabel: 'Count' - add_title: '{{experiment_id_1}} (1)' - set_xlim: [-3, 3] - add_legend: - loc: 'upper left' - statistics: - fields: - - field_name: experiment_1::ombgPassedQc::${variable} - xloc: 0.5 - yloc: -0.10 - kwargs: - color: 'black' - fontsize: 8 - fontfamily: monospace - - field_name: experiment_1::omanPassedQc::${variable} - xloc: 0.5 - yloc: -0.13 - kwargs: - color: 'red' - fontsize: 8 - fontfamily: monospace - statistics_variables: - - n - - min - - mean - - max - - std - layers: - - type: Histogram - data: - variable: experiment_1::ombgPassedQc::${variable} - color: 'red' - label: 'observations minus background ' - bins: ${dynamic_bins} - alpha: 0.5 - density: true - - type: Histogram - data: - variable: experiment_1::omanPassedQc::${variable} - color: 'blue' - label: 'observations minus analysis' - bins: ${dynamic_bins} - alpha: 0.5 - density: true - - - add_xlabel: 'Difference' - add_ylabel: 'Count' - add_title: '{{experiment_id_2}} (2)' - set_xlim: [-3, 3] - add_legend: - loc: 'upper left' - statistics: - fields: - - field_name: experiment_2::ombgPassedQc::${variable} - xloc: 0.5 - yloc: -0.10 - kwargs: - color: 'black' - fontsize: 8 - fontfamily: monospace - - field_name: experiment_2::omanPassedQc::${variable} - xloc: 0.5 - yloc: -0.13 - kwargs: - color: 'red' - fontsize: 8 - fontfamily: monospace - statistics_variables: - - n - - min - - mean - - max - - std - layers: - - type: Histogram - data: - variable: experiment_2::ombgPassedQc::${variable} - color: 'red' - label: 'observations minus background ' - bins: ${dynamic_bins} - alpha: 0.5 - density: true - - type: Histogram - data: - variable: experiment_2::omanPassedQc::${variable} - color: 'blue' - label: 'observations minus analysis' - bins: ${dynamic_bins} - alpha: 0.5 - density: true - \ No newline at end of file From 435ccf499b1cb8f6400a4b77a00ebccd7e0e287e Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Tue, 16 Dec 2025 14:13:58 -0500 Subject: [PATCH 25/51] Revise plots --- .../eva/jedi_log-geos_atmosphere.yaml | 15 +-- .../eva/jedi_log-geos_atmosphere.yaml | 15 +-- .../comparison_jedi_log-geos_atmosphere.yaml | 92 +++++++++++++++++++ src/swell/tasks/eva_comparison_jedi_log.py | 13 +++ 4 files changed, 121 insertions(+), 14 deletions(-) diff --git a/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml b/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml index 6f1a6f669..2d848d549 100644 --- a/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml +++ b/src/swell/suites/3dfgat_atmos/eva/jedi_log-geos_atmosphere.yaml @@ -72,17 +72,18 @@ graphics: add_legend: layers: - type: LinePlot - label: 'jb' + label: 'jojc' x: variable: JediLogTest::convergence::total_iteration y: - variable: JediLogTest::convergence::jb - color: 'black' - linestyle: '--' + variable: JediLogTest::convergence::jojc + color: 'blue' + markersize: 2 - type: LinePlot - label: 'jojc' + label: 'jb' x: variable: JediLogTest::convergence::total_iteration y: - variable: JediLogTest::convergence::jojc - color: 'black' + variable: JediLogTest::convergence::jb + color: 'red' + markersize: 2 diff --git a/src/swell/suites/3dvar_atmos/eva/jedi_log-geos_atmosphere.yaml b/src/swell/suites/3dvar_atmos/eva/jedi_log-geos_atmosphere.yaml index 6f1a6f669..2d848d549 100644 --- a/src/swell/suites/3dvar_atmos/eva/jedi_log-geos_atmosphere.yaml +++ b/src/swell/suites/3dvar_atmos/eva/jedi_log-geos_atmosphere.yaml @@ -72,17 +72,18 @@ graphics: add_legend: layers: - type: LinePlot - label: 'jb' + label: 'jojc' x: variable: JediLogTest::convergence::total_iteration y: - variable: JediLogTest::convergence::jb - color: 'black' - linestyle: '--' + variable: JediLogTest::convergence::jojc + color: 'blue' + markersize: 2 - type: LinePlot - label: 'jojc' + label: 'jb' x: variable: JediLogTest::convergence::total_iteration y: - variable: JediLogTest::convergence::jojc - color: 'black' + variable: JediLogTest::convergence::jb + color: 'red' + markersize: 2 diff --git a/src/swell/suites/compare/eva/comparison_jedi_log-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_jedi_log-geos_atmosphere.yaml index 5ae7bc073..4c8a89d9f 100644 --- a/src/swell/suites/compare/eva/comparison_jedi_log-geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_jedi_log-geos_atmosphere.yaml @@ -106,3 +106,95 @@ graphics: variable: JediLogTest_2::convergence::norm_reduction_log color: 'green' label: 'Log norm reduction 2' + + - figure: + title: 'Cost Function Plot' + output name: '{{cycle_dir}}/eva/jedi_log/cost_function/cost_function.png' + layout: [3, 1] + #figure size: [10, 30] + plots: + - add_xlabel: 'Total inner iteration number' + add_ylabel: 'Quadratic Cost Function' + add_legend: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: LinePlot + label: 'jb' + x: + variable: JediLogTest_1::convergence::total_iteration + y: + variable: JediLogTest_1::convergence::jb + color: 'red' + linestyle: '--' + markersize: 2 + - type: LinePlot + label: 'jojc' + x: + variable: JediLogTest_1::convergence::total_iteration + y: + variable: JediLogTest_1::convergence::jojc + color: 'blue' + markersize: 2 + + - add_xlabel: 'Total inner iteration number' + add_ylabel: 'Quadratic Cost Function' + add_legend: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: LinePlot + label: 'jb' + x: + variable: JediLogTest_2::convergence::total_iteration + y: + variable: JediLogTest_2::convergence::jb + color: 'green' + linestyle: '--' + markersize: 0 + - type: LinePlot + label: 'jojc' + x: + variable: JediLogTest_2::convergence::total_iteration + y: + variable: JediLogTest_2::convergence::jojc + color: 'black' + markersize: 0 + + - add_xlabel: 'Total inner iteration number' + add_ylabel: 'Quadratic Cost Function' + add_legend: + add_title: '1 - 2 diff' + layers: + - type: LinePlot + label: 'jb 1' + x: + variable: JediLogTest_1::convergence::total_iteration + y: + variable: JediLogTest_1::convergence::jb + color: 'red' + linestyle: '--' + markersize: 2 + - type: LinePlot + label: 'jojc 1' + x: + variable: JediLogTest_1::convergence::total_iteration + y: + variable: JediLogTest_1::convergence::jojc + color: 'blue' + markersize: 2 + - type: LinePlot + label: 'jb 2' + x: + variable: JediLogTest_2::convergence::total_iteration + y: + variable: JediLogTest_2::convergence::jb + color: 'green' + linestyle: '--' + markersize: 2 + - type: LinePlot + label: 'jojc 2' + x: + variable: JediLogTest_2::convergence::total_iteration + y: + variable: JediLogTest_2::convergence::jojc + color: 'black' + markersize: 2 diff --git a/src/swell/tasks/eva_comparison_jedi_log.py b/src/swell/tasks/eva_comparison_jedi_log.py index 51bb18757..28e27a81b 100644 --- a/src/swell/tasks/eva_comparison_jedi_log.py +++ b/src/swell/tasks/eva_comparison_jedi_log.py @@ -45,6 +45,16 @@ def execute(self) -> None: experiment_path_1 = experiment_paths[0] experiment_path_2 = experiment_paths[1] + with open(experiment_path_1, 'r') as f: + experiment_dict_1 = yaml.safe_load(f) + + experiment_id_1 = experiment_dict_1['experiment_id'] + + with open(experiment_path_2, 'r') as f: + experiment_dict_2 = yaml.safe_load(f) + + experiment_id_2 = experiment_dict_2['experiment_id'] + cycle_dir_1 = os.path.join(os.path.dirname(experiment_path_1), '..', 'run', self.__datetime__.string_directory(), self.get_model()) cycle_dir_2 = os.path.join(os.path.dirname(experiment_path_2), '..', 'run', @@ -62,6 +72,9 @@ def execute(self) -> None: eva_override['cycle_dir_1'] = cycle_dir_1 eva_override['cycle_dir_2'] = cycle_dir_2 + eva_override['experiment_id_1'] = experiment_id_1 + eva_override['experiment_id_2'] = experiment_id_2 + eva_override['log_type'] = log_type # Override the eva dictionary From 08287dad07b648146f5f9784b19bf72524444793 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Tue, 16 Dec 2025 11:44:41 -0500 Subject: [PATCH 26/51] Add other suites --- ...arison_observations-3dvar-geos_marine.yaml | 530 +++++++++ ...ervations-3dvar_atmos-geos_atmosphere.yaml | 1002 +++++++++++++++++ src/swell/utilities/run_jedi_executables.py | 19 +- 3 files changed, 1541 insertions(+), 10 deletions(-) create mode 100644 src/swell/suites/compare/eva/comparison_observations-3dvar-geos_marine.yaml create mode 100644 src/swell/suites/compare/eva/comparison_observations-3dvar_atmos-geos_atmosphere.yaml diff --git a/src/swell/suites/compare/eva/comparison_observations-3dvar-geos_marine.yaml b/src/swell/suites/compare/eva/comparison_observations-3dvar-geos_marine.yaml new file mode 100644 index 000000000..916a6f1d8 --- /dev/null +++ b/src/swell/suites/compare/eva/comparison_observations-3dvar-geos_marine.yaml @@ -0,0 +1,530 @@ +datasets: + +- name: experiment_1 + type: IodaObsSpace + filenames: + - {{obs_path_file_1}} + groups: + - name: ObsValue + variables: &variables {{simulated_variables}} + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: MetaData + - name: EffectiveQC0 + - name: EffectiveQC1 + +- name: experiment_2 + type: IodaObsSpace + filenames: + - {{obs_path_file_2}} + groups: + - name: ObsValue + variables: *variables + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: MetaData + - name: EffectiveQC0 + - name: EffectiveQC1 + +transforms: + +# Generate Increment for JEDI 1 +- transform: arithmetic + new name: experiment_1::increment::${variable} + equals: experiment_1::ombg::${variable}-experiment_1::oman::${variable} + for: + variable: *variables + +# Generate Increment for JEDI 2 +- transform: arithmetic + new name: experiment_2::increment::${variable} + equals: experiment_2::ombg::${variable}-experiment_2::oman::${variable} + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::hofx0PassedQc::${variable} + starting field: experiment_1::hofx0::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::hofx0PassedQc::${variable} + starting field: experiment_2::hofx0::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx1 that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::hofx1PassedQc::${variable} + starting field: experiment_1::hofx1::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate hofx1 that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::hofx1PassedQc::${variable} + starting field: experiment_2::hofx1::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ombgPassedQc::${variable} + starting field: experiment_1::ombg::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ombgPassedQc::${variable} + starting field: experiment_2::ombg::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::omanPassedQc::${variable} + starting field: experiment_1::oman::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::omanPassedQc::${variable} + starting field: experiment_2::oman::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate obs that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ObsValuePassedQc::${variable} + starting field: experiment_1::ObsValue::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate obs that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ObsValuePassedQc::${variable} + starting field: experiment_2::ObsValue::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +graphics: + + plotting_backend: Emcpy + figure_list: + + # Correlation scatter plots + # ------------------------- + + # JEDI h(x) vs Observations + - batch figure: + variables: *variables + figure: + layout: [2,1] + figure size: [20, 10] + title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}/jedi_hofx_vs_obs_{{instrument}}_${variable}.png' + plots: + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x)' + add_title: '{{experiment_id_1}} (1)' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + markersize: 5 + color: 'black' + label: 'JEDI h(x)_0 versus obs (passed QC in JEDI)' + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx1PassedQc::${variable} + markersize: 5 + color: 'red' + label: 'JEDI h(x)_1 versus obs (passed QC in JEDI)' + + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x)' + add_title: '{{experiment_id_2}} (2)' + add_grid: + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + markersize: 5 + color: 'black' + label: 'JEDI h(x)_0 versus obs (passed QC in JEDI)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx1PassedQc::${variable} + markersize: 5 + color: 'red' + label: 'JEDI h(x)_1 versus obs (passed QC in JEDI)' + + # Histogram plots + # --------------- + + # JEDI h(x) vs Observations + - batch figure: + variables: *variables + dynamic options: + - type: histogram_bins + data variable: experiment_1::omanPassedQc::${variable} + number of bins rule: 'rice' + figure: + layout: [2,1] + figure size: [20, 10] + title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histogram/${variable}/ombg_oman_{{instrument}}_${variable}.png' + plots: + - add_xlabel: 'Difference' + add_ylabel: 'Count' + add_title: '{{experiment_id_1}} (1)' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_1::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_1::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_1::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_1::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + - add_xlabel: 'Difference' + add_ylabel: 'Count' + add_title: '{{experiment_id_2}} (2)' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_2::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_2::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_2::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_2::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + # Map plots + # --------- + # Increment + - batch figure: + variables: *variables + dynamic options: + - type: vminvmaxcmap + data variable: experiment_1::ombgPassedQc::${variable} + figure: + figure size: [40,10] + layout: [4,1] + title: '{{instrument_title}} | Passed QC' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/ombg_oman_{{instrument}}_${variable}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ombgPassedQc::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::omanPassedQc::${variable} + markersize: 2 + label: OmBg + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ombgPassedQc::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::omanPassedQc::${variable} + markersize: 2 + label: OmBg + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - batch figure: + variables: *variables + dynamic options: + - type: vminvmaxcmap + data variable: experiment_1::EffectiveQC1::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: '{{instrument_title}} | Passed QC' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/effectiveQC_{{instrument}}_${variable}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: EffectiveQC1 + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::EffectiveQC1::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: EffectiveQC1 + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::EffectiveQC1::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - batch figure: + variables: *variables + dynamic options: + - type: vminvmaxcmap + data variable: experiment_1::increment::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: '{{instrument_title}} | Passed QC' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}/increment_{{instrument}}_${variable}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: Increment (OmBg - OmAn) + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::increment::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: Increment (OmBg - OmAn) + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::increment::${variable} + markersize: 2 + label: OmAn + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} diff --git a/src/swell/suites/compare/eva/comparison_observations-3dvar_atmos-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dvar_atmos-geos_atmosphere.yaml new file mode 100644 index 000000000..8c79a47b1 --- /dev/null +++ b/src/swell/suites/compare/eva/comparison_observations-3dvar_atmos-geos_atmosphere.yaml @@ -0,0 +1,1002 @@ +datasets: + +- name: experiment_1 + type: IodaObsSpace + filenames: + - {{obs_path_file_1}} + channels: &channels {{channels}} + groups: + - name: ObsValue + variables: &variables {{simulated_variables}} + - name: GsiHofXBc + #- name: GsiEffectiveQC + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: EffectiveQC0 + - name: EffectiveQC1 + - name: MetaData + +- name: experiment_2 + type: IodaObsSpace + filenames: + - {{obs_path_file_2}} + channels: *channels + groups: + - name: ObsValue + variables: *variables + - name: GsiHofXBc + #- name: GsiEffectiveQC + - name: hofx0 + - name: hofx1 + - name: ombg + - name: oman + - name: EffectiveQC0 + - name: EffectiveQC1 + - name: MetaData + +transforms: + +# Generate hofx0 for GSI 1 +- transform: arithmetic + new name: experiment_1::ObsValueMinusGsiHofXBc::${variable} + equals: experiment_1::ObsValue::${variable}-experiment_1::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx0 for GSI 2 +- transform: arithmetic + new name: experiment_2::ObsValueMinusGsiHofXBc::${variable} + equals: experiment_2::ObsValue::${variable}-experiment_2::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx0 for JEDI 1 +- transform: arithmetic + new name: experiment_1::ObsValueMinusHofx0::${variable} + equals: experiment_1::ObsValue::${variable}-experiment_1::hofx0::${variable} + for: + variable: *variables + +# Generate hofx0 for JEDI 2 +- transform: arithmetic + new name: experiment_2::ObsValueMinusHofx0::${variable} + equals: experiment_2::ObsValue::${variable}-experiment_2::hofx0::${variable} + for: + variable: *variables + +# Generate hofx difference 1 +- transform: arithmetic + new name: experiment_1::Hofx0MinusGsiHofXBc::${variable} + equals: experiment_1::hofx0::${variable}-experiment_1::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx difference 2 +- transform: arithmetic + new name: experiment_2::Hofx0MinusGsiHofXBc::${variable} + equals: experiment_2::hofx0::${variable}-experiment_2::GsiHofXBc::${variable} + for: + variable: *variables + +# Generate hofx that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::hofx0PassedQc::${variable} + starting field: experiment_1::hofx0::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::hofx0PassedQc::${variable} + starting field: experiment_2::hofx0::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate GSI hofx that passed JEDI QC 1 +- transform: accept where + new name: experiment_1::GsiHofXBcPassedQc::${variable} + starting field: experiment_1::GsiHofXBc::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate GSI hofx that passed JEDI QC 2 +- transform: accept where + new name: experiment_2::GsiHofXBcPassedQc::${variable} + starting field: experiment_2::GsiHofXBc::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ObsValueMinushofx0PassedQc::${variable} + starting field: experiment_1::ObsValueMinusHofx0::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ObsValueMinushofx0PassedQc::${variable} + starting field: experiment_2::ObsValueMinusHofx0::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for GSI 1 +- transform: accept where + new name: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} + starting field: experiment_1::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate hofx0 that passed QC for GSI 2 +- transform: accept where + new name: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} + starting field: experiment_2::ObsValueMinusGsiHofXBc::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::ombgPassedQc::${variable} + starting field: experiment_1::ombg::${variable} + where: + - experiment_1::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate ombg that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::ombgPassedQc::${variable} + starting field: experiment_2::ombg::${variable} + where: + - experiment_2::EffectiveQC0::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 1 +- transform: accept where + new name: experiment_1::omanPassedQc::${variable} + starting field: experiment_1::oman::${variable} + where: + - experiment_1::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate oman that passed QC for JEDI 2 +- transform: accept where + new name: experiment_2::omanPassedQc::${variable} + starting field: experiment_2::oman::${variable} + where: + - experiment_2::EffectiveQC1::${variable} == 0 + for: + variable: *variables + +# Generate obs contribution to analysis (OmA*OmA)-(OmB*OmB) 1 +- transform: arithmetic + new name: experiment_1::ResidualRMSdiff::${variable} + equals: (experiment_1::omanPassedQc::${variable})*(experiment_1::omanPassedQc::${variable})-(experiment_1::ombgPassedQc::${variable})*(experiment_1::ombgPassedQc::${variable}) + for: + variable: *variables + +# Generate obs contribution to analysis (OmA*OmA)-(OmB*OmB) 2 +- transform: arithmetic + new name: experiment_2::ResidualRMSdiff::${variable} + equals: (experiment_2::omanPassedQc::${variable})*(experiment_2::omanPassedQc::${variable})-(experiment_2::ombgPassedQc::${variable})*(experiment_2::ombgPassedQc::${variable}) + for: + variable: *variables + +graphics: + + plotting_backend: Emcpy + figure_list: + + # Correlation scatter plots + # ------------------------- + + # JEDI h(x) vs Observations + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + figure size: [20, 10] + title: 'Observations vs. JEDI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x)' + add_grid: + add_title: '{{experiment_id_1}} (1)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI)' + + - add_xlabel: 'Observation Value' + add_ylabel: 'JEDI h(x)' + add_grid: + add_title: '{{experiment_id_2}} (2)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus obs (passed QC in JEDI)' + + # GSI h(x) vs Observations + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + figure size: [20, 10] + title: 'Observations vs. GSI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_obs_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation Value' + add_ylabel: 'GSI h(x)' + add_grid: + add_title: '{{experiment_id_1}} (1)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::GsiHofXBc::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValue::${variable} + y: + variable: experiment_1::GsiHofXBcPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI h(x) versus obs (passed QC in JEDI)' + + - add_xlabel: 'Observation Value' + add_ylabel: 'GSI h(x)' + add_grid: + add_title: '{{experiment_id_2}} (2)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::GsiHofXBc::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI h(x) versus obs (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValue::${variable} + y: + variable: experiment_2::GsiHofXBcPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI h(x) versus obs (passed QC in JEDI)' + + # JEDI h(x) vs GSI h(x) + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + figure size: [20, 10] + title: 'JEDI h(x) vs. GSI h(x) | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx_vs_jedi0_hofx_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GSI h(x)' + add_ylabel: 'JEDI h(x)' + add_grid: + add_title: '{{experiment_id_1}}' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::GsiHofXBc::${variable} + y: + variable: experiment_1::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus GSI h(x)' + - type: Scatter + x: + variable: experiment_1::GsiHofXBcPassedQc::${variable} + y: + variable: experiment_1::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' + + - add_xlabel: 'GSI h(x)' + add_ylabel: 'JEDI h(x)' + add_grid: + add_title: '{{experiment_id_2}}' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::GsiHofXBc::${variable} + y: + variable: experiment_2::hofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'JEDI h(x) versus GSI h(x)' + - type: Scatter + x: + variable: experiment_2::GsiHofXBcPassedQc::${variable} + y: + variable: experiment_2::hofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'JEDI h(x) versus GSI h(x) (passed QC in JEDI)' + + # JEDI hofx0 vs GSI hofx0 + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + figure size: [20, 10] + title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'GSI observation minus h(x)' + add_ylabel: 'JEDI observation minus h(x)' + add_grid: + add_title: '{{experiment_id_1}} (1)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + y: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI hofx0 vs JEDI hofx0 (all obs)' + - type: Scatter + x: + variable: experiment_1::ObsValueMinusGsiHofXBcPassedQc::${variable} + y: + variable: experiment_1::ObsValueMinushofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' + + - add_xlabel: 'GSI observation minus h(x)' + add_ylabel: 'JEDI observation minus h(x)' + add_grid: + add_title: '{{experiment_id_2}} (2)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + y: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'GSI hofx0 vs JEDI hofx0 (all obs)' + - type: Scatter + x: + variable: experiment_2::ObsValueMinusGsiHofXBcPassedQc::${variable} + y: + variable: experiment_2::ObsValueMinushofx0PassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'GSI hofx0 vs JEDI hofx0 (passed QC in JEDI)' + + # JEDI oma vs omb + - batch figure: + variables: *variables + channels: *channels + figure: + layout: [2,1] + figure size: [20, 10] + title: 'OmA vs. OmB | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_oma_vs_omb_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'OmA' + add_ylabel: 'OmB' + add_grid: + add_title: '{{experiment_id_1}} (1)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_1::oman::${variable} + y: + variable: experiment_1::ombg::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'OmA versus OmB (all residuals)' + - type: Scatter + x: + variable: experiment_1::omanPassedQc::${variable} + y: + variable: experiment_1::ombgPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'OmA versus OmB (passed QC)' + + - add_xlabel: 'OmA' + add_ylabel: 'OmB' + add_grid: + add_title: '{{experiment_id_2}} (2)' + add_legend: + loc: 'upper left' + layers: + - type: Scatter + x: + variable: experiment_2::oman::${variable} + y: + variable: experiment_2::ombg::${variable} + channel: ${channel} + markersize: 5 + color: 'black' + label: 'OmA versus OmB (all residuals)' + - type: Scatter + x: + variable: experiment_2::omanPassedQc::${variable} + y: + variable: experiment_2::ombgPassedQc::${variable} + channel: ${channel} + markersize: 5 + color: 'red' + label: 'OmA versus OmB (passed QC)' + +# Map plots# --------- + + # Observations + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValue::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: 'Observations | {{instrument_title}} | Obs Value' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/observations_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: "{{experiment_id_1}} (1)" + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ObsValue::${variable} + channel: ${channel} + markersize: 2 + label: ObsValue + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: ObsValue + add_grid: + add_title: "{{experiment_id_2}} (2)" + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValue::${variable} + channel: ${channel} + markersize: 2 + label: ObsValue + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx0 jedi + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValueMinusHofx0::${variable} + figure: + figure size: [20,10] + layout: [2,1] + title: 'JEDI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_jedi_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx0 gsi + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: 'GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_gsi_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # hofx difference + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: 'Hofx0 Difference | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/hofx0_difference_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::Hofx0MinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::Hofx0MinusGsiHofXBc::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + # RMS(oma)-RMS(omb) difference + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: vminvmaxcmap + channel: ${channel} + data variable: experiment_1::ResidualRMSdiff::${variable} + figure: + figure size: [40,10] + layout: [2,1] + title: 'RMS Residual Difference | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/map_plots/${variable}${channel}/rmsres_difference_{{instrument}}_${variable}${channel}.png' + plots: + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_1}} (1)' + layers: + - type: MapScatter + longitude: + variable: experiment_1::MetaData::longitude + latitude: + variable: experiment_1::MetaData::latitude + data: + variable: experiment_1::ResidualRMSdiff::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + + - mapping: + projection: plcarr + domain: global + add_map_features: ['coastline'] + add_colorbar: + label: '${variable}' + add_grid: + add_title: '{{experiment_id_2}} (2)' + layers: + - type: MapScatter + longitude: + variable: experiment_2::MetaData::longitude + latitude: + variable: experiment_2::MetaData::latitude + data: + variable: experiment_2::ResidualRMSdiff::${variable} + channel: ${channel} + markersize: 2 + label: '${variable}' + colorbar: true + cmap: ${dynamic_cmap} + vmin: ${dynamic_vmin} + vmax: ${dynamic_vmax} + +# Histogram plots# --------------- + + # hofx0 vs hofx0 + - batch figure: + variables: *variables + channels: *channels + dynamic options: + - type: histogram_bins + channel: ${channel} + number of bins rule: sturges + data variable: experiment_1::ObsValueMinusHofx0::${variable} + figure: + layout: [2,1] + figure size: [20, 10] + title: 'JEDI hofx0 vs. GSI hofx0 | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}${channel}/gsi_hofx0_vs_jedi_hofx0_{{instrument}}_${variable}${channel}.png' + plots: + - add_xlabel: 'Observation minus h(x)' + add_ylabel: 'Count' + add_title: '{{experiment_id_1}} (1)' + add_legend: + loc: 'upper left' + layers: + - type: Histogram + data: + variable: experiment_1::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + color: 'blue' + label: 'GSI hofx0 (all obs)' + bins: ${dynamic_bins} + alpha: 0.5 + - type: Histogram + data: + variable: experiment_1::ObsValueMinusHofx0::${variable} + channel: ${channel} + color: 'red' + label: 'JEDI hofx0 (all obs)' + bins: ${dynamic_bins} + alpha: 0.5 + + - add_xlabel: 'Observation minus h(x)' + add_ylabel: 'Count' + add_title: '{{experiment_id_2}} (2)' + add_legend: + loc: 'upper left' + layers: + - type: Histogram + data: + variable: experiment_2::ObsValueMinusGsiHofXBc::${variable} + channel: ${channel} + color: 'blue' + label: 'GSI hofx0 (all obs)' + bins: ${dynamic_bins} + alpha: 0.5 + - type: Histogram + data: + variable: experiment_2::ObsValueMinusHofx0::${variable} + channel: ${channel} + color: 'red' + label: 'JEDI hofx0 (all obs)' + bins: ${dynamic_bins} + alpha: 0.5 + + # JEDI omb vs oma + - batch figure: + variables: *variables + dynamic options: + - type: histogram_bins + data variable: experiment_1::omanPassedQc::${variable} + number of bins rule: 'rice' + figure: + layout: [2,1] + figure size: [20, 10] + title: 'OmB vs. OmA | {{instrument_title}} | ${variable_title}' + output name: '{{cycle_dir}}/eva/{{instrument}}/histograms/${variable}/ombg_oman_{{instrument}}_${variable}.png' + plots: + - add_xlabel: 'Difference' + add_ylabel: 'Count' + add_title: '{{experiment_id_1}} (1)' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_1::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_1::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_1::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_1::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + + - add_xlabel: 'Difference' + add_ylabel: 'Count' + add_title: '{{experiment_id_2}} (2)' + set_xlim: [-3, 3] + add_legend: + loc: 'upper left' + statistics: + fields: + - field_name: experiment_2::ombgPassedQc::${variable} + xloc: 0.5 + yloc: -0.10 + kwargs: + color: 'black' + fontsize: 8 + fontfamily: monospace + - field_name: experiment_2::omanPassedQc::${variable} + xloc: 0.5 + yloc: -0.13 + kwargs: + color: 'red' + fontsize: 8 + fontfamily: monospace + statistics_variables: + - n + - min + - mean + - max + - std + layers: + - type: Histogram + data: + variable: experiment_2::ombgPassedQc::${variable} + color: 'red' + label: 'observations minus background ' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + - type: Histogram + data: + variable: experiment_2::omanPassedQc::${variable} + color: 'blue' + label: 'observations minus analysis' + bins: ${dynamic_bins} + alpha: 0.5 + density: true + diff --git a/src/swell/utilities/run_jedi_executables.py b/src/swell/utilities/run_jedi_executables.py index f2e75d224..cf33436cc 100644 --- a/src/swell/utilities/run_jedi_executables.py +++ b/src/swell/utilities/run_jedi_executables.py @@ -37,11 +37,10 @@ def check_obs( # Open file and check if number of location dimension is nonzero # -------------------------------------------------------------- - dataset = nc.Dataset(filename, 'r') - - for dim_name, dim in dataset.dimensions.items(): - if dim_name == 'Location' and dim.size > 0: - use_observation = True + with nc.Dataset(filename, 'r') as dataset: + for dim_name, dim in dataset.dimensions.items(): + if dim_name == 'Location' and dim.size > 0: + use_observation = True if input_and_output: # Check if observations in output file exists @@ -51,12 +50,12 @@ def check_obs( # Open file and check if number of location dimension is nonzero # -------------------------------------------------------------- - dataset = nc.Dataset(filename, 'r') + with nc.Dataset(filename, 'r') as dataset: - for dim_name, dim in dataset.dimensions.items(): - if dim_name == 'Location' and dim.size < 1: - print(f'IODA {observation} output has {dim.size} location dimension(s)') - use_observation = False + for dim_name, dim in dataset.dimensions.items(): + if dim_name == 'Location' and dim.size < 1: + print(f'IODA {observation} output has {dim.size} location dimension(s)') + use_observation = False return use_observation From c6cf1510a97e60abc4cafc0b36d7aeeee6b9a32c Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Tue, 16 Dec 2025 13:54:39 -0500 Subject: [PATCH 27/51] Fix figure size --- .../comparison_observations-3dfgat_atmos-geos_atmosphere.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml index ed914a220..b56bafdc4 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml @@ -620,7 +620,7 @@ graphics: channels: *channels figure: layout: [4,1] - figure size: [40, 10] + figure size: [10, 40] title: 'OmA vs. OmB | {{instrument_title}} | ${variable_title}' output name: '{{cycle_dir}}/eva/{{instrument}}/correlation_scatter/${variable}${channel}/jedi_oma_vs_omb_{{instrument}}_${variable}${channel}.png' plots: From 351dbfecb9a6330e609c3d5b574049b2b193d188 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 12 Jan 2026 14:17:16 -0500 Subject: [PATCH 28/51] Use tags for experiment names --- src/swell/tasks/jedi_log_comparison.py | 40 +++++++++++++---------- src/swell/utilities/comparisons.py | 44 ++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 src/swell/utilities/comparisons.py diff --git a/src/swell/tasks/jedi_log_comparison.py b/src/swell/tasks/jedi_log_comparison.py index ca8e8ea72..c701a13d1 100644 --- a/src/swell/tasks/jedi_log_comparison.py +++ b/src/swell/tasks/jedi_log_comparison.py @@ -14,6 +14,7 @@ import numpy as np from swell.tasks.base.task_base import taskBase +from swell.utilities.comparisons import comparison_tags # -------------------------------------------------------------------------------------------------- @@ -28,6 +29,11 @@ def execute(self): experiment_paths = self.config.comparison_experiment_paths() + experiment_tag_paths = comparison_tags(experiment_paths) + + exp_tag_0 = experiment_tag_paths.keys()[0] + exp_tag_1 = experiment_tag_paths.keys()[0] + # Get the number of iterations between experiments iterations_list = [] for path in experiment_paths: @@ -50,7 +56,7 @@ def execute(self): log_type = self.config.comparison_log_type() - for exp_num, experiment_path in enumerate(experiment_paths): + for exp_tag, experiment_path in experiment_tag_paths.items(): # Paths to cycle dirs cycles_path = os.path.join(os.path.dirname(experiment_path), '..', 'run') @@ -86,9 +92,9 @@ def execute(self): # val = field['dtype'](val) if key not in cycle_results.keys(): - cycle_results[key] = {f'exp{exp_num}': val} + cycle_results[key] = {exp_tag: val} else: - cycle_results[key][f'exp{exp_num}'] = val + cycle_results[key][exp_tag] = val for key in cycle_results.keys(): for field_name in comparison_fields.keys(): @@ -96,9 +102,9 @@ def execute(self): dtype = comparison_fields[field_name]['dtype'] if dtype == float: - if 'exp0' in cycle_results[key] and 'exp1' in cycle_results[key]: - diff = float(cycle_results[key]['exp0']) - \ - float(cycle_results[key]['exp1']) + if exp_tag_0 in cycle_results[key] and exp_tag_1 in cycle_results[key]: + diff = float(cycle_results[key][exp_tag_0]) - \ + float(cycle_results[key][exp_tag_1]) cycle_results[key]['diff'] = str(diff) if key in tolerances: key_passed = np.abs(diff) < tolerances[key] @@ -113,14 +119,14 @@ def execute(self): cycle_results[key]['diff'] = 'N/A' cycle_results[key]['pass'] = '' - widths = {'key': len(cycle), 'exp0': 0, 'exp1': 0, 'diff': 0, 'pass': 0} + widths = {'key': len(cycle), exp_tag_0: 0, exp_tag_1: 0, 'diff': 0, 'pass': 0} for cycle, cycle_results in all_results.items(): for key in cycle_results: if 'exp0' not in cycle_results[key]: - cycle_results[key]['exp0'] = 'N/A' + cycle_results[key][exp_tag_0] = 'N/A' if 'exp1' not in cycle_results[key]: - cycle_results[key]['exp1'] = 'N/A' + cycle_results[key][exp_tag_1] = 'N/A' if 'diff' not in cycle_results[key]: cycle_results[key]['diff'] = 'N/A' if 'pass' not in cycle_results[key]: @@ -128,22 +134,22 @@ def execute(self): passed = False widths['key'] = max(widths['key'], len(key)) - widths['exp0'] = max(widths['exp0'], len(cycle_results[key]['exp0'])) - widths['exp1'] = max(widths['exp1'], len(cycle_results[key]['exp1'])) + widths[exp_tag_0] = max(widths[exp_tag_0], len(cycle_results[key][exp_tag_0])) + widths[exp_tag_1] = max(widths[exp_tag_1], len(cycle_results[key][exp_tag_1])) widths['diff'] = max(widths['diff'], len(str(cycle_results[key]['diff']))) for key, val in widths.items(): widths[key] = val + 2 out_string = '\n' - out_string += f'exp0: {experiment_paths[0]}\n' - out_string += f'exp1: {experiment_paths[1]}\n' + out_string += f'{exp_tag_0}: {experiment_paths[0]}\n' + out_string += f'{exp_tag_1}: {experiment_paths[1]}\n' out_string += '\n' for cycle, cycle_results in all_results.items(): out_string += cycle + ' ' * (widths['key'] - len(cycle)) - out_string += 'exp0' + ' ' * (widths['exp0'] - len('exp0')) - out_string += 'exp1' + ' ' * (widths['exp1'] - len('exp1')) + out_string += exp_tag_0 + ' ' * (widths[exp_tag_0] - len(exp_tag_0)) + out_string += exp_tag_1 + ' ' * (widths[exp_tag_1] - len(exp_tag_1)) out_string += 'diff' + ' ' * (widths['diff'] - len('diff')) out_string += 'pass' + ' ' * (widths['pass'] - len('pass')) @@ -154,8 +160,8 @@ def execute(self): val_dict = cycle_results[key] out_string += key + ' ' * (widths['key'] - len(key)) - out_string += val_dict['exp0'] + ' ' * (widths['exp0'] - len(val_dict['exp0'])) - out_string += val_dict['exp1'] + ' ' * (widths['exp1'] - len(val_dict['exp1'])) + out_string += val_dict[exp_tag_0] + ' ' * (widths[exp_tag_0] - len(val_dict[exp_tag_0])) + out_string += val_dict[exp_tag_1] + ' ' * (widths[exp_tag_1] - len(val_dict[exp_tag_1])) out_string += val_dict['diff'] + ' ' * (widths['diff'] - len(val_dict['diff'])) out_string += str(val_dict['pass']) + ' ' * ( widths['pass'] - len(str(val_dict['pass']))) diff --git a/src/swell/utilities/comparisons.py b/src/swell/utilities/comparisons.py new file mode 100644 index 000000000..4e70f6fd9 --- /dev/null +++ b/src/swell/utilities/comparisons.py @@ -0,0 +1,44 @@ +# (C) Copyright 2021- United States Government as represented by the Administrator of the +# National Aeronautics and Space Administration. All Rights Reserved. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + + +# -------------------------------------------------------------------------------------------------- + +from swell.utilities.logger import Logger + +# -------------------------------------------------------------------------------------------------- + +def comparison_tags(pathspecs: list | dict, + logger: Logger) -> dict: + + '''Check for the correct number of experiments. Automatically assign tags + if they are not already assigned. + + The experiment in the first position will be given the label 'CTL', and + the experiment in the second position will be given the label 'EXP'. + + Parameters: + pathspecs: list or dictionary specifying the experiments to be compared. + + Returns: + Dictionary mapping tags to experiments. If the input is a dictionary, + no changes will be made.''' + + if len(pathspecs) != 2: + logger.abort(f'Exactly 2 experiments should be specified.') + + if isinstance(pathspecs, list): + pathspecs_out = {} + pathspecs_out['CTL'] = pathspecs[0] + pathspecs_out['EXP'] = pathspecs[1] + else: + pathspecs_out[str(pathspecs.keys()[0])] = pathspecs.values()[0] + pathspecs_out[str(pathspecs.keys()[1])] = pathspecs.values()[1] + + return pathspecs_out + + +# -------------------------------------------------------------------------------------------------- \ No newline at end of file From 34b8062f0824c6f7f8fa3bdbd61fcdf7d48fc105 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 12 Jan 2026 14:37:33 -0500 Subject: [PATCH 29/51] fixes --- src/swell/tasks/jedi_log_comparison.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/swell/tasks/jedi_log_comparison.py b/src/swell/tasks/jedi_log_comparison.py index c701a13d1..bd9d72b72 100644 --- a/src/swell/tasks/jedi_log_comparison.py +++ b/src/swell/tasks/jedi_log_comparison.py @@ -29,10 +29,10 @@ def execute(self): experiment_paths = self.config.comparison_experiment_paths() - experiment_tag_paths = comparison_tags(experiment_paths) + experiment_tag_paths = comparison_tags(experiment_paths, self.logger) - exp_tag_0 = experiment_tag_paths.keys()[0] - exp_tag_1 = experiment_tag_paths.keys()[0] + exp_tag_0 = list(experiment_tag_paths.keys())[0] + exp_tag_1 = list(experiment_tag_paths.keys())[1] # Get the number of iterations between experiments iterations_list = [] @@ -123,9 +123,9 @@ def execute(self): for cycle, cycle_results in all_results.items(): for key in cycle_results: - if 'exp0' not in cycle_results[key]: + if exp_tag_0 not in cycle_results[key]: cycle_results[key][exp_tag_0] = 'N/A' - if 'exp1' not in cycle_results[key]: + if exp_tag_1 not in cycle_results[key]: cycle_results[key][exp_tag_1] = 'N/A' if 'diff' not in cycle_results[key]: cycle_results[key]['diff'] = 'N/A' From 3c92211fd3231c90432b2bfd86d80dfba84f206b Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Tue, 13 Jan 2026 12:42:44 -0500 Subject: [PATCH 30/51] Use tags in eva plots --- .../comparison_increment-geos_atmosphere.yaml | 154 ++++++++++++------ src/swell/tasks/eva_comparison_increment.py | 13 +- src/swell/tasks/eva_comparison_jedi_log.py | 13 +- .../tasks/eva_comparison_observations.py | 14 +- 4 files changed, 138 insertions(+), 56 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml index 981058d50..b11ca5e7d 100644 --- a/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml @@ -486,8 +486,9 @@ graphics: projection: plcarr domain: global add_map_features: ['coastline'] + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_colorbar: - label: Temperature Increment 1 + label: Temperature Increment add_grid: layers: - type: MapGridded @@ -509,8 +510,9 @@ graphics: projection: plcarr domain: global add_map_features: ['coastline'] + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_colorbar: - label: Temperature Increment 2 + label: Temperature Increment add_grid: layers: - type: MapGridded @@ -532,8 +534,9 @@ graphics: projection: plcarr domain: global add_map_features: ['coastline'] + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' add_colorbar: - label: Temperature Increment Diff (1-2) + label: Temperature Increment Diff add_grid: layers: - type: MapGridded @@ -565,8 +568,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment 1 + label: Zonal Wind Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -587,8 +591,9 @@ graphics: projection: plcarr domain: global add_map_features: ['coastline'] + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_colorbar: - label: Zonal Wind Increment 2 + label: Zonal Wind Increment add_grid: layers: - type: MapGridded @@ -610,8 +615,9 @@ graphics: projection: plcarr domain: global add_map_features: ['coastline'] + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' add_colorbar: - label: Zonal Wind Increment Diff (1-2) + label: Zonal Wind Increment Diff add_grid: layers: - type: MapGridded @@ -642,8 +648,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment 1 + label: Zonal Wind Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -659,14 +666,15 @@ graphics: vmin: *vmin_ua vmax: 1 - # Experiment 1 + # Experiment 2 - mapping: projection: plcarr domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment 2 + label: Zonal Wind Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -682,13 +690,14 @@ graphics: vmin: *vmin_ua vmax: 1 - # Experiment 1 + # Experiment diff - mapping: projection: plcarr domain: global add_map_features: ['coastline'] + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' add_colorbar: - label: Zonal Wind Increment 1 + label: Zonal Wind Increment diff add_grid: layers: - type: MapGridded @@ -720,8 +729,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment 1 + label: Zonal Wind Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -743,8 +753,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment 2 + label: Zonal Wind Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -766,8 +777,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment Diff (1-2) + label: Zonal Wind Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -798,8 +810,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment 1 + label: Zonal Wind Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -821,7 +834,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment 2 + label: Zonal Wind Increment + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: layers: - type: MapGridded @@ -844,7 +858,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment Diff (1-2) + label: Zonal Wind Increment Diff + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' add_grid: layers: - type: MapGridded @@ -876,8 +891,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment 1 + label: Zonal Wind Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -899,7 +915,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment 2 + label: Zonal Wind Increment + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: layers: - type: MapGridded @@ -924,6 +941,7 @@ graphics: add_colorbar: label: Zonal Wind Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -954,8 +972,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment 1 + label: Zonal Wind Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -977,8 +996,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment 1 + label: Zonal Wind Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -1000,8 +1020,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Zonal Wind Increment Diff (1-2) + label: Zonal Wind Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -1032,7 +1053,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment 1 + label: Meridional Wind Increment + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: layers: - type: MapGridded @@ -1055,8 +1077,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment 2 + label: Meridional Wind Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -1078,7 +1101,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment Diff (1-2) + label: Meridional Wind Increment Diff + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' add_grid: layers: - type: MapGridded @@ -1110,7 +1134,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment 1 + label: Meridional Wind Increment + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: layers: - type: MapGridded @@ -1133,8 +1158,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment 2 + label: Meridional Wind Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -1156,8 +1182,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment Diff (1-2) + label: Meridional Wind Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -1188,8 +1215,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment 1 + label: Meridional Wind Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -1211,8 +1239,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment 2 + label: Meridional Wind Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -1234,8 +1263,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment Diff (1-2) + label: Meridional Wind Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -1266,8 +1296,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment 1 + label: Meridional Wind Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -1289,8 +1320,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment 2 + label: Meridional Wind Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -1313,8 +1345,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment Diff (1-2) + label: Meridional Wind Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -1345,8 +1378,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment 1 + label: Meridional Wind Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -1368,7 +1402,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Meridional Wind Increment 2 + label: Meridional Wind Increment + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: layers: - type: MapGridded @@ -1393,6 +1428,7 @@ graphics: add_colorbar: label: Meridional Wind Increment Diff (1-2) add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -1425,6 +1461,7 @@ graphics: add_colorbar: label: Meridional Wind Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -1448,6 +1485,7 @@ graphics: add_colorbar: label: Meridional Wind Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -1471,6 +1509,7 @@ graphics: add_colorbar: label: Meridional Wind Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -1502,8 +1541,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment 1 + label: Specific Humidity Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -1524,7 +1564,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment 2 + label: Specific Humidity Increment + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: layers: - type: MapGridded @@ -1546,8 +1587,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment Diff (1-2) + label: Specific Humidity Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -1578,8 +1620,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment 1 + label: Specific Humidity Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -1601,8 +1644,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment 2 + label: Specific Humidity Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -1624,8 +1668,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment Diff (1-2) + label: Specific Humidity Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -1656,8 +1701,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment 1 + label: Specific Humidity Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -1681,6 +1727,7 @@ graphics: add_colorbar: label: Specific Humidity Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -1702,8 +1749,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment Diff (1-2) + label: Specific Humidity Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -1734,8 +1782,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment 1 + label: Specific Humidity Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -1757,7 +1806,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment 2 + label: Specific Humidity Increment + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: layers: - type: MapGridded @@ -1780,8 +1830,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment Diff (1-2) + label: Specific Humidity Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -1812,8 +1863,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment 1 + label: Specific Humidity Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -1835,8 +1887,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment 2 + label: Specific Humidity Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -1858,8 +1911,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Specific Humidity Increment Diff (1-2) + label: Specific Humidity Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: diff --git a/src/swell/tasks/eva_comparison_increment.py b/src/swell/tasks/eva_comparison_increment.py index b6855011e..ea00610f5 100644 --- a/src/swell/tasks/eva_comparison_increment.py +++ b/src/swell/tasks/eva_comparison_increment.py @@ -17,6 +17,7 @@ from swell.tasks.base.task_base import taskBase from swell.utilities.jinja2 import template_string_jinja2 from swell.utilities.data_assimilation_window_params import DataAssimilationWindowParams +from swell.utilities.comparisons import comparison_tags # -------------------------------------------------------------------------------------------------- @@ -48,8 +49,13 @@ def execute(self) -> None: # Get the paths for the two experiments experiment_paths = self.config.comparison_experiment_paths() - experiment_path_1 = experiment_paths[0] - experiment_path_2 = experiment_paths[1] + experiment_tag_paths = comparison_tags(experiment_paths, self.logger) + + experiment_tag_1 = list(experiment_tag_paths.keys())[0] + experiment_tag_2 = list(experiment_tag_paths.keys())[0] + + experiment_path_1 = list(experiment_tag_paths.values())[0] + experiment_path_2 = list(experiment_tag_paths.values())[1] window_type, window_length = self.window_info_from_config(experiment_path_1) @@ -119,6 +125,9 @@ def execute(self) -> None: eva_override['increment_file_path_1'] = increment_file_path_1 eva_override['increment_file_path_2'] = increment_file_path_2 + eva_override['experiment_tag_1'] = experiment_tag_1 + eva_override['experiment_tag_2'] = experiment_tag_2 + # Override the eva dictionary eva_str = template_string_jinja2(self.logger, eva_str_template, eva_override) eva_dict = yaml.safe_load(eva_str) diff --git a/src/swell/tasks/eva_comparison_jedi_log.py b/src/swell/tasks/eva_comparison_jedi_log.py index 28e27a81b..8b25a9b9c 100644 --- a/src/swell/tasks/eva_comparison_jedi_log.py +++ b/src/swell/tasks/eva_comparison_jedi_log.py @@ -15,6 +15,7 @@ from swell.tasks.base.task_base import taskBase from swell.utilities.jinja2 import template_string_jinja2 +from swell.utilities.comparisons import comparison_tags # -------------------------------------------------------------------------------------------------- @@ -42,8 +43,13 @@ def execute(self) -> None: # Get the paths for the two experiments experiment_paths = self.config.comparison_experiment_paths() - experiment_path_1 = experiment_paths[0] - experiment_path_2 = experiment_paths[1] + experiment_tag_paths = comparison_tags(experiment_paths, self.logger) + + experiment_tag_1 = list(experiment_tag_paths.keys())[0] + experiment_tag_2 = list(experiment_tag_paths.keys())[0] + + experiment_path_1 = list(experiment_tag_paths.values())[0] + experiment_path_2 = list(experiment_tag_paths.values())[1] with open(experiment_path_1, 'r') as f: experiment_dict_1 = yaml.safe_load(f) @@ -75,6 +81,9 @@ def execute(self) -> None: eva_override['experiment_id_1'] = experiment_id_1 eva_override['experiment_id_2'] = experiment_id_2 + eva_override['experiment_tag_1'] = experiment_tag_1 + eva_override['experiment_tag_2'] = experiment_tag_2 + eva_override['log_type'] = log_type # Override the eva dictionary diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index 37ce9937b..b2bc04698 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -22,6 +22,7 @@ from swell.utilities.observations import ioda_name_to_long_name from swell.utilities.run_jedi_executables import check_obs from swell.utilities.observations import ioda_name_to_long_name +from swell.utilities.comparisons import comparison_tags # -------------------------------------------------------------------------------------------------- @@ -45,8 +46,14 @@ def execute(self) -> None: # Get the experiment paths # ------------------------ experiment_paths = self.config.comparison_experiment_paths() - experiment_path_1 = experiment_paths[0] - experiment_path_2 = experiment_paths[1] + + experiment_tag_paths = comparison_tags(experiment_paths, self.logger) + + experiment_tag_1 = list(experiment_tag_paths.keys())[0] + experiment_tag_2 = list(experiment_tag_paths.keys())[0] + + experiment_path_1 = list(experiment_tag_paths.values())[0] + experiment_path_2 = list(experiment_tag_paths.values())[1] model = self.get_model() @@ -199,6 +206,9 @@ def execute(self) -> None: eva_override['experiment_id_1'] = experiment_id_1 eva_override['experiment_id_2'] = experiment_id_2 + eva_override['experiment_tag_1'] = experiment_tag_1 + eva_override['experiment_tag_2'] = experiment_tag_2 + # If filename contains icec_ change map projection to polar stereographic # ----------------------------------------------------------------------- if 'icec_' in obs_file_1: From b9c87ca7b620bfc2ca8ab539de91294ccbcec659 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Tue, 13 Jan 2026 13:37:07 -0500 Subject: [PATCH 31/51] add experiment ids --- src/swell/tasks/eva_comparison_increment.py | 7 ++++- src/swell/utilities/comparisons.py | 29 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/swell/tasks/eva_comparison_increment.py b/src/swell/tasks/eva_comparison_increment.py index ea00610f5..8887bee83 100644 --- a/src/swell/tasks/eva_comparison_increment.py +++ b/src/swell/tasks/eva_comparison_increment.py @@ -17,7 +17,7 @@ from swell.tasks.base.task_base import taskBase from swell.utilities.jinja2 import template_string_jinja2 from swell.utilities.data_assimilation_window_params import DataAssimilationWindowParams -from swell.utilities.comparisons import comparison_tags +from swell.utilities.comparisons import comparison_tags, experiment_ids # -------------------------------------------------------------------------------------------------- @@ -57,6 +57,8 @@ def execute(self) -> None: experiment_path_1 = list(experiment_tag_paths.values())[0] experiment_path_2 = list(experiment_tag_paths.values())[1] + experiment_id_1, experiment_id_2 = experiment_ids(experiment_paths) + window_type, window_length = self.window_info_from_config(experiment_path_1) # Create the cycle dir for this experiment @@ -128,6 +130,9 @@ def execute(self) -> None: eva_override['experiment_tag_1'] = experiment_tag_1 eva_override['experiment_tag_2'] = experiment_tag_2 + eva_override['experiment_id_1'] = experiment_id_1 + eva_override['experiment_id_2'] = experiment_id_2 + # Override the eva dictionary eva_str = template_string_jinja2(self.logger, eva_str_template, eva_override) eva_dict = yaml.safe_load(eva_str) diff --git a/src/swell/utilities/comparisons.py b/src/swell/utilities/comparisons.py index 4e70f6fd9..bb14e6531 100644 --- a/src/swell/utilities/comparisons.py +++ b/src/swell/utilities/comparisons.py @@ -7,6 +7,7 @@ # -------------------------------------------------------------------------------------------------- +from ruamel.yaml import YAML from swell.utilities.logger import Logger # -------------------------------------------------------------------------------------------------- @@ -40,5 +41,33 @@ def comparison_tags(pathspecs: list | dict, return pathspecs_out +# -------------------------------------------------------------------------------------------------- + +def experiment_ids(experiment_paths) -> tuple: + '''Get experiment ids from path's experiment.yaml + + Arguments: + experiment_paths: List of two experiment paths + + Returns: + Tuple (experiment_id_1, experiment_id_2) + ''' + + experiment_path_1 = experiment_paths[0] + experiment_path_2 = experiment_paths[1] + + yaml = YAML(typ='safe') + + with open(experiment_path_1, 'r') as f: + experiment_dict_1 = yaml.load(f) + + experiment_id_1 = experiment_dict_1['experiment_id'] + + with open(experiment_path_2, 'r') as f: + experiment_dict_2 = yaml.load(f) + + experiment_id_2 = experiment_dict_2['experiment_id'] + + return experiment_id_1, experiment_id_2 # -------------------------------------------------------------------------------------------------- \ No newline at end of file From cb7355841658288c09c3a45733eb5aefeeb89668 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Tue, 13 Jan 2026 14:39:10 -0500 Subject: [PATCH 32/51] fixes --- .../comparison_increment-geos_atmosphere.yaml | 50 +++++++++++++------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml index b11ca5e7d..b86941e85 100644 --- a/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml @@ -32,6 +32,7 @@ graphics: add_colorbar: label: Surface Pressure Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -53,6 +54,7 @@ graphics: add_colorbar: label: Surface Pressure Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -73,8 +75,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Surface Pressure Increment Diff (1-2) + label: Surface Pressure Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -104,7 +107,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment 1 + label: Temperature Increment + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: layers: - type: MapGridded @@ -126,8 +130,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment 2 + label: Temperature Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -148,7 +153,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment Diff (1-2) + label: Temperature Increment Diff + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' add_grid: layers: - type: MapGridded @@ -179,8 +185,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment 1 + label: Temperature Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -201,8 +208,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment 2 + label: Temperature Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -223,7 +231,8 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment Diff (1-2) + label: Temperature Increment Diff + add_title: '({{experiment_tag_1}}) - ({{experiment_id_2}})' add_grid: layers: - type: MapGridded @@ -254,8 +263,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment 1 + label: Temperature Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -277,8 +287,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment 2 + label: Temperature Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -300,8 +311,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment Diff (1-2) + label: Temperature Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -331,8 +343,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment 1 + label: Temperature Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -354,8 +367,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment 2 + label: Temperature Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -377,8 +391,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment Diff (1-2) + label: Temperature Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -409,8 +424,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment 1 + label: Temperature Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -432,8 +448,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment 2 + label: Temperature Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -455,8 +472,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: Temperature Increment Diff (1-2) + label: Temperature Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: From 31a613dd0d3516e8fd1d4dbe0ab03f41f5ba6e0b Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Tue, 13 Jan 2026 17:18:27 -0500 Subject: [PATCH 33/51] fixes --- src/swell/tasks/eva_comparison_increment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/swell/tasks/eva_comparison_increment.py b/src/swell/tasks/eva_comparison_increment.py index 8887bee83..124ea8183 100644 --- a/src/swell/tasks/eva_comparison_increment.py +++ b/src/swell/tasks/eva_comparison_increment.py @@ -52,7 +52,7 @@ def execute(self) -> None: experiment_tag_paths = comparison_tags(experiment_paths, self.logger) experiment_tag_1 = list(experiment_tag_paths.keys())[0] - experiment_tag_2 = list(experiment_tag_paths.keys())[0] + experiment_tag_2 = list(experiment_tag_paths.keys())[1] experiment_path_1 = list(experiment_tag_paths.values())[0] experiment_path_2 = list(experiment_tag_paths.values())[1] From 9176f8ec5fb3c4691794b2ee82a55b5ea43f46a3 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Tue, 13 Jan 2026 17:19:25 -0500 Subject: [PATCH 34/51] formatting fixes --- .../comparison_increment-geos_atmosphere.yaml | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml index b86941e85..0cd6712aa 100644 --- a/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_increment-geos_atmosphere.yaml @@ -19,7 +19,7 @@ graphics: - batch figure: variables: [ps] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}.png' @@ -96,7 +96,7 @@ graphics: - batch figure: variables: [t] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_1000.png' @@ -174,7 +174,7 @@ graphics: - batch figure: variables: [t] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_850.png' @@ -413,7 +413,7 @@ graphics: - batch figure: variables: [t] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_10.png' @@ -494,7 +494,7 @@ graphics: - batch figure: variables: [t] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_1.png' @@ -655,7 +655,7 @@ graphics: - batch figure: variables: [ua] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_850.png' @@ -736,7 +736,7 @@ graphics: - batch figure: variables: [ua] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_500.png' @@ -817,7 +817,7 @@ graphics: - batch figure: variables: [ua] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_200.png' @@ -898,7 +898,7 @@ graphics: - batch figure: variables: [ua] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_10.png' @@ -979,7 +979,7 @@ graphics: - batch figure: variables: [ua] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_1.png' @@ -1141,7 +1141,7 @@ graphics: - batch figure: variables: [va] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_850.png' @@ -1222,7 +1222,7 @@ graphics: - batch figure: variables: [va] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_500.png' @@ -1303,7 +1303,7 @@ graphics: - batch figure: variables: [va] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_200.png' @@ -1385,7 +1385,7 @@ graphics: - batch figure: variables: [va] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_10.png' @@ -1466,7 +1466,7 @@ graphics: - batch figure: variables: [va] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_1.png' @@ -1708,7 +1708,7 @@ graphics: - batch figure: variables: [q] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_500.png' @@ -1789,7 +1789,7 @@ graphics: - batch figure: variables: [q] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_200.png' @@ -1870,7 +1870,7 @@ graphics: - batch figure: variables: [q] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Increment from JEDI' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}_10.png' From 8de434893b3144b6c90417ba354fb803d2ff02f4 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 14 Jan 2026 10:08:11 -0500 Subject: [PATCH 35/51] add tags to marine --- .../eva/comparison_increment-geos_marine.yaml | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_increment-geos_marine.yaml b/src/swell/suites/compare/eva/comparison_increment-geos_marine.yaml index 7168a27e6..325eb34b3 100644 --- a/src/swell/suites/compare/eva/comparison_increment-geos_marine.yaml +++ b/src/swell/suites/compare/eva/comparison_increment-geos_marine.yaml @@ -24,7 +24,7 @@ graphics: - batch figure: variables: [ave_ssh] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'SOCA Increment' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}.png' @@ -36,8 +36,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: SSH Increment 1 + label: SSH Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -58,8 +59,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: SSH Increment 2 + label: SSH Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -80,8 +82,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: SSH Increment (1-2) Diff + label: SSH Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -97,7 +100,7 @@ graphics: - batch figure: variables: [Temp] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Soca Increment' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}.png' @@ -108,8 +111,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: SST Increment 1 + label: SST Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -131,8 +135,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: SST Increment 2 + label: SST Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -154,8 +159,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: SST Increment (1-2) Diff + label: SST Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -165,14 +171,14 @@ graphics: data: variable: experiment_increment_1::SOCAVars::Temp_diff slices: '[0,...]' - label: SST increment (1-2) Diff + label: SST increment Diff colorbar: true cmap: 'bwr' - batch figure: variables: [Salt] figure: - figure size: [60,10] + figure size: [60,20] layout: [3,1] title: 'Soca Increment' output name: '{{cycle_dir}}/eva/increment/map_plots/${variable}/inc_${variable}.png' @@ -183,8 +189,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: SSS Increment 1 + label: SSS Increment add_grid: + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapGridded longitude: @@ -206,8 +213,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: SSS Increment 2 + label: SSS Increment add_grid: + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapGridded longitude: @@ -217,7 +225,7 @@ graphics: data: variable: experiment_increment_2::SOCAVars::Salt slices: '[0,...]' - label: SSS increment 2 + label: SSS increment colorbar: true cmap: 'bwr' vmin: *vmin_salt @@ -229,8 +237,9 @@ graphics: domain: global add_map_features: ['coastline'] add_colorbar: - label: SSS Increment (1-2) Diff + label: SSS Increment Diff add_grid: + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}})' layers: - type: MapGridded longitude: @@ -240,7 +249,7 @@ graphics: data: variable: experiment_increment_1::SOCAVars::Salt_diff slices: '[0,...]' - label: SSS increment (1-2) Diff + label: SSS increment Diff colorbar: true cmap: 'bwr' From ccdbaf203b07b47243ca9ccb2d08f70a46ee1abe Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 14 Jan 2026 16:38:44 -0500 Subject: [PATCH 36/51] add jedi_log plots --- .../comparison_jedi_log-geos_atmosphere.yaml | 105 ++---------------- .../eva/comparison_jedi_log-geos_marine.yaml | 48 +------- 2 files changed, 13 insertions(+), 140 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_jedi_log-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_jedi_log-geos_atmosphere.yaml index 4c8a89d9f..f0d42a6bf 100644 --- a/src/swell/suites/compare/eva/comparison_jedi_log-geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_jedi_log-geos_atmosphere.yaml @@ -31,49 +31,10 @@ graphics: figure_list: - figure: - layout: [3,1] figure size: [12,10] title: 'Residual Norm and Norm Reduction Plots' output name: '{{cycle_dir}}/eva/jedi_log/convergence/residual_norm_reduction.png' plots: - - add_xlabel: 'Total inner iteration number' - add_ylabel: 'Residual norm' - add_legend: - layers: - - type: LinePlot - x: - variable: JediLogTest_1::convergence::total_iteration - y: - variable: JediLogTest_1::convergence::residual_norm - color: 'red' - label: 'Experiment 1' - - type: LinePlot - x: - variable: JediLogTest_2::convergence::total_iteration - y: - variable: JediLogTest_2::convergence::residual_norm - color: 'blue' - label: 'Experiment 2' - - - add_xlabel: 'Total inner iteration number' - add_ylabel: 'Log(norm reduction)' - add_legend: - layers: - - type: LinePlot - x: - variable: JediLogTest_1::convergence::total_iteration - y: - variable: JediLogTest_1::convergence::norm_reduction - color: 'red' - label: 'Experiment 1' - - type: LinePlot - x: - variable: JediLogTest_2::convergence::total_iteration - y: - variable: JediLogTest_2::convergence::norm_reduction - color: 'blue' - label: 'Experiment 2' - - add_xlabel: 'Total inner iteration number' add_ylabel: 'Log(reduction)' add_legend: @@ -84,88 +45,40 @@ graphics: y: variable: JediLogTest_1::convergence::residual_norm_log color: 'red' - label: 'Log(residual norm) 1' + label: '{{experiment_tag_1}} Log(residual norm)' - type: LinePlot x: variable: JediLogTest_2::convergence::total_iteration y: variable: JediLogTest_2::convergence::residual_norm_log color: 'blue' - label: 'Log(residual norm) 2' + label: '{{experiment_tag_2}} Log(residual norm)' - type: LinePlot x: variable: JediLogTest_1::convergence::total_iteration y: variable: JediLogTest_1::convergence::norm_reduction_log color: 'yellow' - label: 'Log norm reduction 1' + label: '{{experiment_tag_1}} Log norm reduction' - type: LinePlot x: variable: JediLogTest_2::convergence::total_iteration y: variable: JediLogTest_2::convergence::norm_reduction_log color: 'green' - label: 'Log norm reduction 2' + label: '{{experiment_tag_1}} Log norm reduction' - figure: title: 'Cost Function Plot' output name: '{{cycle_dir}}/eva/jedi_log/cost_function/cost_function.png' - layout: [3, 1] - #figure size: [10, 30] plots: - add_xlabel: 'Total inner iteration number' add_ylabel: 'Quadratic Cost Function' add_legend: - add_title: '{{experiment_id_1}} (1)' - layers: - - type: LinePlot - label: 'jb' - x: - variable: JediLogTest_1::convergence::total_iteration - y: - variable: JediLogTest_1::convergence::jb - color: 'red' - linestyle: '--' - markersize: 2 - - type: LinePlot - label: 'jojc' - x: - variable: JediLogTest_1::convergence::total_iteration - y: - variable: JediLogTest_1::convergence::jojc - color: 'blue' - markersize: 2 - - - add_xlabel: 'Total inner iteration number' - add_ylabel: 'Quadratic Cost Function' - add_legend: - add_title: '{{experiment_id_2}} (2)' - layers: - - type: LinePlot - label: 'jb' - x: - variable: JediLogTest_2::convergence::total_iteration - y: - variable: JediLogTest_2::convergence::jb - color: 'green' - linestyle: '--' - markersize: 0 - - type: LinePlot - label: 'jojc' - x: - variable: JediLogTest_2::convergence::total_iteration - y: - variable: JediLogTest_2::convergence::jojc - color: 'black' - markersize: 0 - - - add_xlabel: 'Total inner iteration number' - add_ylabel: 'Quadratic Cost Function' - add_legend: - add_title: '1 - 2 diff' + add_title: '({{experiment_tag_1}}) - ({{experiment_tag_2}}) diff' layers: - type: LinePlot - label: 'jb 1' + label: '{{experiment_tag_1}} jb' x: variable: JediLogTest_1::convergence::total_iteration y: @@ -174,7 +87,7 @@ graphics: linestyle: '--' markersize: 2 - type: LinePlot - label: 'jojc 1' + label: '{{experiment_tag_1}} jojc' x: variable: JediLogTest_1::convergence::total_iteration y: @@ -182,7 +95,7 @@ graphics: color: 'blue' markersize: 2 - type: LinePlot - label: 'jb 2' + label: '{{experiment_tag_2}} jb' x: variable: JediLogTest_2::convergence::total_iteration y: @@ -191,7 +104,7 @@ graphics: linestyle: '--' markersize: 2 - type: LinePlot - label: 'jojc 2' + label: '{{experiment_tag_2}} jojc' x: variable: JediLogTest_2::convergence::total_iteration y: diff --git a/src/swell/suites/compare/eva/comparison_jedi_log-geos_marine.yaml b/src/swell/suites/compare/eva/comparison_jedi_log-geos_marine.yaml index a2aa01fac..d30224207 100644 --- a/src/swell/suites/compare/eva/comparison_jedi_log-geos_marine.yaml +++ b/src/swell/suites/compare/eva/comparison_jedi_log-geos_marine.yaml @@ -18,49 +18,9 @@ graphics: figure_list: - figure: - layout: [3,1] - figure size: [12,10] title: 'Residual Norm and Norm Reduction Plots' output name: '{{cycle_dir}}/eva/jedi_log/convergence/residual_norm_reduction.png' plots: - - add_xlabel: 'Total inner iteration number' - add_ylabel: 'Residual norm' - add_legend: - layers: - - type: LinePlot - x: - variable: jedi_log_test_1::convergence::total_iteration - y: - variable: jedi_log_test_1::convergence::residual_norm - color: 'red' - label: 'Experiment 1' - - type: LinePlot - x: - variable: jedi_log_test_2::convergence::total_iteration - y: - variable: jedi_log_test_2::convergence::residual_norm - color: 'blue' - label: 'Experiment 2' - - - add_xlabel: 'Total inner iteration number' - add_ylabel: 'Norm reduction' - add_legend: - layers: - - type: LinePlot - x: - variable: jedi_log_test_1::convergence::total_iteration - y: - variable: jedi_log_test_1::convergence::norm_reduction - color: 'red' - label: 'Experiment 1' - - type: LinePlot - x: - variable: jedi_log_test_2::convergence::total_iteration - y: - variable: jedi_log_test_2::convergence::norm_reduction - color: 'blue' - label: 'Experiment 2' - - add_xlabel: 'Total inner iteration number' add_ylabel: 'Normalized Value' add_legend: @@ -71,25 +31,25 @@ graphics: y: variable: jedi_log_test_1::convergence::residual_norm_normalized color: 'red' - label: 'Normalized residual norm 1' + label: '{{experiment_tag_1}} Normalized residual norm' - type: LinePlot x: variable: jedi_log_test_2::convergence::total_iteration y: variable: jedi_log_test_2::convergence::residual_norm_normalized color: 'blue' - label: 'Normalized residual norm 2' + label: '{{experiment_tag_2}} Normalized residual norm' - type: LinePlot x: variable: jedi_log_test_1::convergence::total_iteration y: variable: jedi_log_test_1::convergence::norm_reduction_normalized color: 'yellow' - label: 'Normalized norm reduction 1' + label: '{{experiment_tag_1}} Normalized norm reduction' - type: LinePlot x: variable: jedi_log_test_2::convergence::total_iteration y: variable: jedi_log_test_2::convergence::norm_reduction_normalized color: 'green' - label: 'Normalized norm reduction 2' + label: '{{experiment_tag_2}} Normalized norm reduction' From 66f8cbc11a73ab11c1055ca8fa87b02d9a0d4d41 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 14 Jan 2026 16:45:11 -0500 Subject: [PATCH 37/51] fix --- src/swell/tasks/eva_comparison_jedi_log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/swell/tasks/eva_comparison_jedi_log.py b/src/swell/tasks/eva_comparison_jedi_log.py index 8b25a9b9c..8822bc089 100644 --- a/src/swell/tasks/eva_comparison_jedi_log.py +++ b/src/swell/tasks/eva_comparison_jedi_log.py @@ -46,7 +46,7 @@ def execute(self) -> None: experiment_tag_paths = comparison_tags(experiment_paths, self.logger) experiment_tag_1 = list(experiment_tag_paths.keys())[0] - experiment_tag_2 = list(experiment_tag_paths.keys())[0] + experiment_tag_2 = list(experiment_tag_paths.keys())[1] experiment_path_1 = list(experiment_tag_paths.values())[0] experiment_path_2 = list(experiment_tag_paths.values())[1] From ced4a08c8c72ec41c7462ed6483db722467a463b Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 14 Jan 2026 16:55:44 -0500 Subject: [PATCH 38/51] Update obs to use tag --- ...rvations-3dfgat_atmos-geos_atmosphere.yaml | 60 +++++++++---------- ...observations-3dfgat_cycle-geos_marine.yaml | 36 +++++------ ...arison_observations-3dvar-geos_marine.yaml | 24 ++++---- ...ervations-3dvar_atmos-geos_atmosphere.yaml | 44 +++++++------- 4 files changed, 82 insertions(+), 82 deletions(-) diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml index b56bafdc4..4899b1d1a 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_atmos-geos_atmosphere.yaml @@ -334,7 +334,7 @@ graphics: plots: - add_xlabel: 'Observation Value' add_ylabel: 'JEDI h(x)' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: add_legend: loc: 'upper left' @@ -360,7 +360,7 @@ graphics: - add_xlabel: 'Observation Value' add_ylabel: 'JEDI h(x)' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: add_legend: loc: 'upper left' @@ -396,7 +396,7 @@ graphics: plots: - add_xlabel: 'Observation Value' add_ylabel: 'GSI h(x)' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: add_legend: loc: 'upper left' @@ -422,7 +422,7 @@ graphics: - add_xlabel: 'Observation Value' add_ylabel: 'GSI h(x)' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: add_legend: loc: 'upper left' @@ -458,7 +458,7 @@ graphics: plots: - add_xlabel: 'GSI h(x)' add_ylabel: 'JEDI h(x)' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: add_legend: loc: 'upper left' @@ -484,7 +484,7 @@ graphics: - add_xlabel: 'GSI h(x)' add_ylabel: 'JEDI h(x)' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: add_legend: loc: 'upper left' @@ -520,7 +520,7 @@ graphics: plots: - add_xlabel: 'GSI observation minus h(x)' add_ylabel: 'JEDI observation minus h(x)' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: add_legend: loc: 'upper left' @@ -546,7 +546,7 @@ graphics: - add_xlabel: 'GSI observation minus h(x)' add_ylabel: 'JEDI observation minus h(x)' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: add_legend: loc: 'upper left' @@ -582,7 +582,7 @@ graphics: plots: - add_xlabel: 'GSI observation minus h(x)' add_ylabel: 'JEDI h(x) minus GSI h(x)' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: add_legend: loc: 'upper left' @@ -599,7 +599,7 @@ graphics: - add_xlabel: 'GSI observation minus h(x)' add_ylabel: 'JEDI h(x) minus GSI h(x)' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: add_legend: loc: 'upper left' @@ -626,7 +626,7 @@ graphics: plots: - add_xlabel: 'OmA' add_ylabel: 'OmB' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: add_legend: loc: 'upper left' @@ -652,7 +652,7 @@ graphics: - add_xlabel: 'OmA' add_ylabel: 'OmB' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: add_legend: loc: 'upper left' @@ -676,8 +676,8 @@ graphics: color: 'red' label: 'OmA versus OmB (passed QC)' - - add_xlabel: 'OmA {{experiment_id_1}} (1)' - add_ylabel: 'OmA {{experiment_id_2}} (2)' + - add_xlabel: 'OmA ({{experiment_tag_1}}) {{experiment_id_1}}' + add_ylabel: 'OmA ({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: add_legend: loc: 'upper left' @@ -691,8 +691,8 @@ graphics: markersize: 5 color: 'black' - - add_xlabel: 'OmB {{experiment_id_1}} (1)' - add_ylabel: 'OmB {{experiment_id_2}} (2)' + - add_xlabel: 'OmB ({{experiment_tag_1}}) {{experiment_id_1}}' + add_ylabel: 'OmB ({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: add_legend: loc: 'upper left' @@ -718,7 +718,7 @@ graphics: plots: - add_xlabel: 'GsiFinalObsError' add_ylabel: 'JediFinalObsError' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: add_legend: loc: 'upper left' @@ -744,7 +744,7 @@ graphics: - add_xlabel: 'GsiFinalObsError' add_ylabel: 'JediFinalObsError' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: add_legend: loc: 'upper left' @@ -780,7 +780,7 @@ graphics: plots: - add_xlabel: 'GsiFinalObsError' add_ylabel: 'JediFinalObsError' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: add_legend: loc: 'upper left' @@ -806,7 +806,7 @@ graphics: - add_xlabel: 'GsiFinalObsError' add_ylabel: 'JediFinalObsError' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: add_legend: loc: 'upper left' @@ -854,7 +854,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -878,7 +878,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -916,7 +916,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -940,7 +940,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -978,7 +978,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -1002,7 +1002,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -1040,7 +1040,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -1101,7 +1101,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -1161,7 +1161,7 @@ graphics: plots: - add_xlabel: 'Observation minus h(x)' add_ylabel: 'Count' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_legend: loc: 'upper left' layers: @@ -1219,7 +1219,7 @@ graphics: plots: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' set_xlim: [-3, 3] add_legend: loc: 'upper left' diff --git a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml index b7b197b13..ea2aedf31 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dfgat_cycle-geos_marine.yaml @@ -206,7 +206,7 @@ graphics: plots: - add_xlabel: 'Observation Value' add_ylabel: 'JEDI h(x)' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: add_legend: loc: 'upper left' @@ -231,7 +231,7 @@ graphics: - add_xlabel: 'Observation Value' add_ylabel: 'JEDI h(x)' add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_legend: loc: 'upper left' layers: @@ -311,7 +311,7 @@ graphics: plots: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -358,7 +358,7 @@ graphics: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -417,7 +417,7 @@ graphics: plots: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -464,7 +464,7 @@ graphics: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -530,7 +530,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_1}} (1) ombg' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}} ombg' layers: - type: MapScatter longitude: @@ -553,7 +553,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_1}} (1) oman' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}} oman' layers: - type: MapScatter longitude: @@ -576,7 +576,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_2}} (2) ombg' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}} ombg' layers: - type: MapScatter longitude: @@ -599,7 +599,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_2}} (2) oman' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}} oman' layers: - type: MapScatter longitude: @@ -633,7 +633,7 @@ graphics: add_colorbar: label: EffectiveQC1 add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -656,7 +656,7 @@ graphics: add_colorbar: label: EffectiveQC1 add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -691,7 +691,7 @@ graphics: add_colorbar: label: Increment (OmBg - OmAn) add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -714,7 +714,7 @@ graphics: add_colorbar: label: Increment (OmBg - OmAn) add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -749,7 +749,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -772,7 +772,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -795,7 +795,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -818,7 +818,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: diff --git a/src/swell/suites/compare/eva/comparison_observations-3dvar-geos_marine.yaml b/src/swell/suites/compare/eva/comparison_observations-3dvar-geos_marine.yaml index 916a6f1d8..d5ff62033 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dvar-geos_marine.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dvar-geos_marine.yaml @@ -155,7 +155,7 @@ graphics: plots: - add_xlabel: 'Observation Value' add_ylabel: 'JEDI h(x)' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_grid: add_legend: loc: 'upper left' @@ -179,7 +179,7 @@ graphics: - add_xlabel: 'Observation Value' add_ylabel: 'JEDI h(x)' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_grid: add_legend: loc: 'upper left' @@ -219,7 +219,7 @@ graphics: plots: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -265,7 +265,7 @@ graphics: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -330,7 +330,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -353,7 +353,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -376,7 +376,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -399,7 +399,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -433,7 +433,7 @@ graphics: add_colorbar: label: EffectiveQC1 add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -456,7 +456,7 @@ graphics: add_colorbar: label: EffectiveQC1 add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -490,7 +490,7 @@ graphics: add_colorbar: label: Increment (OmBg - OmAn) add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -513,7 +513,7 @@ graphics: add_colorbar: label: Increment (OmBg - OmAn) add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: diff --git a/src/swell/suites/compare/eva/comparison_observations-3dvar_atmos-geos_atmosphere.yaml b/src/swell/suites/compare/eva/comparison_observations-3dvar_atmos-geos_atmosphere.yaml index 8c79a47b1..1e33df6d0 100644 --- a/src/swell/suites/compare/eva/comparison_observations-3dvar_atmos-geos_atmosphere.yaml +++ b/src/swell/suites/compare/eva/comparison_observations-3dvar_atmos-geos_atmosphere.yaml @@ -223,7 +223,7 @@ graphics: - add_xlabel: 'Observation Value' add_ylabel: 'JEDI h(x)' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_legend: loc: 'upper left' layers: @@ -249,7 +249,7 @@ graphics: - add_xlabel: 'Observation Value' add_ylabel: 'JEDI h(x)' add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_legend: loc: 'upper left' layers: @@ -285,7 +285,7 @@ graphics: - add_xlabel: 'Observation Value' add_ylabel: 'GSI h(x)' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_legend: loc: 'upper left' layers: @@ -311,7 +311,7 @@ graphics: - add_xlabel: 'Observation Value' add_ylabel: 'GSI h(x)' add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_legend: loc: 'upper left' layers: @@ -409,7 +409,7 @@ graphics: - add_xlabel: 'GSI observation minus h(x)' add_ylabel: 'JEDI observation minus h(x)' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_legend: loc: 'upper left' layers: @@ -435,7 +435,7 @@ graphics: - add_xlabel: 'GSI observation minus h(x)' add_ylabel: 'JEDI observation minus h(x)' add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_legend: loc: 'upper left' layers: @@ -471,7 +471,7 @@ graphics: - add_xlabel: 'OmA' add_ylabel: 'OmB' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_legend: loc: 'upper left' layers: @@ -497,7 +497,7 @@ graphics: - add_xlabel: 'OmA' add_ylabel: 'OmB' add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_legend: loc: 'upper left' layers: @@ -543,7 +543,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: "{{experiment_id_1}} (1)" + add_title: "({{experiment_tag_1}}) {{experiment_id_1}}" layers: - type: MapScatter longitude: @@ -567,7 +567,7 @@ graphics: add_colorbar: label: ObsValue add_grid: - add_title: "{{experiment_id_2}} (2)" + add_title: "({{experiment_tag_2}}) {{experiment_id_2}}" layers: - type: MapScatter longitude: @@ -605,7 +605,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -629,7 +629,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -667,7 +667,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -691,7 +691,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -729,7 +729,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -753,7 +753,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -791,7 +791,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' layers: - type: MapScatter longitude: @@ -815,7 +815,7 @@ graphics: add_colorbar: label: '${variable}' add_grid: - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' layers: - type: MapScatter longitude: @@ -851,7 +851,7 @@ graphics: plots: - add_xlabel: 'Observation minus h(x)' add_ylabel: 'Count' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' add_legend: loc: 'upper left' layers: @@ -874,7 +874,7 @@ graphics: - add_xlabel: 'Observation minus h(x)' add_ylabel: 'Count' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' add_legend: loc: 'upper left' layers: @@ -910,7 +910,7 @@ graphics: plots: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{{experiment_id_1}} (1)' + add_title: '({{experiment_tag_1}}) {{experiment_id_1}}' set_xlim: [-3, 3] add_legend: loc: 'upper left' @@ -956,7 +956,7 @@ graphics: - add_xlabel: 'Difference' add_ylabel: 'Count' - add_title: '{{experiment_id_2}} (2)' + add_title: '({{experiment_tag_2}}) {{experiment_id_2}}' set_xlim: [-3, 3] add_legend: loc: 'upper left' From c165885464af7e0e0aba89443cc912aa714fdd76 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Thu, 15 Jan 2026 12:41:13 -0500 Subject: [PATCH 39/51] fixes --- docs/examples/soca/comparison_workflows.md | 9 ++++++ src/swell/deployment/create_experiment.py | 2 ++ src/swell/suites/compare/flow.cylc | 7 ++++ src/swell/tasks/eva_comparison_increment.py | 2 +- .../tasks/eva_comparison_observations.py | 2 +- src/swell/tasks/jedi_log_comparison.py | 18 +++++++---- src/swell/utilities/comparisons.py | 32 +++++++++++-------- 7 files changed, 51 insertions(+), 21 deletions(-) diff --git a/docs/examples/soca/comparison_workflows.md b/docs/examples/soca/comparison_workflows.md index 9f02b99ec..0ec9b2a4e 100644 --- a/docs/examples/soca/comparison_workflows.md +++ b/docs/examples/soca/comparison_workflows.md @@ -9,6 +9,15 @@ comparison_experiment_paths: - /path/to/experiment1/experiment.yaml - /path/to/experiment2/experiment.yaml ``` + +Filepaths are assigned tags depending on order, which will be used to distinguish them in the task output plots and text. By default, the filepath in the first position will be referred to as `CTL` for control, and the path in the second position will be `EXP` for experiment. Users can select their own tags by specifying `comparison_experiment_paths` as a dictionary, for example: + +```yaml +comparison_experiment_paths: + test1: /path/to/experiment1/experiment.yaml + test2: /path/to/experiment2/experiment.yaml +``` + 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. diff --git a/src/swell/deployment/create_experiment.py b/src/swell/deployment/create_experiment.py index 7e7bdd114..bb524096c 100644 --- a/src/swell/deployment/create_experiment.py +++ b/src/swell/deployment/create_experiment.py @@ -123,6 +123,8 @@ def prepare_config( final_cycle_point = experiment_dict['final_cycle_point'] if experiment_dict['start_cycle_point'] is None: config_list = experiment_dict['comparison_experiment_paths'] + if isinstance(config_list, dict): + config_list = list(config_list.values()) for model in experiment_dict['model_components']: cycle_times = experiment_dict['models'][model]['cycle_times'] start_cycle_point, final_cycle_point, cycle_times = check_da_params( diff --git a/src/swell/suites/compare/flow.cylc b/src/swell/suites/compare/flow.cylc index 979445d77..f014ef27a 100644 --- a/src/swell/suites/compare/flow.cylc +++ b/src/swell/suites/compare/flow.cylc @@ -73,10 +73,17 @@ --{{key}} = {{value}} {%- endfor %} + {% if comparison_experiment_paths is mapping %} + {% for path in comparison_experiment_paths.values() %} + [[JediOopsLogParser-{{model_component}}-{{ loop.index0 }}]] + script = "swell task JediOopsLogParser {{path}} -d $datetime -m {{model_component}}" + {% endfor %} + {% else %} {% for path in comparison_experiment_paths %} [[JediOopsLogParser-{{model_component}}-{{ loop.index0 }}]] script = "swell task JediOopsLogParser {{path}} -d $datetime -m {{model_component}}" {% endfor %} + {% endif %} [[JediLogComparison-{{model_component}}]] script = "swell task JediLogComparison $config -m {{model_component}}" diff --git a/src/swell/tasks/eva_comparison_increment.py b/src/swell/tasks/eva_comparison_increment.py index 124ea8183..b6345fe44 100644 --- a/src/swell/tasks/eva_comparison_increment.py +++ b/src/swell/tasks/eva_comparison_increment.py @@ -48,7 +48,7 @@ def execute(self) -> None: # Get the paths for the two experiments experiment_paths = self.config.comparison_experiment_paths() - + print(experiment_paths) experiment_tag_paths = comparison_tags(experiment_paths, self.logger) experiment_tag_1 = list(experiment_tag_paths.keys())[0] diff --git a/src/swell/tasks/eva_comparison_observations.py b/src/swell/tasks/eva_comparison_observations.py index b2bc04698..59a318cbe 100644 --- a/src/swell/tasks/eva_comparison_observations.py +++ b/src/swell/tasks/eva_comparison_observations.py @@ -50,7 +50,7 @@ def execute(self) -> None: experiment_tag_paths = comparison_tags(experiment_paths, self.logger) experiment_tag_1 = list(experiment_tag_paths.keys())[0] - experiment_tag_2 = list(experiment_tag_paths.keys())[0] + experiment_tag_2 = list(experiment_tag_paths.keys())[1] experiment_path_1 = list(experiment_tag_paths.values())[0] experiment_path_2 = list(experiment_tag_paths.values())[1] diff --git a/src/swell/tasks/jedi_log_comparison.py b/src/swell/tasks/jedi_log_comparison.py index bd9d72b72..7d17c1c49 100644 --- a/src/swell/tasks/jedi_log_comparison.py +++ b/src/swell/tasks/jedi_log_comparison.py @@ -34,9 +34,12 @@ def execute(self): exp_tag_0 = list(experiment_tag_paths.keys())[0] exp_tag_1 = list(experiment_tag_paths.keys())[1] + experiment_path_0 = list(experiment_tag_paths.values())[0] + experiment_path_1 = list(experiment_tag_paths.values())[1] + # Get the number of iterations between experiments iterations_list = [] - for path in experiment_paths: + for path in experiment_tag_paths.values(): with open(path, 'r') as f: exp_dict = yaml.safe_load(f) num_iters = int(exp_dict['models'][self.get_model()]['number_of_iterations'][0]) @@ -102,7 +105,8 @@ def execute(self): dtype = comparison_fields[field_name]['dtype'] if dtype == float: - if exp_tag_0 in cycle_results[key] and exp_tag_1 in cycle_results[key]: + if exp_tag_0 in cycle_results[key] and exp_tag_1 in \ + cycle_results[key]: diff = float(cycle_results[key][exp_tag_0]) - \ float(cycle_results[key][exp_tag_1]) cycle_results[key]['diff'] = str(diff) @@ -142,8 +146,8 @@ def execute(self): widths[key] = val + 2 out_string = '\n' - out_string += f'{exp_tag_0}: {experiment_paths[0]}\n' - out_string += f'{exp_tag_1}: {experiment_paths[1]}\n' + out_string += f'{exp_tag_0}: {experiment_path_0}\n' + out_string += f'{exp_tag_1}: {experiment_path_1}\n' out_string += '\n' for cycle, cycle_results in all_results.items(): @@ -160,8 +164,10 @@ def execute(self): val_dict = cycle_results[key] out_string += key + ' ' * (widths['key'] - len(key)) - out_string += val_dict[exp_tag_0] + ' ' * (widths[exp_tag_0] - len(val_dict[exp_tag_0])) - out_string += val_dict[exp_tag_1] + ' ' * (widths[exp_tag_1] - len(val_dict[exp_tag_1])) + out_string += val_dict[exp_tag_0] + ' ' * (widths[exp_tag_0] - + len(val_dict[exp_tag_0])) + out_string += val_dict[exp_tag_1] + ' ' * (widths[exp_tag_1] - + len(val_dict[exp_tag_1])) out_string += val_dict['diff'] + ' ' * (widths['diff'] - len(val_dict['diff'])) out_string += str(val_dict['pass']) + ' ' * ( widths['pass'] - len(str(val_dict['pass']))) diff --git a/src/swell/utilities/comparisons.py b/src/swell/utilities/comparisons.py index bb14e6531..0a0bad253 100644 --- a/src/swell/utilities/comparisons.py +++ b/src/swell/utilities/comparisons.py @@ -12,22 +12,23 @@ # -------------------------------------------------------------------------------------------------- + def comparison_tags(pathspecs: list | dict, logger: Logger) -> dict: - + '''Check for the correct number of experiments. Automatically assign tags if they are not already assigned. - + The experiment in the first position will be given the label 'CTL', and - the experiment in the second position will be given the label 'EXP'. - + the experiment in the second position will be given the label 'EXP'. + Parameters: pathspecs: list or dictionary specifying the experiments to be compared. - + Returns: Dictionary mapping tags to experiments. If the input is a dictionary, no changes will be made.''' - + if len(pathspecs) != 2: logger.abort(f'Exactly 2 experiments should be specified.') @@ -36,13 +37,13 @@ def comparison_tags(pathspecs: list | dict, pathspecs_out['CTL'] = pathspecs[0] pathspecs_out['EXP'] = pathspecs[1] else: - pathspecs_out[str(pathspecs.keys()[0])] = pathspecs.values()[0] - pathspecs_out[str(pathspecs.keys()[1])] = pathspecs.values()[1] + pathspecs_out = pathspecs return pathspecs_out # -------------------------------------------------------------------------------------------------- + def experiment_ids(experiment_paths) -> tuple: '''Get experiment ids from path's experiment.yaml @@ -52,12 +53,17 @@ def experiment_ids(experiment_paths) -> tuple: Returns: Tuple (experiment_id_1, experiment_id_2) ''' - - experiment_path_1 = experiment_paths[0] - experiment_path_2 = experiment_paths[1] + if isinstance(experiment_paths, list): + experiment_path_1 = experiment_paths[0] + experiment_path_2 = experiment_paths[1] + elif isinstance(experiment_paths, dict): + experiment_path_1 = list(experiment_paths.values())[0] + experiment_path_2 = list(experiment_paths.values())[1] + else: + raise TypeError('Experiment paths are not of type list or dict.') yaml = YAML(typ='safe') - + with open(experiment_path_1, 'r') as f: experiment_dict_1 = yaml.load(f) @@ -70,4 +76,4 @@ def experiment_ids(experiment_paths) -> tuple: return experiment_id_1, experiment_id_2 -# -------------------------------------------------------------------------------------------------- \ No newline at end of file +# -------------------------------------------------------------------------------------------------- From 85fe1973b9d714586394ada0f31548934ff5525d Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Thu, 29 Jan 2026 16:35:24 -0500 Subject: [PATCH 40/51] pycodestyle fix --- src/swell/tasks/eva_comparison_jedi_log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/swell/tasks/eva_comparison_jedi_log.py b/src/swell/tasks/eva_comparison_jedi_log.py index 2da9e00d1..7c96a4155 100644 --- a/src/swell/tasks/eva_comparison_jedi_log.py +++ b/src/swell/tasks/eva_comparison_jedi_log.py @@ -50,7 +50,7 @@ def execute(self) -> None: experiment_path_1 = list(experiment_tag_paths.values())[0] experiment_path_2 = list(experiment_tag_paths.values())[1] - + yaml = YAML(typ='safe') with open(experiment_path_1, 'r') as f: experiment_dict_1 = yaml.load(f) From e706b977944e2b7d532adbbf0ae46cc94af83e97 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 2 Feb 2026 15:49:11 -0500 Subject: [PATCH 41/51] Remove cost function from marine plots --- .../3dvar/eva/jedi_log-geos_marine.yaml | 23 ------------------- .../3dvar_cycle/eva/jedi_log-geos_marine.yaml | 23 ------------------- 2 files changed, 46 deletions(-) diff --git a/src/swell/suites/3dvar/eva/jedi_log-geos_marine.yaml b/src/swell/suites/3dvar/eva/jedi_log-geos_marine.yaml index 8bf009e48..fa1f32de3 100644 --- a/src/swell/suites/3dvar/eva/jedi_log-geos_marine.yaml +++ b/src/swell/suites/3dvar/eva/jedi_log-geos_marine.yaml @@ -56,26 +56,3 @@ graphics: color: 'blue' label: 'Normalized norm reduction' - - figure: - title: 'Cost Function Plot' - output name: '{{cycle_dir}}/eva/jedi_log/cost_function/cost_function.png' - plots: - - add_xlabel: 'Total inner iteration number' - add_ylabel: 'Quadratic Cost Function' - add_legend: - layers: - - type: LinePlot - label: 'jb' - x: - variable: JediLogTest::convergence::total_iteration - y: - variable: JediLogTest::convergence::jb - color: 'black' - linestyle: '--' - - type: LinePlot - label: 'jojc' - x: - variable: JediLogTest::convergence::total_iteration - y: - variable: JediLogTest::convergence::jojc - color: 'black' \ No newline at end of file diff --git a/src/swell/suites/3dvar_cycle/eva/jedi_log-geos_marine.yaml b/src/swell/suites/3dvar_cycle/eva/jedi_log-geos_marine.yaml index a0805cc50..fa1f32de3 100644 --- a/src/swell/suites/3dvar_cycle/eva/jedi_log-geos_marine.yaml +++ b/src/swell/suites/3dvar_cycle/eva/jedi_log-geos_marine.yaml @@ -56,26 +56,3 @@ graphics: color: 'blue' label: 'Normalized norm reduction' - - figure: - title: 'Cost Function Plot' - output name: '{{cycle_dir}}/eva/jedi_log/cost_function/cost_function.png' - plots: - - add_xlabel: 'Total inner iteration number' - add_ylabel: 'Quadratic Cost Function' - add_legend: - layers: - - type: LinePlot - label: 'jb' - x: - variable: JediLogTest::convergence::total_iteration - y: - variable: JediLogTest::convergence::jb - color: 'black' - linestyle: '--' - - type: LinePlot - label: 'jojc' - x: - variable: JediLogTest::convergence::total_iteration - y: - variable: JediLogTest::convergence::jojc - color: 'black' From c6b2ff333c438c44d3a11d56d87f3248a7f17a6f Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 2 Feb 2026 15:57:38 -0500 Subject: [PATCH 42/51] Make eva tasks optional --- src/swell/suites/compare/flow.cylc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/swell/suites/compare/flow.cylc b/src/swell/suites/compare/flow.cylc index f014ef27a..5544ba283 100644 --- a/src/swell/suites/compare/flow.cylc +++ b/src/swell/suites/compare/flow.cylc @@ -30,12 +30,13 @@ {{cycle_time.cycle_time}} = """ {% for model_component in model_components %} {% if cycle_time[model_component] %} - EvaComparisonIncrement-{{model_component}} - EvaComparisonJediLog-{{model_component}} - EvaComparisonObservations-{{model_component}} {% for path in comparison_experiment_paths %} - JediOopsLogParser-{{model_component}}-{{ loop.index0 }} => JediLogComparison-{{model_component}} + JediOopsLogParser-{{model_component}}-{{ loop.index0 }} {% endfor %} + JediLogComparison-{{model_component}}? + JediLogComparison-{{model_component}}:fail? => EvaComparisonIncrement-{{model_component}} + JediLogComparison-{{model_component}}:fail? => EvaComparisonJediLog-{{model_component}} + JediLogComparison-{{model_component}}:fail? => EvaComparisonObservations-{{model_component}} {% endif %} {% endfor %} """ From 6bf37aeb8de81a65f0ef84d4d8731d6eb6933bd4 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Mon, 2 Feb 2026 17:00:31 -0500 Subject: [PATCH 43/51] Run plots only when residual norm fails --- src/swell/suites/compare/flow.cylc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/swell/suites/compare/flow.cylc b/src/swell/suites/compare/flow.cylc index 5544ba283..7df94f8c8 100644 --- a/src/swell/suites/compare/flow.cylc +++ b/src/swell/suites/compare/flow.cylc @@ -36,7 +36,7 @@ JediLogComparison-{{model_component}}? JediLogComparison-{{model_component}}:fail? => EvaComparisonIncrement-{{model_component}} JediLogComparison-{{model_component}}:fail? => EvaComparisonJediLog-{{model_component}} - JediLogComparison-{{model_component}}:fail? => EvaComparisonObservations-{{model_component}} + JediLogComparison-{{model_component}}:fail? => EvaComparisonObservations-{{model_component}} => comparison_fail {% endif %} {% endfor %} """ @@ -58,6 +58,9 @@ datetime = $CYLC_TASK_CYCLE_POINT config = $CYLC_SUITE_DEF_PATH/experiment.yaml + [[comparison_fail]] + script = "exit 1" + {% for model_component in model_components %} [[EvaComparisonIncrement-{{model_component}}]] script = "swell task EvaComparisonIncrement $config -d $datetime -m {{model_component}}" From 0d9e000783b29f4e85226dc0126ab26b66d37e85 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 11 Feb 2026 14:44:14 -0500 Subject: [PATCH 44/51] Add task to publish comparisons --- src/swell/tasks/task_questions.py | 9 +++++++++ src/swell/utilities/question_defaults.py | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/swell/tasks/task_questions.py b/src/swell/tasks/task_questions.py index 974b15971..8c3bae60e 100644 --- a/src/swell/tasks/task_questions.py +++ b/src/swell/tasks/task_questions.py @@ -493,6 +493,15 @@ class TaskQuestions(QuestionContainer, Enum): # -------------------------------------------------------------------------------------------------- + PublishComparisons = QuestionList( + list_name="PublishComparisons", + questions=[ + qd.publish_directory() + ] + ) + + # -------------------------------------------------------------------------------------------------- + PrepareAnalysis = QuestionList( list_name="PrepareAnalysis", questions=[ diff --git a/src/swell/utilities/question_defaults.py b/src/swell/utilities/question_defaults.py index df01ae2cf..ae8619313 100644 --- a/src/swell/utilities/question_defaults.py +++ b/src/swell/utilities/question_defaults.py @@ -1219,6 +1219,16 @@ class produce_geovals(TaskQuestion): # -------------------------------------------------------------------------------------------------- + @dataclass + class publish_directory(TaskQuestion): + default_value: str = None + question_name: str = "publish_directory" + ask_question: bool = False + prompt: str = "Provide an external directory to publish relevant results to." + widget_type: WType = WType.STRING + + # -------------------------------------------------------------------------------------------------- + @dataclass class r2d2_local_path(TaskQuestion): default_value: str = "defer_to_platform" From c86c6b5949624980b9bf9d82842e7a0742c7bf62 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 11 Feb 2026 14:49:08 -0500 Subject: [PATCH 45/51] add task --- src/swell/tasks/publish_comparisons.py | 69 ++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/swell/tasks/publish_comparisons.py diff --git a/src/swell/tasks/publish_comparisons.py b/src/swell/tasks/publish_comparisons.py new file mode 100644 index 000000000..9f9ea468d --- /dev/null +++ b/src/swell/tasks/publish_comparisons.py @@ -0,0 +1,69 @@ +# (C) Copyright 2021- United States Government as represented by the Administrator of the +# National Aeronautics and Space Administration. All Rights Reserved. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + + +# -------------------------------------------------------------------------------------------------- + + +import os +import re +import glob +import shutil + +from swell.tasks.base.task_base import taskBase + +# -------------------------------------------------------------------------------------------------- + + +class PublishComparisons(taskBase): + + '''Copies releveant text files and plots to a specified "publish location". + + If 'publish_directory' is None, the files will not be copied. + ''' + + def execute(self) -> None: + + # Output path base to copy files to + publish_directory = self.config.publish_directory(None) + + # Skip this task if there is no publish directory + if publish_directory is None: + return + + # For CI tests - contain results under the run ID + github_run_id = os.environ.get('GITHUB_RUN_ID') + experiment_id = self.experiment_id() + if github_run_id is not None: + experiment_id = os.path.join(github_run_id, experiment_id) + + # Name the location after the experiment ID + publish_location = os.path.join(self.config.publish_directory(), experiment_id) + + os.makedirs(publish_location, exist_ok=True) + + # Copy the JEDI log file comparison + log_file = os.path.join(self.experiment_path(), 'jedi_log_comparison.txt') + shutil.copy(log_file, publish_location) + + # Get the cycles + cycle_path = os.path.join(self.experiment_path(), 'run') + cycles = [d for d in os.listdir(cycle_path) if re.match('[0-9]*T[0-9]*Z', d)] + + for cycle in cycles: + for model in self.config.model_components(): + if os.path.isdir(os.path.join(cycle, model, 'eva')): + + # Copy eva png files + files = glob.glob(os.path.join(cycle_path, cycle, model, 'eva', '**', '*.png')) + out_path = os.path.join(publish_directory, cycle, model) + + os.makedirs(out_path, exist_ok=True) + + for file in files: + shutil.copy(file, out_path) + +# -------------------------------------------------------------------------------------------------- \ No newline at end of file From 890dfa764099dbdad5078595cae5c1fc6a3b10d6 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 11 Feb 2026 15:34:49 -0500 Subject: [PATCH 46/51] Fixes --- src/swell/tasks/publish_comparisons.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/swell/tasks/publish_comparisons.py b/src/swell/tasks/publish_comparisons.py index 9f9ea468d..e405fa343 100644 --- a/src/swell/tasks/publish_comparisons.py +++ b/src/swell/tasks/publish_comparisons.py @@ -21,7 +21,7 @@ class PublishComparisons(taskBase): '''Copies releveant text files and plots to a specified "publish location". - + If 'publish_directory' is None, the files will not be copied. ''' @@ -33,7 +33,7 @@ def execute(self) -> None: # Skip this task if there is no publish directory if publish_directory is None: return - + # For CI tests - contain results under the run ID github_run_id = os.environ.get('GITHUB_RUN_ID') experiment_id = self.experiment_id() @@ -55,15 +55,17 @@ def execute(self) -> None: for cycle in cycles: for model in self.config.model_components(): - if os.path.isdir(os.path.join(cycle, model, 'eva')): + if os.path.isdir(os.path.join(cycle_path, cycle, model, 'eva')): # Copy eva png files - files = glob.glob(os.path.join(cycle_path, cycle, model, 'eva', '**', '*.png')) - out_path = os.path.join(publish_directory, cycle, model) + files = glob.glob(os.path.join(cycle_path, cycle, model, + 'eva', '**', '*.png'), recursive=True) + + out_path = os.path.join(publish_location, cycle, model) os.makedirs(out_path, exist_ok=True) for file in files: shutil.copy(file, out_path) -# -------------------------------------------------------------------------------------------------- \ No newline at end of file +# -------------------------------------------------------------------------------------------------- From b945ffb473061bbef4c7f00fd1a935aedd55fdcd Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 11 Feb 2026 15:36:53 -0500 Subject: [PATCH 47/51] Add model_components --- src/swell/tasks/task_questions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/swell/tasks/task_questions.py b/src/swell/tasks/task_questions.py index 8c3bae60e..620fd5901 100644 --- a/src/swell/tasks/task_questions.py +++ b/src/swell/tasks/task_questions.py @@ -496,6 +496,7 @@ class TaskQuestions(QuestionContainer, Enum): PublishComparisons = QuestionList( list_name="PublishComparisons", questions=[ + qd.model_components(), qd.publish_directory() ] ) From a98dda8fa257c4b84b379cc2f0557eb0aa427b2d Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 11 Feb 2026 15:51:58 -0500 Subject: [PATCH 48/51] Add to workflow --- src/swell/suites/compare/flow.cylc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/swell/suites/compare/flow.cylc b/src/swell/suites/compare/flow.cylc index 7df94f8c8..596b03008 100644 --- a/src/swell/suites/compare/flow.cylc +++ b/src/swell/suites/compare/flow.cylc @@ -34,9 +34,11 @@ JediOopsLogParser-{{model_component}}-{{ loop.index0 }} {% endfor %} JediLogComparison-{{model_component}}? - JediLogComparison-{{model_component}}:fail? => EvaComparisonIncrement-{{model_component}} - JediLogComparison-{{model_component}}:fail? => EvaComparisonJediLog-{{model_component}} - JediLogComparison-{{model_component}}:fail? => EvaComparisonObservations-{{model_component}} => comparison_fail + JediLogComparison-{{model_component}}:fail? => EvaComparisonIncrement-{{model_component}} => PublishComparisons + JediLogComparison-{{model_component}}:fail? => EvaComparisonJediLog-{{model_component}} => PublishComparisons + JediLogComparison-{{model_component}}:fail? => EvaComparisonObservations-{{model_component}} => PublishComparisons + + PublishComparisons => comparison_fail {% endif %} {% endfor %} """ @@ -93,4 +95,7 @@ script = "swell task JediLogComparison $config -m {{model_component}}" {% endfor %} + [[PublishComparisons]] + script = "swell task PublishComparisons $config" + # -------------------------------------------------------------------------------------------------- From df2033b8006f46e4f7c2ecb099ffcdfe9c112863 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 11 Feb 2026 17:57:52 -0500 Subject: [PATCH 49/51] Make a cycling task --- src/swell/tasks/publish_comparisons.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/swell/tasks/publish_comparisons.py b/src/swell/tasks/publish_comparisons.py index e405fa343..039d8ea57 100644 --- a/src/swell/tasks/publish_comparisons.py +++ b/src/swell/tasks/publish_comparisons.py @@ -49,23 +49,16 @@ def execute(self) -> None: log_file = os.path.join(self.experiment_path(), 'jedi_log_comparison.txt') shutil.copy(log_file, publish_location) - # Get the cycles - cycle_path = os.path.join(self.experiment_path(), 'run') - cycles = [d for d in os.listdir(cycle_path) if re.match('[0-9]*T[0-9]*Z', d)] + if os.path.isdir(os.path.join(self.cycle_dir(), 'eva')): - for cycle in cycles: - for model in self.config.model_components(): - if os.path.isdir(os.path.join(cycle_path, cycle, model, 'eva')): + # Copy eva png files + files = glob.glob(os.path.join(self.cycle_dir(), 'eva', '**', '*.png'), recursive=True) - # Copy eva png files - files = glob.glob(os.path.join(cycle_path, cycle, model, - 'eva', '**', '*.png'), recursive=True) + out_path = os.path.join(publish_location, self.__datetime__.string_directory(), self.get_model()) - out_path = os.path.join(publish_location, cycle, model) + os.makedirs(out_path, exist_ok=True) - os.makedirs(out_path, exist_ok=True) - - for file in files: - shutil.copy(file, out_path) + for file in files: + shutil.copy(file, out_path) # -------------------------------------------------------------------------------------------------- From 26b034031e0db9d8f8cafaab5e0a186c51955755 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Wed, 11 Feb 2026 17:58:07 -0500 Subject: [PATCH 50/51] Fix flow.cylc --- src/swell/suites/compare/flow.cylc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/swell/suites/compare/flow.cylc b/src/swell/suites/compare/flow.cylc index 596b03008..8e030f405 100644 --- a/src/swell/suites/compare/flow.cylc +++ b/src/swell/suites/compare/flow.cylc @@ -26,6 +26,11 @@ runahead limit = {{runahead_limit}} [[graph]] + R1 = """ + {% for model_component in model_components %} + JediLogComparison-{{model_component}}? + {% endfor %} + """ {% for cycle_time in cycle_times %} {{cycle_time.cycle_time}} = """ {% for model_component in model_components %} @@ -33,12 +38,9 @@ {% for path in comparison_experiment_paths %} JediOopsLogParser-{{model_component}}-{{ loop.index0 }} {% endfor %} - JediLogComparison-{{model_component}}? - JediLogComparison-{{model_component}}:fail? => EvaComparisonIncrement-{{model_component}} => PublishComparisons - JediLogComparison-{{model_component}}:fail? => EvaComparisonJediLog-{{model_component}} => PublishComparisons - JediLogComparison-{{model_component}}:fail? => EvaComparisonObservations-{{model_component}} => PublishComparisons - - PublishComparisons => comparison_fail + 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 {% endif %} {% endfor %} """ @@ -79,6 +81,9 @@ --{{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 }}]] @@ -95,7 +100,4 @@ script = "swell task JediLogComparison $config -m {{model_component}}" {% endfor %} - [[PublishComparisons]] - script = "swell task PublishComparisons $config" - # -------------------------------------------------------------------------------------------------- From 0ccff57bb1f4ae7b791a8814ea496b883eb8dc77 Mon Sep 17 00:00:00 2001 From: Michael Anstett Date: Thu, 12 Feb 2026 14:16:37 -0500 Subject: [PATCH 51/51] test fixes --- src/swell/tasks/publish_comparisons.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/swell/tasks/publish_comparisons.py b/src/swell/tasks/publish_comparisons.py index 039d8ea57..63d97c1d0 100644 --- a/src/swell/tasks/publish_comparisons.py +++ b/src/swell/tasks/publish_comparisons.py @@ -9,7 +9,6 @@ import os -import re import glob import shutil @@ -32,8 +31,10 @@ def execute(self) -> None: # Skip this task if there is no publish directory if publish_directory is None: + print('Skipping') return + print('Not skipped') # For CI tests - contain results under the run ID github_run_id = os.environ.get('GITHUB_RUN_ID') experiment_id = self.experiment_id() @@ -54,7 +55,8 @@ def execute(self) -> None: # Copy eva png files files = glob.glob(os.path.join(self.cycle_dir(), 'eva', '**', '*.png'), recursive=True) - out_path = os.path.join(publish_location, self.__datetime__.string_directory(), self.get_model()) + out_path = os.path.join(publish_location, self.__datetime__.string_directory(), + self.get_model()) os.makedirs(out_path, exist_ok=True)