6 [&](
const std::shared_ptr<Block>& p){ return p.get() == observer.get(); });
13 [&](
const std::shared_ptr<Block>& p){ return p.get() == observer.get(); });
18 for (
size_t i = 0; i <
observers.size(); ++i) {
20 if (!observer)
continue;
33 for (
auto& [_, param] : this->
items) {
39 for (
auto& [_, param] : this->
items) {
45 for (
auto& [_, param] : this->
items) {
59 id.
to_string(),
". Available keys are", std::make_shared<Block>(*
this));
61 return this->
items.at(
id);
69 if (!w.expired()) param->set_owner_block(w);
71 this->
items.emplace(
id, std::move(param));
76 this->
items.erase(
id);
81 LOG_ERROR(
"KeyError",
"Cannot update non-existing parameter", key.
to_string(),
"in block", this->blockname);
83 auto& dst = this->
items.at(key);
84 dst->overwrite_payload_from(*param);
86 dst->notifyObservers();
92 LOG_ERROR(
"KeyError",
"Cannot update non-existing parameter", key.
to_string(),
"in block", this->blockname);
94 auto& p = this->
items.at(key);
95 p->set_expected(value);
100 store(
id, std::move(param));
102 assign(
id, std::move(param));
114 if (!this->
items.contains(
id)) {
117 this->
items.at(
id)->clear_below();
118 this->
items.erase(
id);
120 auto dependents = std::exchange(
observers, {});
121 for (
auto& obs : dependents) {
122 if (obs) obs->destroy();
127 for (
auto& [_, param] :
items) {
128 param->set_owner(type);
143 this->
items = other->getItems();
145 if (other->has_scale()) this->
set_scale(other->get_scale());
149 for (
auto& [
id, p] :
items)
if (p) p->set_owner_block(w);
154 auto clone = std::make_shared<Block>();
156 if (this->
scale.has_value()) {
157 clone->scale = this->
scale;
160 for (
const auto& [
id, param] : this->
items) {
164 clone->items.emplace(
id, std::make_shared<Parameter>(*param));
171 for (
auto& param: this->
items) {
172 param.second->clear_above();
177 std::vector<std::shared_ptr<Parameter>> snapshot;
178 snapshot.reserve(
items.size());
179 for (
auto& kv :
items) snapshot.push_back(kv.second);
181 for (
auto& p : snapshot) {
182 if (p) p->clear_below();
188 return this->
scale.has_value();
193 LOG_ERROR(
"LogicError",
"Cannot set scale of a block which already has one.");
195 this->scale.emplace(
scale);
200 LOG_ERROR(
"LogicError",
"Scale for the block ", this->
get_name() ,
" has not been set, cannot retrieve it.");
202 return this->
scale.value_or(0.0);
206 auto dependents = std::exchange(
observers, {});
211 for (
auto& obs : dependents) {
212 if (obs) obs->destroy();
221 auto me_base = shared_from_this();
222 auto me_dep = std::static_pointer_cast<DependentBlock>(me_base);
225 for (
auto& [_, src] : sourceBlocks) src->addObserver(me_base);
235 this->frozen =
false;
239 if (this->update_at_unfreeze) {
241 this->update_at_unfreeze =
false;
246 LOG_DEBUG(
"Destruct dependentBlock at", self.lock().get());
247 if (
auto me_dep = self.lock()) {
248 auto me_base = std::static_pointer_cast<Block>(me_dep);
249 for (
auto& [_, src] : sourceBlocks) {
250 src->removeObserver(me_base);
259 LOG_ERROR(
"KeyError",
"Cannot update non-existing parameter", key.
to_string(),
"in block", this->blockname);
262 auto& dst = this->
items.at(key);
263 dst->overwrite_payload_from(*param);
271 LOG_ERROR(
"KeyError",
"Cannot update non-existing parameter", key.
to_string(),
"in block", this->blockname);
273 this->
items.at(key)->set_expected(value);
277 return this->sourceBlocks;
281 if (
auto me = self.lock()) {
282 for (
auto& [_, block] : sourceBlocks) {
283 block->removeObserver(me);
294 for (
auto& obs : snapshot) {
295 if (obs) obs->clear_below();
300 return sourceBlocks.contains(blockName) && sourceBlocks.at(blockName) !=
nullptr;
306 auto dependents = std::exchange(
observers, {});
310 for (
auto& kv :
items) {
311 kv.second->clear_below();
315 for (
auto& obs : dependents) {
316 if (obs) obs->destroy();
321 if (dependency_detached)
return;
327 for (
auto& [_, p] :
items) {
328 if (
auto dp = std::dynamic_pointer_cast<DependentParameter>(p)) {
333 sourceBlocks.clear();
334 recalculateLambda = {};
337 update_at_unfreeze =
false;
338 dependency_detached =
true;
344 if (!dependency_detached)
return;
346 sourceBlocks = saved_sourceBlocks;
347 recalculateLambda = saved_recalculateLambda;
349 for (
auto& [_, p] :
items) {
350 if (
auto dp = std::dynamic_pointer_cast<DependentParameter>(p)) {
355 if (
auto me = self.lock()) {
356 for (
auto& [_, src] : sourceBlocks) {
357 if (src) src->addObserver(me);
363 update_at_unfreeze =
false;
364 dependency_detached =
false;
374 if (
auto dep = std::dynamic_pointer_cast<DependentBlock>(obs)) {
379 for (
auto& [_, p] :
items) {
380 if (p) p->notifyParamObserversOnly();
385 if (frozen) { update_at_unfreeze =
true;
return; }
389void DependentBlock::ensure_up_to_date_impl() {
393 for (
auto& [name, src] : sourceBlocks) {
395 if (
auto depSrc = std::dynamic_pointer_cast<DependentBlock>(src)) {
396 depSrc->ensure_up_to_date();
402 if (!recalculateLambda)
LOG_ERROR(
"Error",
"DependentBlock has no recalculateLambda");
403 auto me_dep = std::static_pointer_cast<DependentBlock>(shared_from_this());
406 for (
auto& [_, p] :
items) {
407 if (p) p->notifyParamObserversOnly();
413std::ostream &
operator<<(std::ostream &os, std::shared_ptr<Block> ba) {
414 os <<
"Block " << ba->get_name() <<
":\n";
415 for (
auto &[
id, val] : ba->getItems()) {
416 os <<
'\t' <<
id <<
": " << val->get_val() <<
'\n';
std::ostream & operator<<(std::ostream &os, std::shared_ptr< Block > ba)
Defines classes used to store parameters and to build derived/dependent parameter blocks.
#define LOG_ERROR(type,...)
Macro for logging error messages and terminating the application.
#define LOG_DEBUG(...)
Macro for logging debug messages.
std::string to_string(const LhaID &id)
Convenience stringification for LhaID.
std::unordered_set< T > get_keys(const std::map< T, U > &map)
Extracts the key set from a std::map into an unordered_set.
Lightweight view over a set of source blocks.
virtual void freeze()
Freezes all parameters contained in the block.
double get_scale()
Returns the block-wide scale.
void addObserver(std::shared_ptr< Block > observer)
Adds a block observer if not already present.
virtual void update()
Updates the block.
std::unordered_set< LhaID > getAllIDs()
Returns the set of all parameter ids stored in the block.
std::map< LhaID, std::shared_ptr< Parameter > > items
List of observing blocks notified through notifyObservers().
virtual void unfreeze()
Unfreezes all parameters contained in the block.
void store_or_assign(const LhaID &key, std::shared_ptr< Parameter > param) override
Stores a parameter if absent, otherwise assigns into the existing one.
void removeObserver(std::shared_ptr< Block > observer)
Removes a previously registered observer block.
virtual void destroy()
Destroys the block and its downstream block dependencies.
void set_owner(ParameterType type)
Sets the owner ParameterType on all contained parameters.
void notifyObservers()
Notifies all observer blocks that this block has changed.
std::shared_ptr< Block > deep_clone_plain() const
Deep-copies this block as a plain independent block.
void erase_local(const LhaID &id)
Erases an entry from the local storage map only.
void assign(const LhaID &key, std::shared_ptr< Parameter > param) override
Replaces the payload of an existing parameter from another parameter object.
virtual void clear_below()
Clears parameter dependencies below this block.
void set_scale(double scale)
Sets the block-wide scale.
BlockName blockname
Name of the block (e.g. "SMINPUTS", "MASS", "FWCOEF"...)
std::vector< std::shared_ptr< Block > > observers
bool has_scale()
Returns whether the block has an associated scale.
Block()=default
Default constructor.
virtual void clear_above()
Clears parameter dependencies above this block.
void remove(const LhaID &key) override
Removes a parameter and clears its downstream dependency subtree.
std::optional< double > scale
Internal storage of parameters indexed by LHA id.
virtual std::unordered_map< std::string, std::shared_ptr< Block > > get_source_blocks() const
Returns the source blocks of this block.
virtual void ensure_up_to_date()
Ensures that the block content is up to date.
void copy(std::shared_ptr< Block > other)
Copies the content and metadata from another block.
bool contains(const LhaID &key) const override
Checks whether the block contains a parameter with the given id.
void store(const LhaID &id, std::shared_ptr< Parameter > param) override
Stores a new parameter under the given LHA id.
std::weak_ptr< Block > self_weak()
Optional explicit self-reference used to rebind owner_block on contained parameters.
const std::map< LhaID, std::shared_ptr< Parameter > > & getItems()
Returns the internal parameter map.
std::shared_ptr< Parameter > retrieve(const LhaID &id) override
Retrieves a stored parameter by id.
std::vector< std::shared_ptr< Block > > getObservers() const
Returns the current list of observer blocks.
BlockName get_name() const
Returns the name of the block.
void clear_below() override
Clears downstream block dependencies.
std::unordered_map< std::string, std::shared_ptr< Block > > get_source_blocks() const override
Returns the map of source blocks for this dependent block.
void destroy() override
Destroys this dependent block and its downstream block dependencies.
void mark_dirty()
Marks this block dirty and propagates the dirty state downstream.
void update() override
Marks the block as dirty.
void detach()
Temporarily detaches this block from its dependency graph.
bool dependsOn(const std::string &blockName)
Checks whether this dependent block uses a given source block name.
~DependentBlock()
Destructor.
void freeze() override
Freezes the block and all contained parameters.
void unfreeze() override
Unfreezes the block and contained parameters.
void init() override
Initializes the dependency graph for this block.
void assign(const LhaID &key, std::shared_ptr< Parameter > param)
Overwrites the payload of a local parameter without triggering block-level notification.
void ensure_up_to_date() override
Ensures this dependent block is up to date.
void reattach()
Reattaches a previously detached dependent block.
void clear_above() override
Clears upstream block dependencies.
Represents an identifier of a LHA element, possibly containing several sub-ids.
std::string to_string() const
Returns the canonical string representation of this LhaID.