diff --git a/dartwrf/assim_synth_obs.py b/dartwrf/assim_synth_obs.py index 48b74ace071c306ded1c272f96ca4477f0ed72aa..f3cdace497ef03675a3a41dd83e09a20ee85e86d 100755 --- a/dartwrf/assim_synth_obs.py +++ b/dartwrf/assim_synth_obs.py @@ -3,17 +3,15 @@ import time as time_module import datetime as dt import numpy as np -from dartwrf.utils import symlink, copy, sed_inplace, append_file, mkdir, try_remove, print, shell, write_txt -from dartwrf.obs import error_models as err -import dartwrf.create_obsseq as osq +from dartwrf.utils import symlink, copy, mkdir, try_remove, print, shell, write_txt from dartwrf import wrfout_add_geo -from dartwrf import obsseq +from dartwrf.obs import error_models as err +from dartwrf.obs import obsseq +from dartwrf.obs import create_obsseq_out as osq_out from dartwrf import dart_nml -from dartwrf import exp_config -exp = exp_config.exp -from dartwrf import server_config -cluster = server_config.cluster +from dartwrf.exp_config import exp +from dartwrf.server_config import cluster wrfout_format = 'wrfout_d01_%Y-%m-%d_%H:%M:%S' @@ -115,19 +113,6 @@ def write_list_of_outputfiles(): files.append("./filter_restart_d01." + str(iens).zfill(4)) write_txt(files, cluster.dart_rundir+'/output_list.txt') -def run_perfect_model_obs(nproc=12, verbose=True): - if verbose: - print("generating observations - running ./perfect_model_obs") - os.chdir(cluster.dart_rundir) - - try_remove(cluster.dart_rundir + "/obs_seq.out") - if not os.path.exists(cluster.dart_rundir + "/obs_seq.in"): - raise RuntimeError("obs_seq.in does not exist in " + cluster.dart_rundir) - shell(cluster.dart_modules+' mpirun -np '+str(nproc)+" ./perfect_model_obs > log.perfect_model_obs") - if not os.path.exists(cluster.dart_rundir + "/obs_seq.out"): - raise RuntimeError( - "obs_seq.out does not exist in " + cluster.dart_rundir, - "\n look for " + cluster.dart_rundir + "/log.perfect_model_obs") def filter(nproc=12): print("time now", dt.datetime.now()) @@ -219,10 +204,11 @@ def set_obserr_assimilate_in_obsseqout(oso, outfile="./obs_seq.out"): osf_prior (ObsSeq): python representation of obs_seq.final (output of filter in evaluate-mode without posterior) contains prior values; used for parameterized errors """ + from dartwrf.obs.obskind import obs_kind_nrs for obscfg in exp.observations: kind_str = obscfg['kind'] # e.g. 'RADIOSONDE_TEMPERATURE' - kind = osq.obs_kind_nrs[kind_str] # e.g. 263 + kind = obs_kind_nrs[kind_str] # e.g. 263 # modify observation error of each kind sequentially where_oso_iskind = oso.df.kind == kind @@ -343,80 +329,25 @@ def evaluate(assim_time, obs_seq_out=False, copy(cluster.dart_rundir + "/obs_seq.final", fout) print(fout, "saved.") - - -def generate_obsseq_out(time): - - def ensure_physical_vis(oso): # set reflectance < surface albedo to surface albedo - print(" 2.2) removing obs below surface albedo ") - clearsky_albedo = 0.2928 - - if_vis_obs = oso.df['kind'].values == 262 - if_obs_below_surface_albedo = oso.df['observations'].values < clearsky_albedo - oso.df.loc[if_vis_obs & if_obs_below_surface_albedo, ('observations')] = clearsky_albedo - oso.to_dart(f=cluster.dart_rundir + "/obs_seq.out") - return oso - - - def apply_superobbing(oso): - try: - f_oso = dir_obsseq + time.strftime("/%Y-%m-%d_%H:%M_obs_seq.out-before_superob") - shutil.copy(cluster.dart_rundir + "/obs_seq.out-before_superob", f_oso) - print('saved', f_oso) - except Exception as e: - warnings.warn(str(e)) - - print(" 2.3) superobbing to", exp.superob_km, "km") - oso.df = oso.df.superob(window_km=exp.superob_km) - oso.to_dart(f=cluster.dart_rundir + "/obs_seq.out") - - - ############################## - - dir_obsseq=cluster.archivedir + "/obs_seq_out/" - os.makedirs(dir_obsseq, exist_ok=True) - - osq.create_obs_seq_in(time, exp.observations) - run_perfect_model_obs() # generate observation, draws from gaussian - - print(" 2.1) obs preprocessing") - oso = obsseq.ObsSeq(cluster.dart_rundir + "/obs_seq.out") - - oso = ensure_physical_vis(oso) - - if getattr(exp, "superob_km", False): - oso = apply_superobbing(oso) - - # archive complete obsseqout - f_oso = dir_obsseq + time.strftime("/%Y-%m-%d_%H:%M_obs_seq.out") - shutil.copy(cluster.dart_rundir + "/obs_seq.out", f_oso) - print('saved', f_oso) - return oso - - def get_obsseq_out(time): + """Prepares an obs_seq.out file in the run_DART folder + + Args: + time (datetime): time of assimilation - # did we specify an obsseqout inputfile? + Returns: + obsseq.ObsSeq + """ if exp.use_existing_obsseq != False: + # use an existing obs_seq.out file f_obsseq = time.strftime(exp.use_existing_obsseq) copy(f_obsseq, cluster.dart_rundir+'/obs_seq.out') print(f_obsseq, 'copied to', cluster.dart_rundir+'/obs_seq.out') - oso = obsseq.ObsSeq(cluster.dart_rundir + "/obs_seq.out") - else: - # decision to NOT use existing obs_seq.out file - - # did we already generate observations? - # f_oso_thisexp = cluster.archivedir+'/obs_seq_out/'+time.strftime("/%Y-%m-%d_%H:%M_obs_seq.out") - # if os.path.isfile(f_oso_thisexp): - # # oso exists - # copy(f_oso_thisexp, cluster.dart_rundir+'/obs_seq.out') - # print('copied existing obsseqout from', f_oso_thisexp) - # oso = obsseq.ObsSeq(cluster.dart_rundir + "/obs_seq.out") - # else: - - # generate observations with new observation noise - oso = generate_obsseq_out(time) - + oso = obsseq.ObsSeq(cluster.dart_rundir + "/obs_seq.out") # read the obs_seq.out file + else: + # do NOT use an existing obs_seq.out file + # but generate observations with new observation noise + oso = osq_out.generate_obsseq_out(time) return oso def prepare_inflation_2(time, prior_init_time): diff --git a/dartwrf/create_obs_upfront.py b/dartwrf/create_obs_upfront.py index 4cf876bdd39e918501b5a83d826d5161f8c554bb..c2ffc99ca2c46ef8dcf6c11d892fd130b3ca77f1 100755 --- a/dartwrf/create_obs_upfront.py +++ b/dartwrf/create_obs_upfront.py @@ -7,8 +7,8 @@ import numpy as np from dartwrf.exp_config import exp from dartwrf.server_config import cluster from dartwrf.utils import copy, print -import dartwrf.create_obsseq as osq -from dartwrf import obsseq +import dartwrf.obs.create_obsseq_in as osq +from dartwrf.obs import obsseq from dartwrf import assim_synth_obs as aso tformat = '%Y-%m-%d_%H:%M' diff --git a/dartwrf/create_obsseq.py b/dartwrf/obs/create_obsseq_in.py similarity index 99% rename from dartwrf/create_obsseq.py rename to dartwrf/obs/create_obsseq_in.py index b7792f1b54ba76b6f71f7adb88537cd2912f75da..ebcbed58a36b22a5351e3603308739dfa9618f53 100755 --- a/dartwrf/create_obsseq.py +++ b/dartwrf/obs/create_obsseq_in.py @@ -8,9 +8,9 @@ import datetime as dt from pysolar.solar import get_altitude, get_azimuth from dartwrf.server_config import cluster -from dartwrf.obs import calculate_obs_locations as col from dartwrf import utils -from dartwrf.obskind import obs_kind_nrs # dictionary string => DART internal indices +from dartwrf.obs import calculate_obs_locations as col +from dartwrf.obs.obskind import obs_kind_nrs # dictionary string => DART internal indices # position on earth for RTTOV ray geometry lat0 = 45. diff --git a/dartwrf/obs/create_obsseq_out.py b/dartwrf/obs/create_obsseq_out.py new file mode 100644 index 0000000000000000000000000000000000000000..cb56e85dacbf2508dc98e962351878257774d7e8 --- /dev/null +++ b/dartwrf/obs/create_obsseq_out.py @@ -0,0 +1,70 @@ +import os, shutil, warnings + +from dartwrf.utils import try_remove, print, shell +import dartwrf.obs.create_obsseq_in as osi +from dartwrf.obs import obsseq + +from dartwrf.exp_config import exp +from dartwrf.server_config import cluster + +def generate_obsseq_out(time): + + def ensure_physical_vis(oso): # set reflectance < surface albedo to surface albedo + print(" 2.2) removing obs below surface albedo ") + clearsky_albedo = 0.2928 + + if_vis_obs = oso.df['kind'].values == 262 + if_obs_below_surface_albedo = oso.df['observations'].values < clearsky_albedo + oso.df.loc[if_vis_obs & if_obs_below_surface_albedo, ('observations')] = clearsky_albedo + oso.to_dart(f=cluster.dart_rundir + "/obs_seq.out") + return oso + + + def apply_superobbing(oso): + try: + f_oso = dir_obsseq + time.strftime("/%Y-%m-%d_%H:%M_obs_seq.out-before_superob") + shutil.copy(cluster.dart_rundir + "/obs_seq.out-before_superob", f_oso) + print('saved', f_oso) + except Exception as e: + warnings.warn(str(e)) + + print(" 2.3) superobbing to", exp.superob_km, "km") + oso.df = oso.df.superob(window_km=exp.superob_km) + oso.to_dart(f=cluster.dart_rundir + "/obs_seq.out") + + + ############################## + + dir_obsseq=cluster.archivedir + "/obs_seq_out/" + os.makedirs(dir_obsseq, exist_ok=True) + + osi.create_obs_seq_in(time, exp.observations) + run_perfect_model_obs() # generate observation, draws from gaussian + + print(" 2.1) obs preprocessing") + oso = obsseq.ObsSeq(cluster.dart_rundir + "/obs_seq.out") + + oso = ensure_physical_vis(oso) + + if getattr(exp, "superob_km", False): + oso = apply_superobbing(oso) + + # archive complete obsseqout + f_oso = dir_obsseq + time.strftime("/%Y-%m-%d_%H:%M_obs_seq.out") + shutil.copy(cluster.dart_rundir + "/obs_seq.out", f_oso) + print('saved', f_oso) + return oso + +def run_perfect_model_obs(nproc=12, verbose=True): + if verbose: + print("generating observations - running ./perfect_model_obs") + os.chdir(cluster.dart_rundir) + + try_remove(cluster.dart_rundir + "/obs_seq.out") + if not os.path.exists(cluster.dart_rundir + "/obs_seq.in"): + raise RuntimeError("obs_seq.in does not exist in " + cluster.dart_rundir) + shell(cluster.dart_modules+' mpirun -np '+str(nproc)+" ./perfect_model_obs > log.perfect_model_obs") + if not os.path.exists(cluster.dart_rundir + "/obs_seq.out"): + raise RuntimeError( + "obs_seq.out does not exist in " + cluster.dart_rundir, + "\n look for " + cluster.dart_rundir + "/log.perfect_model_obs") \ No newline at end of file diff --git a/dartwrf/obskind.py b/dartwrf/obs/obskind.py similarity index 100% rename from dartwrf/obskind.py rename to dartwrf/obs/obskind.py diff --git a/dartwrf/obsseq.py b/dartwrf/obs/obsseq.py similarity index 99% rename from dartwrf/obsseq.py rename to dartwrf/obs/obsseq.py index fc20e51572049ad447b21f2d8363572311631ef9..e108e70491dcf26489db1958fb24fbf4e865368c 100755 --- a/dartwrf/obsseq.py +++ b/dartwrf/obs/obsseq.py @@ -703,7 +703,7 @@ class ObsSeq(object): if __name__ == "__main__": - from config.cluster import cluster + from dartwrf.server_config import cluster # for testing purposes # f = cluster.scriptsdir + "/../tests/obs_seq.orig.out" diff --git a/dartwrf/obsseq_2dim.py b/dartwrf/obs/obsseq_2dim.py similarity index 98% rename from dartwrf/obsseq_2dim.py rename to dartwrf/obs/obsseq_2dim.py index c9a647c128ac59d26f28b20bcf9b8b2342cc3ccd..7239906206672579edf2320578784032fc0bec3a 100755 --- a/dartwrf/obsseq_2dim.py +++ b/dartwrf/obs/obsseq_2dim.py @@ -22,7 +22,7 @@ import numpy as np from dartwrf.server_config import cluster from dartwrf import utils from dartwrf import assim_synth_obs as aso -from dartwrf import obsseq +from dartwrf.obs import obsseq def _get_n_obs_per_layer(oso): """Get number of observations per layer""" diff --git a/dartwrf/obsseq_to_netcdf.py b/dartwrf/obs/obsseq_to_netcdf.py similarity index 95% rename from dartwrf/obsseq_to_netcdf.py rename to dartwrf/obs/obsseq_to_netcdf.py index 14b04475990049d6a653ed555d240f359cb68481..db40ff16c015f5af7dc8083fd0b08dd3b9580b1c 100644 --- a/dartwrf/obsseq_to_netcdf.py +++ b/dartwrf/obs/obsseq_to_netcdf.py @@ -2,7 +2,7 @@ import os, sys, glob, warnings from dartwrf.exp_config import exp from dartwrf.server_config import cluster -import dartwrf.run_obs_diag as rod +import dartwrf.obs.run_obs_diag as rod def listdir_dirs(path): return [a for a in os.listdir(path) if os.path.isdir(os.path.join(path, a))] diff --git a/dartwrf/run_obs_diag.py b/dartwrf/obs/run_obs_diag.py similarity index 100% rename from dartwrf/run_obs_diag.py rename to dartwrf/obs/run_obs_diag.py diff --git a/dartwrf/workflows.py b/dartwrf/workflows.py index bbc67b4bdf3c0544c3e3b51d75a8f25465af1043..62e1b6a7a7042be82f0e25fdd568a4135d15a5f4 100644 --- a/dartwrf/workflows.py +++ b/dartwrf/workflows.py @@ -112,7 +112,7 @@ class WorkFlows(object): # copy obs kind def to config, we will read a table from there # file needs to exist within package so sphinx can read it - _dict_to_py(_obskind_read(), this_dir+'/obskind.py') + _dict_to_py(_obskind_read(), this_dir+'/obs/obskind.py') _copy_dartwrf_to_archive() # includes config files diff --git a/tests/test_assim.py b/tests/test_assim.py index d53b53bfb51b8cd0b87a6b880cb5fde67d2d65ef..7f61e27ee4c8bb929023db89c1883121d1dc0731 100644 --- a/tests/test_assim.py +++ b/tests/test_assim.py @@ -1,7 +1,8 @@ import os, shutil import datetime as dt -from dartwrf import obsseq, assim_synth_obs +from dartwrf import assim_synth_obs +from dartwrf.obs import obsseq from dartwrf.server_config import cluster class ExperimentConfiguration(object): diff --git a/tests/test_dart-rttov.py b/tests/test_dart-rttov.py index ada56bf197c835b338060ea095365a446bd3afa5..f5f3153317bb119559a60e05ba5ce5fbc5fd8a3f 100644 --- a/tests/test_dart-rttov.py +++ b/tests/test_dart-rttov.py @@ -3,8 +3,8 @@ import numpy as np import datetime as dt import pandas as pd -from dartwrf import obsseq -import dartwrf.create_obsseq as osq +from dartwrf.obs import obsseq +import dartwrf.obs.create_obsseq_in as osq import dartwrf.assim_synth_obs as aso from dartwrf import wrfout_add_geo diff --git a/tests/test_obsseq.py b/tests/test_obsseq.py index 215df541510027a777bf621083759e8c7f404a5d..776946537d028366cfdcce9632b53954c1c1fd67 100644 --- a/tests/test_obsseq.py +++ b/tests/test_obsseq.py @@ -2,7 +2,7 @@ import os, filecmp, shutil import numpy as np from dartwrf.server_config import cluster -from dartwrf import obsseq +from dartwrf.obs import obsseq def test_oso():