1"""Python wrappers for lambda-backed custom decays and observables.
3The C++ binding exposes the low-level ``LambdaDecay`` callback context. This
4module keeps the public Python API wrapper-only: user callbacks receive
5``LambdaDecayContext`` and normal Python ids/enums instead of raw pybind objects.
8from __future__
import annotations
10from dataclasses
import dataclass, field
11from typing
import Callable, Sequence, Set
13from pyhyperiso.phyperiso.pyhyperiso
import observable
as _obs
21from pyhyperiso.core.Math.Scalar
import Scalar
25 """Return the bound C++ enum stored in the Python enum wrapper.
27 The public wrappers use Python ``Enum`` objects whose ``.value`` is the
28 pybind enum. If a caller already passes the bound enum, it is returned as-is.
30 return getattr(value,
"value", value)
34 """Convert a C++/Python observable id to the Python wrapper id."""
35 if isinstance(obs_id, ObservableId):
41 """Wrapper around the C++ ``LambdaDecay`` callback context.
43 User-defined observable callbacks receive this object. It hides the raw
44 pybind context and accepts the normal Python wrappers for Wilson ids,
51 def get_M(self, group, coeff, order: QCDOrder, contribution: ContributionType) -> Scalar:
52 """Return a matching coefficient as ``Scalar``."""
53 return Scalar.from_cpp(
62 def get_FM(self, group, coeff, order: QCDOrder, contribution: ContributionType) -> Scalar:
63 """Return a full matching coefficient as ``Scalar``."""
64 return Scalar.from_cpp(
73 def get_R(self, group, coeff, order: QCDOrder, contribution: ContributionType) -> Scalar:
74 """Return a running coefficient as ``Scalar``."""
75 return Scalar.from_cpp(
84 def get_FR(self, group, coeff, order: QCDOrder, contribution: ContributionType) -> Scalar:
85 """Return a full running coefficient as ``Scalar``."""
86 return Scalar.from_cpp(
95 def get_sm_param(self, pid: ParamId, data_type: DataType = DataType.VALUE) -> Scalar:
96 """Return an SM parameter as ``Scalar``."""
99 def get_flavor_param(self, pid: ParamId, data_type: DataType = DataType.VALUE) -> Scalar:
100 """Return a FLAVOR parameter as ``Scalar``."""
104 """Return the currently requested bins."""
109 """Runtime observable computed by a Python callable.
112 canonical: Canonical observable name registered in the mapper layer.
113 compute: Callback receiving ``(ctx, observable_id)`` for scalar
114 observables, or ``(ctx, bin, observable_id)`` for binned observables.
115 aliases: Optional aliases accepted by ``ObservableMapper.id_of``.
116 flha: Optional FLHA id for experimental input/output conventions.
117 Required when the observable is passed to ``StatisticInterface``.
118 dependencies: Parameter dependencies visible to Statistic.
119 binned: Whether ``compute`` should be called with the current bin.
126 aliases: Sequence[str] |
None =
None,
127 flha: LhaID |
None =
None,
128 dependencies: Sequence[ParamId] | Set[ParamId] |
None =
None,
129 binned: bool =
False,
133 def wrapped_compute(ctx, bin_range, obs_id):
136 factory = _obs.LambdaObservableConfig.binned_scalar
139 def wrapped_compute(ctx, obs_id):
142 factory = _obs.LambdaObservableConfig.scalar
144 self.
_cpp_obj = factory(canonical, wrapped_compute)
145 self.
_cpp_obj.aliases = list(aliases
or [])
146 self.
_cpp_obj.flha =
None if flha
is None else flha.to_cpp()
148 p.to_cpp()
if isinstance(p, ParamId)
else p
for p
in (dependencies
or [])
156 aliases: Sequence[str] |
None =
None,
157 flha: LhaID |
None =
None,
158 dependencies: Sequence[ParamId] | Set[ParamId] |
None =
None,
159 ) ->
"LambdaObservableConfig":
160 """Create an unbinned scalar observable.
162 ``compute`` receives ``(ctx, observable_id)`` and can return ``float`` or
163 any object implementing ``__float__`` such as ``Scalar``.
166 canonical, compute, aliases=aliases, flha=flha, dependencies=dependencies, binned=
False
174 aliases: Sequence[str] |
None =
None,
175 flha: LhaID |
None =
None,
176 dependencies: Sequence[ParamId] | Set[ParamId] |
None =
None,
177 ) ->
"LambdaObservableConfig":
178 """Create a binned scalar observable.
180 ``compute`` receives ``(ctx, (q2_min, q2_max), observable_id)`` and can
181 return ``float`` or any object implementing ``__float__``.
184 canonical, compute, aliases=aliases, flha=flha, dependencies=dependencies, binned=
True
188 """Return the bound C++ ``LambdaObservableConfig``."""
194 """Runtime decay backed by Python observable lambdas.
196 This config is the Python counterpart of C++ ``LambdaDecayConfig``. It can
197 declare builtin Wilson groups, lambda-backed custom Wilson groups and one or
198 more custom observables. Declared dependencies are propagated to Statistic.
202 observables: Sequence[LambdaObservableConfig]
203 aliases: Sequence[str] = field(default_factory=list)
204 matching_scale: float = 81.0
205 hadronic_scale: float = 4.8
206 order: QCDOrder = QCDOrder.LO
207 max_order: QCDOrder = QCDOrder.NNLO
208 wilson_groups: Sequence[WGroupId | str] = field(default_factory=list)
209 custom_wilson_groups: Sequence[CustomWilsonGroupConfig] = field(default_factory=list)
210 propagate_custom_wilson_dependencies: bool =
True
213 """Convert to the bound C++ ``LambdaDecayConfig``."""
214 cpp = _obs.LambdaDecayConfig()
216 cpp.aliases = list(self.
aliases)
221 cpp.wilson_groups = {
225 cpp.custom_wilson_groups = [
226 g.to_cpp()
if isinstance(g, CustomWilsonGroupConfig)
else g
230 o.to_cpp()
if isinstance(o, LambdaObservableConfig)
else o
for o
in self.
observables
236__all__ = [
"LambdaObservableConfig",
"LambdaDecayConfig",
"LambdaDecayContext"]
static IdOf< WGroupTag > id_of(std::string_view s)
Resolves a string into an IdOf<Tag> via the registry.
bool propagate_custom_wilson_dependencies
Sequence custom_wilson_groups
Scalar get_FM(self, group, coeff, QCDOrder order, ContributionType contribution)
Scalar get_R(self, group, coeff, QCDOrder order, ContributionType contribution)
Scalar get_M(self, group, coeff, QCDOrder order, ContributionType contribution)
Scalar get_flavor_param(self, ParamId pid, DataType data_type=DataType.VALUE)
Scalar get_FR(self, group, coeff, QCDOrder order, ContributionType contribution)
Scalar get_sm_param(self, ParamId pid, DataType data_type=DataType.VALUE)
"LambdaObservableConfig" binned_scalar(cls, str canonical, Callable compute, Sequence[str]|None aliases=None, LhaID|None flha=None, Sequence[ParamId]|Set[ParamId]|None dependencies=None)
"LambdaObservableConfig" scalar(cls, str canonical, Callable compute, Sequence[str]|None aliases=None, LhaID|None flha=None, Sequence[ParamId]|Set[ParamId]|None dependencies=None)
__init__(self, str canonical, Callable compute, Sequence[str]|None aliases=None, LhaID|None flha=None, Sequence[ParamId]|Set[ParamId]|None dependencies=None, bool binned=False)
ObservableId _to_observable_id(obs_id)