import pandas as pd
from logging import debug
import numpy as np
from .....utils.datastores.crop_monitor import crop_monitor
from .....utils.dates import date_range
[docs]
def forward(
transform,
inout_datastore,
controlvect,
obsvect,
mapper,
di,
df,
mode,
runsubdir,
workdir,
onlyinit=False,
**kwargs
):
if onlyinit:
return
ddi = min(di, df)
ddf = max(di, df)
datastore = inout_datastore["inputs"]
datavect = obsvect.datavect
tracer_ids = mapper["inputs"]
for tracer_id in tracer_ids:
if tracer_id not in datastore:
continue
mod_input = tracer_id[0]
trcr = tracer_id[1]
# If this type of input is not considered in the control vector,
# ignoring the model sensitivity
component = getattr(getattr(datavect, "components", None),
mod_input,
None)
parameters = getattr(component, "parameters", None)
# Now fetch info from data structure to common structure
param = getattr(parameters, trcr, None)
if param is None or not getattr(param, "isobs", False):
debug("{}/{} was not is the observation vector. Passing"
.format(trcr, mod_input))
continue
if datastore.get(tracer_id, None) is None:
debug("{}/{} was not provided any data to put back "
"in the observation vector".format(trcr, mod_input))
continue
data_sim = datastore[tracer_id][ddi]["maindata"]
if "spec" not in data_sim:
continue
# Keep only sub-period if `split_freq` is specified
ds_meta = param.datastore
crop_index = np.arange(len(ds_meta), dtype=int)
weight = 1
if hasattr(transform, "split_freq"):
obsvect_dates = date_range(
transform.datei, transform.datef, period=transform.split_freq)
i0 = np.argwhere(obsvect_dates == ddi)[0][0]
split_ddf = obsvect_dates[i0 + 1]
crop_index, weight = crop_monitor(
ds_meta, ddi, split_ddf,
return_index=True,
return_weight=True,
keep_partial=True
)
obsvect.ysim[param.ypointer: param.ypointer + param.dim][crop_index] += \
np.asarray(data_sim.loc[:, "spec"]).astype(float).flatten() * weight
obsvect.dy[param.ypointer: param.ypointer + param.dim][crop_index] += \
np.asarray(data_sim.loc[:, "incr"]).astype(float).flatten() * weight
# Set increment to zero if not in observation vector
obsvect.dy[~obsvect.obsvect_mask] = 0
# Update the reference datastore
columns2update = [
('maindata', 'spec'),
('maindata', 'incr'),
('maindata', 'adj_out')
]
for c in columns2update:
if c not in datastore[tracer_id][ddi]:
continue
if c not in param.datastore:
param.datastore[c] = pd.NA
ind_column = param.datastore.columns.get_loc(c)
try:
param.datastore.iloc[crop_index, ind_column] = \
datastore[tracer_id][ddi].loc[:, c].values
except:
print(__file__)
import code
code.interact(local=dict(locals(), **globals()))