Source code for pycif.plugins.models.lmdz_ico.io.outputs.read_sim

from __future__ import annotations

import copy
import datetime
from os import PathLike
from pathlib import Path
from typing import Any, Literal

import numpy as np
import pandas as pd
import xarray as xr

from ......utils.check.errclass import CifFileNotFoundError
from ......utils.hdf5 import _hdf5_lock


[docs] def read_sim( self, data2dump: dict[tuple[str, str], dict[str | datetime.datetime, Any]], ddi: datetime.datetime, runsubdir: str | PathLike, mode: Literal["fwd", "tl", "adj"], ) -> dict[tuple[str, str], Any]: """Extract simulated concentrations""" runsubdir = Path(runsubdir) obs_file = runsubdir / "obs.nc" sim_file = runsubdir / "obs_out.nc" if sim_file.exists(): # Read simulation file (should not be empty) with _hdf5_lock: with xr.open_dataset(sim_file) as ds: sim = ds.to_dataframe() # Read observations, if simulation file is present, observation file should also with _hdf5_lock: with xr.open_dataset(obs_file) as ds: tracer_index = ds["itrac"].values - 1 elif not obs_file.exists(): # Empty dataframe sim = pd.DataFrame( columns=[ "spec", "incr", "pressure", "dpressure", "hlay", "airm", ] # type: ignore ) tracer_index = np.zeros(0, dtype=int) else: # Simulation file, should be present if observation file is raise CifFileNotFoundError( f"LMDZ did not produce a obs_out.nc file in '{runsubdir}'." ) active_species = list(self.chemistry.active_species) tracer_name = pd.Series(active_species).iloc[tracer_index].values dataout = {} for trid in data2dump: component, spec = trid dataloc = data2dump[trid][ddi] if len(dataloc) == 0: continue # Putting values to the local data store spec_str = spec.replace("__sample#", "_") mask = tracer_name == spec_str sim_spec = sim.loc[mask] # Redistributing extracting data into correct rows of the dataframe chunk_indexes = self.chunk_indexes[ddi][component][spec_str] dataavg = sim_spec.loc[chunk_indexes] # Put values in dataloc dataloc.loc[:, ("maindata", "spec")] = dataavg.loc[:, "spec"].values if mode == "tl": dataloc.loc[:, ("maindata", "incr")] = dataavg.loc[:, "incr"].values # Put simulated value into correct column # Different case if concs, or other parameters such as pressure # Put pressure and other auxiliary data into spec column for later # interpolation if trid[0] != "concs": # Column name col = trid[0] dataloc.loc[:, ("maindata", "spec")] = copy.deepcopy( dataavg.loc[:, col].values ) dataloc.loc[:, ("maindata", "incr")] = 0.0 dataout[trid] = copy.deepcopy(dataloc) return dataout