Hyperiso 1.0.3
Modular flavour-physics calculations, Wilson coefficients and statistical inference
Loading...
Searching...
No Matches
ParamId.py
Go to the documentation of this file.
1"""Composite identifiers for model and nuisance parameters."""
2
3from pyhyperiso.phyperiso.pyhyperiso import common
4from pyhyperiso.core.Common.GeneralEnum import ParameterType
5from dataclasses import dataclass, field
6from typing import Optional, List, Union
7from pyhyperiso.core.Common.BlockName import BlockName
8from pyhyperiso.core.Common.LhaID import LhaID
9
10
11@dataclass
12class ParamId:
13 """Python wrapper around the C++ ``ParamId`` composite identifier.
14
15 A ``ParamId`` uniquely identifies a parameter in LHA/SLHA-like structures by:
16 - an optional semantic parameter type (``ParameterType``),
17 - a block name (``BlockName`` with alias support),
18 - an index or multi-index within that block (``LhaID``).
19
20 This mirrors the C++ struct:
21
22 - ``type`` is optional (can be unset / ``None``),
23 - ``block`` is a block identifier with aliases,
24 - ``code`` is an ``LhaID`` (single-part or multi-part).
25
26 Attributes:
27 type (Optional[ParameterType]): Optional high-level parameter category.
28 ``None`` means "unset" (equivalent to ``std::nullopt`` in C++).
29 block (Union[str, BlockName]): Block identifier. The dataclass field is
30 declared as ``str`` for convenience, but after initialization it is
31 normalized to a ``BlockName`` instance.
32 code (Union[LhaID, int, str, List[int]]): Parameter index / multi-index.
33 After initialization it is normalized to a ``LhaID`` instance.
34
35 Notes:
36 - The default/null ``ParamId`` corresponds to:
37 ``type=None``, ``block="NULL"``, ``code=0``.
38 - This class keeps an underlying C++ object in ``_cpp_obj``.
39 """
40
41 type: Optional[ParameterType] = None
42 block: str = "NULL"
43 code: Union[LhaID, int, str, List[int]] = field(default_factory=lambda: LhaID(0))
44 _cpp_obj: common.ParamId = field(init=False, repr=False)
45
46 def __post_init__(self):
47 """Build and normalize the underlying C++ ``ParamId`` after init.
48
49 This method:
50 1) Normalizes ``code`` to ``PyLhaID`` if needed.
51 2) Normalizes ``block`` to ``PyBlockName`` if needed.
52 3) Constructs the C++ ``ParamId`` depending on whether ``type`` is set
53 and whether the (block, code) pair corresponds to the default/null
54 sentinel.
55
56 Raises:
57 TypeError: If ``block`` or ``code`` cannot be converted to the expected
58 wrapper types.
59 """
60 if not isinstance(self.codecode, LhaID):
61 self.codecode = LhaID(self.codecode)
62
63 if not isinstance(self.blockblock, BlockName):
65
66 if self.typetype is not None:
67 self._cpp_obj_cpp_obj = common.ParamId(self.typetype.value, self.blockblock._cpp_obj, self.codecode._cpp_obj)
68 else:
69 if str(self.blockblock) == "NULL" and int(self.codecode) == 0:
70 self._cpp_obj_cpp_obj = common.ParamId()
71 else:
72 self._cpp_obj_cpp_obj = common.ParamId(self.blockblock._cpp_obj, self.codecode._cpp_obj)
73
74 self.typetype = ParameterType(self._cpp_obj_cpp_obj.type) if self._cpp_obj_cpp_obj.type is not None else None
75 self.blockblock = BlockName(self._cpp_obj_cpp_obj.block)
76 self.codecode = LhaID(self._cpp_obj_cpp_obj.code)
77
78 def set_parameter_type(self, param_type: ParameterType):
79 """Set or overwrite the parameter type.
80
81 Args:
82 param_type (ParameterType): New parameter type to assign.
83 """
84 self._cpp_obj_cpp_obj.set_parameter_type(param_type.value)
85 self.typetype = param_type
86
87 def to_dict(self):
88 """Serialize this identifier into a Python dictionary.
89
90 The output is intended for logging/debugging and lightweight serialization.
91
92 Returns:
93 dict: A mapping with keys:
94 - ``"type"``: type name as ``str`` or ``None`` if unset,
95 - ``"block"``: the current ``PyBlockName`` object,
96 - ``"code"``: canonical string representation of the ``LhaID``.
97
98 Notes:
99 If you need a JSON-serializable dict, you may want:
100 ``{"block": str(self.block)}`` instead of returning the object.
101 """
102 return {
103 "type": self.typetype.name if self.typetype else None,
104 "block": self.blockblock,
105 "code": self.codecode.to_string(),
106 }
107
108 @classmethod
109 def from_cpp(cls, cpp_obj: common.ParamId) -> "ParamId":
110 """Wrap an existing bound C++ ``ParamId`` instance.
111
112 Args:
113 cpp_obj (common.ParamId): C++ object coming from pybind.
114
115 Returns:
116 PyParamId: A Python wrapper around the provided C++ object.
117 """
118 instance = cls()
119 instance._cpp_obj = cpp_obj
120 instance.type = ParameterType(cpp_obj.type)
121 instance.block = BlockName(cpp_obj.block)
122 instance.code = LhaID(cpp_obj.code)
123 return instance
124
125 def to_cpp(self):
126 """Return the underlying bound C++ object.
127
128 Returns:
129 common.ParamId: The wrapped pybind11 C++ instance.
130 """
131 return self._cpp_obj_cpp_obj
132
133 def __repr__(self):
134 """Return a debug representation.
135
136 Returns:
137 str: Debug-style string including type, block and code.
138 """
139 return f"ParamId(type={self.type}, block='{self.block}', code={self.code})"
140
141 def __eq__(self, other):
142 if not isinstance(other, ParamId):
143 return NotImplemented
144 return (
145 self.typetype,
146 str(self.blockblock),
147 self.codecode.to_string(),
148 ) == (
149 other.type,
150 str(other.block),
151 other.code.to_string(),
152 )
153
154 def __hash__(self):
155 return hash(
156 (
157 self.typetype,
158 str(self.blockblock),
159 self.codecode.to_string(),
160 )
161 )
std::string to_string(const LhaID &id)
Convenience stringification for LhaID.
Definition SourceView.cpp:9
set_parameter_type(self, ParameterType param_type)
Definition ParamId.py:78
"ParamId" from_cpp(cls, common.ParamId cpp_obj)
Definition ParamId.py:109