-
Notifications
You must be signed in to change notification settings - Fork 168
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
Prepare GTS snow depth observations for JEDI-based Land DA #1761
Prepare GTS snow depth observations for JEDI-based Land DA #1761
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of minor comments
scripts/exglobal_prep_land_obs.py
Outdated
@@ -17,7 +17,10 @@ | |||
|
|||
# Take configuration from environment and cast it as python dictionary | |||
config = cast_strdict_as_dtypedict(os.environ) | |||
HH = os.environ.get("CDATE")[8:] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't there cyc
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just checked the cyc
is not defined as below:
print(f"cyc: {cyc}")
NameError: name 'cyc' is not defined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aerorahul is going to have a preferred solution for this.
logger.debug(f"{self.task_config.GTS_OBS_LIST}:\n{pformat(prep_gts_config)}") | ||
|
||
# copy the GTS obs files from COM_OBS to DATA/obs | ||
logger.info("Copying GTS obs for BUFR2IODAX") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggest BUFR2IODAX
to bufr2ioda.x
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly looks great. Just some minor points.
Now that there are multiple observation processing steps, we may want to bring those methods out in the near future to keep DA and preprocessing separate to enable testing.
scripts/exglobal_prep_land_obs.py
Outdated
@@ -17,7 +17,10 @@ | |||
|
|||
# Take configuration from environment and cast it as python dictionary | |||
config = cast_strdict_as_dtypedict(os.environ) | |||
HH = os.environ.get("CDATE")[8:] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HH = os.environ.get("CDATE")[8:] |
There is no need to go to os.environ
after creating config
from the environment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done as suggested.
scripts/exglobal_prep_land_obs.py
Outdated
|
||
# Instantiate the land prepare task | ||
LandAnl = LandAnalysis(config) | ||
LandAnl.prepare_IMS() | ||
LandAnl.prepare_GTS() | ||
if HH == '18': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CoryMartin-NOAA I think you are thinking of this.
if HH == '18': | |
if LandAnl.runtime_config.cyc == '18': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made the changes. Thanks @aerorahul
@@ -35,6 +35,7 @@ def __init__(self, config): | |||
_res = int(self.config['CASE'][1:]) | |||
_window_begin = add_to_datetime(self.runtime_config.current_cycle, -to_timedelta(f"{self.config['assim_freq']}H") / 2) | |||
_letkfoi_yaml = os.path.join(self.runtime_config.DATA, f"{self.runtime_config.RUN}.t{self.runtime_config['cyc']:02d}z.letkfoi.yaml") | |||
_bufr2ioda_yaml = os.path.join(self.runtime_config.DATA, f"bufr_adpsfc_snow.yaml") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_bufr2ioda_yaml = os.path.join(self.runtime_config.DATA, f"bufr_adpsfc_snow.yaml") |
I need to think of this a bit. I don't think this belongs in the constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed as suggested.
@@ -47,13 +48,89 @@ def __init__(self, config): | |||
'LAND_WINDOW_LENGTH': f"PT{self.config['assim_freq']}H", | |||
'OPREFIX': f"{self.runtime_config.RUN}.t{self.runtime_config.cyc:02d}z.", | |||
'APREFIX': f"{self.runtime_config.RUN}.t{self.runtime_config.cyc:02d}z.", | |||
'jedi_yaml': _letkfoi_yaml | |||
'jedi_yaml': _letkfoi_yaml, | |||
'bufr2ioda_yaml': _bufr2ioda_yaml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'bufr2ioda_yaml': _bufr2ioda_yaml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed as suggested.
# generate bufr2ioda YAML file | ||
logger.info(f"Generate BUFR2IODA YAML file: {self.task_config.bufr2ioda_yaml}") | ||
bufr2ioda_yaml = parse_j2yaml(self.task_config.BUFR2IODAYAML, self.task_config) | ||
save_as_yaml(bufr2ioda_yaml, self.task_config.bufr2ioda_yaml) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just define the name of the file here and save it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As suggested, the bufr2ioda_yaml
is defined locally.
Thanks @aerorahul for your review. I made the changes as suggested, and I have tested the changes successfully. |
@CoryMartin-NOAA Would you please merge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for updating so quickly.
Look great.
@jiaruidong2017 NOAA-EMC/GDASApp@7966501 was merged in manually |
Thanks @CoryMartin-NOAA, and I have updated the GDASApp's commit hash. |
if not os.path.isfile(f"{os.path.join(localconf.DATA, output_file)}"): | ||
logger.exception(f"{self.task_config.BUFR2IODAX} failed to produce {output_file}") | ||
raise FileNotFoundError(f"{os.path.join(localconf.DATA, output_file)}") | ||
else: | ||
logger.info(f"Copy {output_file} to {self.task_config.COM_OBS}") | ||
FileHandler(prep_gts_config.gtsioda).sync() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need to do the extra check here. If the source file doesn't exist, FileHandler.sync()
will already raise an exception. We can just call the method and let the Exception rise through if it occurs. sync()
also already writes the copy info to the logger, so we don't need to repeat that here.
if not os.path.isfile(f"{os.path.join(localconf.DATA, output_file)}"): | |
logger.exception(f"{self.task_config.BUFR2IODAX} failed to produce {output_file}") | |
raise FileNotFoundError(f"{os.path.join(localconf.DATA, output_file)}") | |
else: | |
logger.info(f"Copy {output_file} to {self.task_config.COM_OBS}") | |
FileHandler(prep_gts_config.gtsioda).sync() | |
FileHandler(prep_gts_config.gtsioda).sync() |
If you really want to add the message about BUFR2IODAX, just catch the exception briefly:
if not os.path.isfile(f"{os.path.join(localconf.DATA, output_file)}"): | |
logger.exception(f"{self.task_config.BUFR2IODAX} failed to produce {output_file}") | |
raise FileNotFoundError(f"{os.path.join(localconf.DATA, output_file)}") | |
else: | |
logger.info(f"Copy {output_file} to {self.task_config.COM_OBS}") | |
FileHandler(prep_gts_config.gtsioda).sync() | |
try: | |
FileHandler(prep_gts_config.gtsioda).sync() | |
except OSError err: | |
logger.exception(f"{self.task_config.BUFR2IODAX} failed to produce {output_file}") | |
raise Exception(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @WalterKolczynski-NOAA for your review and suggestions. I made and committed the changes.
FileHandler(prep_gts_config.gtsioda).sync() | ||
except OSError: | ||
logger.exception(f"{self.task_config.BUFR2IODAX} failed to produce {output_file}") | ||
raise Exception(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
raise Exception(err) | |
raise OSError(err) |
Raise the appropriate exception not the generic exception.
Also, err is undefined.
This will not work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about that.
# If so, copy to COM_OBS/ | ||
try: | ||
FileHandler(prep_gts_config.gtsioda).sync() | ||
except OSError: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
except OSError: | |
except OSError as err: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @aerorahul and made a fix as suggested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conditionally approved pending CI success.
Automated global-workflow Testing Results:
|
Automated global-workflow Testing Results:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this work and the reviewers.
Automated global-workflow Testing Results:
|
Automated global-workflow Testing Results:
|
Automated global-workflow Testing Results:
|
Thank you all for your reviews and suggestions. |
Automated global-workflow Testing Results:
|
Automated global-workflow Testing Results:
|
Automated global-workflow Testing Results:
|
Automated global-workflow Testing Results:
|
Automated global-workflow Testing Results:
|
Automated global-workflow Testing Results:
|
Automated global-workflow Testing Results:
|
This PR:
prep.sh
job to bring GTS adpsfc bufr data. To test this type of data DMPDIR inconfig.base
needed to be pointed to "/scratch1/NCEPDEV/global/Jiarui.Dong/JEDI/GlobalWorkflow/para_gfs/glopara_dump".prepare_GTS
for this type of data.The
preplandobs
job runs at the all four cycles in the workflow. Theprepare_IMS
job runs only at 18z cycle, and this is controlled in the script.Checklist