8 if (init_default_decays) {
39 auto dec_it = decays.find(dec_id);
40 if (dec_it == decays.end()) {
42 "is attached to decay", dec_id.
str(),
43 "but this decay is not registered in ObsManager.");
46 if (dec_it->second->is_observable_binned(
id)) {
51 ". Use add_observable(BinnedObservableId, ...) or add_observables(decay, ..., bin)."
55 dec_it->second->set_order(order);
57 auto obs_ptr = std::make_shared<Observable>(
id, dec_it->second, obs_port_conf.
iobspp_sm);
58 obss.emplace(
id, obs_ptr);
69 return add_obs(obs_id, order, add_deps);
77 auto dec_it = this->decays.find(decay);
78 if (dec_it == this->decays.end()) {
79 LOG_ERROR(
"KeyError",
"Decay", decay.
str(),
"is not registered in ObsManager.");
81 return dec_it->second->is_binned();
90 auto dec_it = this->decays.find(dec_id);
91 if (dec_it == this->decays.end()) {
93 "is attached to decay", dec_id.
str(),
94 "but this decay is not registered in ObsManager.");
96 return dec_it->second->is_observable_binned(obs);
108 "Adding binned observable",
122 auto dec_it = this->decays.find(dec_id);
123 if (dec_it == this->decays.end()) {
128 "not present in ObsManager for observable",
133 if (!dec_it->second->is_observable_binned(
id.s)) {
136 "Observable", obs_name,
138 ". Use add_observable(ObservableId, ...) or add_observables(decay, ...)."
142 dec_it->second->set_order(order);
144 if (!this->obss.contains(
id.s)) {
145 auto obs_ptr = std::make_shared<Observable>(
151 obss.emplace(
id.s, obs_ptr);
158 dec_it->second->add_bin(
id.p);
161 "Successfully added bin [",
176 id = ensure_present(
id,
false);
180 if (dec_id.has_value() && active_decay.has_value() && active_decay.value() == dec_id.value()) {
181 bool still_used =
false;
182 for (
const auto& [obs_id, _] : obss) {
184 if (other_dec.has_value() && other_dec.value() == dec_id.value()) {
190 auto dec_it = decays.find(dec_id.value());
191 if (dec_it != decays.end()) {
192 dec_it->second->disable();
194 active_decay.reset();
203 return obss.at(ensure_present(
id))->compute();
216 "does not accept q² bins. Use compute_observable(ObservableId) instead.");
221 for (
auto result : results) {
222 if (result.bin.value_or(std::pair<double, double>({0.,0.})) ==
id.p) {
231 std::map<ObservableId, std::vector<ObservableValue>> all_ests;
232 for (
auto &[k, k_ptr] : obss) {
233 all_ests.emplace(k, k_ptr->compute());
239 ptr->bind_wilson_builder(this->obs_port_conf.
iobswb);
241 this->decays[id] = std::move(ptr);
259 obss.at(ensure_present(
id))->add_dependence(param);
269 std::unordered_set<ParamId> accepted;
272 for (
auto &p : params) {
280 obss.at(ensure_present(
id))->add_dependences(std::move(accepted));
293 obss.at(ensure_present(
id))->add_dependences(allowed);
294 }
catch (
const std::out_of_range&) {
296 "- adding it without automatic dependencies. Use add_obs_deps(...) "
297 "or LambdaObservableConfig::dependencies for runtime observables.");
302 if (obss.contains(
id)) {
303 const auto& attached = obss.at(
id)->get_dependences();
304 if (!attached.empty()) {
311 }
catch (
const std::out_of_range&) {
313 "- returning an empty dependency set.");
319 std::vector<BinnedObservableId> ids;
320 for (
const auto& [oid, _] : this->obss) {
322 auto decay = this->decays.at(dec_id);
323 auto bins = decay->get_bins();
324 if (!decay->is_observable_binned(oid) || !bins.has_value()) {
325 ids.emplace_back(oid);
328 for (
auto bin : bins.value())
329 ids.emplace_back(oid, bin);
340 return this->obss.at(ensure_present(
id));
348 auto target_it = this->decays.find(target);
349 if (target_it == this->decays.end()) {
354 "is attached to decay",
356 "but this decay is not registered in ObsManager."
360 if (active_decay.has_value() && active_decay.value() != target) {
361 auto previous_it = this->decays.find(active_decay.value());
362 if (previous_it != this->decays.end()) {
363 previous_it->second->disable();
365 }
else if (!active_decay.has_value()) {
368 for (
auto& [dec_id, decay] : this->decays) {
369 if (dec_id != target && decay && decay->is_enabled()) {
375 target_it->second->enable();
376 active_decay = target;
385 return ensure_present(obs_id);
389 if (!obss.contains(
id)) {
399 for (
auto& elem: this->decays) {
400 if (elem.second && elem.second->is_enabled()) {
401 elem.second->load_params();
407 std::unordered_set<DecayId> unique_decays;
408 for (
auto& elem: this->obss) {
410 if (!
id.has_value()) {
411 LOG_ERROR(
"ValueError",
"DecayId does not exist for", elem.first.str());
413 unique_decays.emplace(
id.value());
416 for (
auto& did : unique_decays) {
417 auto dec_it = this->decays.find(did);
418 if (dec_it == this->decays.end()) {
419 LOG_ERROR(
"KeyError",
"Decay", did.str(),
"not present in ObsManager.");
421 dec_it->second->enable();
426 active_decay.reset();
432 this->decays.at(dec_id)->set_n_threads(n_threads);
439 for (
const auto& [decay_id, decay] : decays) {
440 if (decay && decay->supports_thread_config()) {
441 snapshot.emplace(decay_id, decay->get_n_threads());
448 for (
auto& [_, decay] : decays) {
449 if (decay && decay->supports_thread_config()) {
450 decay->set_n_threads(n_threads);
456 for (
const auto& [decay_id, n_threads] : snapshot) {
457 auto it = decays.find(decay_id);
458 if (it != decays.end() && it->second && it->second->supports_thread_config()) {
459 it->second->set_n_threads(n_threads);
466 for (
const auto& [decay_id, decay] : decays) {
471 auto cfg = decay->get_config();
472 if (cfg.has_value()) {
473 snapshot.emplace(decay_id, std::move(cfg));
480 for (
const auto& [decay_id, cfg] : snapshot) {
481 auto it = decays.find(decay_id);
482 if (it != decays.end() && it->second && cfg.has_value()) {
483 it->second->set_config(cfg);
489 std::vector<ObservableSelectionSnapshot> out;
491 for (
const auto& [obs_id, obs] : obss) {
493 auto dec_it = decays.find(decay_id);
494 if (dec_it == decays.end() || !dec_it->second) {
498 const bool binned_obs = dec_it->second->is_observable_binned(obs_id);
499 const auto order = dec_it->second->get_order();
500 const auto deps = obs ? obs->get_dependences() : std::unordered_set<ParamId>{};
503 auto bins = dec_it->second->get_bins();
504 if (!bins.has_value() || bins->empty()) {
508 for (
const auto& bin : bins.value()) {
#define LOG_ERROR(type,...)
Macro for logging error messages and terminating the application.
#define LOG_DEBUG(...)
Macro for logging debug messages.
#define LOG_VERBOSE(...)
Macro for logging verbose messages.
#define LOG_WARN(...)
Macro for logging warning messages.
High-level manager for observable evaluation.
std::unordered_map< DecayId, size_t > DecayThreadSnapshot
std::unordered_map< DecayId, std::any > DecayConfigSnapshot
static DecayId get_decay_id_or_throw(const ObservableId &obs)
Throwing variant of get_decay_id().
static std::optional< DecayId > get_decay_id(const ObservableId &obs)
Return the parent decay id of an observable id.
static bool is_param_allowed(Observables id, ParamId pid)
Tests whether a given parameter is allowed for a given observable.
static std::unordered_set< ParamId > get_allowed_parameters(Observables id)
Returns the set of allowed parameters for a given observable.
static std::optional< Observables > enum_of(const IdOf< ObservableTag > &id)
Attempts to recover the enum value associated with an identifier.
static IdOf< DecayTag > to_id(Decays e)
Converts an enum value to an IdOf<Tag>.
static std::string str(const IdOf< ObservableTag > &id)
Returns the string representation of an identifier.
bool is_decay_binned(Decays decay) const
Return whether this decay has at least one observable requiring q² bins.
ObsManager set_decay_threads(Decays dec, size_t n_threads)
Set the thread option for a decay that supports parallel cache filling.
std::map< ObservableId, std::vector< ObservableValue > > evaluate_all()
Evaluate all currently registered observables.
void restore_decay_configs(const DecayConfigSnapshot &snapshot)
Restore runtime decay configurations on matching decays.
void set_decay_config(Decays dec, std::any config)
Set a decay configuration object.
std::unordered_set< ParamId > get_all_ops_deps(ObservableId id)
Get the full allowed dependency set for a given observable.
std::vector< BinnedObservableId > get_current_obss()
Get the set of observable ids currently registered in the manager.
void add_custom_decay(DecayId id, std::shared_ptr< DecayParent > ptr)
Register a custom decay implementation.
void add_obs_deps(Observables id, std::unordered_set< ParamId > params)
Add a set of dependencies (parameters) to an observable (public enum).
ObsManager set_lblll_threads(size_t n_threads)
Set the thread option for the Lambda_b -> Lambda l+ l- decay.
void reload_params()
Reload cached parameters for all registered decays.
ObsManager remove_obs(Observables id)
Remove an observable (public enum) from the manager.
void set_all_decay_threads(size_t n_threads)
Set all thread-configurable decays to the same thread count.
void add_obs_dep(Observables id, ParamId param)
Add a single dependency (parameter) to an observable (public enum).
ObsManager set_bkstarll_threads(size_t n_threads)
Set the thread option for the B -> K* l+ l- decay.
std::vector< ObservableValue > evaluate(Observables id)
Evaluate a single observable (public enum).
ObsManager(ObservablePortsConfig obs_port_conf, bool init_default_decays=true)
Construct an observable manager with the required ports.
void add_all_obs_deps(Observables id)
Attach all allowed dependencies to an observable (public enum).
void select_decay(ObservableId id)
Enable the decay needed by an observable and disable all others.
DecayThreadSnapshot snapshot_decay_threads() const
Snapshot thread settings for all decays with thread configuration support.
bool is_observable_binned(Observables obs) const
Return whether a specific observable requires q² bins.
DecayConfigSnapshot snapshot_decay_configs() const
Snapshot runtime decay configurations that expose one.
ObsManager set_bsphi_threads(size_t n_threads)
Set the thread option for the Bs -> phi l+ l- decay.
void enable_obs()
Enable all observables' decays sequentially.
void restore_decay_threads(const DecayThreadSnapshot &snapshot)
Restore a previous decay thread snapshot.
std::shared_ptr< Observable > get_obs(Observables id)
Retrieve an observable (public enum).
ObsManager add_obs(Observables id, QCDOrder order, bool add_deps=false)
Add an observable (public enum) to the manager.
ObsManager set_bkll_threads(size_t n_threads)
Set the thread option for the B -> K l+ l- decay.
std::vector< ObservableSelectionSnapshot > snapshot_observable_selection() const
Capture selected observables, bins, orders and dependencies.
const std::string & str() const
Returns the underlying string.
Identifies an observable together with a numerical bin.
Dependency container (“ports”) for observable computations.
std::shared_ptr< IObsWilsonBuilder > iobswb
Builder used to (re)build Wilson coefficient groups on demand.
std::shared_ptr< IObsParameterProxy< ParamId, DataType, std::string, LhaID > > iobspp_sm
Parameter proxy for SM / Wilson / observable parameters.
Container for a computed observable value, optionally binned.
Composite identifier for a single parameter.
BlockName block
Name of the block where the parameter is stored.
LhaID code
Index or multi-index of the parameter inside the block.