diff --git a/src/swell/configuration/jedi/interfaces/geos_atmosphere/suite_questions.yaml b/src/swell/configuration/jedi/interfaces/geos_atmosphere/suite_questions.yaml index 9db1cd1b..9dcf3013 100644 --- a/src/swell/configuration/jedi/interfaces/geos_atmosphere/suite_questions.yaml +++ b/src/swell/configuration/jedi/interfaces/geos_atmosphere/suite_questions.yaml @@ -1,3 +1,6 @@ cycle_times: default_value: ['T00', 'T06', 'T12', 'T18'] options: ['T00', 'T06', 'T12', 'T18'] + +window_type: + default_value: '4d' diff --git a/src/swell/configuration/jedi/interfaces/geos_atmosphere/task_questions.yaml b/src/swell/configuration/jedi/interfaces/geos_atmosphere/task_questions.yaml index 9a11b899..35d20241 100644 --- a/src/swell/configuration/jedi/interfaces/geos_atmosphere/task_questions.yaml +++ b/src/swell/configuration/jedi/interfaces/geos_atmosphere/task_questions.yaml @@ -242,6 +242,3 @@ window_length: window_offset: default_value: PT3H -window_type: - default_value: 4D - diff --git a/src/swell/configuration/jedi/interfaces/geos_ocean/suite_questions.yaml b/src/swell/configuration/jedi/interfaces/geos_ocean/suite_questions.yaml index f29c4a4c..06e7eef4 100644 --- a/src/swell/configuration/jedi/interfaces/geos_ocean/suite_questions.yaml +++ b/src/swell/configuration/jedi/interfaces/geos_ocean/suite_questions.yaml @@ -1,3 +1,6 @@ cycle_times: default_value: ['T00', 'T12'] options: ['T00', 'T12'] + +window_type: + default_value: '3d' diff --git a/src/swell/configuration/jedi/interfaces/geos_ocean/task_questions.yaml b/src/swell/configuration/jedi/interfaces/geos_ocean/task_questions.yaml index 4d819509..b0d1ac7f 100644 --- a/src/swell/configuration/jedi/interfaces/geos_ocean/task_questions.yaml +++ b/src/swell/configuration/jedi/interfaces/geos_ocean/task_questions.yaml @@ -88,6 +88,3 @@ window_length: window_offset: default_value: PT6H -window_type: - default_value: 3D - diff --git a/src/swell/deployment/create_experiment.py b/src/swell/deployment/create_experiment.py index b63a8007..e465af08 100644 --- a/src/swell/deployment/create_experiment.py +++ b/src/swell/deployment/create_experiment.py @@ -362,8 +362,9 @@ def prepare_cylc_suite_jinja2(logger, swell_suite_path, exp_suite_path, experime 'start_cycle_point', 'final_cycle_point', 'runahead_limit', + 'window_type', 'model_components', - 'platform', + 'platform' ] # Copy elements from experiment dictionary to render dictionary diff --git a/src/swell/suites/3dvar/flow.cylc b/src/swell/suites/3dvar/flow.cylc index 7abb1214..cea87406 100644 --- a/src/swell/suites/3dvar/flow.cylc +++ b/src/swell/suites/3dvar/flow.cylc @@ -48,7 +48,7 @@ # Task triggers for: {{model_component}} # ------------------ # Get background - GetBackground-{{model_component}} + GetBackground3d-{{model_component}} # Get observations GetObservations-{{model_component}} @@ -63,7 +63,7 @@ BuildJediByLinking[^]? | BuildJedi[^] => RunJediVariationalExecutable-{{model_component}} StageJedi-{{model_component}}[^] => RunJediVariationalExecutable-{{model_component}} StageJediCycle-{{model_component}} => RunJediVariationalExecutable-{{model_component}} - GetBackground-{{model_component}} => RunJediVariationalExecutable-{{model_component}} + GetBackground3d-{{model_component}} => RunJediVariationalExecutable-{{model_component}} GenerateBClimatologyByLinking-{{model_component}} => RunJediVariationalExecutable-{{model_component}} GetObservations-{{model_component}} => RunJediVariationalExecutable-{{model_component}} @@ -128,8 +128,8 @@ [[StageJediCycle-{{model_component}}]] script = "swell task StageJedi $config -d $datetime -m {{model_component}}" - [[ GetBackground-{{model_component}} ]] - script = "swell task GetBackground $config -d $datetime -m {{model_component}}" + [[ GetBackground3d-{{model_component}} ]] + script = "swell task GetBackground3d $config -d $datetime -m {{model_component}}" [[GetObservations-{{model_component}}]] script = "swell task GetObservations $config -d $datetime -m {{model_component}}" diff --git a/src/swell/suites/hofx/flow.cylc b/src/swell/suites/hofx/flow.cylc index 86e9d43e..cbb28281 100644 --- a/src/swell/suites/hofx/flow.cylc +++ b/src/swell/suites/hofx/flow.cylc @@ -55,7 +55,7 @@ CloneGeosAna-{{model_component}}[^] => GenerateObservingSystemRecords-{{model_component}} # Get background - GetBackground-{{model_component}} + GetBackground{{window_type}}-{{model_component}} # Get observations GetObservations-{{model_component}} @@ -67,7 +67,7 @@ BuildJediByLinking[^]? | BuildJedi[^] => RunJediHofxExecutable-{{model_component}} StageJedi-{{model_component}}[^] => RunJediHofxExecutable-{{model_component}} StageJediCycle-{{model_component}} => RunJediHofxExecutable-{{model_component}} - GetBackground-{{model_component}} => RunJediHofxExecutable-{{model_component}} + GetBackground{{window_type}}-{{model_component}} => RunJediHofxExecutable-{{model_component}} GetObservations-{{model_component}} => RunJediHofxExecutable-{{model_component}} GenerateObservingSystemRecords-{{model_component}} => RunJediHofxExecutable-{{model_component}} @@ -136,8 +136,8 @@ [[StageJediCycle-{{model_component}}]] script = "swell task StageJedi $config -d $datetime -m {{model_component}}" - [[ GetBackground-{{model_component}} ]] - script = "swell task GetBackground $config -d $datetime -m {{model_component}}" + [[ GetBackground{{window_type}}-{{model_component}} ]] + script = "swell task GetBackground{{window_type}} $config -d $datetime -m {{model_component}}" [[GetObservations-{{model_component}}]] script = "swell task GetObservations $config -d $datetime -m {{model_component}}" diff --git a/src/swell/suites/hofx/suite_questions.yaml b/src/swell/suites/hofx/suite_questions.yaml index 71c889f6..6e81b220 100644 --- a/src/swell/suites/hofx/suite_questions.yaml +++ b/src/swell/suites/hofx/suite_questions.yaml @@ -1,3 +1,10 @@ +window_type: + ask_question: True + default_value: 3d + options: ['3d', '4d'] + prompt: Do you want to use a 3d or 4d (including FGAT) window? + type: string-drop-list + start_cycle_point: ask_question: True default_value: '2021-12-12T00:00:00Z' diff --git a/src/swell/tasks/get_background3d.py b/src/swell/tasks/get_background3d.py new file mode 100644 index 00000000..0e805854 --- /dev/null +++ b/src/swell/tasks/get_background3d.py @@ -0,0 +1,115 @@ +# (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.tasks.base.task_base import taskBase + +import isodate +import os +from r2d2 import fetch + + +# -------------------------------------------------------------------------------------------------- + +r2d2_model_dict = { + 'geos_atmosphere': 'geos', + 'geos_ocean': 'mom6_cice6_UFS', +} + + +# -------------------------------------------------------------------------------------------------- + +class GetBackground3d(taskBase): + + def execute(self): + + """Acquires 3D background files for a given experiment and cycle + + Parameters + ---------- + All inputs are extracted from the JEDI experiment file configuration. + See the taskBase constructor for more information. + """ + + bkg_step = None + + # Parse config + background_experiment = self.config.background_experiment() + forecast_offset = self.config.analysis_forecast_window_offset() + horizontal_resolution = self.config.horizontal_resolution() + window_length = self.config.window_length() + window_offset = self.config.window_offset() + + # Get window parameters + local_background_time = self.da_window_params.local_background_time(window_offset, '3D') + + # Add to jedi config rendering dictionary + self.jedi_rendering.add_key('local_background_time', local_background_time) + + # Convert to datetime durations + # ----------------------------- + window_length_dur = isodate.parse_duration(window_length) + forecast_offset_dur = isodate.parse_duration(forecast_offset) + + # Duration between the start of the forecast that generated the background + # and the middle of the current window + # ------------------------------------------------------------------------------- + forecast_duration_for_background = window_length_dur - forecast_offset_dur + + # Append the list of backgrounds to get with the first background + # ----------------------------------------------------------------- + bkg_step = isodate.duration_isoformat(forecast_duration_for_background) + + # Get the forecast start time + # --------------------------- + forecast_start_time = self.cycle_time_dto() - window_length_dur + forecast_offset_dur + + # Get name of this model component + # -------------------------------- + model_component = self.get_model() + + # Loop over background files in the R2D2 config and fetch + # ------------------------------------------------------- + self.logger.info(f"Background step being fetched: {bkg_step}") + + # Get r2d2 dictionary + r2d2_dict = self.jedi_rendering.render_interface_model('r2d2') + + # Loop over fc + # ------------ + for fc in r2d2_dict['fetch']['fc']: + + # Reset target file + # -------------------- + file_type = fc['file_type'] + target_file_template = fc['filename'] + + # Set the datetime format for the output files + # -------------------------------------------- + background_time = forecast_start_time + isodate.parse_duration(bkg_step) + + # Set the datetime templating in the target file name + # --------------------------------------------------- + target_file = background_time.strftime(target_file_template) + + fetch( + date=forecast_start_time, + target_file=target_file, + model=r2d2_model_dict[model_component], + file_type=file_type, + fc_date_rendering='analysis', + step=bkg_step, + resolution=horizontal_resolution, + type='fc', + experiment=background_experiment) + + # Change permission + os.chmod(target_file, 0o644) + +# -------------------------------------------------------------------------------------------------- diff --git a/src/swell/tasks/get_background.py b/src/swell/tasks/get_background4d.py similarity index 78% rename from src/swell/tasks/get_background.py rename to src/swell/tasks/get_background4d.py index a7196ee7..3e803bcf 100644 --- a/src/swell/tasks/get_background.py +++ b/src/swell/tasks/get_background4d.py @@ -25,11 +25,11 @@ # -------------------------------------------------------------------------------------------------- -class GetBackground(taskBase): +class GetBackground4d(taskBase): def execute(self): - """Acquires background files for a given experiment and cycle + """Acquires 4D background files for a given experiment and cycle Parameters ---------- @@ -40,6 +40,7 @@ def execute(self): # Get duration into forecast for first background file # ---------------------------------------------------- bkg_steps = [] + #raise ValueError(str(self.config.__model_components__)) # Parse config background_experiment = self.config.background_experiment() @@ -48,11 +49,9 @@ def execute(self): horizontal_resolution = self.config.horizontal_resolution() window_length = self.config.window_length() window_offset = self.config.window_offset() - window_type = self.config.window_type() # Get window parameters - local_background_time = self.da_window_params.local_background_time(window_offset, - window_type) + local_background_time = self.da_window_params.local_background_time(window_offset, "4D") # Add to jedi config rendering dictionary self.jedi_rendering.add_key('local_background_time', local_background_time) @@ -70,9 +69,8 @@ def execute(self): # If the window type is 4D then remove the window offset as first background # occurs at the beginning of the window # ------------------------------------------------------------------------------- - if window_type == "4D": - window_offset_dur = isodate.parse_duration(window_offset) - forecast_duration_for_background = forecast_duration_for_background - window_offset_dur + window_offset_dur = isodate.parse_duration(window_offset) + forecast_duration_for_background = forecast_duration_for_background - window_offset_dur # Append the list of backgrounds to get with the first background # ----------------------------------------------------------------- @@ -80,28 +78,27 @@ def execute(self): # If background is provided though files get all backgrounds # ---------------------------------------------------------- - if window_type == "4D": + bkg_freq_dur = isodate.parse_duration(background_frequency) - bkg_freq_dur = isodate.parse_duration(background_frequency) + # Check for a sensible frequency + # ------------------------------ + if (window_length_dur/bkg_freq_dur) % 2: + self.logger.abort('Window length not divisible by background frequency') - # Check for a sensible frequency - # ------------------------------ - if (window_length_dur/bkg_freq_dur) % 2: - self.logger.abort('Window length not divisible by background frequency') + print('self.cycle_time_dto()', self.cycle_time_dto()) + print('window_offset_dur', window_offset_dur) - # Loop over window - print('self.cycle_time_dto()', self.cycle_time_dto()) - print('window_offset_dur', window_offset_dur) + start_date = self.cycle_time_dto() - window_offset_dur + final_date = self.cycle_time_dto() + window_offset_dur - start_date = self.cycle_time_dto() - window_offset_dur - final_date = self.cycle_time_dto() + window_offset_dur + loop_date = start_date + bkg_freq_dur - loop_date = start_date + bkg_freq_dur - - while loop_date <= final_date: - duration_in = loop_date - start_date + forecast_duration_for_background - bkg_steps.append(isodate.duration_isoformat(duration_in)) - loop_date += bkg_freq_dur + # Loop over window + # ---------------- + while loop_date <= final_date: + duration_in = loop_date - start_date + forecast_duration_for_background + bkg_steps.append(isodate.duration_isoformat(duration_in)) + loop_date += bkg_freq_dur # Get the forecast start time # --------------------------- diff --git a/src/swell/tasks/task_questions.yaml b/src/swell/tasks/task_questions.yaml index 5dcdcd10..cceaee2b 100644 --- a/src/swell/tasks/task_questions.yaml +++ b/src/swell/tasks/task_questions.yaml @@ -5,7 +5,9 @@ analysis_forecast_window_offset: - all prompt: What is the duration from the middle of the window when forecasts start? tasks: - - GetBackground + - GetBackground{{window_type}} + - GetBackground3d + - GetBackground4d - LinkGeosOutput - MoveDaRestart - PrepareAnalysis @@ -43,21 +45,24 @@ background_experiment: - all prompt: What is the name of the name of the experiment providing the backgrounds? tasks: - - GetBackground + - GetBackground{{window_type}} + - GetBackground3d + - GetBackground4d - StoreBackground type: string background_frequency: ask_question: false default_value: defer_to_model - depends: - key: window_type - value: 4D +# depends: +# key: window_type +# value: 4d models: - all prompt: What is the frequency of the background files? tasks: - - GetBackground + - GetBackground{{window_type}} + - GetBackground4d - RunJediHofxExecutable - RunJediVariationalExecutable - StoreBackground @@ -355,7 +360,9 @@ horizontal_resolution: tasks: - GenerateBClimatology - GenerateBClimatologyByLinking - - GetBackground + - GetBackground{{window_type}} + - GetBackground3d + - GetBackground4d - RunJediHofxExecutable - RunJediLocalEnsembleDaExecutable - RunJediVariationalExecutable @@ -389,9 +396,9 @@ jedi_build_method: jedi_forecast_model: ask_question: true default_value: defer_to_model - depends: - key: window_type - value: 4D +# depends: +# key: window_type +# value: 4d models: - all options: defer_to_model @@ -825,7 +832,9 @@ window_length: - all prompt: What is the duration for the data assimilation window? tasks: - - GetBackground + - GetBackground{{window_type}} + - GetBackground3d + - GetBackground4d - GetGeovals - GetGsiBc - GetObservations @@ -846,7 +855,9 @@ window_offset: tasks: - EvaObservations - GenerateBClimatology - - GetBackground + - GetBackground{{window_type}} + - GetBackground3d + - GetBackground4d - GetGeovals - GetObservations - GsiBcToIoda @@ -858,22 +869,3 @@ window_offset: - SaveObsDiags - StoreBackground type: iso-duration - -window_type: - ask_question: true - default_value: defer_to_model - models: - - all - options: - - 3D - - 4D - prompt: Do you want to use a 3D or 4D (including FGAT) window? - tasks: - - GenerateBClimatology - - GetBackground - - RunJediHofxExecutable - - RunJediLocalEnsembleDaExecutable - - RunJediVariationalExecutable - - StoreBackground - type: string-drop-list - diff --git a/src/swell/test/suite_tests/geosadas-tier1.yaml b/src/swell/test/suite_tests/geosadas-tier1.yaml index 9ff9be29..7772ce7e 100644 --- a/src/swell/test/suite_tests/geosadas-tier1.yaml +++ b/src/swell/test/suite_tests/geosadas-tier1.yaml @@ -2,6 +2,7 @@ jedi_build_method: use_existing existing_jedi_source_directory: /discover/nobackup/gmao_ci/swell/tier2/stable/build_jedi/jedi_bundle/source/ existing_jedi_build_directory: /discover/nobackup/gmao_ci/swell/tier2/stable/build_jedi/jedi_bundle/build/ bundles: REMOVE +window_type: 3d model_components: ['geos_atmosphere'] models: geos_atmosphere: @@ -41,7 +42,6 @@ models: #- sondes - ssmis_f17 produce_geovals: false - window_type: 3D gradient_norm_reduction: 1e-6 number_of_iterations: - 5