Source code for pycif.plugins.models.TM5.io.inputs.params

# JvP 20210202: added import statements, MODULE_NAME module level logger
# JvP 20210720: added import of os
import logging
import sys
import os

from ......utils.check.errclass import CifRuntimeError
MODULE_NAME = __name__[__name__.index('TM5'):] if 'TM5' in __name__ else __name__
logger = logging.getLogger(MODULE_NAME)


[docs] def pp_list( some_list, indent=0, items_per_line=8 ): """ PURPOSE Pretty Print a list with names (i.e. strings) such as returned by the dir function. RETURNS A string with the list items concatenated and inserted newlines. ARGS some_list = the list to print KWARGS indent = additional indent so that the list items line up nicely if they are printed on multiple lines. items_per_line = number of list items to print on a single line ASSUMPTIONS none EXCEPTIONS When this function encounters a problem that it cannot solve, it will raise a RuntimeError. Pythons exeception handling will provide a traceback, including files, calls and line numbers. PYTHON VERSION 3.8.6 VERSION CHANGE HISTORY 1.0 15-04-2021 by J.C.A. van Peet. Original code. """ return ("\n" + " " * indent).join( [ ', '.join(some_list[i:i + items_per_line]) for i in range(0, len(some_list), items_per_line) ] )
# end function pp_list
[docs] def write_tm5_rc(self, config_file, runsubdir, mode, **kwargs): """ PURPOSE There are two types of rc files for running TM5: 'tm5.rc' and 'tmvar-precon-run.rc'. The first is used in the jobs 'fwd', 'apos' and 'grd', the second in the jobs 'g2gc' and 'xc2x'. Some parameters in the 'tm5.rc' file vary from iteration to iteration, but most are constant. These few parameters are changed using the keyword arguments to this function. The same is true for the 'tmvar-precon-run.rc' files, but the set of parameters is very different than that for the 'tm5.rc' files, so they are written in their own function. IN/OUT self = TM5 model plugin, containing all TM5 settings. config_file = filename to write the config settings to mode = String with the mode of the TM5 run. Can be either 'fwd' for a forward run or 'adj' for an adjoint run. KWARGS A lot, probably. To keep the function header clean, they are set in the function body using kwargs.pop(...). ASSUMPTIONS none EXCEPTIONS When this function encounters a problem that it cannot solve, it will raise a RuntimeError. Pythons exeception handling will provide a traceback, including files, calls and line numbers. PYTHON VERSION 3.8.6 VERSION CHANGE HISTORY 2.2 28-10-2021 by J.C.A. van Peet. Updated determination of iter_nr. 2.1 22-10-2021 by J.C.A. van Peet. Updated path to point departures file following changes by Antoine. 2.0 20-07-2021 by J.C.A. van Peet. *) Added the mode argument to indicate forward (fwd) or adjoint (adj) runs. *) Added extraction of the iteration number from config_file. *) Updated the setting of station.list.file *) Updated write statements to include adj variables when they are different than the fwd variables. 1.1 22-02-2021 by J.C.A. van Peet. Added runsubdir as a parameter to this function. See the function make_config below for more information. 1.0 03-02-2021 by J.C.A. van Peet. Original code. """ # Set the name of this function PROG_NAME = MODULE_NAME + ".write_tm5_rc" # Local logger logger = logging.getLogger(PROG_NAME) logger.setLevel(logging.DEBUG) # Keyword arguments # bagger = kwargs.pop("bagger", "bagger") # Debug messages indent = 35 logger.debug("") logger.debug("*" * 30) logger.debug(PROG_NAME + " => DEBUG:") logger.debug( f" self = {self}" ) logger.debug( f" dir(self) = {pp_list(dir(self), indent=indent)}" ) logger.debug( f" self.attributes = {pp_list(self.attributes, indent=indent)}" ) logger.debug( f" datei = {self.datei}" ) logger.debug( f" datef = {self.datef}" ) logger.debug( f" dir(self.chemistry) = {pp_list(dir(self.chemistry), indent=indent)}" ) logger.debug( f" self.chemistry.attributes = {pp_list(self.chemistry.attributes, indent=indent)}" ) logger.debug( f" dir(self.flux) = {pp_list(dir(self.flux), indent=indent)}" ) logger.debug( f" self.flux.attributes = {pp_list(self.flux.attributes, indent=indent)}" ) logger.debug( f" dir(self.meteo) = {pp_list(dir(self.meteo), indent=indent)}" ) logger.debug( f" self.meteo.attributes = {pp_list(self.meteo.attributes, indent=indent)}" ) logger.debug( f" dir(self.inicond) = {pp_list(dir(self.inicond), indent=indent)}" ) logger.debug( f" self.inicond.attributes = {pp_list(self.inicond.attributes, indent=indent)}" ) logger.debug( f" dir(self.chemistry.acspecies) = {pp_list(dir(self.chemistry.acspecies), indent=indent)}" ) logger.debug( f" self.chemistry.dir_sink = {self.chemistry.dir_sink}" ) logger.debug( f" self.chemistry.dir_tipp = {self.chemistry.dir_tipp}" ) logger.debug( f" self.chemistry.dirchem_ref = {self.chemistry.dirchem_ref}" ) logger.debug( f" self.chemistry.init_dir = {self.chemistry.init_dir}" ) logger.debug( f" self.chemistry.workdir = {self.chemistry.workdir}" ) # JvP 20210414: added printing of tm5_meteo_dir # JvP 20210503: After some changes by Antoine, use # self.workdir+'/datavect/meteo/' instead of tm5_meteo_dir logger.debug("") # logger.debug(" tm5_meteo_dir = %s", self.tm5_meteo_dir ) logger.debug( f" self.workdir+'/datavect/meteo/' = {self.workdir + '/datavect/meteo/'}" ) logger.debug("") # logger.debug("") # logger.debug("*"*30) # logger.debug("JvP: Computer says no!") # logger.debug("*"*30) # logger.debug("") # try: # raise RuntimeError # except RuntimeError as e: # #logger.exception("OOPS!") # logger.critical(e, exc_info=True) # #raise # => Will display the traceback on screen a second time # sys.exit() # => Just exit. # end try logger.debug("*" * 30) logger.debug("") # Check the domain definition (also done in compile.py). # Only glb600x400 is currently supported in CIF. # if ( self.domain.tm5_label != 'glb600x400' ): logger.critical("") logger.critical("*" * 30) logger.critical( PROG_NAME + " => ERROR: self.domain.tm5_label must be 'glb600x400'!") logger.critical(" self.domain.tm5_label = " + self.domain.tm5_label) logger.critical(" Computer says no...") logger.critical("*" * 30) logger.critical("") raise CifRuntimeError( PROG_NAME + " => ERROR: self.domain.tm5_label must be 'glb600x400'!") # end if # >>> JvP 20211028 # Get the iteration number from the rc filename, since it is not stored # somewhere easily accessible. According to Antoine (TM5-CIF telecon # 27-10-2021) the iteration number is -1 for the apriori run (or first # iteration), -2 for the aposterior run (or final iteration) and 2,3,... # for the 'normal' iterations. This means that when you convert the # iteration number to a string with '%04i'%iter_nr, the apriori iter_nr # number will become '-001', the aposteriori iter_nr will become '-002', # and the rest will become '0002', '0003' etc. If you combine the iter_nr # with a prefix like 'fwd_', the strings become (in chronological order): # 'fwd_-001', 'fwd_0002', 'fwd_0003', ..., 'fwd_-002'. # Notes: # *) Luckily, you only need the string representation of this number, so # it is sufficient to extract the part after '[fwd|adj]_'. # *) Similar code is used in make_obs.make_obs(...) # Split config_file into path and filename components config_path, config_base = os.path.split(config_file) config_path_parts = config_path.split(sep='/') # Check if config_path_parts[-2] starts with either 'fwd_' or 'adj_'. if ( not config_path_parts[-2].startswith( ('fwd_', 'adj_') ) ): logger.critical("") logger.critical("*" * 30) logger.critical( PROG_NAME + " => ERROR: path component does not start with 'fwd_' or 'adj_'!") logger.critical(" config_file = " + config_file ) logger.critical(" config_path = " + config_path ) logger.critical(" config_base = " + config_base ) logger.critical(f" config_path parts = {config_path_parts}" ) logger.critical(" Computer says no..." ) logger.critical("*" * 30) logger.critical("") raise CifRuntimeError # end if # Get the string representing the iteration number, and log a message. iter_nr = config_path_parts[-2][4:] logger.info(PROG_NAME + f" => iter_nr = {iter_nr}") # <<< JvP 20211028 # Info message logger.info(PROG_NAME + " => Writing TM5 config file to " + config_file) # Write config file # The values in this file are copied from the rc file from the forward run # in the first iteration of 20200918-tm5_sf-18m_sat_only-with_bc-ERA5. To # get all values without comment or white lines, use the following: # grep -iEv '(^!|^$)' tm5.rc # Some values (e.g. path names) have been updated using the keywords to # this function. # JvP 20210517: Updated the values in this file to match those from the # rc-file from the forward run in the first iteration of # 20210222-tm5_sf-18m_points_only-ERA5-spiv. TM5 will only try to use # point observations, and use Spivakovski OH... # JvP 20210720: Updated the adj values to match those in # .../20210222-tm5_sf-18m_points_only-ERA5-spiv/tmvar/var4d/iter-0001/grd/tm5.rc # # Mode dependent variables: if ( mode == 'fwd' ): my_runmode = '1' start_51_file = runsubdir + '/ini.nc' mass_input_dir = 'bagger/rommel/zooi/mass_input_dir' departures_point_file = 'bagger/rommel/zooi/point_departures.nc4' elif ( mode == 'adj' ): my_runmode = '2' start_51_file = 'None' # Note that the MASS directory is defined below as mass.output.subdir # mass_input_dir = '../../fwd_'+iter_nr+'/'+config_path_parts[-1]+'/output/MASS' # ../fwd/output/MASS # Use self.adj_refdir defined in run.py # to be sure to use the last forward mass_input_dir = f'{self.adj_refdir}/{config_path_parts[-1]}//output/MASS' # ../fwd/output/MASS # JvP 20211022: departure files are now written to the adjoint directory. # departures_point_file = '../../fwd_'+iter_nr+'/'+config_path_parts[-1]+'/point_departures.nc4' departures_point_file = '../../adj_' + iter_nr + '/' + \ config_path_parts[-1] + '/point_departures.nc4' else: logger.critical("") logger.critical("*" * 30) logger.critical(PROG_NAME + " => ERROR: unknown mode!") logger.critical(" mode must be in ['fwd', 'adj']!") logger.critical(" Computer says no...") logger.critical("*" * 30) logger.critical("") raise CifRuntimeError(PROG_NAME + " => ERROR: unknown mode!") # end if with open(config_file, "w") as file_id: print_kwds = {"file": file_id, "sep": ""} print("region.maxref : 10", **print_kwds) print("region.globe.xcyc : 1", **print_kwds) print("region.globe.touch_np : 1", **print_kwds) print("region.globe.touch_sp : 1", **print_kwds) print("region.globe.xbeg : %4i" % (self.domain.xmin), **print_kwds) # -180 print("region.globe.xend : %4i" % (self.domain.xmax), **print_kwds) # 180 print("region.globe.ybeg : %4i" % (self.domain.ymin), **print_kwds) # -90 print("region.globe.yend : %4i" % (self.domain.ymax), **print_kwds) # 90 print("region.globe.im : 1", **print_kwds) print("region.globe.jm : 1", **print_kwds) print("region.globe.xref : 1", **print_kwds) print("region.globe.yref : 1", **print_kwds) print("region.globe.zref : 1", **print_kwds) print("region.globe.tref : 1", **print_kwds) print("region.globe.redgrid.nh.n : 0", **print_kwds) print("region.globe.redgrid.nh.comb :", **print_kwds) print("region.globe.redgrid.sh.n : 0", **print_kwds) print("region.globe.redgrid.sh.comb :", **print_kwds) print("region.glb100x100.xcyc : 1", **print_kwds) print("region.glb100x100.touch_np : 1", **print_kwds) print("region.glb100x100.touch_sp : 1", **print_kwds) print("region.glb100x100.xbeg : -180", **print_kwds) print("region.glb100x100.xend : 180", **print_kwds) print("region.glb100x100.ybeg : -90", **print_kwds) print("region.glb100x100.yend : 90", **print_kwds) print("region.glb100x100.im : 360", **print_kwds) print("region.glb100x100.jm : 180", **print_kwds) print("region.glb100x100.xref : 1", **print_kwds) print("region.glb100x100.yref : 1", **print_kwds) print("region.glb100x100.zref : 1", **print_kwds) print("region.glb100x100.tref : 1", **print_kwds) print("region.glb100x100.redgrid.nh.n : 10", **print_kwds) print("region.glb100x100.redgrid.nh.comb : 360 360 180 180 90 90 30 30 15 5", **print_kwds) print("region.glb100x100.redgrid.sh.n : 10", **print_kwds) print("region.glb100x100.redgrid.sh.comb : 360 360 180 180 90 90 30 30 15 5", **print_kwds) # 6.0 print( f"region.dx : {self.domain.dx:4.1f}", **print_kwds) # 4.0 print( f"region.dy : {self.domain.dy:4.1f}", **print_kwds) print("region.dz : 1.0", **print_kwds) # glb600x400 print( f"regions : {self.domain.tm5_label}", **print_kwds) print("region.glb600x400.parent : globe", **print_kwds) # glb600x400 print( f"my.region1 : {self.domain.tm5_label}", **print_kwds) print("my.region2 :", **print_kwds) print("my.region3 :", **print_kwds) print("my.region1s : glb6x4", **print_kwds) print("my.region2s :", **print_kwds) print("my.region3s :", **print_kwds) print("region.glb600x400.xcyc : 1", **print_kwds) print("region.glb600x400.touch_np : 1", **print_kwds) print("region.glb600x400.touch_sp : 1", **print_kwds) print("region.glb600x400.xbeg : %4i" % (self.domain.xmin), **print_kwds) # -180 print("region.glb600x400.xend : %4i" % (self.domain.xmax), **print_kwds) # 180 print("region.glb600x400.ybeg : %4i" % (self.domain.ymin), **print_kwds) # -90 print("region.glb600x400.yend : %4i" % (self.domain.ymax), **print_kwds) # 90 print("region.glb600x400.im : %4i" % (self.domain.nlon), **print_kwds) # 60 print("region.glb600x400.jm : %4i" % (self.domain.nlat), **print_kwds) # 45 print("region.glb600x400.xref : 1", **print_kwds) print("region.glb600x400.yref : 1", **print_kwds) print("region.glb600x400.zref : 1", **print_kwds) print("region.glb600x400.tref : 1", **print_kwds) print("region.glb600x400.redgrid.nh.n : 4", **print_kwds) print("region.glb600x400.redgrid.nh.comb : 60 20 10 5", **print_kwds) print("region.glb600x400.redgrid.sh.n : 4", **print_kwds) print("region.glb600x400.redgrid.sh.comb : 60 20 10 5", **print_kwds) print("region.glbsfc : glb100x100", **print_kwds) print("region.globe : globe", **print_kwds) print("ppobs.nasim : 10800", **print_kwds) # 1 for fwd, 2 for adj print(f"my.runmode : {my_runmode}", **print_kwds) print("runid : RUNID", **print_kwds) print("jobstep.timerange.start : %s" % ( # 2018-01-01 00:00:00 self.datei.strftime('%Y-%m-%d %H:%M:%S')), **print_kwds) print("jobstep.timerange.end : %s" % ( # 2019-07-01 00:00:00 self.datef.strftime('%Y-%m-%d %H:%M:%S')), **print_kwds) print("timestep.read : 3600", **print_kwds) print("ndyn : 3600", **print_kwds) # /scratch/shared/jpt930/TM5-SF_4DVAR-a/20210222-tm5_sf-18m_points_only-ERA5-spiv/input print( f"input.dir : {self.workdir + '/model/input'}", **print_kwds) print("istart : 51", **print_kwds) # JvP 20210222: added runsubdir+ini.nc and continued updating variables. # /scratch/shared/jpt930/TM5-SF_4DVAR-a/20210222-tm5_sf-18m_points_only-ERA5-spiv/input/iniconc.nc4 print(f"start.51.file : {start_51_file}", **print_kwds) print("my.meteo_id : EA", **print_kwds) print("meteo.convec.files : convec", **print_kwds) print("my.meteo.unpacked : T", **print_kwds) print("my.meteo.resol : coarsened ! coarsened to levels and regions", **print_kwds) print("my.meteo.class : ea", **print_kwds) print("my.meteo.format : tm5-nc ! NetCDF files", **print_kwds) print("diffusion.files : T", **print_kwds) # The DIFFCOEFF subdirectory is created in TM5s __init__.py. If you don't want that, # try switching off diffusion.files above # /scratch/shared/jpt930/TM5-SF_4DVAR-a/20210222-tm5_sf-18m_points_only-ERA5-spiv/DIFFCOEFF print( f"diffusion.dir : {self.workdir + '/DIFFCOEFF'}", **print_kwds) print("my.ecclass_ecl : ea", **print_kwds) print("my.meteo.nlev : 137", **print_kwds) print("my.meteo.pfx : ec", **print_kwds) print("my.mlevs : tropo25a", **print_kwds) print("meteo.tinterp.* : interp1", **print_kwds) print("meteo.tinterp.sfc.aver : aver1", **print_kwds) print("meteo.tinterp.ml : interp3", **print_kwds) print("meteo.tinterp.convec : aver3", **print_kwds) print("meteo.tinterp.oro : const", **print_kwds) print("meteo.tinterp.lsm : const", **print_kwds) print("meteo.tinterp.srols : month", **print_kwds) print("my.mext : /<yyyy>", **print_kwds) print("my.msep : /", **print_kwds) print("my.glb600x400.m : glb600x400", **print_kwds) print("my.convec.filekey : filekey=convec", **print_kwds) print("tmm.sourcekey.*.sfc.an : tm5-nc:mdir=ec/ea/an0tr1/sfc/glb100x100/<yyyy>;tres=_00p01;namesep=/", **print_kwds) print("tmm.sourcekey.*.sfc.fc : tm5-nc:mdir=ec/ea/h06h18tr1/sfc/glb100x100/<yyyy>;tres=_00p01;namesep=/", **print_kwds) print("tmm.sourcekey.glb600x400.ml : tm5-nc:mdir=ec/ea/h06h18tr3/tropo25a/glb600x400/<yyyy>;tres=_00p03;namesep=/", **print_kwds) print("tmm.sourcekey.glb600x400.convec : tm5-nc:mdir=ec/ea/h06h18tr3/tropo25a/glb600x400/<yyyy>;tres=_00p03;namesep=/;filekey=convec", **print_kwds) # # JvP 20210517: update tmm.dir and my.meteo.source.dir # /projects/0/tm5meteo/tm5-nc print( f"tmm.dir : {runsubdir + '/meteo/'}", **print_kwds) # /projects/0/tm5meteo/tm5-nc print( f"my.meteo.source.dir : {runsubdir + '/meteo/'}", **print_kwds) print("my.region1m : glb600x400", **print_kwds) print("my.levs : tropo25a", **print_kwds) print("emissions.source : PyShell", **print_kwds) # # JvP 20210517: @Antoine: TM5 requires the following two PyShell variables. The first should be set # to the emission file specified in the yaml file in datavect/components/fluxes/parameters/CH4/"dir+file". # The second should be set to the updated emission file of the previous iteration. How do I do that? # JvP 20210609: Set both to sunsubdir+'emission.nc4'. See the following files: # *) pycif/plugins/models/TM5/io/inputs/make_fluxes.py # *) pycif/plugins/fluxes/tm5/write.py # *) pycif/plugins/fluxes/tm5/read.py # /scratch/shared/jpt930/TM5-SF_4DVAR-a/20210222-tm5_sf-18m_points_only-ERA5-spiv/input/emission.nc4 print( f"PyShell.em.apri.filename : {runsubdir + '/emission.nc4'}", **print_kwds) # ../../iter-0000/xc2x/emission.nc4 print( f"PyShell.em.filename : {runsubdir + '/emission.nc4'}", **print_kwds) # print("emission.dailycycle : F", **print_kwds) print("my.oh_id : SP", **print_kwds) print("my.strat_id : EC", **print_kwds) print("chemistry.ch4.Lrates : L_OH_tropo L_OH_strato L_Cl_strato L_O1D_strato", **print_kwds) print("chemistry.ch4.lrate.dsec : 10800", **print_kwds) print("chemistry.ch4.L_OH_tropo.domain : tropo", **print_kwds) print("chemistry.ch4.L_OH_tropo.source : Spivakovsky", **print_kwds) print("chemistry.ch4.L_OH_tropo.factor : 0.92", **print_kwds) print("chemistry.ch4.L_OH_tropo.file : OH_troposphere-Spivakovsky-2000-ml60-glb100x100.hdf", **print_kwds) # /home/jpt930/TM5-SF-data/TIPP/CH4/bc print( f"chemistry.ch4.L_OH_tropo.dir : {self.workdir + '/chemical_scheme/TIPP/CH4/bc'}", **print_kwds) print("chemistry.ch4.L_OH_strato.domain : strato", **print_kwds) print("chemistry.ch4.L_OH_strato.source : Bruehl_GG", **print_kwds) print("chemistry.ch4.L_OH_strato.file : Bruehl_ECHAM_Lrate_CH4+OH.nc", **print_kwds) # /home/jpt930/TM5-SF-data/SINKS print( f"chemistry.ch4.L_OH_strato.dir : {self.workdir + '/chemical_scheme/SINKS'}", **print_kwds) print("chemistry.ch4.L_OH_strato.factor : 1.0", **print_kwds) print("chemistry.ch4.L_Cl_strato.domain : strato", **print_kwds) print("chemistry.ch4.L_Cl_strato.source : Bruehl_GG", **print_kwds) print("chemistry.ch4.L_Cl_strato.file : Bruehl_ECHAM_Lrate_CH4+Cl.nc", **print_kwds) # /home/jpt930/TM5-SF-data/SINKS print( f"chemistry.ch4.L_Cl_strato.dir : {self.workdir + '/chemical_scheme/SINKS'}", **print_kwds) print("chemistry.ch4.L_Cl_strato.factor : 1.0", **print_kwds) print("chemistry.ch4.L_O1D_strato.domain : strato", **print_kwds) print("chemistry.ch4.L_O1D_strato.source : Bruehl_GG", **print_kwds) print("chemistry.ch4.L_O1D_strato.file : Bruehl_ECHAM_Lrate_CH4+OD.nc", **print_kwds) # /home/jpt930/TM5-SF-data/SINKS print( f"chemistry.ch4.L_O1D_strato.dir : {self.workdir + '/chemical_scheme/SINKS'}", **print_kwds) print("chemistry.ch4.L_O1D_strato.factor : 1.0", **print_kwds) print("chemistry.ch4.lrate.archive : F", **print_kwds) print("proces.diffusion.eps_d : 0.0", **print_kwds) print("convection.with_ev_slopes : F", **print_kwds) print("proces.advection : T", **print_kwds) print("proces.chemistry : T", **print_kwds) print("proces.source : T", **print_kwds) print("mask.apply : F", **print_kwds) print("budget.global : T", **print_kwds) print("budget.output : True", **print_kwds) print("budget.output.subdir : budget", **print_kwds) print("budget.store.from : <output.dir>", **print_kwds) print("budget.store.files : budget.tar", **print_kwds) print("budget.store.tarfilter : budget", **print_kwds) print("output.dir : output", **print_kwds) print("output.after.step : o", **print_kwds) print("cfl.outputstep : 3600", **print_kwds) print("model.output : F", **print_kwds) print("output.point : T", **print_kwds) print("output.point.verbose : T", **print_kwds) print("station.repr_error : 5", **print_kwds) print("output.point.errors : repr_error=5", **print_kwds) print("output.point.sample.parent : F", **print_kwds) # JvP 20210614: line below not yet used in TM5, waiting for the next crash... # /scratch/shared/jpt930/TM5-SF_4DVAR-a/20210222-tm5_sf-18m_points_only-ERA5-spiv/input/point_input.nc4 print( f"output.point.infile : {runsubdir + '/point_input.nc4'}", **print_kwds) print("output.point.meteo : T", **print_kwds) print("output.point.minerror : 0.5 ! ppm", **print_kwds) print("output.point.timewindow : 0.5 ! hours", **print_kwds) print("output.point.interpolation_method : linear", **print_kwds) print("output.point.dryair.mixratio : F", **print_kwds) print("station.ppobs.data.sel : 2", **print_kwds) print("output.point.extrapol2surf : T", **print_kwds) # JvP 20210723: added departures_point_file to line below # ../dep/point_departures.nc4 print( f"departures.point.file : {departures_point_file}", **print_kwds) print("output.satellite : T", **print_kwds) print("output.satellite.verbose : T", **print_kwds) # JvP 20210614: path below not yet used in TM5, waiting for the next crash... print(f"output.satellite.departure.dir : bagger/rommel/zooi/departure_dir", **print_kwds) # ../dep/satellite print("output.satellite.sample.parent : T", **print_kwds) print("output.satellite.sample.time_window : 10800", **print_kwds) print("output.satellite.interpolation_method : linear", **print_kwds) print("output.satellite.errors : neighbors", **print_kwds) print("output.satellite.meteo.CH4 : F", **print_kwds) print("output.satellite.dryair.mixratio : F", **print_kwds) print("station.output : T", **print_kwds) print("station.extrapol2surf : T", **print_kwds) print("station.output.subdir : STATION", **print_kwds) # # print("fts.list.file : /home/jpt930/TM5-SF-data_JvP/stationlist_FTS_TCCON-JvP-20200901.dat" , **print_kwds) print( f"fts.list.file : {self.TCCON_FTS_list}", **print_kwds) # print("fts.list.format : 1", **print_kwds) print("fts.output : T", **print_kwds) print("fts.output.subdir : FTS", **print_kwds) print("output.tccon : F", **print_kwds) print("validation.output : F", **print_kwds) print("validation.output.subdir : VALIDATION", **print_kwds) print("mixhdf.output : T", **print_kwds) print("mixhdf.output.subdir : MIXHDF", **print_kwds) print("output.mix : F", **print_kwds) print("output.mix.tstep : 10800", **print_kwds) print("output.mix.filename.prefix : mix_", **print_kwds) print("mmix.output : T", **print_kwds) print("mmix.output.subdir : MMIX", **print_kwds) print("column.output : F", **print_kwds) print("column.output.subdir : COLUMN", **print_kwds) print("mass.output.subdir : MASS", **print_kwds) # ../fwd/output/MASS print( f"mass.input.dir : {mass_input_dir}", **print_kwds) print("save.output.subdir : save", **print_kwds) print("timing.output.subdir : timing", **print_kwds) print("adjoint.input.satellite : F", **print_kwds) print("okdebug : F", **print_kwds) print("optimize.emission : T", **print_kwds) print( f"var4d.optim_emis.type : {self.optim_emis_type}", **print_kwds) # # JvP 20210614: I'm not sure how to implement a single source. For now, just try setting # categories to 1, category1 to total (name in the netCDF file, and keep tres on monthly # print("emission.CH4.glb600x400.categories : 4" , **print_kwds) # print("emission.CH4.glb600x400.category1 : wetlands" , **print_kwds) # print("emission.CH4.glb600x400.category1.tres : monthly" , **print_kwds) # print("emission.CH4.glb600x400.category2 : rice" , **print_kwds) # print("emission.CH4.glb600x400.category2.tres : monthly" , **print_kwds) # print("emission.CH4.glb600x400.category3 : biomass-burning" , **print_kwds) # print("emission.CH4.glb600x400.category3.tres : monthly" , **print_kwds) # print("emission.CH4.glb600x400.category4 : other" , **print_kwds) # print("emission.CH4.glb600x400.category4.tres : monthly" , **print_kwds) print("emission.CH4.glb600x400.categories : 1", **print_kwds) print("emission.CH4.glb600x400.category1 : total", **print_kwds) print("emission.CH4.glb600x400.category1.tres : monthly", **print_kwds) # # JvP 20210614: I'm not entirely sure that the station.list.file is actually being used. # In the original rc file, there appears not to be a loop around this variable, so I'm # not sure if the "...%{tracer}..." part will be replaced by something like CH4... # JvP 20210706: Well, apparently the "...%{tracer}..." part is replaced by something # (environment variable???), because tm5 crashes if it doesn't find this file. For now, # I'll hardcode it here, but it should be moved to the yaml file... # JvP 20210720: the file defined in station.list.file is now based on the actual locations # of the observations and is generated in make_obs.py. # print("station.list.file : /home/jpt930/TM5-SF-data/STATION//stationlist_%{tracer}_NOAA014_F3_v2.dat" , **print_kwds) # print("station.list.file : %s" % '/bagger/rommel/zooi/meuk.dat' , **print_kwds) # print("station.list.file : %s" % (self.input_dir+'/stationlist_CH4_NOAA014_F3_v2.dat',), **print_kwds) print( f"station.list.file : {runsubdir + '/stationlist_CH4.dat'}", **print_kwds) # print("station.list.format : 3", **print_kwds) print("station.list.file2 : ", **print_kwds) print("station.list.format2 : 3", **print_kwds) # # JvP 20210614: The current setup is for a surface only inversion, so the setting # of the output.directory should not matter... # print("output.satellite.output.directory : /scratch/shared/jpt930/TM5-SF_4DVAR-a/20210222-tm5_sf-18m_points_only-ERA5-spiv/input/satellites" , **print_kwds) print(f"output.satellite.output.directory : /bagger/rommel/zooi/satellite_output_dir", **print_kwds) print("output.satellite.split.period : m", **print_kwds)
# end with # end write_tm5_rc
[docs] def make_config(self, runsubdir, sdc, mode): """ PURPOSE Write a configuration file for running TM5. This file will have the name 'tm5.rc' and is therefore also called an rc-file. This function is imported/called in native2inputs.py. IN/OUT self = TM5 model plugin, containing all TM5 settings. runsubdir = The directory in which TM5 is run. Probably depends on iteration number and date. sdc = No idea. Is set in native2inputs as ddi = min(datei, datef) sdc = ddi.strftime("%Y%m%d%H") so it is probably the formatted start date of the current iteration. mode = in native2inputs this is described as "running mode: one of 'fwd', 'adj' and 'tl'". I'm not sure what 'tl' stands for. KWARGS none ASSUMPTIONS none EXCEPTIONS When this function encounters a problem that it cannot solve, it will raise a RuntimeError. Pythons exeception handling will provide a traceback, including files, calls and line numbers. PYTHON VERSION 3.8.6 VERSION CHANGE HISTORY 2.0 20-07-2021 by J.C.A. van Peet. Added selection of fwd and adj mode, and writing of corresponding rc-files. 1.2 22-02-2021 by J.C.A. van Peet. As Antoine pointed out, the initial condition file defined in the yaml file (datavect.components.inicond.[dir|file]) is linked as ini.nc in runsubdir (see make_inicond.py). So to access that file from TM5, you only have to set runsubdir/ini.nc in the rc-file. But runsubdir is not part of the TM5 object ('self') but passed as a parameter to the current function. So you have to pass it explicitly to the function write_tm5_rc, to be able to write it to rc file. 1.1 02-02-2021 by J.C.A. van Peet. *) Added MODULE_NAME *) Added import of the logging module *) Updated PROG_NAME *) Used new PROG_NAME as local logger name. *) Moved writing of rc-file to separate function. 1.0 09-11-2020 by J.C.A. van Peet. Original code. """ # Set the name of this function PROG_NAME = MODULE_NAME + ".make_config" # JvP 20210202: Local logger logger = logging.getLogger(PROG_NAME) logger.setLevel(logging.DEBUG) # Debug messages logger.debug("") logger.debug("*" * 30) logger.debug(PROG_NAME + " => DEBUG:") logger.debug(" self = %s", self ) logger.debug(" runsubdir = %s", runsubdir) logger.debug(" sdc = %s", sdc ) logger.debug(" mode = %s", mode ) logger.debug("*" * 30) logger.debug("") # Write the config file config_file_name = f"{runsubdir}/tm5.rc" logger.info(PROG_NAME + " => Writing TM5 config file to " + config_file_name) # JvP 20210222: added runsubdir as a parameter to write_tm5_rc # JvP 20210720: added mode as an argument to write_tm5_rc write_tm5_rc(self, config_file_name, runsubdir, mode )
# end function make_config