Source code for pycif.plugins.transforms.complex.isotopes.native2obsvect



[docs] def native2obsvect( transf, y0, mapper, mod_input, ddi, ddf, mode, runsubdir, workdir, **kwargs ): inputs = transf.parameters_in.names outputs = transf.parameters_out.names unit = transf.unit r_std = transf.parameters_in.standard iso_mass = transf.parameters_out.iso_mass spec_mass = transf.parameters_out.spec_mass if not mod_input == "obs": return y0 dfs = [y0.loc[y0["parameter"] == s.lower()] for s in outputs] mask_iso = dfs[0]["parameter_ref"] == inputs[0].lower() mask_tot = dfs[0]["parameter_ref"] == inputs[1].lower() isotopologue_iso = dfs[1].loc[mask_iso, "sim"] spec_ref_iso = dfs[0].loc[mask_iso, "sim"] isotopologue_tot = dfs[1].loc[mask_tot, "sim"] spec_ref_tot = dfs[0].loc[mask_tot, "sim"] # Saving forward simulations for later use by adjoint transf.fwd_data[ddi] = { "isotopologue_iso": isotopologue_iso, "spec_ref_iso": spec_ref_iso, "isotopologue_tot": isotopologue_tot, "spec_ref_tot": spec_ref_tot, } iso = isotopologue_iso / spec_ref_iso if unit == "volume": tot = isotopologue_tot + spec_ref_tot else: tot = ( spec_ref_tot / iso_mass[0] * spec_mass + isotopologue_tot / iso_mass[1] * spec_mass ) iso *= iso_mass[0] / iso_mass[1] iso /= r_std iso = (iso - 1) * 1000 # Filling the original datastore with correct values # Changing names as well ind_iso = dfs[0].loc[mask_iso, "indorig"] ind_tot = dfs[0].loc[mask_tot, "indorig"] dfout = y0.drop_duplicates(subset='indorig', keep='first') dfout.iloc[ind_iso, dfout.columns.get_loc("sim")] = iso dfout.iloc[ind_tot, dfout.columns.get_loc("sim")] = tot dfout.iloc[ind_iso, dfout.columns.get_loc("parameter")] = inputs[0].lower() dfout.iloc[ind_tot, dfout.columns.get_loc("parameter")] = inputs[1].lower() # Applying tangent-linear if mode == "tl": isotopologue_iso_tl = dfs[1].loc[mask_iso, "sim_tl"] spec_ref_iso_tl = dfs[0].loc[mask_iso, "sim_tl"] isotopologue_tot_tl = dfs[1].loc[mask_tot, "sim_tl"] spec_ref_tot_tl = dfs[0].loc[mask_tot, "sim_tl"] iso_tl = ( isotopologue_iso_tl / spec_ref_iso - isotopologue_iso / spec_ref_iso ** 2 * spec_ref_iso_tl ) if unit == "volume": tot_tl = isotopologue_tot_tl + spec_ref_tot_tl else: tot_tl = ( isotopologue_iso_tl * iso_mass[0] / spec_mass + spec_ref_tot_tl * iso_mass[1] / spec_mass ) iso_tl *= iso_mass[0] / iso_mass[1] iso_tl /= r_std / 1000 dfout.iloc[ind_iso, dfout.columns.get_loc("sim_tl")] = iso_tl dfout.iloc[ind_tot, dfout.columns.get_loc("sim_tl")] = tot_tl return dfout