import numpy as np
import pandas as pd
from logging import info, error
from ....utils.classes.setup import Setup
from ....utils.classes.domains import Domain
from ....utils.check.errclass import PluginError
[docs]
def ini_mapper(model, general_mapper={}, backup_comps={},
transforms_order=[], ref_transform="",
transform_name="", **kwargs):
info("Initializing mapper for ICONART.")
mapper = {"inputs": {}, "outputs": {}}
# Get species to monitor
acspecies = model.chemistry.acspecies.attributes
emspecies = model.chemistry.emis_species
acspecies_bg = [acs + '_BG' for acs in acspecies]
allspecies = list(set(emspecies + acspecies_bg))
allspecies += [s + '_POST' for s in allspecies]
allspecies = sorted(acspecies + allspecies)
# -----------------------------------------------------
# -- DEFINITION OF IFS DOMAIN FOR INICOND AND LBC
# -----------------------------------------------------
domain_icon = model.domain
domain_ifs137 = Setup.load_registered(
domain_icon.plugin.name, domain_icon.plugin.version,
"domain", plg_orig=domain_icon
)
domain_ifs137.nlon = domain_icon.nlon
domain_ifs137.nlat = domain_icon.nlat
domain_ifs137.zlon = domain_icon.zlon
domain_ifs137.zlat = domain_icon.zlat
domain_ifs137.zlonc = domain_icon.zlonc
domain_ifs137.zlatc = domain_icon.zlatc
df_ifs137 = pd.read_csv(domain_icon.ifs_137_level_def_file)
domain_ifs137.pressure_unit = 'Pa'
domain_ifs137.nlev = 137
domain_ifs137.sigma_a = df_ifs137['a [Pa]'].values
domain_ifs137.sigma_b = df_ifs137['b'].values
domain_ifs137.get_vmiddle()
# -----------------------------------------------------
# -- INTERVALS
# -----------------------------------------------------
flx_intervals = {
ddi: np.append(
model.input_dates[ddi][:-1, np.newaxis],
model.input_dates[ddi][1:, np.newaxis],
axis=1)
for ddi in model.input_dates}
lbc_intervals = {
ddi: np.append(
model.lbc_input_dates[ddi][:-1, np.newaxis],
model.lbc_input_dates[ddi][1:, np.newaxis],
axis=1)
for ddi in model.lbc_input_dates}
output_intervals = {
ddi: np.append(
model.tstep_dates[ddi][:-1, np.newaxis],
model.tstep_dates[ddi][1:, np.newaxis],
axis=1)
for ddi in model.tstep_dates}
# -----------------------------------------------------
# -- INPUTS
# -----------------------------------------------------
# Fluxes (flux)
mapper["inputs"] = {
('flux', spec): {
"input_dates": flx_intervals,
"force_dump": True,
"sparse_data": False,
"sampled": False,
"force_loadin": True
}
for spec in model.chemistry.emis_species
}
# Initial concentrations (inicond and restart_inicond for EnSRF)
if getattr(model, "ensrf_restart_file", False):
for spec in acspecies:
mapper["inputs"][('restart_inicond', spec)] = {
"input_dates": {model.datei: np.array([[model.datei, model.datei]])},
"domain": domain_icon,
"force_dump": True,
"sparse_data": False,
"sampled": False,
"break_fwd_onlyinit_pipe": False,
"break_adj_onlyinit_pipe": False
}
else:
for spec in acspecies:
mapper["inputs"][('inicond', spec)] = {
"input_dates": {model.datei: np.array([[model.datei, model.datei]])},
"domain": domain_ifs137,
"force_dump": True,
"sparse_data": False,
"sampled": False,
"loadin_perturb_full_vertical": False,
"surface_level": -1,
"break_fwd_onlyinit_pipe": False,
"break_adj_onlyinit_pipe": False
}
# Lateral boundary conditions (lbc)
if model.meteo_lbc_dir:
for spec in acspecies:
mapper["inputs"][('lbc', spec)] = {
"input_dates": lbc_intervals,
"domain": domain_ifs137,
"force_dump": True,
"sparse_data": False,
"sampled": False,
"loadin_perturb_full_vertical": False,
"surface_level": -1,
"break_fwd_onlyinit_pipe": False,
"break_adj_onlyinit_pipe": False
}
# End concentrations from previous period for all active species
# are needed for later periods
endconcs_in = {
("endconcs", spec):
{"input_dates": {
ddi: np.array(
[[model.input_dates[ddi][0],
model.input_dates[ddi][0]]])
for ddi in list(model.input_dates.keys())[1:]},
"domain": model.domain,
"force_dump": True,
"sparse_data": False,
"sampled": False,
"break_fwd_onlyinit_pipe": True,
"break_adj_onlyinit_pipe": False
}
for spec in acspecies
}
mapper["inputs"].update(endconcs_in)
# -----------------------------------------------------
# -- OUTPUTS
# -----------------------------------------------------
# Output concentrations (concs)
mapper["outputs"] = {
(outcomp, spec): {
"isobs": True,
"force_loadout": True,
"input_dates": output_intervals,
"domain": model.domain,
"sampled": True,
"sparse_data": False,
"continuous_hdomain": False,
"continuous_vdomain": False,
"break_adj_onlyinit_pipe": False,
"break_fwd_onlyinit_pipe": False
}
for spec in allspecies
for outcomp in model.output_components
}
# End concentrations are saved for all periods
endconcs_out = {
("endconcs", spec):
{"input_dates": {
ddi: np.array([[model.input_dates[ddi][-1],
model.input_dates[ddi][-1]]])
for ddi in model.input_dates},
"domain": model.domain,
"force_loadout": True,
"sparse_data": False,
"sampled": False,
"break_fwd_onlyinit_pipe": True,
"break_adj_onlyinit_pipe": True
}
for spec in acspecies
}
mapper["outputs"].update(endconcs_out)
# Force the transformation to be in its own precursors and successors
# to propagate end concentrations
mapper["precursors"] = {trid: [transform_name] for trid in endconcs_in}
mapper["successors"] = {trid: [transform_name] for trid in endconcs_in}
# -----------------------------------------------------
# -- OUTPUT2INPUTS
# -----------------------------------------------------
# Save propagation of perturbations
inputs = ["inicond", "lbc", "restart_inicond"]
mapper["outputs2inputs"] = {
(outcomp, s): [(cmp, s) for cmp in inputs]
+ ([("flux", es) for es in model.chemistry.emis_species])
for s in allspecies
for outcomp in model.output_components
}
return mapper