From 902642660625cce031f855aadb7aea67d1f730ff Mon Sep 17 00:00:00 2001
From: lkugler <lukas.kugler@gmail.com>
Date: Mon, 22 May 2023 13:10:50 +0200
Subject: [PATCH] consistent config, geo_em optional

---
 analysis_only.py                       |  2 +-
 config/{cfg.py => exp_template.py}     |  4 ++++
 config/jet.py                          |  2 +-
 config/srvx1.py                        |  5 +++--
 dartwrf/assim_synth_obs.py             | 16 ++++++++++------
 dartwrf/dart_nml.py                    |  7 +++++--
 dartwrf/obs/calculate_obs_locations.py |  2 +-
 dartwrf/obsseq.py                      |  2 +-
 dartwrf/utils.py                       |  9 ++++++++-
 dartwrf/workflows.py                   |  2 +-
 10 files changed, 35 insertions(+), 16 deletions(-)
 rename config/{cfg.py => exp_template.py} (96%)

diff --git a/analysis_only.py b/analysis_only.py
index 899241d..840e603 100755
--- a/analysis_only.py
+++ b/analysis_only.py
@@ -11,7 +11,7 @@ prior_init_time = dt.datetime(2008,7,30,12)
 prior_valid_time = dt.datetime(2008,7,30,13)
 assim_time = prior_valid_time
 
-w = WorkFlows(exp_config='cfg.py', server_config='srvx1.py')
+w = WorkFlows(exp_config='exp_template.py', server_config='srvx1.py')
 
 id = w.assimilate(assim_time, prior_init_time, prior_valid_time, prior_path_exp)
 
diff --git a/config/cfg.py b/config/exp_template.py
similarity index 96%
rename from config/cfg.py
rename to config/exp_template.py
index 3cdf202..c45c6f7 100755
--- a/config/cfg.py
+++ b/config/exp_template.py
@@ -25,6 +25,10 @@ exp.dart_nml = {'&assim_tools_nml':
                             num_output_state_members=exp.n_ens,
                             num_output_obs_members=exp.n_ens,
                             inf_flavor=['0', '0'],
+                            output_members='.true',
+                            output_mean='.true.',
+                            output_sd='.true.',
+                            stages_to_write=[''],
                         ),
                 '&location_nml':
                     dict(horiz_dist_only='.true.',
diff --git a/config/jet.py b/config/jet.py
index 757b95c..377275f 100755
--- a/config/jet.py
+++ b/config/jet.py
@@ -72,7 +72,7 @@ cluster.rttov_srcdir = '/jetfs/home/lkugler/data/compile/RTTOV13/rtcoef_rttov13/
 cluster.scriptsdir = '/jetfs/home/lkugler/DART-WRF/dartwrf/'
 
 # other inputs
-cluster.geo_em = '/jetfs/home/lkugler/data/geo_em.d01.nc'
+cluster.geo_em_for_WRF_ideal = '/jetfs/home/lkugler/data/geo_em.d01.nc'
 cluster.obs_impact_filename = cluster.scriptsdir+'/../templates/impactfactor_T.txt'
 cluster.namelist = cluster.scriptsdir+'/../templates/namelist.input'
 cluster.run_WRF = '/jetfs/home/lkugler/DART-WRF/dartwrf/run_ens.jet.sh'
diff --git a/config/srvx1.py b/config/srvx1.py
index 9a22186..7d9003e 100755
--- a/config/srvx1.py
+++ b/config/srvx1.py
@@ -33,7 +33,8 @@ scriptsdir              path where DART-WRF scripts reside, e.g. /home/DART-WRF/
 namelist                path to a namelist template; strings like <hist_interval>, will be overwritten in scripts/prepare_namelist.py
 run_WRF                 path to script which runs WRF on a node of the cluster
 obs_impact_filename     path to obs_impact_filename (see DART guide; module assim_tools_mod and program obs_impact_tool)
-geo_em                  path to NetCDF file of WRF domain (see WRF guide)
+overwrite_coordinates_with_geo_em   if WRF ideal: path to NetCDF file of WRF domain (see WRF guide)
+                                    if WRF real: set to False
 
 slurm_cfg               python dictionary, containing options of SLURM
                             defined in SLURM docs (https://slurm.schedmd.com/sbatch.html)
@@ -66,7 +67,7 @@ cluster.srcdir = '/users/staff/lkugler/AdvDA23/DART/WRF-4.3/run'
 cluster.dart_srcdir = '/users/students/lehre/advDA_s2023/DART/models/wrf/work'
 cluster.rttov_srcdir = '/users/students/lehre/advDA_s2023/RTTOV13/rtcoef_rttov13/'
 cluster.dartwrf_dir = utils.userhome+'/AdvDA23/DART-WRF/'
-cluster.geo_em = '/users/students/lehre/advDA_s2023/data/geo_em.d01.nc'
+cluster.geo_em_for_WRF_ideal = '/users/students/lehre/advDA_s2023/data/geo_em.d01.nc'
 
 # templates/run scripts
 cluster.namelist = cluster.dartwrf_dir+'/../templates/namelist.input'
diff --git a/dartwrf/assim_synth_obs.py b/dartwrf/assim_synth_obs.py
index 9c79deb..a189db7 100755
--- a/dartwrf/assim_synth_obs.py
+++ b/dartwrf/assim_synth_obs.py
@@ -36,7 +36,9 @@ def link_nature_to_dart_truth(time):
 def prepare_nature_dart(time):
     print("linking nature to DART & georeferencing")
     link_nature_to_dart_truth(time)
-    wrfout_add_geo.run(cluster.geo_em, cluster.dart_rundir + "/wrfout_d01")
+
+    if cluster.geo_em_for_WRF_ideal:
+        wrfout_add_geo.run(cluster.geo_em_for_WRF_ideal, cluster.dart_rundir + "/wrfout_d01")
 
 
 def prepare_prior_ensemble(assim_time, prior_init_time, prior_valid_time, prior_path_exp):
@@ -73,7 +75,8 @@ def prepare_prior_ensemble(assim_time, prior_init_time, prior_valid_time, prior_
                     cluster.dart_rundir+"/wrfout_d01 "+ wrfout_dart)
 
         # this seems to be necessary (else wrong level selection)
-        wrfout_add_geo.run(cluster.geo_em, wrfout_dart)
+        if cluster.geo_em_for_WRF_ideal:
+            wrfout_add_geo.run(cluster.geo_em_for_WRF_ideal, wrfout_dart)
 
     write_list_of_inputfiles_prior()
     write_list_of_outputfiles()
@@ -405,7 +408,7 @@ def get_obsseq_out(time):
     return oso
 
 def prepare_inflation_2(time, prior_init_time):
-    """Prepare inflation files
+    """Prepare inflation files (spatially varying)
     
     Recycles inflation files from previous assimilations
     or takes default files from archive.
@@ -525,7 +528,7 @@ def main(time, prior_init_time, prior_valid_time, prior_path_exp):
     nproc = cluster.max_nproc
 
     prepare_run_DART_folder()
-    dart_nml.write_namelist()
+    nml = dart_nml.write_namelist()
 
     print("prepare nature")
     prepare_nature_dart(time)  # link WRF files to DART directory
@@ -546,7 +549,8 @@ def main(time, prior_init_time, prior_valid_time, prior_path_exp):
         print(" 2.3) reject observations? ")
         qc_obs(time, oso, osf_prior)
 
-    if exp.prior_inflation == 2:
+    print('prior inflation=', nml['&filter_nml']['inf_flavor'][0])
+    if nml['&filter_nml']['inf_flavor'][0]:
         prepare_inflation_2(time, prior_init_time)
 
     print(" 3) run filter ")
@@ -554,7 +558,7 @@ def main(time, prior_init_time, prior_valid_time, prior_path_exp):
     filter(nproc=nproc)
     archive_filteroutput(time)
 
-    if exp.prior_inflation == 2:
+    if exp.dart_nml:
         archive_inflation_2(time)
 
     print(" 4) evaluate posterior observations for all observations (incl rejected)")
diff --git a/dartwrf/dart_nml.py b/dartwrf/dart_nml.py
index 37c9be9..f0c9108 100644
--- a/dartwrf/dart_nml.py
+++ b/dartwrf/dart_nml.py
@@ -334,5 +334,8 @@ def write_namelist(just_prior_values=False):
     write_namelist_from_dict(nml, cluster.dart_rundir + "/input.nml")
 
     # append section for RTTOV
-    rttov_nml = cluster.dartwrf_dir + "/../templates/obs_def_rttov.VIS.nml"
-    append_file(cluster.dart_rundir + "/input.nml", rttov_nml)
\ No newline at end of file
+    rttov_nml = cluster.dartwrf_dir + "/templates/obs_def_rttov.VIS.nml"
+    append_file(cluster.dart_rundir + "/input.nml", rttov_nml)
+    # alternatively, we could do this in cfg.py or the template input.nml in DART's model/wrf/work folder
+
+    return nml  # in case we want to access namelist settings in python
\ No newline at end of file
diff --git a/dartwrf/obs/calculate_obs_locations.py b/dartwrf/obs/calculate_obs_locations.py
index 43e09c9..e381133 100755
--- a/dartwrf/obs/calculate_obs_locations.py
+++ b/dartwrf/obs/calculate_obs_locations.py
@@ -56,7 +56,7 @@ def evenly_on_grid(n_obs, omit_covloc_radius_on_boundary=True):
     Returns
         tuple of (lat, lon) coordinates
     """
-    fcoords = cluster.geo_em
+    fcoords = cluster.geo_em_for_WRF_ideal  # TODO: in case of WRF real, need to find a file providing coordinates, e.g. nature wrfout
     ds = xr.open_dataset(fcoords)
 
     lons = ds.XLONG_M.isel(Time=0).values
diff --git a/dartwrf/obsseq.py b/dartwrf/obsseq.py
index 439d09f..3508941 100755
--- a/dartwrf/obsseq.py
+++ b/dartwrf/obsseq.py
@@ -620,7 +620,7 @@ class ObsSeq(object):
         import matplotlib.pyplot as plt
         import xarray as xr
 
-        georef = xr.open_dataset("/gpfs/data/fs71386/lkugler/run_DART/geo_em.d01.nc")
+        georef = xr.open_dataset(cluster.geo_em_for_WRF_ideal)
         lon = georef.XLONG_M.values.squeeze()
         lat = georef.XLAT_M.values.squeeze()
 
diff --git a/dartwrf/utils.py b/dartwrf/utils.py
index 8e28b3d..890023c 100755
--- a/dartwrf/utils.py
+++ b/dartwrf/utils.py
@@ -32,10 +32,15 @@ class ClusterConfig(object):
     @property
     def scripts_rundir(self):
         """Path to the directory where the DART-WRF scripts are executed
+
+        Note:
+            If you want to execute scripts from the folder where you develop code, use `self.dartwrf_dir`
+            If you want to execute the code from a different place ('research'), then use `self.archivedir+'/DART-WRF/'`
         
         Example:
             `/user/data/sim_archive/DART-WRF/`
         """
+        # return self.dartwrf_dir
         return self.archivedir+'/DART-WRF/'
 
     @property
@@ -187,7 +192,9 @@ def append_file(f_main, f_gets_appended):
     Returns:
         None
     """
-    os.system('cat '+f_gets_appended+' >> '+f_main)
+    rc = os.system('cat '+f_gets_appended+' >> '+f_main)
+    if rc != 0:
+        raise RuntimeError('cat '+f_gets_appended+' >> '+f_main)
 
 def write_txt(lines, fpath):
     """Write a list of strings to a text file
diff --git a/dartwrf/workflows.py b/dartwrf/workflows.py
index 27d7d8d..1a08071 100644
--- a/dartwrf/workflows.py
+++ b/dartwrf/workflows.py
@@ -34,7 +34,7 @@ class WorkFlows(object):
                 print('scripts have been copied to', self.cluster.archivedir)
             except FileExistsError as e:
                 warnings.warn(str(e))
-                if input('Scripts already exist and will not be overwritten. Continue? (Y/n) ') in ['Y', 'y']:
+                if input('The experiment name already exists! Scripts will not be overwritten. Continue? (Y/n) ') in ['Y', 'y']:
                     pass
                 else:
                     raise e
-- 
GitLab