From 52dab2b5df30ee54059405a59d721c8dd2053805 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 7 Jul 2021 10:06:20 -0600 Subject: [PATCH 1/4] modified logic to all loop by valid time for TCPairs when loop order = processes --- metplus/wrappers/command_builder.py | 20 +++++++++++++++++ metplus/wrappers/tc_pairs_wrapper.py | 33 +++++++--------------------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/metplus/wrappers/command_builder.py b/metplus/wrappers/command_builder.py index c6c802ca9..5d2b8642f 100755 --- a/metplus/wrappers/command_builder.py +++ b/metplus/wrappers/command_builder.py @@ -2283,3 +2283,23 @@ def get_met_config(self, **kwargs): @returns METConfigInfo object """ return met_config(**kwargs) + + def get_start_time_input_dict(self): + """! Get the first run time specified in config. Used if only running + the wrapper once (LOOP_ORDER = processes). + + @returns dictionary containing time information for first run time + """ + use_init = util.is_loop_by_init(self.config) + if use_init is None: + self.log_error('Could not read time info') + return None + + + start_time, _, _ = util.get_start_end_interval_times(self.config) + if start_time is None: + self.log_error("Could not get start time") + return None + + input_dict = util.set_input_dict(start_time, self.config, use_init) + return input_dict diff --git a/metplus/wrappers/tc_pairs_wrapper.py b/metplus/wrappers/tc_pairs_wrapper.py index a82cea3ff..976e503e4 100755 --- a/metplus/wrappers/tc_pairs_wrapper.py +++ b/metplus/wrappers/tc_pairs_wrapper.py @@ -150,19 +150,8 @@ def create_c_dict(self): self.handle_consensus() - init_time_fmt = self.config.getstr('config', 'INIT_TIME_FMT') - clock_time = datetime.datetime.strptime( - self.config.getstr('config', - 'CLOCK_TIME'), - '%Y%m%d%H%M%S' - ) - - init_beg = self.config.getraw('config', 'INIT_BEG') - init_beg_dt = util.get_time_obj(init_beg, - init_time_fmt, - clock_time, - logger=self.logger) - c_dict['INIT_BEG'] = init_beg_dt.strftime('%Y%m%d_%H%M%S') + # if looping by processes, get the init or valid beg time and run once + c_dict['INPUT_DICT'] = self.get_start_time_input_dict() c_dict['INIT_INCLUDE'] = util.getlist( self.get_wrapper_or_generic_config('INIT_INCLUDE') @@ -360,11 +349,8 @@ def handle_consensus(self): def run_all_times(self): """! Build up the command to invoke the MET tool tc_pairs. """ - # use init begin as run time (start of the storm) - input_dict = {'init': - datetime.datetime.strptime(self.c_dict['INIT_BEG'], - '%Y%m%d_%H%M%S') - } + # use first run time + input_dict = self.c_dict.get('INPUT_DICT') # if running in READ_ALL_FILES mode, call tc_pairs once and exit if self.c_dict['READ_ALL_FILES']: @@ -536,10 +522,7 @@ class attributes # add storm month to each cyclone item if reformatting SBU if self.c_dict['REFORMAT_DECK'] and \ self.c_dict['REFORMAT_DECK_TYPE'] == 'SBU': - if time_info is None: - storm_month = self.c_dict['INIT_BEG'][4:6] - else: - storm_month = time_info['init'].strftime('%m') + storm_month = time_info['init'].strftime('%m') cyclone = [storm_month + c for c in cyclone] cyclone = str(cyclone).replace("'", '"') @@ -634,7 +617,7 @@ def process_data(self, basin, cyclone, time_info): return [] # Set up the environment variable to be used in the TCPairs Config - self.set_environment_variables(time_info) + self.set_environment_variables(time_storm_info) self.build() @@ -911,7 +894,7 @@ def _read_all_files(self, input_dict): directories to search for files to let the application determine which data to process - @param input_dict dictionary containing init time set from INIT_BEG + @param input_dict dictionary containing some time information @returns list of tuples containing commands that are run and which env vars were set for the command """ @@ -939,7 +922,7 @@ def _read_all_files(self, input_dict): check_extension='.tcst'): return [] - self.set_environment_variables(input_dict) + self.set_environment_variables(time_storm_info) self.build() return self.all_commands From 6694e7db6532eca12e51db7a1dadf444f7995d63 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 7 Jul 2021 10:39:14 -0600 Subject: [PATCH 2/4] modified unit tests to check if LOOP_BY = INIT and VALID both work when loop_order = processes --- .../pytests/tc_pairs/test_tc_pairs_wrapper.py | 250 ++++++++++-------- 1 file changed, 135 insertions(+), 115 deletions(-) diff --git a/internal_tests/pytests/tc_pairs/test_tc_pairs_wrapper.py b/internal_tests/pytests/tc_pairs/test_tc_pairs_wrapper.py index 1db9b8e65..e662b1ee1 100644 --- a/internal_tests/pytests/tc_pairs/test_tc_pairs_wrapper.py +++ b/internal_tests/pytests/tc_pairs/test_tc_pairs_wrapper.py @@ -15,7 +15,7 @@ time_fmt = '%Y%m%d%H' run_times = ['2014121318'] -def set_minimum_config_settings(config): +def set_minimum_config_settings(config, loop_by='INIT'): # set config variables to prevent command from running and bypass check # if input files actually exist config.set('config', 'DO_NOT_RUN_EXE', True) @@ -23,11 +23,11 @@ def set_minimum_config_settings(config): # set process and time config variables config.set('config', 'PROCESS_LIST', 'TCPairs') - config.set('config', 'LOOP_BY', 'INIT') - config.set('config', 'INIT_TIME_FMT', time_fmt) - config.set('config', 'INIT_BEG', run_times[0]) - config.set('config', 'INIT_END', run_times[-1]) - config.set('config', 'INIT_INCREMENT', '12H') + config.set('config', 'LOOP_BY', loop_by) + config.set('config', f'{loop_by}_TIME_FMT', time_fmt) + config.set('config', f'{loop_by}_BEG', run_times[0]) + config.set('config', f'{loop_by}_END', run_times[-1]) + config.set('config', f'{loop_by}_INCREMENT', '12H') config.set('config', 'TC_PAIRS_CONFIG_FILE', '{PARM_BASE}/met_config/TCPairsConfig_wrapped') config.set('config', 'TC_PAIRS_BDECK_TEMPLATE', bdeck_template) @@ -264,7 +264,7 @@ def test_tc_pairs_storm_id_lists(metplus_config, config_overrides, config.set('config', key, value) wrapper = TCPairsWrapper(config) - assert(wrapper.isOK) + assert wrapper.isOK all_cmds = wrapper.run_all_times() print(f"ALL COMMANDS:") @@ -356,65 +356,78 @@ def test_tc_pairs_storm_id_lists(metplus_config, config_overrides, ) def test_tc_pairs_loop_order_processes(metplus_config, config_overrides, env_var_values): - - config = metplus_config() - - set_minimum_config_settings(config) - - test_data_dir = os.path.join(config.getdir('METPLUS_BASE'), - 'internal_tests', - 'data', - 'tc_pairs') - bdeck_dir = os.path.join(test_data_dir, 'bdeck') - adeck_dir = os.path.join(test_data_dir, 'adeck') - - config.set('config', 'TC_PAIRS_BDECK_INPUT_DIR', bdeck_dir) - config.set('config', 'TC_PAIRS_ADECK_INPUT_DIR', adeck_dir) - - # LOOP_ORDER processes runs once, times runs once per time - config.set('config', 'LOOP_ORDER', 'processes') - - # set config variable overrides - for key, value in config_overrides.items(): - config.set('config', key, value) - - if 'METPLUS_INIT_BEG' not in env_var_values: - env_var_values['METPLUS_INIT_BEG'] = f'init_beg = "{run_times[0]}";' - - if 'METPLUS_INIT_END' not in env_var_values: - env_var_values['METPLUS_INIT_END'] = f'init_end = "{run_times[-1]}";' - - wrapper = TCPairsWrapper(config) - assert(wrapper.isOK) - - app_path = os.path.join(config.getdir('MET_BIN_DIR'), wrapper.app_name) - verbosity = f"-v {wrapper.c_dict['VERBOSITY']}" - config_file = wrapper.c_dict.get('CONFIG_FILE') - out_dir = wrapper.c_dict.get('OUTPUT_DIR') - expected_cmds = [(f"{app_path} {verbosity} " - f"-bdeck {bdeck_dir}/bmlq2014123118.gfso.0104 " - f"-adeck {adeck_dir}/amlq2014123118.gfso.0104 " - f"-config {config_file} " - f"-out {out_dir}/mlq2014121318.gfso.0104"), - ] - - - all_cmds = wrapper.run_all_times() - print(f"ALL COMMANDS: {all_cmds}") - assert(len(all_cmds) == len(expected_cmds)) - - for (cmd, env_vars), expected_cmd in zip(all_cmds, expected_cmds): - # ensure commands are generated as expected - assert(cmd == expected_cmd) - - # check that environment variables were set properly - for env_var_key in wrapper.WRAPPER_ENV_VAR_KEYS: - match = next((item for item in env_vars if - item.startswith(env_var_key)), None) - assert(match is not None) - print(f'Checking env var: {env_var_key}') - actual_value = match.split('=', 1)[1] - assert(env_var_values.get(env_var_key, '') == actual_value) + # run using init and valid time variables + for loop_by in ['INIT', 'VALID']: + remove_beg = remove_end = False + config = metplus_config() + + set_minimum_config_settings(config, loop_by) + + test_data_dir = os.path.join(config.getdir('METPLUS_BASE'), + 'internal_tests', + 'data', + 'tc_pairs') + bdeck_dir = os.path.join(test_data_dir, 'bdeck') + adeck_dir = os.path.join(test_data_dir, 'adeck') + + config.set('config', 'TC_PAIRS_BDECK_INPUT_DIR', bdeck_dir) + config.set('config', 'TC_PAIRS_ADECK_INPUT_DIR', adeck_dir) + + # LOOP_ORDER processes runs once, times runs once per time + config.set('config', 'LOOP_ORDER', 'processes') + + # set config variable overrides + for key, value in config_overrides.items(): + config.set('config', key, value) + + if f'METPLUS_{loop_by}_BEG' not in env_var_values: + env_var_values[f'METPLUS_{loop_by}_BEG'] = ( + f'{loop_by.lower()}_beg = "{run_times[0]}";' + ) + remove_beg = True + + if f'METPLUS_{loop_by}_END' not in env_var_values: + env_var_values[f'METPLUS_{loop_by}_END'] = ( + f'{loop_by.lower()}_end = "{run_times[-1]}";' + ) + remove_end = True + + wrapper = TCPairsWrapper(config) + assert wrapper.isOK + + app_path = os.path.join(config.getdir('MET_BIN_DIR'), wrapper.app_name) + verbosity = f"-v {wrapper.c_dict['VERBOSITY']}" + config_file = wrapper.c_dict.get('CONFIG_FILE') + out_dir = wrapper.c_dict.get('OUTPUT_DIR') + expected_cmds = [(f"{app_path} {verbosity} " + f"-bdeck {bdeck_dir}/bmlq2014123118.gfso.0104 " + f"-adeck {adeck_dir}/amlq2014123118.gfso.0104 " + f"-config {config_file} " + f"-out {out_dir}/mlq2014121318.gfso.0104"), + ] + + + all_cmds = wrapper.run_all_times() + print(f"ALL COMMANDS: {all_cmds}") + assert(len(all_cmds) == len(expected_cmds)) + + for (cmd, env_vars), expected_cmd in zip(all_cmds, expected_cmds): + # ensure commands are generated as expected + assert(cmd == expected_cmd) + + # check that environment variables were set properly + for env_var_key in wrapper.WRAPPER_ENV_VAR_KEYS: + match = next((item for item in env_vars if + item.startswith(env_var_key)), None) + assert(match is not None) + print(f'Checking env var: {env_var_key}') + actual_value = match.split('=', 1)[1] + assert(env_var_values.get(env_var_key, '') == actual_value) + + if remove_beg: + del env_var_values[f'METPLUS_{loop_by}_BEG'] + if remove_end: + del env_var_values[f'METPLUS_{loop_by}_END'] @pytest.mark.parametrize( 'config_overrides, env_var_values', [ @@ -433,61 +446,68 @@ def test_tc_pairs_loop_order_processes(metplus_config, config_overrides, ) def test_tc_pairs_read_all_files(metplus_config, config_overrides, env_var_values): + # run using init and valid time variables + for loop_by in ['INIT', 'VALID']: + config = metplus_config() - config = metplus_config() + set_minimum_config_settings(config, loop_by) - set_minimum_config_settings(config) + test_data_dir = os.path.join(config.getdir('METPLUS_BASE'), + 'internal_tests', + 'data', + 'tc_pairs') + bdeck_dir = os.path.join(test_data_dir, 'bdeck') + adeck_dir = os.path.join(test_data_dir, 'adeck') - test_data_dir = os.path.join(config.getdir('METPLUS_BASE'), - 'internal_tests', - 'data', - 'tc_pairs') - bdeck_dir = os.path.join(test_data_dir, 'bdeck') - adeck_dir = os.path.join(test_data_dir, 'adeck') + config.set('config', 'TC_PAIRS_BDECK_INPUT_DIR', bdeck_dir) + config.set('config', 'TC_PAIRS_ADECK_INPUT_DIR', adeck_dir) - config.set('config', 'TC_PAIRS_BDECK_INPUT_DIR', bdeck_dir) - config.set('config', 'TC_PAIRS_ADECK_INPUT_DIR', adeck_dir) + # LOOP_ORDER processes runs once, times runs once per time + config.set('config', 'LOOP_ORDER', 'processes') - # LOOP_ORDER processes runs once, times runs once per time - config.set('config', 'LOOP_ORDER', 'processes') - - config.set('config', 'TC_PAIRS_READ_ALL_FILES', True) - config.set('config', 'TC_PAIRS_OUTPUT_TEMPLATE', '') + config.set('config', 'TC_PAIRS_READ_ALL_FILES', True) + config.set('config', 'TC_PAIRS_OUTPUT_TEMPLATE', '') - # set config variable overrides - for key, value in config_overrides.items(): - config.set('config', key, value) + # set config variable overrides + for key, value in config_overrides.items(): + config.set('config', key, value) - if 'METPLUS_INIT_BEG' not in env_var_values: - env_var_values['METPLUS_INIT_BEG'] = f'init_beg = "{run_times[0]}";' - - if 'METPLUS_INIT_END' not in env_var_values: - env_var_values['METPLUS_INIT_END'] = f'init_end = "{run_times[-1]}";' + env_var_values[f'METPLUS_{loop_by}_BEG'] = ( + f'{loop_by.lower()}_beg = "{run_times[0]}";' + ) - wrapper = TCPairsWrapper(config) - assert(wrapper.isOK) - - app_path = os.path.join(config.getdir('MET_BIN_DIR'), wrapper.app_name) - verbosity = f"-v {wrapper.c_dict['VERBOSITY']}" - config_file = wrapper.c_dict.get('CONFIG_FILE') - out_dir = wrapper.c_dict.get('OUTPUT_DIR') - expected_cmds = [(f"{app_path} {verbosity} " - f"-bdeck {bdeck_dir} " - f"-adeck {adeck_dir} " - f"-config {config_file} " - f"-out {out_dir}/tc_pairs"), - ] + env_var_values[f'METPLUS_{loop_by}_END'] = ( + f'{loop_by.lower()}_end = "{run_times[-1]}";' + ) - all_cmds = wrapper.run_all_times() - print(f"ALL COMMANDS: {all_cmds}") - assert(len(all_cmds) == len(expected_cmds)) - - for (cmd, env_vars), expected_cmd in zip(all_cmds, expected_cmds): - # check that environment variables were set properly - for env_var_key in wrapper.WRAPPER_ENV_VAR_KEYS: - match = next((item for item in env_vars if - item.startswith(env_var_key)), None) - assert(match is not None) - print(f'Checking env var: {env_var_key}') - actual_value = match.split('=', 1)[1] - assert(env_var_values.get(env_var_key, '') == actual_value) + wrapper = TCPairsWrapper(config) + assert wrapper.isOK + + app_path = os.path.join(config.getdir('MET_BIN_DIR'), wrapper.app_name) + verbosity = f"-v {wrapper.c_dict['VERBOSITY']}" + config_file = wrapper.c_dict.get('CONFIG_FILE') + out_dir = wrapper.c_dict.get('OUTPUT_DIR') + expected_cmds = [(f"{app_path} {verbosity} " + f"-bdeck {bdeck_dir} " + f"-adeck {adeck_dir} " + f"-config {config_file} " + f"-out {out_dir}/tc_pairs"), + ] + + all_cmds = wrapper.run_all_times() + print(f"ALL COMMANDS: {all_cmds}") + assert(len(all_cmds) == len(expected_cmds)) + + for (cmd, env_vars), expected_cmd in zip(all_cmds, expected_cmds): + # check that environment variables were set properly + for env_var_key in wrapper.WRAPPER_ENV_VAR_KEYS: + match = next((item for item in env_vars if + item.startswith(env_var_key)), None) + assert(match is not None) + print(f'Checking env var: {env_var_key}') + actual_value = match.split('=', 1)[1] + assert(env_var_values.get(env_var_key, '') == actual_value) + + # unset begin and end for next loop + del env_var_values[f'METPLUS_{loop_by}_BEG'] + del env_var_values[f'METPLUS_{loop_by}_END'] From d9748f6556ae0f45577e08c42e1b93840e5d4762 Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Wed, 7 Jul 2021 16:57:49 -0600 Subject: [PATCH 3/4] loop over forecast lead list (LEAD_SEQ) if set and run once for each --- metplus/wrappers/tc_pairs_wrapper.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/metplus/wrappers/tc_pairs_wrapper.py b/metplus/wrappers/tc_pairs_wrapper.py index 976e503e4..7a54c6536 100755 --- a/metplus/wrappers/tc_pairs_wrapper.py +++ b/metplus/wrappers/tc_pairs_wrapper.py @@ -371,12 +371,16 @@ def run_at_time(self, input_dict): self.logger.info(f"Processing custom string: {custom_string}") input_dict['custom'] = custom_string - time_info = time_util.ti_calculate(input_dict) - if util.skip_time(time_info, self.c_dict.get('SKIP_TIMES', {})): - self.logger.debug('Skipping run time') - return + lead_seq = util.get_lead_sequence(self.config, input_dict) + for lead in lead_seq: + input_dict['lead'] = lead + time_info = time_util.ti_calculate(input_dict) + + if util.skip_time(time_info, self.c_dict.get('SKIP_TIMES', {})): + self.logger.debug('Skipping run time') + return - self.run_at_time_loop_string(time_info) + self.run_at_time_loop_string(time_info) def run_at_time_loop_string(self, time_info): """! Create the arguments to run MET tc_pairs From 25bcc566ac5128095cc86e73c3dfdb6e1d98f23b Mon Sep 17 00:00:00 2001 From: George McCabe <23407799+georgemccabe@users.noreply.github.com> Date: Mon, 12 Jul 2021 12:59:28 -0600 Subject: [PATCH 4/4] added option to skip looping over forecast lead list in TCPairs to be able to configure the previous behavior for feature relative use cases while still allowing more flexibility in calling TCPairs for other uses --- docs/Users_Guide/glossary.rst | 9 +++++++++ docs/Users_Guide/wrappers.rst | 1 + metplus/wrappers/tc_pairs_wrapper.py | 14 +++++++++++++- .../TCPairs/TCPairs_extra_tropical.conf | 4 ++++ .../met_tool_wrapper/TCPairs/TCPairs_tropical.conf | 6 +++++- ...cstGFS_obsGFS_FeatureRelative_SeriesByLead.conf | 3 ++- ...S_FeatureRelative_SeriesByLead_PyEmbed_IVT.conf | 3 +++ ..._SeriesByLead_PyEmbed_Multiple_Diagnostics.conf | 3 +++ 8 files changed, 40 insertions(+), 3 deletions(-) diff --git a/docs/Users_Guide/glossary.rst b/docs/Users_Guide/glossary.rst index b973d300d..a7076d620 100644 --- a/docs/Users_Guide/glossary.rst +++ b/docs/Users_Guide/glossary.rst @@ -7162,3 +7162,12 @@ METplus Configuration Glossary variable OR :term:`EXTRACT_TILES_TC_STAT_INPUT_TEMPLATE` but not both. | *Used by:* ExtractTiles + + TC_PAIRS_SKIP_LEAD_SEQ + If True and a forecast lead sequence is set in the configuration, do not + loop over list of leads and process for each. This is used for feature + relative use cases where TCPairs is run for each storm initialization time + and SeriesAnalysis is configured to filter the data by forecast leads. + Default value is False. + + | *Used by:* TCPairs diff --git a/docs/Users_Guide/wrappers.rst b/docs/Users_Guide/wrappers.rst index 98c8a4714..341a71405 100644 --- a/docs/Users_Guide/wrappers.rst +++ b/docs/Users_Guide/wrappers.rst @@ -5393,6 +5393,7 @@ METplus Configuration | :term:`TC_PAIRS_CONSENSUS_MEMBERS` | :term:`TC_PAIRS_CONSENSUS_REQUIRED` | :term:`TC_PAIRS_CONSENSUS_MIN_REQ` +| :term:`TC_PAIRS_SKIP_LEAD_SEQ` | .. warning:: **DEPRECATED:** diff --git a/metplus/wrappers/tc_pairs_wrapper.py b/metplus/wrappers/tc_pairs_wrapper.py index 7a54c6536..ea2ad16b5 100755 --- a/metplus/wrappers/tc_pairs_wrapper.py +++ b/metplus/wrappers/tc_pairs_wrapper.py @@ -245,6 +245,12 @@ def create_c_dict(self): self.handle_description() + c_dict['SKIP_LEAD_SEQ'] = ( + self.config.getbool('config', + 'TC_PAIRS_SKIP_LEAD_SEQ', + False) + ) + return c_dict def _read_storm_info(self, c_dict): @@ -371,7 +377,13 @@ def run_at_time(self, input_dict): self.logger.info(f"Processing custom string: {custom_string}") input_dict['custom'] = custom_string - lead_seq = util.get_lead_sequence(self.config, input_dict) + + # if skipping lead sequence, only run once per init/valid time + if self.c_dict['SKIP_LEAD_SEQ']: + lead_seq = [0] + else: + lead_seq = util.get_lead_sequence(self.config, input_dict) + for lead in lead_seq: input_dict['lead'] = lead time_info = time_util.ti_calculate(input_dict) diff --git a/parm/use_cases/met_tool_wrapper/TCPairs/TCPairs_extra_tropical.conf b/parm/use_cases/met_tool_wrapper/TCPairs/TCPairs_extra_tropical.conf index c9060fb8a..cdbc4d633 100644 --- a/parm/use_cases/met_tool_wrapper/TCPairs/TCPairs_extra_tropical.conf +++ b/parm/use_cases/met_tool_wrapper/TCPairs/TCPairs_extra_tropical.conf @@ -38,6 +38,10 @@ TC_PAIRS_INIT_END = {INIT_END} TC_PAIRS_VALID_BEG = TC_PAIRS_VALID_END = +# Skip looping over forecast leads if a list is provided +#TC_PAIRS_SKIP_LEAD_SEQ = False + + ## # # MET TC-Pairs diff --git a/parm/use_cases/met_tool_wrapper/TCPairs/TCPairs_tropical.conf b/parm/use_cases/met_tool_wrapper/TCPairs/TCPairs_tropical.conf index bf1a8a67a..a7192ecba 100644 --- a/parm/use_cases/met_tool_wrapper/TCPairs/TCPairs_tropical.conf +++ b/parm/use_cases/met_tool_wrapper/TCPairs/TCPairs_tropical.conf @@ -22,7 +22,7 @@ INIT_END = 2018083018 # This is the step-size. Increment in seconds from the begin time to the end time # set to 6 hours = 21600 seconds -INIT_INCREMENT = 21600 +INIT_INCREMENT = 21600 # A list of times to include, in format YYYYMMDD_hh TC_PAIRS_INIT_INCLUDE = @@ -54,6 +54,10 @@ TC_PAIRS_REFORMAT_DECK = no # Set to no if you do want to override existing files TC_PAIRS_SKIP_IF_OUTPUT_EXISTS = no +# Skip looping over forecast leads if a list is provided +#TC_PAIRS_SKIP_LEAD_SEQ = False + + # # MET TC-Pairs # diff --git a/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead.conf b/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead.conf index 8bbfa04dc..607cce7ca 100644 --- a/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead.conf +++ b/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead.conf @@ -39,11 +39,12 @@ LEAD_SEQ_2 = begin_end_incr(24,42,6) # forecast lead sequence 2 label LEAD_SEQ_2_LABEL = Day2 - ####### # TCPairs Configurations ####### +TC_PAIRS_SKIP_LEAD_SEQ = True + # A list of times to include, in format YYYYMMDD_hh TC_PAIRS_INIT_INCLUDE = diff --git a/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_IVT.conf b/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_IVT.conf index eb8904dff..c5e864e7e 100644 --- a/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_IVT.conf +++ b/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_IVT.conf @@ -73,6 +73,9 @@ PY_EMBED_INGEST_2_OUTPUT_FIELD_NAME = ivt # TCPairs Configurations ####### +# only run TCPairs once for the init time, not for each forecast lead +TC_PAIRS_SKIP_LEAD_SEQ = True + # A list of times to include, in format YYYYMMDD_hh TC_PAIRS_INIT_INCLUDE = diff --git a/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_Multiple_Diagnostics.conf b/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_Multiple_Diagnostics.conf index 4fd573596..0751ca521 100644 --- a/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_Multiple_Diagnostics.conf +++ b/parm/use_cases/model_applications/medium_range/TCStat_SeriesAnalysis_fcstGFS_obsGFS_FeatureRelative_SeriesByLead_PyEmbed_Multiple_Diagnostics.conf @@ -87,6 +87,9 @@ PY_EMBED_INGEST_2_OUTPUT_GRID = {MODEL_DIR}/{valid?fmt=%Y%m%d}/gfs_4_{valid?fmt= # TCPairs Configurations ####### +# only run TCPairs once for the init time, not for each forecast lead +TC_PAIRS_SKIP_LEAD_SEQ = True + # A list of times to include, in format YYYYMMDD_hh TC_PAIRS_INIT_INCLUDE =