openghg_inversions.experimental.ramsden2022.model#

Modern PyMC implementation of the Ramsden et al. (2022) two-gas model.

The implementation is deliberately prepared-input first. Each gas is supplied as a canonical RHIME-style xarray.Dataset, normally obtained from a RhimePreparedInputs.inv_inputs object. Data retrieval and postprocessing remain outside this historical comparison module.

For primary-gas sector s with state x_s the forward models are

mu_primary = sum_s(H_primary,s @ x_s)

and, for sectors that emit the tracer,

mu_tracer = sum_s(H_tracer,s @ (R_s * x_s)).

The two gases may have different sites, timestamps, and observation counts. Their conditional likelihoods are independent and use the paper’s absolute model-error definition, sqrt(measurement_error**2 + sigma**2).

Use build_ramsden_model() to construct the graph without sampling and run_ramsden_from_prepared_inputs() to sample it. Coupled primary/tracer sensitivities must have exactly matching labelled state coordinates. A ratio may be applied directly to a ratio-free tracer sensitivity, or interpreted as a multiplier when the sensitivity already includes an explicit reference ratio. Boundary states are optional and independent by gas. The caller is responsible for consistent units; this module performs no retrieval, conversion, or postprocessing.

class openghg_inversions.experimental.ramsden2022.model.RamsdenChannelSpec(species: str, observation_units: str, sigma_prior: dict[str, Any], sigma_per_site: bool = True, sigma_frequency: str | None = None, sigma_frequency_anchor: str | datetime | datetime64 | Timestamp | None = None, use_bc: bool = False, bc_prior: dict[str, Any] | None = None)#

Bases: object

Likelihood and boundary settings for one observed gas.

Parameters:
  • species – Gas name used to namespace model variables.

  • observation_units – Units shared by observations, measurement errors, minimum errors, forward-model outputs, and the model-error prior. Supported dataset unit attributes are checked by mol/mol scale; values are not converted.

  • sigma_prior – PyMC prior mapping accepted by parse_prior() for absolute model error. The prior is expanded by site and period, not multiplied by the modelled enhancement.

  • sigma_per_site – Whether model error is independent by observation site.

  • sigma_frequency – Optional pandas-compatible frequency for model-error periods.

  • sigma_frequency_anchor – Optional anchor for fixed-duration periods.

  • use_bc – Whether this channel has an independent boundary component.

  • bc_prior – Prior mapping for the state that scales this channel’s H_bc design.

bc_prior: dict[str, Any] | None = None#
observation_units: str#
sigma_frequency: str | None = None#
sigma_frequency_anchor: str | datetime | datetime64 | Timestamp | None = None#
sigma_per_site: bool = True#
sigma_prior: dict[str, Any]#
species: str#
use_bc: bool = False#
class openghg_inversions.experimental.ramsden2022.model.RamsdenModelSpec(primary: RamsdenChannelSpec, tracer: RamsdenChannelSpec, sectors: tuple[RamsdenSectorSpec, ...])#

Bases: object

Complete specification for the historical two-gas model.

Parameters:
  • primary – Primary-gas likelihood settings.

  • tracer – Tracer-gas likelihood settings.

  • sectors – Ordered primary sectors. At least one sector must also emit the tracer. Sanitized channel names must be distinct, and sanitized sector names must be non-empty and unique.

primary: RamsdenChannelSpec#
sectors: tuple[RamsdenSectorSpec, ...]#
tracer: RamsdenChannelSpec#
class openghg_inversions.experimental.ramsden2022.model.RamsdenPreparedInputs(primary: Dataset, tracer: Dataset, tracer_design_reference_ratios: Mapping[str, float | None], primary_basis_functions: FluxWeightedBasis | None = None, tracer_basis_functions: FluxWeightedBasis | None = None)#

Bases: object

Canonical primary-gas and tracer inputs for one joint inversion.

Each dataset requires H, mf, mf_error, min_error, and site_indicator on nmeasure; H_bc is required when that channel’s boundary component is enabled. Observation axes may differ. Coupled sector designs must have exactly matching labelled state coordinates and, for positional numeric labels, retained basis objects.

Parameters:
  • primary – Canonical RHIME-style dataset for the primary gas.

  • tracer – Canonical RHIME-style dataset for the tracer gas. Its H matrix must use the same labelled state layout as primary.H.

  • tracer_design_reference_ratios – Reference ratio already included in each tracer H source, keyed by tracer source label. Use None for a ratio-free design. These declarations are checked against each sector specification to prevent applying a ratio twice or omitting it.

  • primary_basis_functions – Retained basis used to construct primary.H. Required together with tracer_basis_functions when state labels are positional numbers.

  • tracer_basis_functions – Retained basis used to construct tracer.H. Its source-specific spatial map must equal the primary map for every coupled sector.

primary: Dataset#
primary_basis_functions: FluxWeightedBasis | None = None#
tracer: Dataset#
tracer_basis_functions: FluxWeightedBasis | None = None#
tracer_design_reference_ratios: Mapping[str, float | None]#
class openghg_inversions.experimental.ramsden2022.model.RamsdenResult(prepared_inputs: RamsdenPreparedInputs, model_spec: RamsdenModelSpec, model: Model, idata: InferenceData, sampler: RhimeSampler)#

Bases: object

Result returned by run_ramsden_from_prepared_inputs().

Parameters:
  • prepared_inputs – Labelled inputs consumed by the model.

  • model_spec – Historical model specification.

  • model – Built PyMC model.

  • idata – Joint inference data preserving shared-state/ratio covariance and the two namespaced likelihood and predictive variables.

  • sampler – Modern RHIME sampler used for the run.

idata: InferenceData#
model: Model#
model_spec: RamsdenModelSpec#
prepared_inputs: RamsdenPreparedInputs#
sampler: RhimeSampler#
class openghg_inversions.experimental.ramsden2022.model.RamsdenSectorSpec(name: str, primary_flux_source: str, x_prior: dict[str, Any], tracer_flux_source: str | None = None, ratio_prior: dict[str, Any] | None = None, fixed_ratio: float | None = None, ratio_resolution: Literal['scalar', 'spatial'] = 'spatial', reference_ratio: float | None = None)#

Bases: object

Shared primary-gas state and optional tracer coupling for one sector.

Parameters:
  • name – Semantic sector name.

  • primary_flux_source – Source-provenance label selected from primary.H.

  • x_prior – Prior mapping for the primary-gas scaling state. It must broadcast to the selected state dimension.

  • tracer_flux_source – Source-provenance label selected from tracer.H. None means this sector contributes no tracer, as for the non-fossil methane sector in Ramsden et al. (2022).

  • ratio_prior – Prior for a sampled direct emission ratio or historical ratio multiplier. Exactly one of ratio_prior and fixed_ratio is required for a tracer-emitting sector. The distribution must have non-negative support.

  • fixed_ratio – Fixed direct emission ratio or historical multiplier.

  • ratio_resolution"spatial" creates one sampled/fixed ratio value per state element, so its prior must broadcast to that state; "scalar" shares one value across the sector.

  • reference_ratioNone selects the paper’s direct-ratio contract: tracer.H must be ratio-free and the ratio parameter is applied directly. A positive value selects historical compatibility: tracer.H must already include this reference ratio, the sampled parameter is a dimensionless multiplier, and emission_ratio = reference_ratio * ratio_multiplier is exposed for interpretation. Direct and reference ratios are dimensionless molar ratios (moles tracer per mole primary).

fixed_ratio: float | None = None#
name: str#
primary_flux_source: str#
ratio_prior: dict[str, Any] | None = None#
ratio_resolution: Literal['scalar', 'spatial'] = 'spatial'#
reference_ratio: float | None = None#
tracer_flux_source: str | None = None#
x_prior: dict[str, Any]#
openghg_inversions.experimental.ramsden2022.model.build_ramsden_model(prepared_inputs: RamsdenPreparedInputs, model_spec: RamsdenModelSpec) Model#

Build the historical Ramsden methane/ethane model with modern PyMC.

Parameters:
  • prepared_inputs – Two canonical gas datasets. Each requires H, mf, mf_error, min_error, and site_indicator on nmeasure; H_bc is required for enabled boundary states. Observation coordinates may differ, but coupled sector state coordinates must match exactly.

  • model_spec – Shared-state, ratio, likelihood, unit, and boundary metadata. Direct ratios require ratio-free tracer sensitivities; reference-ratio mode requires tracer sensitivities that already include the declared reference ratio.

Returns:

Built PyMC model ready for RhimeSampler.

Raises:

ValueError – If model metadata, required input variables, source labels, or shared state coordinates are invalid.

Notes

This function builds a PyMC graph only. It performs no data retrieval, sampling, unit conversion, or postprocessing. Observation, error, sigma-prior, and forward-model values must already use each channel’s declared observation_units.

openghg_inversions.experimental.ramsden2022.model.run_ramsden_from_prepared_inputs(*, prepared_inputs: RamsdenPreparedInputs, model_spec: RamsdenModelSpec, sampler: RhimeSampler | None = None) RamsdenResult#

Build and sample a historical two-gas model from canonical inputs.

Parameters:
  • prepared_inputs – Canonical primary and tracer datasets.

  • model_spec – Historical model specification.

  • sampler – Modern RHIME sampling configuration controlling seeds, chains, draws, and predictive output. When omitted, the standard sampler is used with both namespaced gas observations included in posterior predictive sampling.

Returns:

Joint result containing the built model and labelled inference data.

Raises:

ValueError – If model metadata or prepared inputs are invalid.

Notes

This function samples the model and may run multiple chains. It does not retrieve data, convert units, or write postprocessed products. Sampling exceptions raised by RhimeSampler are propagated.