Hyperiso 1.0.3
Modular flavour-physics calculations, Wilson coefficients and statistical inference
Loading...
Searching...
No Matches
decay_ids.hpp
Go to the documentation of this file.
1#ifndef DECAY_IDS_H
2#define DECAY_IDS_H
3
4#include <algorithm>
5#include <mutex>
6#include <optional>
7#include <stdexcept>
8#include <string>
9#include <string_view>
10#include <unordered_map>
11#include <unordered_set>
12#include <utility>
13#include <vector>
14
15#include "generic_mapper.h"
16#include "Map.h"
17#include "LhaID.h"
18#include "observable_ids.hpp"
19
36struct DecayTag {};
37
40
50inline const std::map<Decays, LhaID>& decay_external_mapping() {
51 static const std::map<Decays, LhaID> empty{};
52 return empty;
53}
54
63 std::string canonical;
64 std::vector<std::string> aliases{};
65 std::optional<LhaID> ext = std::nullopt;
66};
67
81 DecayTag,
82 Decays,
83 LhaID,
84 std::hash<LhaID>,
85 decays_mapping,
86 decay_external_mapping
87 >
88{
89public:
92 Decays,
93 LhaID,
94 std::hash<LhaID>,
97 >;
98
100 using Base::id_of;
101 using Base::enum_elt;
102 using Base::str;
103 using Base::to_id;
104 using Base::enum_of;
105 using Base::list_all;
107 using Base::external_of;
108 using Base::set_external;
109
117 static bool register_custom(std::string canonical,
118 std::vector<std::string> aliases = {},
119 std::optional<LhaID> ext = std::nullopt) = delete;
120
129 static std::vector<Observables> get_observables(Decays d) {
130 return decay_observable_mapping().at(d);
131 }
132
139 static std::vector<ObservableId> get_observable_ids(Decays d) {
140 std::vector<ObservableId> out;
141 const auto& obs_enums = decay_observable_mapping().at(d);
142 out.reserve(obs_enums.size());
143
144 for (auto obs : obs_enums) {
145 out.push_back(ObservableMapper::to_id(obs));
146 }
147
148 return out;
149 }
150
165 static std::vector<ObservableId> get_observables(const DecayId& d) {
166 std::vector<ObservableId> out;
167 std::unordered_set<ObservableId> seen;
168
169 auto add = [&](const ObservableId& obs) {
170 if (seen.insert(obs).second) {
171 out.push_back(obs);
172 }
173 };
174
175 for (const auto& obs : DecayGraph::instance().observables_of(d)) {
176 add(obs);
177 }
178
179 if (auto builtin = enum_of(d); builtin) {
180 for (const auto& obs : get_observable_ids(*builtin)) {
181 add(obs);
182 }
183 }
184
185 if (out.empty()) {
186 throw std::runtime_error("Decay has no observable: " + d.str());
187 }
188
189 return out;
190 }
191
198 static std::vector<ObservableId> get_observables(std::string_view d) {
199 return get_observables(id_of(d));
200 }
201
210 static bool has_observables(const DecayId& d) {
212 return true;
213 }
214
215 if (auto builtin = enum_of(d); builtin) {
216 auto it = decay_observable_mapping().find(*builtin);
217 return it != decay_observable_mapping().end() && !it->second.empty();
218 }
219
220 return false;
221 }
222
230 static void require_observables(const DecayId& d) {
231 if (!has_observables(d)) {
232 throw std::runtime_error("Decay must have at least one observable: " + d.str());
233 }
234 }
235
256 static bool register_custom_with_observables(std::string canonical,
257 std::vector<std::string> aliases,
258 std::vector<CustomObservableSpec> observables)
259 {
260 if (observables.empty()) {
261 throw std::invalid_argument(
262 "Cannot register custom decay '" + canonical + "' without observables"
263 );
264 }
265
266 const bool ok = Base::register_custom(canonical, std::move(aliases), std::nullopt);
267 if (!ok) {
268 return false;
269 }
270
271 const DecayId decay_id = Base::id_of(canonical);
272
273 for (auto& obs : observables) {
275 obs.canonical,
276 std::move(obs.aliases),
277 std::move(obs.ext),
278 decay_id
279 );
280 }
281
282 return true;
283 }
284
294 for (const auto& [d, vec] : decay_observable_mapping()) {
295 if (std::find(vec.begin(), vec.end(), obs) != vec.end()) {
296 return d;
297 }
298 }
299 throw std::runtime_error("Observable not mapped to any decay");
300 }
301
307 inline static const std::unordered_map<ObservableId, DecayId>& observable_to_decay() {
308 static std::unordered_map<ObservableId, DecayId> cache;
309 static std::once_flag init;
310
311 std::call_once(init, [] {
312 for (const auto& [decayEnum, vec] : decay_observable_mapping()) {
313 DecayId did = DecayMapper::to_id(decayEnum);
314 for (auto o : vec) {
315 cache.emplace(ObservableMapper::to_id(o), did);
316 }
317 }
318 });
319
320 return cache;
321 }
322
333 inline static std::optional<DecayId> get_decay_id(const ObservableId& obs) {
334 if (auto d = DecayGraph::instance().parent_of(obs); d) {
335 return d;
336 }
337
338 const auto& m = observable_to_decay();
339 if (auto it = m.find(obs); it != m.end()) {
340 return it->second;
341 }
342
343 return std::nullopt;
344 }
345
349 inline static std::optional<DecayId> get_decay_id(Observables obs) {
351 }
352
361 inline static DecayId get_decay_id_or_throw(const ObservableId& obs) {
362 auto d = get_decay_id(obs);
363 if (!d) {
364 throw std::runtime_error("Observable not mapped to any decay: " + obs.str());
365 }
366 return *d;
367 }
368};
369
370#endif // DECAY_IDS_H
Observables
Definition GeneralEnum.h:4
Decays
Lightweight representation of LHAPDF / SLHA-style identifiers.
const std::map< Decays, std::string > & decays_mapping()
Returns the mapping between Decays and their string names.
Definition Map.cpp:1252
const std::map< Decays, std::vector< Observables > > & decay_observable_mapping()
Returns the mapping between Decays and the list of Observables associated with each decay channel.
Definition Map.cpp:1275
Static mappings between enum classes and string (or FLHA) identifiers.
static DecayGraph & instance()
Return the unique global graph instance.
std::vector< ObservableId > observables_of(const DecayId &decay) const
Return all dynamically linked observables for a decay.
Mapper for decay names, dynamic ids and observable membership.
Definition decay_ids.hpp:88
static std::vector< ObservableId > get_observables(std::string_view d)
Dynamic lookup of observables attached to a decay resolved by name.
static DecayId get_decay_id_or_throw(const ObservableId &obs)
Throwing variant of get_decay_id().
static bool register_custom_with_observables(std::string canonical, std::vector< std::string > aliases, std::vector< CustomObservableSpec > observables)
Register a custom decay and its custom observables in one call.
static Decays get_decay(Observables obs)
Legacy static lookup of the builtin decay owning a builtin observable.
static std::optional< DecayId > get_decay_id(const ObservableId &obs)
Return the parent decay id of an observable id.
static void require_observables(const DecayId &d)
Throw if a decay has no observable.
static const std::unordered_map< ObservableId, DecayId > & observable_to_decay()
Static cache mapping builtin observable ids to builtin decay ids.
static std::vector< ObservableId > get_observable_ids(Decays d)
Convert builtin observables of a builtin decay to dynamic ids.
static bool has_observables(const DecayId &d)
Test whether a decay has at least one observable.
static std::optional< DecayId > get_decay_id(Observables obs)
Return the parent decay id of a builtin observable enum.
static std::vector< ObservableId > get_observables(const DecayId &d)
Dynamic lookup of observables attached to a decay id.
static bool register_custom(std::string canonical, std::vector< std::string > aliases={}, std::optional< LhaID > ext=std::nullopt)=delete
Disabled low-level decay registration.
static std::vector< Observables > get_observables(Decays d)
Legacy static lookup of builtin observables for a builtin decay.
Generic enum↔string mapper with external keys and dynamic aliases.
static bool register_custom(std::string canonical, std::vector< std::string > aliases={}, std::optional< LhaID > ext=std::nullopt)
Registers a custom entry with optional external key.
static std::vector< IdOf< DecayTag > > list_all()
Lists all distinct identifiers currently registered.
static std::optional< LhaID > external_of(const IdOf< DecayTag > &id)
Returns the external key associated with a given identifier.
static std::optional< Decays > enum_of(const IdOf< DecayTag > &id)
Attempts to recover the enum value associated with an identifier.
static IdOf< DecayTag > enum_elt(std::string_view s)
Alias for id_of(), kept for compatibility.
static std::optional< IdOf< DecayTag > > from_external(const LhaID &k)
Resolves an external key into an identifier.
static IdOf< DecayTag > to_id(Decays e)
Converts an enum value to an IdOf<Tag>.
static bool set_external(const IdOf< DecayTag > &id, const LhaID &k)
Sets or updates the external key of an existing identifier.
static IdOf< DecayTag > id_of(std::string_view s)
Resolves a string into an IdOf<Tag> via the registry.
static std::string str(const IdOf< DecayTag > &id)
Returns the string representation of an identifier.
static bool register_custom(const std::string &canonical, std::vector< std::string > aliases, std::optional< LhaID > ext, const DecayId &parent_decay)
Register a custom observable and attach it to a parent decay.
const std::string & str() const
Returns the underlying string.
const std::map< Decays, LhaID > & decay_external_mapping()
Placeholder external mapping for decays.
Definition decay_ids.hpp:50
Generic enum↔string (and optional external key) mappers built on DynamicRegistry.
Mapper for builtin and runtime observable identifiers.
Small value object used to register a custom decay with observables.
Definition decay_ids.hpp:62
std::vector< std::string > aliases
Optional aliases.
Definition decay_ids.hpp:64
std::optional< LhaID > ext
Optional FLHA id.
Definition decay_ids.hpp:65
std::string canonical
Canonical observable name.
Definition decay_ids.hpp:63
Tag type for decay identifiers.
Definition decay_ids.hpp:36
Represents an identifier of a LHA element, possibly containing several sub-ids.
Definition LhaID.h:56