diff --git a/dev/parm/config/gcafs/config.aeroanl.j2 b/dev/parm/config/gcafs/config.aeroanl.j2 index fb4a3de649f..676809fa411 100644 --- a/dev/parm/config/gcafs/config.aeroanl.j2 +++ b/dev/parm/config/gcafs/config.aeroanl.j2 @@ -24,6 +24,7 @@ export STATICB_TYPE='diffusion' export TASK_CONFIG_YAML="${PARMgfs}/gdas/aero/aero_det_config.yaml.j2" export OBS_LIST_YAML="${PARMgfs}/gdas/aero/aero_obs_list.yaml.j2" export BIAS_FILES_YAML="${PARMgfs}/gdas/aero/aero_bias_files.yaml.j2" +export UPP_CONFIG_YAML="${PARMgfs}/gdas/aero/aero_upp_config.yaml.j2" export io_layout_x="{{ IO_LAYOUT_X }}" export io_layout_y="{{ IO_LAYOUT_Y }}" diff --git a/dev/parm/config/gcafs/config.resources b/dev/parm/config/gcafs/config.resources index 1fee7c60684..a0373492578 100644 --- a/dev/parm/config/gcafs/config.resources +++ b/dev/parm/config/gcafs/config.resources @@ -520,10 +520,10 @@ case ${step} in echo "FATAL ERROR: Resources not defined for job ${step} at resolution ${CASE}" exit 4 esac - ntasks=1 + ntasks=96 threads_per_task=1 tasks_per_node=$(( max_tasks_per_node / threads_per_task )) - memory="13072M" + memory=${mem_node_max} ;; "marineanlinit") diff --git a/dev/parm/config/gfs/config.com b/dev/parm/config/gfs/config.com index bba449b0db3..9f16be183ca 100644 --- a/dev/parm/config/gfs/config.com +++ b/dev/parm/config/gfs/config.com @@ -110,5 +110,6 @@ declare -rx COM_CHEM_HISTORY_TMPL=${COM_BASE}'/model/chem/history' declare -rx COM_CHEM_ANALYSIS_TMPL=${COM_BASE}'/analysis/chem' declare -rx COM_CHEM_BMAT_TMPL=${COM_CHEM_ANALYSIS_TMPL}'/bmatrix' declare -rx COM_CHEM_ANLMON_TMPL=${COM_BASE}'/products/chem/anlmon' +declare -rx COM_CHEM_GRIB_TMPL=${COM_BASE}'/products/chem/grib2' declare -rx COM_MED_RESTART_TMPL=${COM_BASE}'/model/med/restart' diff --git a/env/GAEAC5.env b/env/GAEAC5.env index b6da2dd1c4f..cccbe63f403 100755 --- a/env/GAEAC5.env +++ b/env/GAEAC5.env @@ -97,6 +97,13 @@ case ${step} in export NTHREADS_AEROANL=${NTHREADSmax} export APRUN_AEROANL="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANL}" ;; + "aeroanlfinal") + + export APRUNCFP="${launcher} -n \$ncmd ${mpmd_opt}" + + export NTHREADS_AEROANLFINAL=${NTHREADSmax} + export APRUN_AEROANLFINAL="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANLFINAL}" + ;; "aeroanlgenb") export NTHREADS_AEROANLGENB=${NTHREADSmax} diff --git a/env/GAEAC6.env b/env/GAEAC6.env index 31182f89da4..3e778155835 100755 --- a/env/GAEAC6.env +++ b/env/GAEAC6.env @@ -100,6 +100,13 @@ case ${step} in export NTHREADS_AEROANL=${NTHREADSmax} export APRUN_AEROANL="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANL}" ;; + "aeroanlfinal") + + export APRUNCFP="${launcher} -n \$ncmd ${mpmd_opt}" + + export NTHREADS_AEROANLFINAL=${NTHREADSmax} + export APRUN_AEROANLFINAL="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANLFINAL}" + ;; "aeroanlgenb") export NTHREADS_AEROANLGENB=${NTHREADSmax} diff --git a/env/HERA.env b/env/HERA.env index a2177cf0986..1fc103a040d 100755 --- a/env/HERA.env +++ b/env/HERA.env @@ -98,6 +98,13 @@ elif [[ "${step}" = "aeroanlvar" ]]; then export NTHREADS_AEROANL=${NTHREADSmax} export APRUN_AEROANL="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANL}" +elif [[ "${step}" = "aeroanlfinal" ]]; then + + export APRUNCFP="${launcher} -n \$ncmd ${mpmd_opt}" + + export NTHREADS_AEROANLFINAL=${NTHREADSmax} + export APRUN_AEROANLFINAL="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANLFINAL}" + elif [[ "${step}" = "aeroanlgenb" ]]; then export NTHREADS_AEROANLGENB=${NTHREADSmax} diff --git a/env/HERCULES.env b/env/HERCULES.env index 806714e38f1..dec59cf4dbf 100755 --- a/env/HERCULES.env +++ b/env/HERCULES.env @@ -102,6 +102,13 @@ case ${step} in export NTHREADS_AEROANL=${NTHREADSmax} export APRUN_AEROANL="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANL}" + ;; + "aeroanlfinal") + + export APRUNCFP="${launcher} -n \$ncmd ${mpmd_opt}" + + export NTHREADS_AEROANLFINAL=${NTHREADSmax} + export APRUN_AEROANLFINAL="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANLFINAL}" ;; "aeroanlgenb") diff --git a/env/ORION.env b/env/ORION.env index 2bfd50bd6a8..f2a29ea4ffb 100755 --- a/env/ORION.env +++ b/env/ORION.env @@ -94,6 +94,13 @@ elif [[ "${step}" = "aeroanlvar" ]]; then export NTHREADS_AEROANL=${NTHREADSmax} export APRUN_AEROANL="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANL}" +elif [[ "${step}" = "aeroanlfinal" ]]; then + + export APRUNCFP="${launcher} -n \$ncmd ${mpmd_opt}" + + export NTHREADS_AEROANLFINAL=${NTHREADSmax} + export APRUN_AEROANLFINAL="${APRUN_default} --cpus-per-task=${NTHREADS_AEROANLFINAL}" + elif [[ "${step}" = "aeroanlgenb" ]]; then export NTHREADS_AEROANLGENB=${NTHREADSmax} diff --git a/env/WCOSS2.env b/env/WCOSS2.env index 1734968ee51..9606254b7a2 100755 --- a/env/WCOSS2.env +++ b/env/WCOSS2.env @@ -80,6 +80,13 @@ elif [[ "${step}" = "aeroanlvar" ]]; then export NTHREADS_AEROANL=${NTHREADSmax} export APRUN_AEROANL="${APRUN_default}" +elif [[ "${step}" = "aeroanlfinal" ]]; then + + export APRUNCFP="${launcher} -np \$ncmd ${mpmd_opt}" + + export NTHREADS_AEROANLFINAL=${NTHREADSmax} + export APRUN_AEROANLFINAL="${APRUN_default}" + elif [[ "${step}" = "aeroanlgenb" ]]; then export NTHREADS_AEROANLGENB=${NTHREADSmax} diff --git a/jobs/JGLOBAL_AERO_ANALYSIS_FINALIZE b/jobs/JGLOBAL_AERO_ANALYSIS_FINALIZE index e2e2f065967..0d7feda2c64 100755 --- a/jobs/JGLOBAL_AERO_ANALYSIS_FINALIZE +++ b/jobs/JGLOBAL_AERO_ANALYSIS_FINALIZE @@ -16,7 +16,8 @@ source "${HOMEgfs}/ush/jjob_header.sh" -e "aeroanlfinal" -c "base aeroanl aeroan YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMOUT_CHEM_ANALYSIS:COM_CHEM_ANALYSIS_TMPL \ COMOUT_CONF:COM_CONF_TMPL \ - COMOUT_ATMOS_RESTART:COM_ATMOS_RESTART_TMPL + COMOUT_ATMOS_RESTART:COM_ATMOS_RESTART_TMPL \ + COMOUT_CHEM_GRIB:COM_CHEM_GRIB_TMPL mkdir -m 755 -p "${COMOUT_CHEM_ANALYSIS}" mkdir -m 755 -p "${COMOUT_ATMOS_RESTART}" diff --git a/jobs/JGLOBAL_AERO_ANALYSIS_INITIALIZE b/jobs/JGLOBAL_AERO_ANALYSIS_INITIALIZE index fca06c3b8cb..db1289cb09b 100755 --- a/jobs/JGLOBAL_AERO_ANALYSIS_INITIALIZE +++ b/jobs/JGLOBAL_AERO_ANALYSIS_INITIALIZE @@ -24,10 +24,12 @@ GDUMP="${GDUMP/gcafs/gcdas}" # Generate COM variables from templates YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMIN_OBS:COM_OBS_TMPL \ + COMIN_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL \ COMOUT_CHEM_ANALYSIS:COM_CHEM_ANALYSIS_TMPL RUN=${GDUMP} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \ COMIN_ATMOS_RESTART_PREV:COM_ATMOS_RESTART_TMPL \ + COMIN_ATMOS_HISTORY_PREV:COM_ATMOS_HISTORY_TMPL \ COMIN_CHEM_BMAT_PREV:COM_CHEM_BMAT_TMPL \ COMIN_CHEM_ANALYSIS_PREV:COM_CHEM_ANALYSIS_TMPL diff --git a/jobs/JGLOBAL_ARCHIVE_TARS b/jobs/JGLOBAL_ARCHIVE_TARS index f3b95db93cc..9ac4d3df111 100755 --- a/jobs/JGLOBAL_ARCHIVE_TARS +++ b/jobs/JGLOBAL_ARCHIVE_TARS @@ -22,6 +22,7 @@ YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMIN_ATMOS_WMO:COM_ATMOS_WMO_TMPL \ COMIN_CHEM_HISTORY:COM_CHEM_HISTORY_TMPL \ COMIN_CHEM_ANALYSIS:COM_CHEM_ANALYSIS_TMPL \ + COMIN_CHEM_GRIB:COM_CHEM_GRIB_TMPL \ COMIN_MED_RESTART:COM_MED_RESTART_TMPL \ COMIN_SNOW_ANALYSIS:COM_SNOW_ANALYSIS_TMPL \ COMIN_SNOW_ANLMON:COM_SNOW_ANLMON_TMPL \ diff --git a/jobs/JGLOBAL_ARCHIVE_VRFY b/jobs/JGLOBAL_ARCHIVE_VRFY index e5965c22706..c3b7557bd63 100755 --- a/jobs/JGLOBAL_ARCHIVE_VRFY +++ b/jobs/JGLOBAL_ARCHIVE_VRFY @@ -11,6 +11,7 @@ YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \ COMIN_ATMOS_HISTORY:COM_ATMOS_HISTORY_TMPL \ COMIN_ATMOS_TRACK:COM_ATMOS_TRACK_TMPL \ COMIN_CHEM_ANALYSIS:COM_CHEM_ANALYSIS_TMPL \ + COMIN_CHEM_GRIB:COM_CHEM_GRIB_TMPL \ COMIN_SNOW_ANALYSIS:COM_SNOW_ANALYSIS_TMPL \ COMIN_OBS:COM_OBS_TMPL \ COMOUT_ATMOS_TRACK:COM_ATMOS_TRACK_TMPL diff --git a/parm/archive/gcafs_arcdir.yaml.j2 b/parm/archive/gcafs_arcdir.yaml.j2 index e1d84d89960..952295712fb 100644 --- a/parm/archive/gcafs_arcdir.yaml.j2 +++ b/parm/archive/gcafs_arcdir.yaml.j2 @@ -21,6 +21,10 @@ {% if DO_AERO_ANL %} {% do det_anl_files.append([COMIN_CHEM_ANALYSIS ~ "/" ~ head ~ "aerostat.tgz", ARCDIR ~ "/aerostat." ~ RUN ~ "." ~ cycle_YMDH ~ ".tgz"]) %} + {% do det_anl_files.append([COMIN_CHEM_GRIB ~ "/" ~ head ~ "aeroanl.grib2", + ARCDIR ~ "/aeroanl." ~ RUN ~ "." ~ cycle_YMDH ~ ".grib2"]) %} + {% do det_anl_files.append([COMIN_CHEM_GRIB ~ "/" ~ head ~ "aeroanl.grib2.idx", + ARCDIR ~ "/aeroanl." ~ RUN ~ "." ~ cycle_YMDH ~ ".grib2.idx"]) %} {% endif %} {% if DO_PREP_OBS_AERO == True %} diff --git a/parm/archive/master_gcdas.yaml.j2 b/parm/archive/master_gcdas.yaml.j2 index 88c704c5ef6..41313ad5b58 100644 --- a/parm/archive/master_gcdas.yaml.j2 +++ b/parm/archive/master_gcdas.yaml.j2 @@ -15,6 +15,8 @@ datasets: - "logs/{{ cycle_YMDH }}/{{ RUN }}_aeroanlvar.log" - "logs/{{ cycle_YMDH }}/{{ RUN }}_aeroanlfinal.log" - "{{ COMIN_CHEM_ANALYSIS | relpath(ROTDIR) }}/{{ head }}aerostat.tgz" + - "{{ COMIN_CHEM_GRIB | relpath(ROTDIR) }}/{{ head }}aeroanl.grib2" + - "{{ COMIN_CHEM_GRIB | relpath(ROTDIR) }}/{{ head }}aeroanl.grib2.idx" - "{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}aerovar.yaml" {% for itile in range(1,7) %} - "{{ COMIN_CHEM_ANALYSIS | relpath(ROTDIR) }}/aeroinc.{{ cycle_YMD }}.{{ cycle_HH }}0000.fv_tracer.res.tile{{ itile }}.nc" diff --git a/parm/post/itag.jinja b/parm/post/itag.jinja index 07aa41f8da3..1cf40c0e639 100644 --- a/parm/post/itag.jinja +++ b/parm/post/itag.jinja @@ -12,5 +12,6 @@ kpo = {{ po | length }}, po = {{ po | join(', ') }}, rdaod = {{ rdaod | to_f90bool }} + nasa_on = {{ nasa_on | to_f90bool }} / diff --git a/parm/post/upp.yaml b/parm/post/upp.yaml index 2193b11d48c..bd9a0d9eb07 100644 --- a/parm/post/upp.yaml +++ b/parm/post/upp.yaml @@ -4,6 +4,7 @@ upp: ioform: "netcdfpara" po: [1000.,975.,950.,925.,900.,875.,850.,825.,800.,775.,750.,725.,700.,675.,650.,625.,600.,575.,550.,525.,500.,475.,450.,425.,400.,375.,350.,325.,300.,275.,250.,225.,200.,175.,150.,125.,100.,70.,50.,40.,30.,20.,15.,10.,7.,5.,3.,2.,1.,0.7,0.4,0.2,0.1,0.07,0.04,0.02,0.01] rdaod: False + nasa_on: False fix_data: mkdir: - "{{ DATA }}" diff --git a/scripts/exglobal_aero_analysis_finalize.py b/scripts/exglobal_aero_analysis_finalize.py index 19adcc4c385..55437bd2573 100755 --- a/scripts/exglobal_aero_analysis_finalize.py +++ b/scripts/exglobal_aero_analysis_finalize.py @@ -8,6 +8,7 @@ from wxflow import Logger, cast_strdict_as_dtypedict from pygfs.task.aero_analysis import AerosolAnalysis +from pygfs.task.upp import UPP # Initialize root logger @@ -22,5 +23,8 @@ # Instantiate the aerosol analysis task AeroAnl = AerosolAnalysis(config) + # Process aerosal products through UPP + AeroAnl.upp_anlproc() + # Finalize JEDI aerosol variational analysis AeroAnl.finalize() diff --git a/sorc/gsi_enkf.fd b/sorc/gsi_enkf.fd index b806a99515d..9ae40630481 160000 --- a/sorc/gsi_enkf.fd +++ b/sorc/gsi_enkf.fd @@ -1 +1 @@ -Subproject commit b806a99515d02de3fbfa80bb6336a454eabf8d8b +Subproject commit 9ae40630481f678c36461868877cd141f2f630f7 diff --git a/sorc/gsi_monitor.fd b/sorc/gsi_monitor.fd index 74df9c1b954..d5380b7a81a 160000 --- a/sorc/gsi_monitor.fd +++ b/sorc/gsi_monitor.fd @@ -1 +1 @@ -Subproject commit 74df9c1b954f52c170c61ac8d4f9836804bc091b +Subproject commit d5380b7a81a51d60afae88e0ea4fb2e074d95d74 diff --git a/sorc/gsi_utils.fd b/sorc/gsi_utils.fd index 4e855b6cc78..c5d3a513cfb 160000 --- a/sorc/gsi_utils.fd +++ b/sorc/gsi_utils.fd @@ -1 +1 @@ -Subproject commit 4e855b6cc789a134a5d759c2f937e7fd52d50c77 +Subproject commit c5d3a513cfb3cf0c9878a83c2b4af017cceac5cf diff --git a/sorc/link_workflow.sh b/sorc/link_workflow.sh index d7d3bdff1ba..c9b659b7e2c 100755 --- a/sorc/link_workflow.sh +++ b/sorc/link_workflow.sh @@ -150,7 +150,7 @@ ${LINK_OR_COPY} "${HOMEgfs}/sorc/ufs_model.fd/tests/parm/noahmptable.tbl" . cd "${HOMEgfs}/parm/post" || exit 1 ${LINK_OR_COPY} "${HOMEgfs}/sorc/upp.fd/parm/params_grib2_tbl_new" . ${LINK_OR_COPY} "${HOMEgfs}/sorc/upp.fd/fix/nam_micro_lookup.dat" . -for dir in gfs gefs sfs +for dir in gfs gcafs gefs sfs do ${LINK_OR_COPY} "${HOMEgfs}/sorc/upp.fd/parm/${dir}" . done @@ -158,6 +158,13 @@ for file in ice_gfs.csv ice_gefs.csv ocean_gfs.csv ocean_gefs.csv ocnicepost.nml ${LINK_OR_COPY} "${HOMEgfs}/sorc/gfs_utils.fd/parm/ocnicepost/${file}" . done +for file in optics_luts_DUST.dat optics_luts_DUST_nasa.dat optics_luts_NITR_nasa.dat \ + optics_luts_SALT.dat optics_luts_SALT_nasa.dat optics_luts_SOOT.dat optics_luts_SOOT_nasa.dat \ + optics_luts_SUSO.dat optics_luts_SUSO_nasa.dat optics_luts_WASO.dat optics_luts_WASO_nasa.dat +do + ${LINK_OR_COPY} "${HOMEgfs}/sorc/upp.fd/fix/chem/${file}" . +done + cd "${HOMEgfs}/scripts" || exit 8 if [[ -d "${HOMEgfs}/sorc/gdas.cd" ]]; then declare -a gdas_scripts=(exglobal_prep_ocean_obs.py) @@ -181,6 +188,7 @@ declare -a ufs_templates=("model_configure.IN" "input_global_nest.nml.IN" "ufs.configure.leapfrog_atm_wav.IN" "ww3_shel.nml.IN" "post_itag_gfs" + "post_itag_gcafs" "global_control.nml.IN") for file in "${ufs_templates[@]}"; do if [[ -s "${file}" ]]; then diff --git a/sorc/ufs_model.fd b/sorc/ufs_model.fd index d2e5b36d902..ea8a818a603 160000 --- a/sorc/ufs_model.fd +++ b/sorc/ufs_model.fd @@ -1 +1 @@ -Subproject commit d2e5b36d902603f20e4d6697e200a9b0c87d4396 +Subproject commit ea8a818a603c741b5be2b6b3af0e7aad2de515aa diff --git a/ush/python/pygfs/task/aero_analysis.py b/ush/python/pygfs/task/aero_analysis.py index d5408e34e68..5ca5774207a 100644 --- a/ush/python/pygfs/task/aero_analysis.py +++ b/ush/python/pygfs/task/aero_analysis.py @@ -11,9 +11,10 @@ FileHandler, to_fv3time, to_timedelta, YAMLFile, parse_j2yaml, - logit + Jinja, logit ) import numpy as np +from pygfs.task.upp import UPP logger = getLogger(__name__.split('.')[-1]) @@ -197,3 +198,136 @@ def add_fv3_increments(self, inc_file_YAML: str, bkg_file_YAML: str, incvars: Li rstfile.variables[vname].delncattr('checksum') # remove the checksum so fv3 does not complain except (AttributeError, RuntimeError): pass # checksum is missing, move on + + @logit(logger) + def upp_anlproc(self) -> None: + """Process aerosol analysis to GRIB2 + + This method processes aerosol analysis products from tracer fields using UPP. + This includes: + - Creating a UPP object + - Staging UPP fix files + - Creating the 'upp_dict' for UPP object + - Generating the upp namelist + - Add aerosol increments since the atmos analysis does not update aerosols + - Execute upp.x + """ + + local_dict = AttrDict( + { + 'UPP_RUN': "analysis", + 'FORECAST_HOUR': 0 + } + ) + self.task_config = AttrDict(**self.task_config, **local_dict) + self.task_config.UPP_CONFIG = self.task_config.UPP_CONFIG_YAML + upp = UPP(self.task_config) + + upp_yaml = upp.task_config.upp_yaml + upp.initialize(upp_yaml) + + upp_dict = AttrDict() + keys = ['APRUN_AEROANLFINAL', 'forecast_hour', + 'atmos_filename', 'flux_filename'] + + upp_dict = AttrDict() + for key in keys: + upp_dict[key] = upp.task_config[key] + + upp_dict['NET'] = 'gfs' # set to 'gfs' since upp doesn't recognize gcafs + upp_dict['valid_datetime'] = self.task_config.current_cycle + upp_dict['DATA'] = os.path.join(self.task_config.DATA, 'upp') + upp_dict.update(upp_yaml['upp']['config']) + + # Configure the namelist and write to file + logger.info("Creating namelist for upp.x") + nml_template = os.path.join(upp_dict.DATA, "itag.jinja") + nml_data = Jinja(nml_template, upp_dict).render + logger.debug(f"itag:\n{nml_data}") + nml_file = os.path.join(upp_dict.DATA, 'itag') + with open(nml_file, "w") as fho: + fho.write(nml_data) + + # ---- add aero increments to atm analysis files + logger.info('Adding aero increments to RESTART files') + bkg_file = os.path.join(upp_dict.DATA, f"{self.task_config.GPREFIX }atm.f006.nc") + inc_filename = f"aeroinc_gauss.{self.task_config.current_cycle.strftime('%Y-%m-%dT%H:%M:%S')}Z.gaussian.modelLevels.nc" + inc_file = os.path.join(self.task_config.DATA, 'anl', inc_filename) + anl_file = os.path.join(upp_dict.DATA, f"{upp_dict.atmos_filename}") + allvars = upp_yaml['aeroincvars'][:] + bkgvars = [var[0] for var in allvars] + incvars = [var[1] for var in allvars] + self.add_aero_gaussian_increments(inc_file, bkg_file, anl_file, incvars, bkgvars) + + # ---- add atmo increments to atmf000 files + logger.info('Adding atmo increments to RESTART files') + inc_file = os.path.join(upp_dict.DATA, f"{self.task_config.APREFIX}increment.atm.i006.nc") + allvars = upp_yaml['atmincvars'][:] + bkgvars = [var[0] for var in allvars] + incvars = [var[1] for var in allvars] + self.add_atm_gaussian_increments(inc_file, bkg_file, anl_file, incvars, bkgvars) + + # reset time to 0 (analysis time) + flux_file = os.path.join(upp_dict.DATA, f"{upp_dict.flux_filename}") + for file in [anl_file, flux_file]: + with Dataset(file, mode='a') as rstfile: + time = rstfile.variables['time'] + time[:] = 0.0 + time.setncattr("units", f"hours since {self.task_config.current_cycle.strftime('%Y-%m-%d %H:%M:%S')}") + + upp.execute(upp_dict.DATA, upp_dict.APRUN_AEROANLFINAL, upp_dict.forecast_hour) + + @logit(logger) + def add_aero_gaussian_increments(self, inc_file: str, bkg_file: str, anl_file: str, incvars: List, bkgvars: List) -> None: + """Add aero gaussian increments to gaussian backgrounds + + Parameters + ---------- + inc_file : str + increment file + bkg_file : str + background file + anl_file : str + analysis file + incvars : List + List of increment variables to add to the background + bkgvars : List + List of background variables to which the increment variables will be added. + """ + with Dataset(inc_file, mode='r') as incfile, Dataset(bkg_file, mode='r') as rstfile, Dataset(anl_file, mode='a') as anlfile: + for incname, bkgname in zip(incvars, bkgvars): + increment = incfile.variables[incname][:] + # reordering the dimensions of increment (latitude, longitude, levels) to macth background (time, levs, lat, lon) + increment_reshape = np.transpose(increment, (2, 0, 1)) + + bkg = rstfile.variables[bkgname][:] + anl = bkg + increment_reshape[np.newaxis, :, :, :] + anlfile.variables[bkgname][:] = anl[:] + + @logit(logger) + def add_atm_gaussian_increments(self, inc_file: str, bkg_file: str, anl_file: str, incvars: List, bkgvars: List) -> None: + """Add atm gaussian increments to gaussian backgrounds + + Parameters + ---------- + inc_file : str + increment file + bkg_file : str + background file + anl_file : str + analysis file + incvars : List + List of increment variables to add to the background + bkgvars : List + List of background variables to which the increment variables will be added. + """ + with Dataset(inc_file, mode='r') as incfile, Dataset(bkg_file, mode='a') as rstfile, Dataset(anl_file, mode='a') as anlfile: + for incname, bkgname in zip(incvars, bkgvars): + increment = incfile.variables[incname][:] + # handel latitude inversion: atminc: lat=-90 to +90, atmbkg: lat=+90 to -90 + lat_axis_index = 1 + increment_lat_inversion = np.flip(increment, axis=lat_axis_index) + + bkg = rstfile.variables[bkgname][:] + anl = bkg + increment_lat_inversion[np.newaxis, :, :, :] + anlfile.variables[bkgname][:] = anl[:]