diff --git a/scripts/apply_obs_op_dart.py b/scripts/apply_obs_op_dart.py index 5b380c68ec9b9564c41d9f12abac6adbff47e63b..3dfa4a5ef36851762a214f73e6ea4a389b36cddf 100644 --- a/scripts/apply_obs_op_dart.py +++ b/scripts/apply_obs_op_dart.py @@ -7,56 +7,13 @@ from config.cfg import exp, cluster from utils import symlink, copy, mkdir, sed_inplace, append_file, print import create_obsseq as osq import assim_synth_obs as aso -from assim_synth_obs import read_prior_obs, set_DART_nml, generate_observations, assimilate import pre_assim +import wrfout_add_geo -def run_operator(obscfg, time): - """ - time_for_dart (dt.datetime) : needs to be consistent with wrfout files! - """ +"""Apply observation operator to some ensemble state +i.e. wrfout files in an archive directory - # get observation file (obs not important, but their locations) - # this should correspond to configuration to have same locations as in real assim - os.chdir(cluster.dartrundir) - - n_obs = obscfg['n_obs'] - error_var = (obscfg['err_std'])**2 - sat_channel = obscfg.get('sat_channel', False) - cov_loc = obscfg['cov_loc_radius_km'] - dist_obs = obscfg.get('distance_between_obs_km', False) - - obs_coords = osq.calc_obs_locations(n_obs, coords_from_domaincenter=False, - distance_between_obs_km=dist_obs, - fpath_obs_locations=None) - osq.sat(time, sat_channel, obs_coords, error_var, - output_path=cluster.dartrundir) - assert os.path.exists(cluster.dartrundir + '/obs_seq.in') - - # prepare dummy nature - os.system('cp ./advance_temp1/wrfout_d01 ./wrfout_d01') - import wrfout_add_geo - wrfout_add_geo.run(cluster.dartrundir+'/geo_em.d01.nc', - cluster.dartrundir+'/wrfout_d01') - - print('running perfect model obs') - os.system('mpirun -np 12 ./perfect_model_obs') - - # set namelist for filter (calc only forward op) - aso.set_DART_nml(sat_channel=sat_channel, - just_prior_values=True) - - # run filter - assert os.path.exists(cluster.dartrundir+'/obs_seq.out') - print('running filter') - os.system('mpirun -np 40 ./filter') - - # copy output to archive - savedir = cluster.archivedir()+'/obs_seq_final_1min/' - mkdir(savedir) - obsname = obscfg['kind'] - - copy(cluster.dartrundir+'/obs_seq.final', savedir+fout) - print('output of observation operator saved to', fout) +""" if __name__ == '__main__': @@ -66,6 +23,7 @@ if __name__ == '__main__': print(prev_forecast_init, time) # link ensemble states to run_DART directory + # we want the observation operator applied to these states! pre_assim.run(time, prev_forecast_init, exppath_firstguess) savedir = cluster.archivedir()+'/obs_seq_final_1min/' @@ -85,9 +43,16 @@ if __name__ == '__main__': just_prior_values=True) osq.create_obsseq_in(time, obscfg) - aso.generate_observations() + + # prepare dummy nature (this Hx is irrelevant) + os.chdir(cluster.dartrundir) + os.system('cp ./advance_temp1/wrfout_d01 ./wrfout_d01') + wrfout_add_geo.run(cluster.dartrundir+'/geo_em.d01.nc', + cluster.dartrundir+'/wrfout_d01') + aso.run_perfect_model_obs() aso.assimilate() archive_stage = savedir+kind + # only the prior state values are of interest in this file aso.archive_diagnostics(archive_stage, time.strftime('/%Y-%m-%d_%H:%M_obs_seq.final')) diff --git a/scripts/assim_synth_obs.py b/scripts/assim_synth_obs.py index c4f1de40a75756c94564a7523ed0b0f977af9585..bff396dfcbaf028308dbe1a10940f7639f7c009b 100755 --- a/scripts/assim_synth_obs.py +++ b/scripts/assim_synth_obs.py @@ -67,27 +67,6 @@ def read_obsseqout(f): obs.append(observed) return true, obs -# def edit_obserr_in_obsseq(fpath_obsseqin, OEs): -# """ -# overwrite observation errors in a obs_seq.out file -# according to the values in OEs -# """ -# # write to txt (write whole obs_seq.out again) -# obsseq = open(fpath_obsseqin, 'r').readlines() -# obsseq_new = obsseq.copy() -# i_obs = 0 -# for i, line in enumerate(obsseq): -# if 'kind\n' in line: -# i_line_oe = i+9 # 9 for satellite obs -# obsseq_new[i_line_oe] = ' '+str(OEs[i_obs])+' \n' -# i_obs += 1 - -# os.rename(fpath_obsseqin, fpath_obsseqin+'-bak') # backup -# # write cloud dependent errors (actually whole file) -# with open(fpath_obsseqin, 'w') as f: -# for line in obsseq_new: -# f.write(line) - def set_DART_nml(sat_channel=False, cov_loc_radius_km=32, cov_loc_vert_km=False, just_prior_values=False): @@ -95,7 +74,7 @@ def set_DART_nml(sat_channel=False, cov_loc_radius_km=32, cov_loc_vert_km=False, cov_loc_radian = cov_loc_radius_km/earth_radius_km if just_prior_values: - template = cluster.scriptsdir+'/../templates/input.prioronly.nml' + template = cluster.scriptsdir+'/../templates/input.eval.nml' else: template = cluster.scriptsdir+'/../templates/input.nml' copy(template, cluster.dartrundir+'/input.nml') @@ -128,6 +107,7 @@ def set_DART_nml(sat_channel=False, cov_loc_radius_km=32, cov_loc_vert_km=False, append_file(cluster.dartrundir+'/input.nml', rttov_nml) def obs_operator_ensemble(): + # assumes that prior ensemble is already linked to advance_temp<i>/wrfout_d01 print('running obs operator on ensemble forecast') os.chdir(cluster.dartrundir) @@ -139,11 +119,11 @@ def obs_operator_ensemble(): # ens members are already linked to advance_temp<i>/wrfout_d01 copy(cluster.dartrundir+'/advance_temp'+str(iens)+'/wrfout_d01', cluster.dartrundir+'/wrfout_d01') - - wrfout_add_geo.run(cluster.dartrundir+'/geo_em.d01.nc', cluster.dartrundir+'/wrfout_d01') - # DART may need a wrfinput file as well, which serves as a template for dimension sizes symlink(cluster.dartrundir+'/wrfout_d01', cluster.dartrundir+'/wrfinput_d01') + + # add geodata + wrfout_add_geo.run(cluster.dartrundir+'/geo_em.d01.nc', cluster.dartrundir+'/wrfout_d01') # run perfect_model obs (forward operator) os.system('mpirun -np 12 ./perfect_model_obs > /dev/null') @@ -160,25 +140,26 @@ def obs_operator_ensemble(): else: raise NotImplementedError() -def obs_operator_nature(): +def obs_operator_nature(time): print('running obs operator on nature run') - prepare_nature_dart() - - os.chdir(cluster.dartrundir) - os.remove(cluster.dartrundir+'/obs_seq.out') - os.system('mpirun -np 12 ./perfect_model_obs') + prepare_nature_dart(time) + run_perfect_model_obs() true, _ = read_obsseqout(cluster.dartrundir+'/obs_seq.out') return true -def prepare_nature_dart(): + +def link_nature_to_dart_truth(time): # get wrfout_d01 from nature run shutil.copy(time.strftime(cluster.nature_wrfout), cluster.dartrundir+'/wrfout_d01') + # DART may need a wrfinput file as well, which serves as a template for dimension sizes + symlink(cluster.dartrundir+'/wrfout_d01', cluster.dartrundir+'/wrfinput_d01') + +def prepare_nature_dart(time): + link_nature_to_dart_truth(time) wrfout_add_geo.run(cluster.dartrundir+'/geo_em.d01.nc', cluster.dartrundir+'/wrfout_d01') - # DART may need a wrfinput file as well, which serves as a template for dimension sizes - symlink(cluster.dartrundir+'/wrfout_d01', cluster.dartrundir+'/wrfinput_d01') def calc_obserr_WV73(Hx_nature, Hx_prior): @@ -196,8 +177,7 @@ def calc_obserr_WV73(Hx_nature, Hx_prior): OEs[iobs] = oe_nature return OEs -def generate_observations(): - print('generate actual observations') +def run_perfect_model_obs(): os.chdir(cluster.dartrundir) try_remove(cluster.dartrundir+'/obs_seq.out') if not os.path.exists(cluster.dartrundir+'/obs_seq.in'): @@ -212,16 +192,17 @@ def assimilate(): raise RuntimeError('obs_seq.out does not exist in '+cluster.dartrundir) os.system('mpirun -np 48 ./filter') -def archive_diagnostics(archive_stage, fname_final): +def archive_diagnostics(archive_dir, time): print('archive obs space diagnostics') - mkdir(archive_stage) - copy(cluster.dartrundir+'/obs_seq.final', archive_stage+'/'+fname_final) + mkdir(archive_dir) + copy(cluster.dartrundir+'/obs_seq.final', + archive_dir+time.strftime('/%Y-%m-%d_%H:%M_obs_seq.final')) - try: - print('archive regression diagnostics') - copy(cluster.dartrundir+'/reg_diagnostics', archive_stage+'/reg_diagnostics') - except Exception as e: - warnings.warn(str(e)) + # try: # what are regression diagnostics?! + # print('archive regression diagnostics') + # copy(cluster.dartrundir+'/reg_diagnostics', archive_dir+'/reg_diagnostics') + # except Exception as e: + # warnings.warn(str(e)) def recycle_output(): print('move output to input') @@ -289,7 +270,7 @@ if __name__ == "__main__": osq.create_obsseq_in(time, obscfg, zero_error=True) # zero error to get truth vals - Hx_nat = obs_operator_nature() + Hx_nat = obs_operator_nature(time) Hx_prior = obs_operator_ensemble() # files are already linked to DART directory obscfg['err_std'] = calc_obserr_WV73(Hx_nat, Hx_prior) @@ -297,10 +278,12 @@ if __name__ == "__main__": obscfg['err_std'] = np.ones(n_obs) * obscfg['err_std'] osq.create_obsseq_in(time, obscfg) # now with correct errors - generate_observations() + prepare_nature_dart(time) + run_perfect_model_obs() assimilate() - archive_diagnostics(archive_stage, '/obs_seq.final') + dir_obsseq = cluster.archivedir()+'/obs_seq_final/assim_stage'+str(istage)+'_'+kind + archive_diagnostics(dir_obsseq, time) if istage < n_stages-1: # recirculation: filter output -> input @@ -311,7 +294,7 @@ if __name__ == "__main__": elif istage == n_stages-1: # last assimilation, continue integration now copy(cluster.dartrundir+'/input.nml', archive_stage+'/input.nml') - pass # call update wrfinput from filteroutput later + archive_output_mean(archive_stage) else: RuntimeError('this should never occur?!') diff --git a/scripts/prepare_namelist.py b/scripts/prepare_namelist.py index fb6c588e715de04fd60d49d0ea353b65b8e3bc33..d69b5dee1c51085b9a9c76df0b2f34ef8193ac13 100755 --- a/scripts/prepare_namelist.py +++ b/scripts/prepare_namelist.py @@ -1,11 +1,17 @@ import os, sys, shutil, warnings import datetime as dt +from config.cfg import exp, cluster -sys.path.append(os.getcwd()) +sys.path.append(cluster.scriptsdir) from config.cfg import exp, cluster from utils import sed_inplace, copy, symlink, mkdir -def run(cluster, iens, begin, end, hist_interval=5, radt=5): +def run(iens, begin, end, hist_interval=5, radt=5, archive=True): + """ + Args: + archive (bool): if True, write to archivedir of experiment + if False, write to WRF run directory + """ rundir = cluster.wrf_rundir(iens) print(rundir) copy(cluster.namelist, rundir+'/namelist.input') @@ -15,10 +21,14 @@ def run(cluster, iens, begin, end, hist_interval=5, radt=5): sed_inplace(rundir+'/namelist.input', '<hist_interval>', str(int(hist_interval))) sed_inplace(rundir+'/namelist.input', '<radt>', str(int(radt))) - archdir = cluster.archivedir()+begin.strftime('/%Y-%m-%d_%H:%M/'+str(iens)+'/') + if archive: + archdir = cluster.archivedir()+begin.strftime('/%Y-%m-%d_%H:%M/'+str(iens)+'/') + os.makedirs(archdir, exist_ok=True) + else: + archdir = './' print('namelist for run from', begin, end, 'output to', archdir) sed_inplace(rundir+'/namelist.input', '<archivedir>', archdir) - os.makedirs(archdir, exist_ok=True) + # set times for k, v in {'<y1>': '%Y', '<m1>': '%m', '<d1>': '%d', @@ -29,15 +39,16 @@ def run(cluster, iens, begin, end, hist_interval=5, radt=5): sed_inplace(rundir+'/namelist.input', k, end.strftime(v)) ######################### - try: - print('copy wrfinput of this run to archive') - wrfin_old = rundir+'/wrfinput_d01' - init_dir = cluster.archivedir()+begin.strftime('/%Y-%m-%d_%H:%M/')+str(iens) - os.makedirs(init_dir, exist_ok=True) - wrfin_arch = init_dir+'/wrfinput_d01' - copy(wrfin_old, wrfin_arch) - except Exception as e: - warnings.warn(str(e)) + if archive: + try: + print('copy wrfinput of this run to archive') + wrfin_old = rundir+'/wrfinput_d01' + init_dir = cluster.archivedir()+begin.strftime('/%Y-%m-%d_%H:%M/')+str(iens) + os.makedirs(init_dir, exist_ok=True) + wrfin_arch = init_dir+'/wrfinput_d01' + copy(wrfin_old, wrfin_arch) + except Exception as e: + warnings.warn(str(e)) if __name__ == '__main__': @@ -48,4 +59,4 @@ if __name__ == '__main__': print('prepare namelists for all ens members') for iens in range(1, exp.n_ens+1): - run(cluster, iens, begin, end, hist_interval=intv, radt=radt) + run(iens, begin, end, hist_interval=intv, radt=radt) diff --git a/scripts/run_obs_diag.py b/scripts/run_obs_diag.py index e9df5d5c9478f5f55a00ff38db8a5cb9b6050d40..4710f5bf5c7b8fbddb1041bd59934bb55f369d37 100644 --- a/scripts/run_obs_diag.py +++ b/scripts/run_obs_diag.py @@ -2,31 +2,40 @@ import os, sys, shutil, glob from config.cfg import exp, cluster from utils import symlink, copy, sed_inplace, append_file -def run(folder_obs_seq_final): - rundir_program = '/home/fs71386/lkugler/data/DART-WRF/rundir/' +rundir_program = '/home/fs71386/lkugler/data/DART-WRF/rundir/' - files = sorted(glob.glob(folder_obs_seq_final+'/*.final')) # input for obs_diag program + +def prepare(obserr_iszero='.true.'): + copy(cluster.scriptsdir+'/../templates/input.eval.nml', + rundir_program+'/input.nml') + sed_inplace(rundir_program+'/input.nml', '<n_ens>', str(int(exp.n_ens))) + sed_inplace(rundir_program+'/input.nml', '<zero_error_obs>', obserr_iszero) + sed_inplace(rundir_program+'/input.nml', '<horiz_dist_only>', '.false.') # dummy + sed_inplace(rundir_program+'/input.nml', '<vert_norm_hgt>', '5000.0') # dummy + + append_file(rundir_program+'/input.nml', cluster.scriptsdir+'/../templates/obs_def_rttov.VIS.nml') + + +def write_input_filelist(filepaths): fpath = rundir_program+'/obsdiag_inputlist.txt' print('writing', fpath) - if os.path.exists(fpath): os.remove(fpath) with open(fpath, 'w') as f: - for fin in files: + for fin in filepaths: f.write(fin) f.write('\n') + +def run_obsdiag(filepaths, f_out='./obsdiag.nc'): + write_input_filelist(filepaths) + for obserr_iszero in ['.true.', '.false.']: - print('ensure correct input.nml') - copy(cluster.scriptsdir+'/../templates/input.prioronly.nml', - rundir_program+'/input.nml') - sed_inplace(rundir_program+'/input.nml', '<n_ens>', str(int(exp.n_ens))) - sed_inplace(rundir_program+'/input.nml', '<zero_error_obs>', obserr_iszero) - append_file(rundir_program+'/input.nml', cluster.scriptsdir+'/../templates/obs_def_rttov.VIS.nml') - - # run obs_diag - print('running obs_diag program') + prepare(obserr_iszero=obserr_iszero) + + # run_allinoneplace obs_diag + print('------ running obs_diag program') os.chdir(rundir_program) symlink(cluster.dart_srcdir+'/obs_diag', rundir_program+'/obs_diag') try: @@ -36,24 +45,29 @@ def run(folder_obs_seq_final): os.system('./obs_diag >& obs_diag.log') # caution, this overwrites obs_seq_to_netcdf # move output to archive - outdir = '/'.join(folder_obs_seq_final.split('/')[:-1]) + #outdir = outdir #'/'.join(folder_obs_seq_final.split('/')[:-1]) if obserr_iszero == '.true.': - fout = '/obs_diag_wrt_truth.nc' + fout = outdir+'/'+f_out[:-3]+'_wrt_truth.nc' elif obserr_iszero == '.false.': - fout = '/obs_diag_wrt_obs.nc' - print('moving output to', outdir+fout) - copy(rundir_program+'/obs_diag_output.nc', outdir+fout) + fout = outdir+'/'+f_out[:-3]+'_wrt_obs.nc' + shutil.move(rundir_program+'/obs_diag_output.nc', fout) + print(fout, 'saved.') - print('running obs_seq_to_netcdf program') - shutil.copy(cluster.dart_srcdir+'/obs_seq_to_netcdf-bak', cluster.dart_srcdir+'/obs_seq_to_netcdf') - symlink(cluster.dart_srcdir+'/obs_seq_to_netcdf', rundir_program+'/obs_seq_to_netcdf') +def run_obs_seq_to_netcdf(filepaths, f_out='./obs_epoch.nc'): + + write_input_filelist(filepaths) + print('------ running obs_seq_to_netcdf program') + shutil.copy(cluster.dart_srcdir+'/obs_seq_to_netcdf-bak', rundir_program+'/obs_seq_to_netcdf') os.system('./obs_seq_to_netcdf >& obs_seq_to_netcdf.log') # caution, overwrites its own binary?! - print('moving output to', outdir+'/obs_seq...') - os.system('mv '+rundir_program+'/obs_epoch_*.nc '+outdir+'/') + shutil.move(rundir_program+'/obs_epoch_001.nc', f_out) + print(f_out, 'saved.') if __name__ == '__main__': - #folder_obs_seq_final = '/home/fs71386/lkugler/data/sim_archive/exp_v1.11_LMU_filter2/obs_seq_final/' + #folder_obs_seq_final = '/home/fs71386/lkugler/data/DART-WRF/rundir/test' folder_obs_seq_final = str(sys.argv[1]) - run(folder_obs_seq_final) + files = sorted(glob.glob(folder_obs_seq_final+'/*.final')) # input for obs_diag program + + run_obsdiag(files, outdir=folder_obs_seq_final) # input must be files with posterior data!! + run_obs_seq_to_netcdf(files, outdir=folder_obs_seq_final) # input can be files without posterior data diff --git a/templates/input.eval.nml b/templates/input.eval.nml new file mode 100644 index 0000000000000000000000000000000000000000..df66d8ea49826c9a97038fead9e9a0af10450b37 --- /dev/null +++ b/templates/input.eval.nml @@ -0,0 +1,578 @@ +&perfect_model_obs_nml + read_input_state_from_file = .true. + single_file_in = .false. + input_state_files = 'wrfout_d01' + init_time_days = -1 + init_time_seconds = -1 + + write_output_state_to_file = .false. + single_file_out = .false. + output_state_files = 'perfect_output_d01.nc' + output_interval = 1 + + obs_seq_in_file_name = "obs_seq.in" + obs_seq_out_file_name = "obs_seq.out" + first_obs_days = -1 + first_obs_seconds = -1 + last_obs_days = -1 + last_obs_seconds = -1 + + async = 0 + adv_ens_command = "../shell_scripts/advance_model.csh" + + trace_execution = .true. + output_timestamps = .false. + print_every_nth_obs = -1 + output_forward_op_errors = .false. + silence = .false. + / + +&filter_nml + async = 0, + adv_ens_command = "../shell_scripts/advance_model.csh", + ens_size = <n_ens>, + obs_sequence_in_name = "obs_seq.out", + obs_sequence_out_name = "obs_seq.final", + input_state_file_list = "input_list.txt" + output_state_file_list = "output_list.txt" + init_time_days = -1, + init_time_seconds = -1, + first_obs_days = -1, + first_obs_seconds = -1, + last_obs_days = -1, + last_obs_seconds = -1, + num_output_state_members = <n_ens>, + num_output_obs_members = <n_ens>, + output_interval = 1, + num_groups = 1, + distributed_state = .true. + compute_posterior = .false. + output_forward_op_errors = .false., + output_timestamps = .false., + trace_execution = .false., + + stages_to_write = 'preassim' + output_members = .false. + output_mean = .false. + output_sd = .false. + write_all_stages_at_end = .false. + + inf_flavor = 0, 0, + inf_initial_from_restart = .true., .false., + inf_sd_initial_from_restart = .true., .false., + inf_initial = 1.0, 1.00, + inf_lower_bound = 1.0, 1.0, + inf_upper_bound = 1000000.0, 1000000.0, + inf_damping = 0.9, 1.0, + inf_sd_initial = 0.6, 0.0, + inf_sd_lower_bound = 0.6, 0.0, + inf_sd_max_change = 1.05, 1.05, + / + +&quality_control_nml + input_qc_threshold = 3.0, + outlier_threshold = -1.0, + enable_special_outlier_code = .false. + / + +&fill_inflation_restart_nml + write_prior_inf = .false. + prior_inf_mean = 1.00 + prior_inf_sd = 0.6 + + write_post_inf = .false. + post_inf_mean = 1.00 + post_inf_sd = 0.6 + + input_state_files = 'wrfinput_d01', 'wrfinput_d02' + single_file = .false. + verbose = .false. + / + +&smoother_nml + num_lags = 0, + start_from_restart = .false., + output_restart = .false., + restart_in_file_name = 'smoother_ics', + restart_out_file_name = 'smoother_restart', + / + +# cutoff is in radians; for the earth, 0.05 is about 300 km. +# cutoff is defined to be the half-width of the localization radius, +# so 0.05 radians for cutoff is about an 600 km effective +# localization radius, where the influence of an obs decreases +# to ~half at 300 km, and ~0 at the edges of the area. +&assim_tools_nml + filter_kind = 1, + cutoff = <cov_loc_radian>, + sort_obs_inc = .false., + spread_restoration = .false., + sampling_error_correction = .true., + adaptive_localization_threshold = -1, + output_localization_diagnostics = .false., + localization_diagnostics_file = 'localization_diagnostics', + convert_all_state_verticals_first = .true. + convert_all_obs_verticals_first = .true. + print_every_nth_obs = 0, + / + +&cov_cutoff_nml + select_localization = 1, + / + +&obs_sequence_nml + write_binary_obs_sequence = .false., + / + +&preprocess_nml + overwrite_output = .true., + input_obs_kind_mod_file = '../../../assimilation_code/modules/observations/DEFAULT_obs_kind_mod.F90', + output_obs_kind_mod_file = '../../../assimilation_code/modules/observations/obs_kind_mod.f90', + input_obs_def_mod_file = '../../../observations/forward_operators/DEFAULT_obs_def_mod.F90', + output_obs_def_mod_file = '../../../observations/forward_operators/obs_def_mod.f90', + input_files = '../../../observations/forward_operators/obs_def_reanalysis_bufr_mod.f90', + '../../../observations/forward_operators/obs_def_radar_mod.f90', + '../../../observations/forward_operators/obs_def_metar_mod.f90', + '../../../observations/forward_operators/obs_def_dew_point_mod.f90', + '../../../observations/forward_operators/obs_def_rel_humidity_mod.f90', + '../../../observations/forward_operators/obs_def_altimeter_mod.f90', + '../../../observations/forward_operators/obs_def_gps_mod.f90', + '../../../observations/forward_operators/obs_def_vortex_mod.f90', + '../../../observations/forward_operators/obs_def_gts_mod.f90', + '../../../observations/forward_operators/obs_def_rttov_mod.f90', + / + +&obs_kind_nml + evaluate_these_obs_types = 'RADIOSONDE_TEMPERATURE', + 'RADIOSONDE_U_WIND_COMPONENT', + 'RADIOSONDE_V_WIND_COMPONENT', + 'SAT_U_WIND_COMPONENT', + 'SAT_V_WIND_COMPONENT', + 'AIRCRAFT_U_WIND_COMPONENT', + 'AIRCRAFT_V_WIND_COMPONENT', + 'AIRCRAFT_TEMPERATURE', + 'ACARS_U_WIND_COMPONENT', + 'ACARS_V_WIND_COMPONENT', + 'ACARS_TEMPERATURE', + 'GPSRO_REFRACTIVITY', + 'DOPPLER_RADIAL_VELOCITY', + 'RADAR_REFLECTIVITY', + 'MSG_4_SEVIRI_RADIANCE', + 'MSG_4_SEVIRI_TB', + 'MSG_4_SEVIRI_BDRF', + 'LAND_SFC_PRESSURE', + 'SYNOP_SURFACE_PRESSURE', + 'SYNOP_TEMPERATURE', + 'SYNOP_SPECIFIC_HUMIDITY' + assimilate_these_obs_types = 'RADIOSONDE_SPECIFIC_HUMIDITY', + / + +# Notes for obs_def_radar_mod_nml: +# (1) Reflectivity limit can be applied to observations and/or forward operator. +# (2) The default constants below match the WRF defaults. They will need to +# be changed for other cases, depending on which microphysics scheme is used. +# + +&obs_def_radar_mod_nml + apply_ref_limit_to_obs = .false., + reflectivity_limit_obs = -10.0, + lowest_reflectivity_obs = -10.0, + apply_ref_limit_to_fwd_op = .false., + reflectivity_limit_fwd_op = -10.0, + lowest_reflectivity_fwd_op = -10.0, + max_radial_vel_obs = 1000000, + allow_wet_graupel = .false., + microphysics_type = 5 , + allow_dbztowt_conv = .false., + dielectric_factor = 0.224, + n0_rain = 8.0e6, + n0_graupel = 4.0e6, + n0_snow = 3.0e6, + rho_rain = 1000.0, + rho_graupel = 400.0, + rho_snow = 100.0, + / + + +# Notes for model_nml: +# (1) vert_localization_coord must be one of: +# 1 = model level +# 2 = pressure +# 3 = height +# 4 = scale height + +# set default_state_variables to .false. to use the explicit list. +# otherwise it uses a hardcoded default list: U, V, W, PH, T, MU, QV only. +# see ../wrf_state_variables_table for a full list of what wrf fields are +# supported in the DART state vector, and what settings should be used here. +# 'UPDATE' and 'NO_COPY_BACK' are supported in the 4th column; 'NO_UPDATE' is +# not yet supported. + +&model_nml + default_state_variables = .false., + wrf_state_variables = 'U', 'QTY_U_WIND_COMPONENT', 'TYPE_U', 'UPDATE','999', + 'V', 'QTY_V_WIND_COMPONENT', 'TYPE_V', 'UPDATE','999', + 'W', 'QTY_VERTICAL_VELOCITY', 'TYPE_W', 'UPDATE','999', + 'PH', 'QTY_GEOPOTENTIAL_HEIGHT', 'TYPE_GZ', 'UPDATE','999', + 'T', 'QTY_POTENTIAL_TEMPERATURE','TYPE_T', 'UPDATE','999', + 'MU', 'QTY_PRESSURE', 'TYPE_MU', 'UPDATE','999', + 'QVAPOR','QTY_VAPOR_MIXING_RATIO', 'TYPE_QV', 'UPDATE','999', + 'QICE', 'QTY_ICE_MIXING_RATIO', 'TYPE_QI', 'UPDATE','999', + 'QCLOUD','QTY_CLOUDWATER_MIXING_RATIO','TYPE_QC', 'UPDATE','999', + 'CLDFRA','QTY_CLOUD_FRACTION', 'TYPE_CFRAC','UPDATE','999', + 'PSFC', 'QTY_SURFACE_PRESSURE', 'TYPE_PSFC', 'UPDATE','999', + 'T2', 'QTY_2M_TEMPERATURE', 'TYPE_T', 'UPDATE','999', + 'TSK', 'QTY_SKIN_TEMPERATURE', 'TYPE_T', 'UPDATE','999', + 'REFL_10CM','QTY_RADAR_REFLECTIVITY','TYPE_REFL', 'UPDATE','999', + wrf_state_bounds = 'QVAPOR','0.0','NULL','CLAMP', + 'QRAIN', '0.0','NULL','CLAMP', + 'QCLOUD','0.0','NULL','CLAMP', + 'QICE','0.0','NULL','CLAMP', + 'CLDFRA','0.0','1.0','CLAMP', + num_domains = 1, + calendar_type = 3, + assimilation_period_seconds = 21600, + vert_localization_coord = 3, + center_search_half_length = 500000., + center_spline_grid_scale = 10, + sfc_elev_max_diff = -1.0, + circulation_pres_level = 80000.0, + circulation_radius = 108000.0, + allow_obs_below_vol = .false. + / + +# vert_normalization_X is amount of X equiv to 1 radian in horiz. +# vert localization is 'cutoff' times the pressure/height/levels, +# only if horiz_dist_only is set to .false. in the namelist below. +# the default nlon/nlat should be good for most experiments. it sets +# an internal structure that speeds up searches. don't change it +# based on your grid size. nlon must be an odd number. +&location_nml + horiz_dist_only = <horiz_dist_only>, + vert_normalization_pressure = 6666666.7, + vert_normalization_height = <vert_norm_hgt>, + vert_normalization_level = 2666.7, + vert_normalization_scale_height = 10.0, + approximate_distance = .false., + nlon = 71, + nlat = 36, + output_box_info = .false., + / + +&utilities_nml + TERMLEVEL = 1, + module_details = .false., + logfilename = 'dart_log.out', + nmlfilename = 'dart_log.nml', + write_nml = 'file', + / + +&mpi_utilities_nml + / + +®_factor_nml + select_regression = 1, + input_reg_file = "time_mean_reg", + save_reg_diagnostics = .true., + reg_diagnostics_file = "reg_diagnostics", + / + +# layout = 2 spreads the IO tasks across the nodes. +# This can greatly improve the performance in IO if +# tasks_per_node is set to match your hardware +&ensemble_manager_nml + layout = 1, + tasks_per_node = 48 + communication_configuration = 1 + debug = .false. + / + +&obs_def_gps_nml + max_gpsro_obs = 100000, + / + +&obs_def_tpw_nml + / + +# The times in the namelist for the obs_diag program are vectors +# that follow the following sequence: +# year month day hour minute second +# max_num_bins can be used to specify a fixed number of bins, +# in which case last_bin_center should be safely in the future. +# +# Acceptable latitudes range from [-90, 90] +# Acceptable longitudes range from [ 0, Inf] + +&obs_diag_nml + obs_sequence_name = '', + obs_sequence_list = 'obsdiag_inputlist.txt', + first_bin_center = 2008, 7,30,10, 0, 0 , + last_bin_center = 2008, 7,30,18, 0, 0 , + bin_separation = 0, 0, 0, 0, 1, 0 , + bin_width = 0, 0, 0, 0, 1, 0 , + time_to_skip = 0, 0, 0, 0, 0, 0 , + max_num_bins = 1000, + trusted_obs = 'null', + Nregions = 1, + lonlim1 = 0.0, 0.0, 0.0, 235.0, + lonlim2 = 360.0, 360.0, 360.0, 295.0, + latlim1 = 20.0, -80.0, -20.0, 25.0, + latlim2 = 80.0, -20.0, 20.0, 55.0, + reg_names = 'all', + print_mismatched_locs = .false., + create_rank_histogram = .true., + outliers_in_histogram = .true., + use_zero_error_obs = <zero_error_obs>, + verbose = .false. + / + +&schedule_nml + calendar = 'Gregorian', + first_bin_start = 1601, 1, 1, 0, 0, 0, + first_bin_end = 2999, 1, 1, 0, 0, 0, + last_bin_end = 2999, 1, 1, 0, 0, 0, + bin_interval_days = 1000000, + bin_interval_seconds = 0, + max_num_bins = 1000, + print_table = .true., + / + +&obs_seq_to_netcdf_nml + obs_sequence_name = '', + obs_sequence_list = 'obsdiag_inputlist.txt', + append_to_netcdf = .true., + lonlim1 = 0.0, + lonlim2 = 360.0, + latlim1 = -90.0, + latlim2 = 90.0, + verbose = .false., + / + +# There is one GIGANTIC difference between the obsdef_mask.txt and .nc +# The netCDF file intentionally ignores the effect of nTmin/nTmax. +# The netCDF file has ALL matching stations, regardless of temporal coverage. + +&obs_seq_coverage_nml + obs_sequences = '' + obs_sequence_list = 'obs_coverage_list.txt' + obs_of_interest = 'METAR_U_10_METER_WIND' + textfile_out = 'METAR_U_10_METER_WIND_obsdef_mask.txt' + netcdf_out = 'METAR_U_10_METER_WIND_obsdef_mask.nc' + first_analysis = 2003, 1, 1, 0, 0, 0 + last_analysis = 2003, 1, 2, 0, 0, 0 + forecast_length_days = 1 + forecast_length_seconds = 0 + verification_interval_seconds = 21600 + temporal_coverage_percent = 100.0 + lonlim1 = 0.0 + lonlim2 = 360.0 + latlim1 = -90.0 + latlim2 = 90.0 + verbose = .true. + / + +# selections_file is a list of obs_defs output +# from the obs_seq_coverage utility. + +&obs_selection_nml + filename_seq = 'obs_seq.out', + filename_seq_list = '', + filename_out = 'obs_seq.processed', + selections_file = 'obsdef_mask.txt', + selections_is_obs_seq = .false., + print_only = .false., + calendar = 'gregorian', + / + +&obs_seq_verify_nml + obs_sequences = '' + obs_sequence_list = 'obs_verify_list.txt' + input_template = 'obsdef_mask.nc' + netcdf_out = 'forecast.nc' + obtype_string = 'METAR_U_10_METER_WIND' + print_every = 10000 + verbose = .true. + debug = .false. + / + +&obs_sequence_tool_nml + num_input_files = 1, + filename_seq = 'obs_seq.out', + filename_out = 'obs_seq.processed', + first_obs_days = -1, + first_obs_seconds = -1, + last_obs_days = -1, + last_obs_seconds = -1, + obs_types = '', + keep_types = .false., + print_only = .false., + min_lat = -90.0, + max_lat = 90.0, + min_lon = 0.0, + max_lon = 360.0, + / + +&replace_wrf_fields_nml + debug = .false., + fail_on_missing_field = .false., + fieldnames = "SNOWC", + "ALBBCK", + "TMN", + "TSK", + "SH2O", + "SMOIS", + "SEAICE", + "HGT_d01", + "TSLB", + "SST", + "SNOWH", + "SNOW", + fieldlist_file = '', + / + +&obs_common_subset_nml + num_to_compare_at_once = 2, + filename_seq = 'obs_seq1.final', 'obs_seq2.final', + filename_seq_list = '', + filename_out_suffix = '.common' , + calendar = 'Gregorian', + print_every = 1000, + dart_qc_threshold = 3, + print_only = .false., + / + +&wrf_dart_to_fields_nml + include_slp = .true., + include_wind_components = .true., + include_height_on_pres = .true., + include_temperature = .true., + include_rel_humidity = .true., + include_surface_fields = .false., + include_sat_ir_temp = .false., + pres_levels = 70000., + / + +&ncepobs_nml + year = 2010, + month = 06, + day = 00, + tot_days = 1, + max_num = 1000000, + ObsBase = 'temp_obs.', + select_obs = 0, + ADPUPA = .false., + AIRCAR = .false., + AIRCFT = .false., + SATEMP = .false., + SFCSHP = .false., + ADPSFC = .false., + SATWND = .true., + obs_U = .false., + obs_V = .false., + obs_T = .false., + obs_PS = .false., + obs_QV = .false., + daily_file = .true., + obs_time = .false., + lat1 = 10.00, + lat2 = 60.00, + lon1 = 210.0, + lon2 = 300.0 + / + +&prep_bufr_nml + obs_window_upa = 1.0, + obs_window_air = 1.0, + obs_window_cw = 1.0, + otype_use = 242.0, 243.0, 245.0, 246.0, 251.0, 252.0, 253.0, 257.0, 259.0 + qctype_use = 0, 1, 2, 3, 4, 9, 15 + / + +&convert_cosmic_gps_nml + gpsro_netcdf_file = '', + gpsro_netcdf_filelist = 'flist', + gpsro_out_file = 'obs_seq.gpsro', + local_operator = .true., + obs_levels = 0.22, 0.55, 1.1, 1.8, 2.7, 3.7, 4.9, + 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, + ray_ds = 5000.0, + ray_htop = 13000.1, + / + +&wrf_obs_preproc_nml + + file_name_input = 'obs_seq20110901' + file_name_output = 'obs_seq.europe.prev' + + overwrite_obs_time = .false. + + obs_boundary = 0.0 + increase_bdy_error = .false. + maxobsfac = 2.5 + obsdistbdy = 1.0 + + sfc_elevation_check = .false. + sfc_elevation_tol = 3000.0 + obs_pressure_top = 0.0 + obs_height_top = 2.0e10 + + include_sig_data = .true. + tc_sonde_radii = -1.0 + + superob_aircraft = .true. + aircraft_horiz_int = 800.0 + aircraft_pres_int = 25000.0 + + superob_sat_winds = .true. + sat_wind_horiz_int = 800.0 + sat_wind_pres_int = 25000.0 + + overwrite_ncep_satwnd_qc = .false. + overwrite_ncep_sfc_qc = .false. + / + +! sonde_extra = 'obs_seq.rawin' +! land_sfc_extra = 'obs_seq.land_sfc' +! metar_extra = 'obs_seq.metar' +! marine_sfc_extra = 'obs_seq.marine' +! sat_wind_extra = 'obs_seq.satwnd' +! profiler_extra = 'obs_seq.profiler' +! gpsro_extra = 'obs_seq.gpsro' +! acars_extra = 'obs_seq.acars' +! trop_cyclone_extra = 'obs_seq.tc' + +&state_vector_io_nml + single_precision_output = .true., + / + +&compare_states_nml + / + +&closest_member_tool_nml + input_restart_file_list = 'input_file_list_d01.txt', + output_file_name = 'closest_results.txt' + ens_size = 3, + single_restart_file_in = .false., + difference_method = 4, + use_only_qtys = 'QTY_U_WIND_COMPONENT' + / + +# To test both domains, you must change 'model_nml:num_domains = 2' + +&model_mod_check_nml + input_state_files = 'wrfinput_d01', 'wrfinput_d02' + output_state_files = 'mmc_output1.nc', 'mmc_output2.nc' + test1thru = 0 + run_tests = 1,2,3,4,5 + x_ind = 87370 + loc_of_interest = 231.0, 40.0, 10.0 + quantity_of_interest = 'QTY_U_WIND_COMPONENT' + interp_test_dlon = 0.1 + interp_test_dlat = 0.1 + interp_test_dvert = 1000.0 + interp_test_lonrange = 250.0, 260.0 + interp_test_latrange = 30.0, 45.0 + interp_test_vertrange = 2000.0, 4000.0 + interp_test_vertcoord = 'VERTISHEIGHT' + verbose = .false. + / diff --git a/templates/input.prioronly.nml b/templates/input.prioronly.nml index 21d7de55e1ff8674e7f24fc0eff8633e007a3e9b..19471bb280abc0e238bc62657d674c5338aa5d10 100644 --- a/templates/input.prioronly.nml +++ b/templates/input.prioronly.nml @@ -31,7 +31,7 @@ async = 0, adv_ens_command = "../shell_scripts/advance_model.csh", ens_size = <n_ens>, - obs_sequence_in_name = "obs_seq_all.out", + obs_sequence_in_name = "obs_seq.out", obs_sequence_out_name = "obs_seq.final", input_state_file_list = "input_list.txt" output_state_file_list = "output_list.txt" @@ -143,7 +143,8 @@ / &obs_kind_nml - assimilate_these_obs_types = 'RADIOSONDE_TEMPERATURE', + assimilate_these_obs_types = , + evaluate_these_obs_types = 'RADIOSONDE_TEMPERATURE', 'RADIOSONDE_U_WIND_COMPONENT', 'RADIOSONDE_V_WIND_COMPONENT', 'SAT_U_WIND_COMPONENT', @@ -156,11 +157,10 @@ 'ACARS_TEMPERATURE', 'GPSRO_REFRACTIVITY', 'DOPPLER_RADIAL_VELOCITY', - 'RADAR_REFLECTIVITY', + 'RADAR_REFLECTIVITY', 'MSG_4_SEVIRI_RADIANCE', - 'MSG_4_SEVIRI_TB', - 'MSG_4_SEVIRI_BDRF' - evaluate_these_obs_types = 'RADIOSONDE_SPECIFIC_HUMIDITY', + 'MSG_4_SEVIRI_TB', + 'MSG_4_SEVIRI_BDRF' / # Notes for obs_def_radar_mod_nml: @@ -246,7 +246,7 @@ &location_nml horiz_dist_only = .false., vert_normalization_pressure = 6666666.7, - vert_normalization_height = 5000000.0, + vert_normalization_height = 500.0, vert_normalization_level = 2666.7, vert_normalization_scale_height = 10.0, approximate_distance = .false.,