Skip to content
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

Create JEDI class #2805

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
72cfc5b
Initial commit
DavidNew-NOAA Aug 2, 2024
dddaec2
Merge branch 'develop' into feature/jedi_class
DavidNew-NOAA Aug 5, 2024
2a313b2
Merge branch 'develop' into feature/jedi_class
DavidNew-NOAA Aug 8, 2024
b2536c5
Move YAML save out of get_jedi_config method
DavidNew-NOAA Aug 8, 2024
a6bc7cc
pynorms
DavidNew-NOAA Aug 8, 2024
f5f4d94
Update exglobal_atmens_analysis_letkf.py
DavidNew-NOAA Aug 8, 2024
e5b7409
Addressing Rahul's comments
DavidNew-NOAA Aug 21, 2024
0ff0521
Merge branch 'feature/jedi_class' of https://github.com/DavidNew-NOAA…
DavidNew-NOAA Aug 21, 2024
e0bd76c
Move jedi.py to its own directory and move logging from jedi.py funct…
DavidNew-NOAA Aug 21, 2024
6617f8b
Merge branch 'develop' into feature/jedi_class
DavidNew-NOAA Aug 21, 2024
e85e993
Finished debugging
DavidNew-NOAA Aug 21, 2024
43a6338
pynorms
DavidNew-NOAA Aug 21, 2024
ef68fad
Update some comments and logging
DavidNew-NOAA Aug 22, 2024
0d01ad0
pynorms
DavidNew-NOAA Aug 22, 2024
d496307
pynorms
DavidNew-NOAA Aug 22, 2024
6b95386
Merge branch 'develop' into feature/jedi_class
DavidNew-NOAA Aug 28, 2024
056d07c
Merge latest develop
DavidNew-NOAA Aug 29, 2024
44f172c
Refactor LETKF observer to work with JEDI class
DavidNew-NOAA Aug 29, 2024
55efedf
Merge branch 'develop' into feature/jedi_class
DavidNew-NOAA Aug 29, 2024
e06f736
Fix small bug
DavidNew-NOAA Aug 29, 2024
4da3d34
Merge branch 'develop' into feature/jedi_class
DavidNew-NOAA Aug 29, 2024
3c6d5b5
Redo some things w/ JEDI class to address YAML archiving error
DavidNew-NOAA Aug 30, 2024
79aca48
Merge branch 'develop' into feature/jedi_class
DavidNew-NOAA Aug 30, 2024
e0e3f40
pynorms
DavidNew-NOAA Aug 30, 2024
a6f4b81
Proposed change to enkf.yaml.j2
DavidNew-NOAA Aug 30, 2024
ed2613b
Revert "Proposed change to enkf.yaml.j2"
DavidNew-NOAA Aug 30, 2024
86b604a
Fix error from my misunderstanding of how obs/sol jobs work for LETKF
DavidNew-NOAA Aug 30, 2024
9b70195
Set JCB algorithm depending on whether running in observer-solver mod…
DavidNew-NOAA Sep 3, 2024
c279e45
Fix error in JCB prototype file name
DavidNew-NOAA Sep 3, 2024
1e034f7
Address some comments
DavidNew-NOAA Sep 3, 2024
526b961
The perils of copypasta
DavidNew-NOAA Sep 3, 2024
d3ecab3
Address comments and update GDAS hash
DavidNew-NOAA Sep 4, 2024
02b3734
Mistakenly had class method marked as static method
DavidNew-NOAA Sep 4, 2024
3d3ccf0
Update
DavidNew-NOAA Sep 4, 2024
d5e2fe0
Update jedi.py
DavidNew-NOAA Sep 4, 2024
ea97ddb
Merge branch 'develop' into feature/jedi_class
DavidNew-NOAA Sep 4, 2024
16868a8
Update jedi.py
DavidNew-NOAA Sep 4, 2024
a423c6f
Update ush/python/pygfs/jedi/jedi.py
DavidNew-NOAA Sep 5, 2024
35c3f49
Update ush/python/pygfs/jedi/jedi.py
DavidNew-NOAA Sep 5, 2024
9a24b48
Update ush/python/pygfs/jedi/jedi.py
DavidNew-NOAA Sep 5, 2024
f1cb728
Update ush/python/pygfs/jedi/jedi.py
DavidNew-NOAA Sep 5, 2024
3bb5336
Update ush/python/pygfs/task/atm_analysis.py
DavidNew-NOAA Sep 5, 2024
ba19cdf
Update ush/python/pygfs/task/atmens_analysis.py
DavidNew-NOAA Sep 5, 2024
287a949
Update ush/python/pygfs/task/atm_analysis.py
DavidNew-NOAA Sep 5, 2024
934d036
Update ush/python/pygfs/task/atm_analysis.py
DavidNew-NOAA Sep 5, 2024
806010f
Update ush/python/pygfs/task/atm_analysis.py
DavidNew-NOAA Sep 5, 2024
79c4d60
Address final comments
DavidNew-NOAA Sep 5, 2024
50db563
Merge branch 'feature/jedi_class' of https://github.com/DavidNew-NOAA…
DavidNew-NOAA Sep 5, 2024
00874e9
Forgot some comments
DavidNew-NOAA Sep 5, 2024
c039881
Final comment block
DavidNew-NOAA Sep 5, 2024
fc437a8
pynorms
DavidNew-NOAA Sep 5, 2024
95974c3
Small bug
DavidNew-NOAA Sep 5, 2024
bc52fcb
Update ush/python/pygfs/task/atmens_analysis.py
aerorahul Sep 5, 2024
f445e28
Update ush/python/pygfs/task/atm_analysis.py
aerorahul Sep 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions scripts/exglobal_atm_analysis_fv3_increment.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# exglobal_atm_analysis_fv3_increment.py
# This script creates an AtmAnalysis object
# and runs the init_fv3_increment and fv3_increment methods
# and runs the initialize_fv3inc and execute methods
# which convert the JEDI increment into an FV3 increment
import os

Expand All @@ -17,7 +17,9 @@
# Take configuration from environment and cast it as python dictionary
config = cast_strdict_as_dtypedict(os.environ)

# Instantiate the atm analysis task
AtmAnl = AtmAnalysis(config)
AtmAnl.init_fv3_increment()
AtmAnl.fv3_increment()
# Instantiate the atm analysis object
AtmAnlFV3Inc = AtmAnalysis(config)

# Initialize and execute
AtmAnlFV3Inc.initialize_fv3inc()
AtmAnlFV3Inc.execute(config.APRUN_ATMANLFV3INC)
2 changes: 1 addition & 1 deletion scripts/exglobal_atm_analysis_initialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@

# Instantiate the atm analysis task
AtmAnl = AtmAnalysis(config)
AtmAnl.initialize()
AtmAnl.initialize_var()
2 changes: 1 addition & 1 deletion scripts/exglobal_atm_analysis_variational.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@

# Instantiate the atm analysis task
AtmAnl = AtmAnalysis(config)
AtmAnl.variational()
AtmAnl.execute(config.APRUN_ATMANLVAR, ['fv3jedi', 'variational'])
12 changes: 7 additions & 5 deletions scripts/exglobal_atmens_analysis_fv3_increment.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# exglobal_atmens_analysis_fv3_increment.py
# This script creates an AtmEnsAnalysis object
# and runs the init_fv3_increment and fv3_increment methods
# and runs the initialize_fv3inc and execute methods
# which convert the JEDI increment into an FV3 increment
import os

Expand All @@ -17,7 +17,9 @@
# Take configuration from environment and cast it as python dictionary
config = cast_strdict_as_dtypedict(os.environ)

# Instantiate the atmens analysis task
AtmEnsAnl = AtmEnsAnalysis(config)
AtmEnsAnl.init_fv3_increment()
AtmEnsAnl.fv3_increment()
# Instantiate the atmens analysis object
AtmEnsAnlFV3Inc = AtmEnsAnalysis(config)

# Initialize and execute
AtmEnsAnlFV3Inc.initialize_fv3inc()
AtmEnsAnlFV3Inc.execute(config.APRUN_ATMENSANLFV3INC)
2 changes: 1 addition & 1 deletion scripts/exglobal_atmens_analysis_initialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@

# Instantiate the atmens analysis task
AtmEnsAnl = AtmEnsAnalysis(config)
AtmEnsAnl.initialize()
AtmEnsAnl.initialize_var()
6 changes: 3 additions & 3 deletions scripts/exglobal_atmens_analysis_letkf.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
# exglobal_atmens_analysis_letkf.py
# This script creates an AtmEnsAnalysis object
# and runs the letkf method
# which executes the global atm local ensemble analysis
# and runs the execute method which executes
# the global atm local ensemble analysis
import os

from wxflow import Logger, cast_strdict_as_dtypedict
Expand All @@ -19,4 +19,4 @@

# Instantiate the atmens analysis task
AtmEnsAnl = AtmEnsAnalysis(config)
AtmEnsAnl.letkf()
AtmEnsAnl.execute(config.APRUN_ATMENSANLLETKF, ['fv3jedi', 'localensembleda']))
101 changes: 34 additions & 67 deletions ush/python/pygfs/task/atm_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,21 @@
import gzip
import tarfile
from logging import getLogger
from typing import Dict, List, Any

from wxflow import (AttrDict,
FileHandler,
add_to_datetime, to_fv3time, to_timedelta, to_YMDH,
chdir,
parse_j2yaml, save_as_yaml,
logit,
Executable,
WorkflowException)
from pygfs.task.analysis import Analysis
Task,
parse_j2yaml,
logit)
from pygfs.task.jedi import JEDI

logger = getLogger(__name__.split('.')[-1])


class AtmAnalysis(Analysis):
class AtmAnalysis(Task):
"""
Class for global atm analysis tasks
Class for JEDI-based global atm analysis tasks
"""
@logit(logger, name="AtmAnalysis")
def __init__(self, config):
Expand All @@ -31,7 +28,6 @@ def __init__(self, config):
_res = int(self.task_config.CASE[1:])
_res_anl = int(self.task_config.CASE_ANL[1:])
_window_begin = add_to_datetime(self.task_config.current_cycle, -to_timedelta(f"{self.task_config.assim_freq}H") / 2)
_jedi_yaml = os.path.join(self.task_config.DATA, f"{self.task_config.RUN}.t{self.task_config.cyc:02d}z.atmvar.yaml")

# Create a local dictionary that is repeatedly used across this class
local_dict = AttrDict(
Expand All @@ -48,7 +44,6 @@ def __init__(self, config):
'OPREFIX': f"{self.task_config.RUN}.t{self.task_config.cyc:02d}z.",
'APREFIX': f"{self.task_config.RUN}.t{self.task_config.cyc:02d}z.",
'GPREFIX': f"gdas.t{self.task_config.previous_cycle.hour:02d}z.",
'jedi_yaml': _jedi_yaml,
'atm_obsdatain_path': f"{self.task_config.DATA}/obs/",
'atm_obsdataout_path': f"{self.task_config.DATA}/diags/",
'BKG_TSTEP': "PT1H" # Placeholder for 4D applications
Expand All @@ -58,21 +53,39 @@ def __init__(self, config):
# Extend task_config with local_dict
self.task_config = AttrDict(**self.task_config, **local_dict)

# Create JEDI object
self.jedi = JEDI(self.task_config)

@logit(logger)
def initialize(self: Analysis) -> None:
def initialize(self) -> None:
"""Initialize a global atm analysis

This method will initialize a global atm analysis using JEDI.
This includes:
- staging observation files
- staging bias correction files
- staging CRTM fix files
- staging FV3-JEDI fix files
- staging B error files
- staging model backgrounds
- generating a YAML file for the JEDI executable
- creating output directories
"""
super().initialize()

# get JEDI variational configuration and save to YAML file
self.jedi.get_config(self.task_config)

# link JEDI variational executable
self.jedi.link_exe(self.task_config)

# stage observations
obs_dict = self.jedi.get_obs_dict()
FileHandler(obs_dict).sync()

# stage bias corrections
bias_dict = self.jedi.get_bias_dict()
FileHandler(bias_dict).sync()

# stage CRTM fix files
logger.info(f"Staging CRTM fix files from {self.task_config.CRTM_FIX_YAML}")
crtm_fix_list = parse_j2yaml(self.task_config.CRTM_FIX_YAML, self.task_config)
Expand Down Expand Up @@ -102,11 +115,6 @@ def initialize(self: Analysis) -> None:
bkg_staging_dict = parse_j2yaml(self.task_config.VAR_BKG_STAGING_YAML, self.task_config)
FileHandler(bkg_staging_dict).sync()

# generate variational YAML file
logger.debug(f"Generate variational YAML file: {self.task_config.jedi_yaml}")
save_as_yaml(self.task_config.jedi_config, self.task_config.jedi_yaml)
logger.info(f"Wrote variational YAML to: {self.task_config.jedi_yaml}")

# need output dir for diags and anl
logger.debug("Create empty output [anl, diags] directories to receive output from executable")
newdirs = [
Expand All @@ -116,64 +124,23 @@ def initialize(self: Analysis) -> None:
FileHandler({'mkdir': newdirs}).sync()

@logit(logger)
def variational(self: Analysis) -> None:

chdir(self.task_config.DATA)

exec_cmd = Executable(self.task_config.APRUN_ATMANLVAR)
exec_name = os.path.join(self.task_config.DATA, 'gdas.x')
exec_cmd.add_default_arg(exec_name)
exec_cmd.add_default_arg('fv3jedi')
exec_cmd.add_default_arg('variational')
exec_cmd.add_default_arg(self.task_config.jedi_yaml)

try:
logger.debug(f"Executing {exec_cmd}")
exec_cmd()
except OSError:
raise OSError(f"Failed to execute {exec_cmd}")
except Exception:
raise WorkflowException(f"An error occured during execution of {exec_cmd}")

pass
def execute(self, aprun_cmd: str, jedi_args: Optional[str] = None) -> None:
super().execute()
DavidNew-NOAA marked this conversation as resolved.
Show resolved Hide resolved

self.jedi.execute(self.task_config, aprun_cmd, jedi_args)

@logit(logger)
def init_fv3_increment(self: Analysis) -> None:
# Setup JEDI YAML file
self.task_config.jedi_yaml = os.path.join(self.task_config.DATA,
f"{self.task_config.JCB_ALGO}.yaml")
save_as_yaml(self.get_jedi_config(self.task_config.JCB_ALGO), self.task_config.jedi_yaml)

# Link JEDI executable to run directory
self.task_config.jedi_exe = self.link_jediexe()

@logit(logger)
def fv3_increment(self: Analysis) -> None:
# Run executable
exec_cmd = Executable(self.task_config.APRUN_ATMANLFV3INC)
exec_cmd.add_default_arg(self.task_config.jedi_exe)
exec_cmd.add_default_arg(self.task_config.jedi_yaml)

try:
logger.debug(f"Executing {exec_cmd}")
exec_cmd()
except OSError:
raise OSError(f"Failed to execute {exec_cmd}")
except Exception:
raise WorkflowException(f"An error occured during execution of {exec_cmd}")

@logit(logger)
def finalize(self: Analysis) -> None:
def finalize(self) -> None:
"""Finalize a global atm analysis

This method will finalize a global atm analysis using JEDI.
This includes:
- tar output diag files and place in ROTDIR
- copy the generated YAML file from initialize to the ROTDIR
- copy the updated bias correction files to ROTDIR
- write UFS model readable atm incrment file

"""
super().finalize()
aerorahul marked this conversation as resolved.
Show resolved Hide resolved

# ---- tar up diags
# path of output tar statfile
atmstat = os.path.join(self.task_config.COM_ATMOS_ANALYSIS, f"{self.task_config.APREFIX}atmstat")
Expand All @@ -198,7 +165,7 @@ def finalize(self: Analysis) -> None:

# copy full YAML from executable to ROTDIR
logger.info(f"Copying {self.task_config.jedi_yaml} to {self.task_config.COM_ATMOS_ANALYSIS}")
src = os.path.join(self.task_config.DATA, f"{self.task_config.RUN}.t{self.task_config.cyc:02d}z.atmvar.yaml")
src = self.task_config.jedi_yaml
dest = os.path.join(self.task_config.COM_ATMOS_ANALYSIS, f"{self.task_config.RUN}.t{self.task_config.cyc:02d}z.atmvar.yaml")
logger.debug(f"Copying {src} to {dest}")
yaml_copy = {
Expand Down
Loading
Loading