DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
ConditionsDependencyHandler.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 // Framework include files
18 #include <DD4hep/Printout.h>
19 #include <TTimeStamp.h>
20 
21 using namespace dd4hep::cond;
22 
23 namespace {
24  std::string dependency_name(const ConditionDependency* d) {
25 #if defined(DD4HEP_CONDITIONS_HAVE_NAME)
26  return d->target.name;
27 #else
28  char text[64];
30  ::snprintf(text,sizeof(text),"%08X %08X",key.values.det_key, key.values.item_key);
31  return text;
32 #endif
33  }
34 }
35 
37  if ( iov_ptr ) {
38  if ( !this->iov ) {
39  this->_iov = *iov_ptr;
40  this->iov = &this->_iov;
41  }
42  else {
43  this->_iov.iov_intersection(*iov_ptr);
44  }
45  }
46 }
47 
50  Work* previous = current;
51  current = this;
52  state = RESOLVED;
53  if ( !condition ) {
54  printout(ERROR,"DependencyHandler","ERROR: Cannot resolve not existing conditions.");
55  }
56  context.dependency->callback->resolve(condition, context);
57  previous->do_intersection(iov);
58  current = previous;
59  return condition;
60 }
61 
64  UserPool& pool,
65  const Dependencies& dependencies,
66  ConditionUpdateUserContext* user_param)
67  : m_manager(mgr.access()), m_pool(pool), m_dependencies(dependencies),
68  m_userParam(user_param), num_callback(0)
69 {
70  const IOV& iov = m_pool.validity();
71  unsigned char* p = new unsigned char[dependencies.size()*sizeof(Work)];
72  m_block = (Work*)p;
73  for(const auto& d : dependencies) {
74  Work* w = new(p) Work(this,d.second,user_param,iov);
75  m_todo.emplace(d.first,w);
76  p += sizeof(Work);
77  }
78  m_iovType = iov.iovType;
79 }
80 
83  m_todo.clear();
84  if ( m_block ) delete [] m_block;
85  m_block = 0;
86 }
87 
91 }
92 
95  m_state = CREATED;
96  for( const auto& i : m_todo ) {
97  if ( !i.second->condition ) {
98  do_callback(i.second);
99  if ( !i.second->condition ) {
100  except("DependencyHandler",
101  "Derived condition was not created after calling the creation callback!");
102  }
103  }
104  // printout(INFO,"UserPool","Already calcluated: %s",d->name());
105  }
106 }
107 
110  PrintLevel prt_lvl = INFO;
111  std::vector<Condition> tmp;
112  std::map<IOV::Key,std::vector<Condition> > work_pools;
113  Work* w;
114 
115  m_state = RESOLVED;
116  for( const auto& c : m_todo ) {
117  w = c.second;
118  m_currentWork = w;
119  if ( w->state != RESOLVED ) {
121  }
122  // Fill an empty map of condition vectors for the block inserts
123  auto ret = work_pools.emplace(w->iov->keyData,tmp);
124  if ( ret.second ) {
125  // There is sort of the hope that most conditions go into 1 pool...
126  ret.first->second.reserve(m_todo.size());
127  }
128  }
129  // Optimize pool interactions: Cache pool in map assuming there are only few pools created
130  for( const auto& c : m_todo ) {
131  w = c.second;
132  auto& section = work_pools[w->iov->keyData];
133  section.emplace_back(w->condition);
134 #if 0
135  printout(prt_lvl,"DependencyHandler","++ Register %s %s %s [%s]",
136  w->context.dependency->target.toString().c_str(),
137  w->context.dependency->detector.path().c_str(),
138  w->condition->iov->str().c_str(),
139  typeName(typeid(*w->condition)).c_str());
140 #endif
141  }
142  // Now block register all conditions to the manager AND to the user pool
143  // In principle at thi stage the conditions manager should be locked
144  // provided all the work done so far can be undone.....in case of an error
145  for( const auto& section : work_pools ) {
146  TTimeStamp start;
147  IOV iov(m_iovType, section.first);
148  size_t result = registerMany(iov, section.second);
149  if ( result != section.second.size() ) {
150  //
151  }
152  TTimeStamp stop;
153  printout(prt_lvl,"DependencyHandler","Inserted %ld [%ld] conditions to pool-iov: %s [%7.5f seconds]",
154  result, section.second.size(), iov.str().c_str(),
155  stop.AsDouble()-start.AsDouble());
156  }
157 }
158 
161  return m_pool.registerOne(iov, cond);
162 }
163 
165 std::size_t
166 ConditionsDependencyHandler::registerMany(const IOV& iov, const std::vector<Condition>& values) {
167  return m_pool.registerMany(iov, values);
168 }
169 
171 std::vector<dd4hep::Condition>
173  return this->get(de.key());
174 }
175 
177 std::vector<dd4hep::Condition>
179  if ( m_state == RESOLVED ) {
180  struct item_selector {
181  std::vector<Condition> conditions;
183  item_selector(Condition::itemkey_type k) : key(k) {}
184  int operator()(Condition cond) {
185  ConditionKey::KeyMaker maker(cond->hash);
186  if ( maker.values.item_key == key ) conditions.emplace_back(cond);
187  return 1;
188  }
189  };
190  item_selector proc(key);
192  for (auto c : proc.conditions ) m_currentWork->do_intersection(c->iov);
193  return proc.conditions;
194  }
195  except("DependencyHandler",
196  "Conditions bulk accesses are only possible during conditions resolution!");
197  return std::vector<Condition>();
198 }
199 
201 std::vector<dd4hep::Condition>
203  if ( m_state == RESOLVED ) {
206  std::vector<Condition> conditions = m_pool.get(lower.hash, upper.hash);
207  for (auto c : conditions ) m_currentWork->do_intersection(c->iov);
208  return conditions;
209  }
210  except("DependencyHandler",
211  "Conditions bulk accesses are only possible during conditions resolution!");
212  return std::vector<Condition>();
213 }
214 
218  return this->get(key, nullptr, throw_if_not);
219 }
220 
224  const ConditionDependency* dependency,
225  bool throw_if_not)
226 {
228  Condition c = m_pool.get(key);
229  if ( c.isValid() ) {
231  return c;
232  }
233  auto i = m_todo.find(key);
234  if ( i != m_todo.end() ) {
235  Work* w = i->second;
236  if ( w->state == RESOLVED ) {
237  return w->condition;
238  }
239  else if ( w->state == CREATED ) {
240  return w->resolve(m_currentWork);
241  }
242  else if ( w->state == INVALID ) {
243  do_callback(w);
244  if ( w->condition && w->state == RESOLVED ) // cross-dependencies...
245  return w->condition;
246  else if ( w->condition )
247  return w->resolve(m_currentWork);
248  }
249  }
250  if ( throw_if_not ) {
251  if ( dependency ) {
252  // We need here more elaborate printout to ease debugging capabilities
253  std::string de_path = dependency->detector.path();
254 #if defined(DD4HEP_CONDITIONS_HAVE_NAME)
255  std::string cond_from = dependency->target.name;
256  std::string cond_to = "UNKNOWN";
257  for(const auto& d : dependency->dependencies) {
258  if ( d.hash == key ) {
259  cond_to = d.name;
260  break;
261  }
262  }
263  printout(ERROR,"DependencyHandler",
264  "Failed to resolve conditon:%016lX for DetElement: %s",
265  key, de_path.c_str());
266  printout(ERROR,"DependencyHandler",
267  "Condition: %s dependent on missing condition: %s",
268  cond_from.c_str(), cond_to.c_str());
269 #else
271  std::string item_from = detail::get_condition_item_name(dependency->target.hash);
272  std::string item_to = detail::get_condition_item_name(key);
273  printout(ERROR,"DependencyHandler",
274  "Failed to resolve conditon:%016lX for DetElement: %s",
275  key, de_path.c_str());
276  printout(ERROR,"DependencyHandler",
277  "Condition: %s#%s dependent on missing condition item: %s",
278  de_path.c_str(), item_from.c_str(), item_to.c_str());
279  }
280 #endif
281  except("DependencyHandler",
282  "Failed to resolve conditon:%016lX for DetElement: %s",
283  key,de_path.c_str());
284  }
285  except("ConditionsDependencyHandler","Failed to resolve conditon:%016lX",key);
286  }
287  return Condition();
288 }
289 
292  const ConditionDependency* dep = work->context.dependency;
293  try {
294  Work* previous = m_currentWork;
295  m_currentWork = work;
296  if ( work->callstack > 0 ) {
297  // if we end up here it means a previous construction call never finished
298  // because the bugger tried to access another condition, which in turn
299  // during the construction tries to access this one.
300  // ---> Classic dead-lock
301  except("DependencyHandler",
302  "++ Handler caught in infinite recursion loop. Key:%s %c%s%c",
303  work->context.dependency->target.toString().c_str(),
304 #if defined(DD4HEP_CONDITIONS_DEBUG)
305  '[',work->context.dependency->detector.path().c_str(),']'
306 #else
307  ' ',"",' '
308 #endif
309  );
310  }
311  ++work->callstack;
312  work->condition = (*dep->callback)(dep->target, work->context).ptr();
313  --work->callstack;
314  m_currentWork = previous;
315  if ( work->condition ) {
316  if ( !work->iov ) {
318  work->iov = &work->_iov;
319  }
320  if ( previous ) {
321  previous->do_intersection(work->iov);
322  }
323  work->condition->iov = work->iov;
324  work->condition->hash = dep->target.hash;
326  work->state = CREATED;
327  ++num_callback;
328  }
329  else {
330  printout(ERROR,"DependencyHandler",
331  "+++ Callback handler returned invalid condition. Key:%s %c%s%c",
332  work->context.dependency->target.toString().c_str(),
333 #if defined(DD4HEP_CONDITIONS_DEBUG)
334  '[',work->context.dependency->detector.path().c_str(),']'
335 #else
336  ' ',"",' '
337 #endif
338  );
339  throw std::runtime_error("Invalid derived condition callback");
340  }
341  return;
342  }
343  catch(const std::exception& e) {
344  printout(ERROR,"DependencyHandler",
345  "+++ Exception while creating dependent Condition %s:",
346  dependency_name(dep).c_str());
347  printout(ERROR,"DependencyHandler","\t\t%s", e.what());
348  }
349  catch(...) {
350  printout(ERROR,"DependencyHandler",
351  "+++ UNKNOWN exception while creating dependent Condition %s.",
352  dependency_name(dep).c_str());
353  }
354  m_pool.print("*");
355  except("DependencyHandler",
356  "++ Exception while creating dependent Condition %s.",
357  dependency_name(dep).c_str());
358 }
dd4hep::IOV::iov_intersection
void iov_intersection(const IOV &comparator)
Set the intersection of this IOV with the argument IOV.
Definition: IOV.cpp:99
dd4hep::cond::ConditionsDependencyHandler::~ConditionsDependencyHandler
~ConditionsDependencyHandler()
Default destructor.
Definition: ConditionsDependencyHandler.cpp:82
dd4hep::DetElement::path
const std::string & path() const
Path of the detector element (not necessarily identical to placement path!)
Definition: DetElement.cpp:158
dd4hep::cond::ConditionsDependencyHandler::detectorDescription
virtual Detector & detectorDescription() const override
Access to the detector description instance.
Definition: ConditionsDependencyHandler.cpp:89
dd4hep::cond::ConditionsDependencyHandler::m_manager
ConditionsManagerObject * m_manager
Reference to conditions manager.
Definition: ConditionsDependencyHandler.h:91
dd4hep::cond::ConditionsDependencyHandler::RESOLVED
@ RESOLVED
Definition: ConditionsDependencyHandler.h:53
dd4hep::Condition::LAST_ITEM_KEY
@ LAST_ITEM_KEY
Definition: Conditions.h:96
dd4hep::detail::have_condition_item_inventory
int have_condition_item_inventory(int value=-1)
Setup conditions item name inventory for debugging.
Definition: Conditions.cpp:49
cond
AlignmentCondition::Object * cond
Definition: AlignmentsCalculator.cpp:68
dd4hep::cond::UserPool::registerMany
virtual size_t registerMany(const IOV &iov, const std::vector< Condition > &values)=0
Do block insertions of conditions with identical IOV.
dd4hep::cond::ConditionsDependencyHandler::INVALID
@ INVALID
Definition: ConditionsDependencyHandler.h:53
dd4hep::DetElement::key
unsigned int key() const
Access hash key of this detector element (Only valid once geometry is closed!)
Definition: DetElement.cpp:134
dd4hep::cond::ConditionsDependencyHandler::ConditionsDependencyHandler
ConditionsDependencyHandler(ConditionsManager mgr, UserPool &pool, const Dependencies &dependencies, ConditionUpdateUserContext *user_param)
Initializing constructor.
Definition: ConditionsDependencyHandler.cpp:63
dd4hep::detail::ConditionObject::hash
Condition::key_type hash
Hash value of the name.
Definition: ConditionsInterna.h:85
dd4hep::Condition::FIRST_ITEM_KEY
@ FIRST_ITEM_KEY
Definition: Conditions.h:95
dd4hep::exception
void exception(const std::string &src, const std::string &msg)
Definition: RootDictionary.h:69
dd4hep::ConditionKey::hash
Condition::key_type hash
Hashed key representation.
Definition: Conditions.h:287
dd4hep::cond::ConditionDependency::target
ConditionKey target
Key to the condition to be updated.
Definition: ConditionDerived.h:326
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:128
dd4hep::IOV::str
std::string str() const
Create string representation of the IOV.
Definition: IOV.cpp:141
dd4hep::IOV::Key
std::pair< Key_value_type, Key_value_type > Key
Definition: IOV.h:74
dd4hep::cond::ConditionDependency::detector
DetElement detector
Reference to the target's detector element.
Definition: ConditionDerived.h:324
dd4hep::ConditionKey::toString
std::string toString() const
Conversion to string.
Definition: Conditions.cpp:301
dd4hep::cond::ConditionUpdateUserContext
ConditionUpdateUserContext class used by the derived conditions calculation mechanism.
Definition: ConditionDerived.h:49
dd4hep::ConditionKey::KeyMaker
Helper union to interprete conditions keys.
Definition: Conditions.h:295
dd4hep::cond::UserPool::validity
const IOV & validity() const
Access the interval of validity for this user pool.
Definition: ConditionsPool.h:167
dd4hep::cond::ConditionsDependencyHandler::Work::condition
Condition::Object * condition
The final result: the condition object.
Definition: ConditionsDependencyHandler.h:63
dd4hep::cond::ConditionsDependencyHandler::m_userParam
ConditionUpdateUserContext * m_userParam
User defined optional processing parameter.
Definition: ConditionsDependencyHandler.h:97
dd4hep::Condition::detkey_type
unsigned int detkey_type
High part of the key identifies the detector element.
Definition: Conditions.h:56
dd4hep::cond::ConditionsDependencyHandler::Work::do_intersection
void do_intersection(const IOV *iov)
Helper to determine the IOV intersection taking into account dependencies.
Definition: ConditionsDependencyHandler.cpp:36
ConditionsManagerObject.h
dd4hep::Condition
Main condition object handle.
Definition: Conditions.h:51
dd4hep::cond
Namespace for implementation details of the AIDA detector description toolkit.
Definition: ConditionsCleanup.h:23
dd4hep::cond::ConditionDependency
Condition dependency definition.
Definition: ConditionDerived.h:316
dd4hep::IOV
Class describing the interval of validty.
Definition: IOV.h:67
dd4hep::cond::ConditionsManagerObject::detectorDescription
Detector & detectorDescription() const
Access to the detector description instance.
Definition: ConditionsManagerObject.h:88
dd4hep::cond::UserPool::print
virtual void print(const std::string &opt) const =0
Print pool content.
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:188
dd4hep::cond::ConditionsDependencyHandler::m_pool
UserPool & m_pool
Reference to the user pool object.
Definition: ConditionsDependencyHandler.h:93
dd4hep::cond::ConditionsDependencyHandler::num_callback
size_t num_callback
Number of callbacks to the handler for monitoring.
Definition: ConditionsDependencyHandler.h:110
dd4hep::cond::ConditionsDependencyHandler::Work::context
ConditionUpdateContext context
Auxiliary information to resolve condition callbacks.
Definition: ConditionsDependencyHandler.h:59
dd4hep::cond::ConditionsDependencyHandler::Work::iov
IOV * iov
Condition IOV.
Definition: ConditionsDependencyHandler.h:61
dd4hep::cond::ConditionsDependencyHandler::do_callback
void do_callback(Work *dep)
Internal call to trigger update callback.
Definition: ConditionsDependencyHandler.cpp:291
dd4hep::cond::UserPool::registerOne
virtual bool registerOne(const IOV &iov, Condition cond)=0
Do single insertion of condition including registration to the manager.
dd4hep::cond::ConditionsDependencyHandler::compute
void compute()
Access the conditions created during processing.
Definition: ConditionsDependencyHandler.cpp:94
dd4hep::IOV::keyData
Key keyData
IOV key (if second==first, discrete, otherwise range)
Definition: IOV.h:82
dd4hep::cond::ConditionsDependencyHandler::CREATED
@ CREATED
Definition: ConditionsDependencyHandler.h:53
dd4hep::cond::ConditionsDependencyHandler::resolve
void resolve()
2nd pass: Handler callback for the second turn to resolve missing dependencies
Definition: ConditionsDependencyHandler.cpp:109
dd4hep::cond::ConditionDependency::callback
std::shared_ptr< ConditionUpdateCall > callback
Reference to the update callback. No auto pointer. callback may be shared.
Definition: ConditionDerived.h:330
dd4hep::cond::ConditionsDependencyHandler::registerOne
virtual bool registerOne(const IOV &iov, Condition cond) override
Interface to handle multi-condition inserts by callbacks: One single insert.
Definition: ConditionsDependencyHandler.cpp:160
dd4hep::cond::ConditionsDependencyHandler::getByItem
virtual std::vector< Condition > getByItem(Condition::itemkey_type key) override
Interface to access conditions by hash value of the item (only valid at resolve!)
Definition: ConditionsDependencyHandler.cpp:178
dd4hep::Condition::itemkey_type
unsigned int itemkey_type
Low part of the key identifies the item identifier.
Definition: Conditions.h:58
dd4hep::cond::ConditionsDependencyHandler::m_state
State m_state
Handler's state.
Definition: ConditionsDependencyHandler.h:103
dd4hep::cond::ConditionsDependencyHandler::registerMany
virtual size_t registerMany(const IOV &iov, const std::vector< Condition > &values) override
Handle multi-condition inserts by callbacks: block insertions of conditions with identical IOV.
Definition: ConditionsDependencyHandler.cpp:166
dd4hep::detail::ConditionObject::setFlag
void setFlag(Condition::mask_type option)
Flag operations: Set a conditons flag.
Definition: ConditionsInterna.h:122
dd4hep::Condition::key_type
unsigned long long int key_type
Forward definition of the key type.
Definition: Conditions.h:54
dd4hep::cond::ConditionsDependencyHandler::Work
Helper structure to define the current update item.
Definition: ConditionsDependencyHandler.h:55
dd4hep::cond::ConditionsManager
Manager class for condition handles.
Definition: ConditionsManager.h:46
dd4hep::cond::UserPool
Interface for conditions pool optimized to host conditions updates.
Definition: ConditionsPool.h:134
dd4hep::cond::ConditionDependency::dependencies
std::vector< ConditionKey > dependencies
Dependency keys this condition depends on.
Definition: ConditionDerived.h:328
dd4hep::cond::UserPool::scan
virtual void scan(const Condition::Processor &processor) const =0
ConditionsMap overload: Interface to scan data content of the conditions mapping.
key
unsigned char key
Definition: AlignmentsCalculator.cpp:69
dd4hep::IOV::MIN_KEY
static constexpr Key_value_type MIN_KEY
Definition: IOV.h:76
dd4hep::cond::ConditionsDependencyHandler::m_dependencies
const Dependencies & m_dependencies
Dependency container to be resolved.
Definition: ConditionsDependencyHandler.h:95
ConditionsDependencyHandler.h
dd4hep::cond::ConditionsDependencyHandler::Work::state
State state
Current conversion state of the item.
Definition: ConditionsDependencyHandler.h:67
dd4hep::IOV::iovType
const IOVType * iovType
Reference to IOV type.
Definition: IOV.h:80
dd4hep::detail::get_condition_item_name
std::string get_condition_item_name(Condition::itemkey_type key)
Resolve key from conditions item name inventory for debugging.
Definition: Conditions.cpp:60
dd4hep::cond::ConditionsDependencyHandler::m_currentWork
Work * m_currentWork
Current item of the block.
Definition: ConditionsDependencyHandler.h:107
dd4hep::cond::ConditionsDependencyHandler::m_iovType
const IOVType * m_iovType
Local cacheL pool's IOV type.
Definition: ConditionsDependencyHandler.h:99
dd4hep::ConditionKey::KeyMaker::hash
Condition::key_type hash
Definition: Conditions.h:296
dd4hep::cond::ConditionsDependencyHandler::Work::_iov
IOV _iov
Definition: ConditionsDependencyHandler.h:57
dd4hep::Condition::DERIVED
@ DERIVED
Definition: Conditions.h:79
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
dd4hep::cond::UserPool::get
virtual Condition get(Condition::key_type key) const =0
Check if a condition exists in the pool and return it to the caller.
dd4hep::cond::ConditionsDependencyHandler::Work::callstack
int callstack
Flag to detect non resolvable circular dependencies.
Definition: ConditionsDependencyHandler.h:65
dd4hep::cond::ConditionsDependencyHandler::Work::resolve
Condition resolve(Work *&current)
Helper function for the second level dependency resolution.
Definition: ConditionsDependencyHandler.cpp:49
dd4hep::cond::ConditionsDependencyHandler::m_todo
WorkConditions m_todo
The objects created during processing.
Definition: ConditionsDependencyHandler.h:101
dd4hep::IOV::MAX_KEY
static constexpr Key_value_type MAX_KEY
Definition: IOV.h:77
dd4hep::detail::ConditionObject::iov
const IOV * iov
Interval of validity.
Definition: ConditionsInterna.h:83
dd4hep::cond::ConditionsDependencyHandler::m_block
Work * m_block
Current block work item.
Definition: ConditionsDependencyHandler.h:105
dd4hep::cond::conditionsProcessor
ConditionsProcessor< typename std::remove_reference< T >::type > conditionsProcessor(T &&obj)
Creator utility function for ConditionsProcessor objects.
Definition: ConditionsProcessor.h:67
dd4hep::cond::ConditionUpdateContext::dependency
const ConditionDependency * dependency
The dependency to be handled within this context.
Definition: ConditionDerived.h:141
dd4hep::ConditionKey::KeyMaker::values
struct dd4hep::ConditionKey::KeyMaker::@2 values
Printout.h
dd4hep::Condition::iov
const IOV & iov() const
Access the IOV block.
Definition: Conditions.cpp:139
dd4hep::cond::ConditionsDependencyHandler::Dependencies
std::map< Condition::key_type, const ConditionDependency * > Dependencies
Definition: ConditionsDependencyHandler.h:86
dd4hep::ConditionKey::KeyMaker::item_key
Condition::itemkey_type item_key
Definition: Conditions.h:302
dd4hep::cond::ConditionsDependencyHandler::get
virtual Condition get(const ConditionKey &key) override
ConditionResolver implementation: Interface to access conditions.
Definition: ConditionsDependencyHandler.h:142
ConditionsProcessor.h