import numpy as np
import datetime
from ....utils.classes.setup import Setup
[docs]
def ini_mapper(model, transform_type, general_mapper={}, backup_comps={},
transforms_order=[], ref_transform="", transform_name="",
**kwargs):
"""
Note: Clean up as soon as it runs.
VERSION HISTORY
2021-10-06 freum Added 'namelist' and 'model' to inputs
2021-10-01 aberchet Uncommented 'isobs' and 'force_loadout' in 'concs'
2021-09-22 freum Edited out model.input_dates
2021-09-20 freum Updated emis dict
2021-08-19 freum Adapted for wrfchem, with some open questions
2021-08-18 Original code in models/lmdz/ini_mapper.py
"""
# input_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}
# freum: replaced model.input_dates with model.meteo_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.input_dates}
for ddi in model.meteo_dates}
# freum: Ok
meteo_intervals = {
ddi: np.append(
model.meteo_dates[ddi][:, np.newaxis],
model.meteo_dates[ddi][:, np.newaxis],
axis=1)
for ddi in model.meteo_dates}
# freum: removed input_dates because I don't have it, dates added in
# as needed below
# default_dict = {"input_dates": input_intervals, "force_dump": True}
default_dict = {"force_dump": True, "sparse_data": False, "sampled": False}
dict_surface = dict(default_dict, **{"domain": model.domain,
"fixed_domain": True})
dict_setup = dict(
dict_surface, **{"input_dates": {
model.datei: np.array([[model.datei, model.datef]])}}
)
dict_lat = dict(dict_surface, **{"is_lbc": True,
"input_dates": meteo_intervals})
dict_ini = dict(
dict_surface, **{"input_dates": {
model.datei: np.array([[model.datei, model.datei]])}}
)
# Executable
mapper = {
"inputs": {
# ("exe", ""): default_dict, # freum: comment until moved from prepro to cif
# ("def", ""): default_dict, # freum: seems lmdz-specific, comment out
# ("traj", ""): default_dict,# freum: seems lmdz-specific, comment out
# ("meteo", ""): meteo_dict, # freum: comment until moved from prepro to cif
# ("chem_fields", ""): default_dict, # freum: not used in WRF so far
},
# freum: commented output attributes are just copied from lmdz
# and dummy. Not sure what is needed.
"outputs": {
(outcomp, s): {
"isobs": True,
"force_loadout": True,
"input_dates": output_intervals,
"domain": model.domain,
"sampled": True,
"sparse_data": False
}
for s in model.chemistry.acspecies.attributes
for outcomp in ["concs", "pressure", "dpressure"]
}
}
# Inputs dict
# freum: new input_dates name specifically for fluxes
flux_intervals = {
ddi: np.append(
model.flux_dates[ddi][:-1, np.newaxis],
model.flux_dates[ddi][1:, np.newaxis],
axis=1)
for ddi in model.flux_dates}
# For fluxes, alter the model domain to be consistent with nlevemis
domain_in = model.domain
domain_out = Setup.load_registered(
domain_in.plugin.name, domain_in.plugin.version,
"domain", plg_orig=domain_in
)
domain_out.nlon = domain_in.nlon
domain_out.nlat = domain_in.nlat
domain_out.zlon = domain_in.zlon
domain_out.zlat = domain_in.zlat
domain_out.zlonc = domain_in.zlonc
domain_out.zlatc = domain_in.zlatc
domain_out.nlon_side = domain_in.nlon_side
domain_out.nlat_side = domain_in.nlat_side
domain_out.zlonc_side = domain_in.zlonc_side
domain_out.zlatc_side = domain_in.zlatc_side
domain_out.zlon_side = domain_in.zlon_side
domain_out.zlat_side = domain_in.zlat_side
domain_out.pressure_unit = domain_in.pressure_unit
domain_out.nlev = model.namelist["chem"]["kemit"]
domain_out.sigma_a = domain_in.sigma_a[:domain_out.nlev + 1]
domain_out.sigma_b = domain_in.sigma_b[:domain_out.nlev + 1]
domain_out.sigma_a_mid = domain_in.sigma_a_mid[:domain_out.nlev]
domain_out.sigma_b_mid = domain_in.sigma_b_mid[:domain_out.nlev]
dict_fluxes = dict(
default_dict, **{"input_dates": flux_intervals,
"domain": domain_out,
"fixed_domain": True,
"tracer_from_previous": True}
)
lbc = {
("latcond", s): dict_lat
for s in model.chemistry.acspecies.attributes
}
mapper["inputs"].update(lbc)
emis = {
("flux", s): dict_fluxes
for s in model.chemistry.emis_species.attributes
}
mapper["inputs"].update(emis)
inicond = {
("inicond", s): dict_ini for s in model.chemistry.acspecies.attributes
}
mapper["inputs"].update(inicond)
inputs = ["inicond", "latcond"]
mapper["outputs2inputs"] = {
(outcomp, s): [(cmp, s) for cmp in inputs]
+ ([("flux", s)] if s in model.chemistry.emis_species.attributes else [])
for s in model.chemistry.acspecies.attributes
for outcomp in ["concs", "pressure", "dpressure"]
}
# freum: from here, some additional code in lmdz's ini_mapper that the
# WRF plugin doesn't use. Commented instead of deleted in case it's
# needed at some point.
# prescrcond = {
# ("prescrconcs", s): dict_surface
# for s in model.chemistry.prescrconcs.attributes
# }
# mapper["inputs"].update(prescrcond)
# End concentrations from previous period for all active species
# are needed for later periods
endconcs_in = {
("endconcs", s):
{"input_dates": {
ddi: np.array(
[[model.meteo_dates[ddi][0],
model.meteo_dates[ddi][0]]])
for ddi in list(model.meteo_dates.keys())[1:]},
"domain": model.domain,
"force_dump": True
}
for s in model.chemistry.acspecies.attributes
}
mapper["inputs"].update(endconcs_in)
# End concentrations are saved for all periods
endconcs_out = {
("endconcs", s):
{"input_dates": {
ddi: np.array(
[[model.meteo_dates[ddi][-1],
model.meteo_dates[ddi][-1]]])
for ddi in model.meteo_dates},
"domain": model.domain,
"force_loadout": True
}
for s in model.chemistry.acspecies.attributes
}
mapper["outputs"].update(endconcs_out)
# Photochemistry
# list_var = \
# [j[1][1] for j in model.chemistry.photo_rates.iterrows()] \
# + ['pmid', 'temp']
# photj = {
# ("kinetic", l): dict_surface
# for l in list_var
# }
# model.photj = photj
# mapper["inputs"].update(photj)
# freum: I think wrf handles this if needed, comment out
# if hasattr(model.chemistry, "prodloss3d"):
# prodloss3d = {
# ("prodloss3d", s): dict_surface
# for s in model.chemistry.prodloss3d.attributes
# }
# else:
# prodloss3d = {}
# mapper["inputs"].update(prodloss3d)
# Accepts backup components instead of reference ones
# if hasattr(model, "backup_comps"):
# backup_comps.update(model.backup_comps)
# 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}
return mapper