Source code for pycif.plugins.models.wrfchem.io.inputs.make_inicond

import filecmp
import os
import shutil
import pathlib
import numpy as np
from netCDF4 import Dataset
import xarray as xr
from logging import warning

from ......utils import path
from ......utils.check.errclass import CifValueError
# from .utils import replace_dates

# Copied from chimere on 2022-01-03


[docs] def make_inicond(self, datastore, runsubdir, datei, mode): """Write or symlink the WRF-Chem initial concentration file ``wrfinput_d01``. Mirrors the logic of the CHIMERE ``make_inicond``: links from disk when no CIF-modified data exists, otherwise copies and overwrites the relevant species variables. Args: self: WRF-Chem model plugin instance. datastore (dict): tracer-ID-keyed CIF data-store entries. runsubdir (str): path to the period run directory. datei (datetime): period start date. mode (str): ``'fwd'``, ``'tl'``, or ``'adj'``. """ # Fixed name for initial conditions file fileout = f"{runsubdir}/wrfinput_d01" # # Getting the forward initial concentrations (needed even for adjoint) # # if chained period # subsimu_dates = self.subsimu_dates # if mode == "adj" and hasattr(self, "fwd_chain") \ # and datei != self.datei: # date_index = np.where(subsimu_dates == datei)[0][0] # refdir = self.adj_refdir # filein = subsimu_dates[date_index - 1].strftime( # "{}/chain/end.%Y%m%d%H.{}.nc".format(refdir, nho) # ) # path.link(filein, fileout) # Exit if not first period if datei != self.datei: return # If in datastore, take data, otherwise, link to original INI_CONCS for spec in self.chemistry.acspecies.attributes: trid = ("inicond", spec) # If spec not explicitly defined in datastore, # fetch general component information if available if trid in datastore: pass elif trid not in datastore and ("inicond", "") in datastore: trid = ("inicond", "") else: continue tracer = datastore[trid] tracer_data = tracer["data"][datei] # If no data is provided, just copy from original file # (this is for the inicond plugin in datastreams/fields/wrfchem_icbc, # which fetches wrfinput files, so they only have to be linked into # the run directory) if "spec" not in tracer_data: dirorig = tracer["dirorig"] fileorig = tracer["fileorig"] fileini = f"{dirorig}/{fileorig}" # If does not exist, just link # linked = False if not os.path.isfile(fileout): path.link(fileini, fileout) # linked = True # freum: didn't need this in fluxes, so commenting it here too # # Otherwise, check for difference # if not linked: # if not os.path.isfile(fileini): # warning("The initial condition file {} does not exist to " # "initialize the species {}. The concentrations will" # " be initialized to zero. Please check your yaml if" # " you expect a different behaviour" # .format(fileini, spec)) # continue # # if not filecmp.cmp(fileini, fileout): # with Dataset(fileini, "r") as ds: # if spec not in ds.variables: # warning("{} is not accounted " # "for in the initial conditions file {}. " # "Please check your IC whether it should be" # .format(spec, fileini)) # continue # # iniin = ds.variables[spec][:] # iniin = xr.DataArray( # iniin[np.newaxis, ...], # coords={"time": [min(datei, datef)]}, # dims=("time", "lev", "lat", "lon"), # ) # # # If ini file is still a link, should be copied # # to be able to modify it locally # if os.path.islink(fileout): # file_orig = pathlib.Path(fileout).resolve() # os.unlink(fileout) # shutil.copy(file_orig, fileout) # # # Now writes the new value for the corresponding species # self.inicond.write(spec, fileout, iniin, # comp_type="inicond") # freum: no tl mode for wrf # # Repeat operations for tangent linear # if mode == "tl": # # If does not exist, just link # if not os.path.isfile(fileoutincr): # shutil.copy(fileini, fileoutincr) # # with Dataset(fileoutincr, "a") as fout: # if spec in fout.variables: # fout.variables[spec][:] = 0.0 else: # Copy wrfinput file(s) from source_dir (assumes that # real.exe already ran) # (Only do this once) if os.path.islink(fileout): raise CifValueError("Link shouldnt exist...?") if not os.path.exists(fileout): shutil.copy(os.path.join(self.source_dir, "wrfinput_d01"), fileout) # Write initial conditions ini_fwd = tracer_data["spec"] varname = getattr(self.chemistry.acspecies, spec).varname self.inicond.write(varname, fileout, ini_fwd, comp_type="inicond")
# freum: no tl mode for wrf # if mode == "tl": # path.copyfromlink(fileoutincr) # ini_tl = tracer_data.get("incr", 0.0 * ini_fwd) # self.inicond.write( # spec, fileoutincr, ini_tl, comp_type="inicond" # ) # Check that the dates are consistent with what wrf expects # Commented, because WRF checks that too. # wrfinput_times, _ = self.wrfhelper.wrf_times([fileout]) # ok = False # if len(wrfinput_times) == 1): # if wrfinput_times[0] == datei: # ok = True # if not ok: # raise ValueError("Dates in {} are not what WRF expects.")