Hyperiso 1.0.3
Modular flavour-physics calculations, Wilson coefficients and statistical inference
Loading...
Searching...
No Matches
ExperimentObs.py
Go to the documentation of this file.
1"""Experiment-scoped observable identifiers for statistical selections."""
2
3from __future__ import annotations
4
5from dataclasses import dataclass, field
6
7from pyhyperiso.phyperiso.pyhyperiso import common
8from pyhyperiso.core.Common.BinnedObservableId import BinnedObservableId
9
10
11@dataclass(frozen=True)
13 """Identify one experimental measurement by experiment and observable bin.
14
15 Args:
16 experiment: Experiment label as stored in the experimental database.
17 obs: Binned observable identifier associated with the measurement.
18
19 Attributes:
20 experiment: Experiment label.
21 obs: Python :class:`BinnedObservableId` wrapper.
22
23 Examples:
24 Build an exact selection entry for a CMS measurement::
25
26 selection = ExperimentObs(
27 "CMS",
28 BinnedObservableId(Observables.F_L_B0__KSTAR0_MU_MU, (1.1, 2.0)),
29 )
30 """
31
32 experiment: str
33 obs: BinnedObservableId
34 _cpp_obj: common.ExperimentObs = field(init=False, repr=False, compare=False)
35
36 def __post_init__(self) -> None:
37 """Validate fields and construct the bound C++ value object."""
38 if not isinstance(self.experimentexperiment, str):
39 raise TypeError(f"experiment must be str, received {type(self.experiment)!r}.")
40 if not self.experimentexperiment:
41 raise ValueError("experiment must not be empty.")
42 if not isinstance(self.obsobs, BinnedObservableId):
43 raise TypeError(
44 f"obs must be a Python BinnedObservableId, received {type(self.obs)!r}."
45 )
46
47 object.__setattr__(
48 self,
49 "_cpp_obj",
50 common.ExperimentObs(self.experimentexperiment, self.obsobs.to_cpp()),
51 )
52
53 @classmethod
54 def from_cpp(cls, cpp_obj: common.ExperimentObs) -> "ExperimentObs":
55 """Create a Python wrapper from a bound C++ ``ExperimentObs``."""
56 inst = cls.__new__(cls)
57 object.__setattr__(inst, "experiment", str(cpp_obj.experiment))
58 object.__setattr__(inst, "obs", BinnedObservableId.from_cpp(cpp_obj.obs))
59 object.__setattr__(inst, "_cpp_obj", cpp_obj)
60 return inst
61
62 def to_cpp(self) -> common.ExperimentObs:
63 """Return the bound C++ value object."""
64 return self._cpp_obj
65
66 def __hash__(self) -> int:
67 """Hash both the experiment label and binned observable identifier."""
68 return hash((self.experimentexperiment, self.obsobs))
69
70 def __str__(self) -> str:
71 """Return a compact human-readable identifier."""
72 return f"{self.experiment} :: {self.obs}"
73
74 def __repr__(self) -> str:
75 """Return an unambiguous debugging representation."""
76 return f"ExperimentObs(experiment={self.experiment!r}, obs={self.obs!r})"
77
78
79__all__ = ["ExperimentObs"]
"ExperimentObs" from_cpp(cls, common.ExperimentObs cpp_obj)
common.ExperimentObs to_cpp(self)