-
Notifications
You must be signed in to change notification settings - Fork 203
Add capability to create aerosol AOD analysis products in GRIB2 format via UPP #3889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 27 commits
3da2797
3333a7e
63e3233
6c67cf1
5e4a341
33daaf2
6e6ea86
3757474
2f23293
8b26fb8
d27ab35
0323953
c5333e4
51fd3b3
91c3338
4332bf5
3e5e9a2
5b34437
0018c9f
5dcd41b
eafddaa
8f225d2
d5dfc8c
cebf39d
f0cedc0
1156e05
799423a
a296a06
bcda940
8a8cee6
63879af
4291edb
41561d6
ef9a9eb
af28fc6
a8ff6ed
b34ef72
25ac018
b5d9759
6551e4f
ccca20c
8262265
f62921b
6c1be3b
4c0ee0b
4d613f4
7109685
73a7ea3
bd0e5c6
3914b30
4b44b61
afb2a25
70d48ff
860d847
7375d4e
426498a
b01276d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,13 +11,14 @@ | |
|
|
||
| from wxflow import (AttrDict, | ||
| FileHandler, | ||
| add_to_datetime, to_fv3time, to_timedelta, | ||
| add_to_datetime, to_timedelta, | ||
| to_fv3time, | ||
| Task, | ||
| Task, Jinja, | ||
| YAMLFile, parse_j2yaml, | ||
| logit) | ||
| from pygfs.jedi import Jedi | ||
| import numpy as np | ||
| from pygfs.task.upp import UPP | ||
|
|
||
| logger = getLogger(__name__.split('.')[-1]) | ||
|
|
||
|
|
@@ -262,3 +263,133 @@ 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 | ||
| - Adding atmos and aerosol increments to the background | ||
| - 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' so upp can recognize | ||
| 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 atmf000 files | ||
| logger.info('Adding aero increments to RESTART files') | ||
| bkg_file = os.path.join(upp_dict.DATA, f"{upp_dict.atmos_filename}") | ||
| 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) | ||
| 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, 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}atminc.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, incvars, bkgvars) | ||
|
|
||
| # reset time to 0 (analysis time) | ||
| flux_file = os.path.join(upp_dict.DATA, f"{upp_dict.flux_filename}") | ||
| with Dataset(flux_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, incvars: List, bkgvars: List) -> None: | ||
| """Add aero gaussian increments to gaussian backgrounds | ||
|
|
||
| Parameters | ||
| ---------- | ||
| inc_file : str | ||
| increment file | ||
| bkg_file : str | ||
| background 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: | ||
| for incname, bkgname in zip(incvars, bkgvars): | ||
| increment = incfile.variables[incname][:] | ||
| # reordering the dimensions of increment to macth background | ||
| increment_reshape = np.transpose(increment, (2, 0, 1)) | ||
|
|
||
| bkg = rstfile.variables[bkgname][:] | ||
| anl = bkg + increment_reshape[np.newaxis, :, :, :] | ||
| rstfile.variables[bkgname][:] = anl[:] | ||
| 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')}") | ||
|
|
||
| @logit(logger) | ||
| def add_atm_gaussian_increments(self, inc_file: str, bkg_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 | ||
| 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: | ||
| for incname, bkgname in zip(incvars, bkgvars): | ||
| increment = incfile.variables[incname][:] | ||
| # handel latitude inversion in atminc | ||
| 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, :, :, :] | ||
| rstfile.variables[bkgname][:] = anl[:] | ||
Uh oh!
There was an error while loading. Please reload this page.