File indexing completed on 2025-01-30 09:16:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DDCond/ConditionsDependencyHandler.h>
0016 #include <DDCond/ConditionsManagerObject.h>
0017 #include <DD4hep/ConditionsProcessor.h>
0018 #include <DD4hep/Printout.h>
0019 #include <TTimeStamp.h>
0020
0021 using namespace dd4hep::cond;
0022
0023 namespace {
0024 std::string dependency_name(const ConditionDependency* d) {
0025 #if defined(DD4HEP_CONDITIONS_HAVE_NAME)
0026 return d->target.name;
0027 #else
0028 char text[64];
0029 dd4hep::ConditionKey::KeyMaker key(d->target.hash);
0030 ::snprintf(text,sizeof(text),"%08X %08X",key.values.det_key, key.values.item_key);
0031 return text;
0032 #endif
0033 }
0034 }
0035
0036 void ConditionsDependencyHandler::Work::do_intersection(const IOV* iov_ptr) {
0037 if ( iov_ptr ) {
0038 if ( !this->iov ) {
0039 this->_iov = *iov_ptr;
0040 this->iov = &this->_iov;
0041 }
0042 else {
0043 this->_iov.iov_intersection(*iov_ptr);
0044 }
0045 }
0046 }
0047
0048 dd4hep::Condition
0049 ConditionsDependencyHandler::Work::resolve(Work*& current) {
0050 Work* previous = current;
0051 current = this;
0052 state = RESOLVED;
0053 if ( !condition ) {
0054 printout(ERROR,"DependencyHandler","ERROR: Cannot resolve not existing conditions.");
0055 }
0056 context.dependency->callback->resolve(condition, context);
0057 previous->do_intersection(iov);
0058 current = previous;
0059 return condition;
0060 }
0061
0062
0063 ConditionsDependencyHandler::ConditionsDependencyHandler(ConditionsManager mgr,
0064 UserPool& pool,
0065 const Dependencies& dependencies,
0066 ConditionUpdateUserContext* user_param)
0067 : m_manager(mgr.access()), m_pool(pool), m_dependencies(dependencies),
0068 m_userParam(user_param), num_callback(0)
0069 {
0070 const IOV& iov = m_pool.validity();
0071 unsigned char* p = new unsigned char[dependencies.size()*sizeof(Work)];
0072 m_block = (Work*)p;
0073 for(const auto& d : dependencies) {
0074 Work* w = new(p) Work(this,d.second,user_param,iov);
0075 m_todo.emplace(d.first,w);
0076 p += sizeof(Work);
0077 }
0078 m_iovType = iov.iovType;
0079 }
0080
0081
0082 ConditionsDependencyHandler::~ConditionsDependencyHandler() {
0083 m_todo.clear();
0084 if ( m_block ) delete [] m_block;
0085 m_block = 0;
0086 }
0087
0088
0089 dd4hep::Detector& ConditionsDependencyHandler::detectorDescription() const {
0090 return m_manager->detectorDescription();
0091 }
0092
0093
0094 void ConditionsDependencyHandler::compute() {
0095 m_state = CREATED;
0096 for( const auto& i : m_todo ) {
0097 if ( !i.second->condition ) {
0098 do_callback(i.second);
0099 if ( !i.second->condition ) {
0100 except("DependencyHandler",
0101 "Derived condition was not created after calling the creation callback!");
0102 }
0103 }
0104
0105 }
0106 }
0107
0108
0109 void ConditionsDependencyHandler::resolve() {
0110 PrintLevel prt_lvl = INFO;
0111 std::vector<Condition> tmp;
0112 std::map<IOV::Key,std::vector<Condition> > work_pools;
0113 Work* w;
0114
0115 m_state = RESOLVED;
0116 for( const auto& c : m_todo ) {
0117 w = c.second;
0118 m_currentWork = w;
0119 if ( w->state != RESOLVED ) {
0120 w->resolve(m_currentWork);
0121 }
0122
0123 auto ret = work_pools.emplace(w->iov->keyData,tmp);
0124 if ( ret.second ) {
0125
0126 ret.first->second.reserve(m_todo.size());
0127 }
0128 }
0129
0130 for( const auto& c : m_todo ) {
0131 w = c.second;
0132 auto& section = work_pools[w->iov->keyData];
0133 section.emplace_back(w->condition);
0134 #if 0
0135 printout(prt_lvl,"DependencyHandler","++ Register %s %s %s [%s]",
0136 w->context.dependency->target.toString().c_str(),
0137 w->context.dependency->detector.path().c_str(),
0138 w->condition->iov->str().c_str(),
0139 typeName(typeid(*w->condition)).c_str());
0140 #endif
0141 }
0142
0143
0144
0145 for( const auto& section : work_pools ) {
0146 TTimeStamp start;
0147 IOV iov(m_iovType, section.first);
0148 size_t result = registerMany(iov, section.second);
0149 if ( result != section.second.size() ) {
0150
0151 }
0152 TTimeStamp stop;
0153 printout(prt_lvl,"DependencyHandler","Inserted %ld [%ld] conditions to pool-iov: %s [%7.5f seconds]",
0154 result, section.second.size(), iov.str().c_str(),
0155 stop.AsDouble()-start.AsDouble());
0156 }
0157 }
0158
0159
0160 bool ConditionsDependencyHandler::registerOne(const IOV& iov, Condition cond) {
0161 return m_pool.registerOne(iov, cond);
0162 }
0163
0164
0165 std::size_t
0166 ConditionsDependencyHandler::registerMany(const IOV& iov, const std::vector<Condition>& values) {
0167 return m_pool.registerMany(iov, values);
0168 }
0169
0170
0171 std::vector<dd4hep::Condition>
0172 ConditionsDependencyHandler::get(DetElement de) {
0173 return this->get(de.key());
0174 }
0175
0176
0177 std::vector<dd4hep::Condition>
0178 ConditionsDependencyHandler::getByItem(Condition::itemkey_type key) {
0179 if ( m_state == RESOLVED ) {
0180 struct item_selector {
0181 std::vector<Condition> conditions;
0182 Condition::itemkey_type key;
0183 item_selector(Condition::itemkey_type k) : key(k) {}
0184 int operator()(Condition cond) {
0185 ConditionKey::KeyMaker maker(cond->hash);
0186 if ( maker.values.item_key == key ) conditions.emplace_back(cond);
0187 return 1;
0188 }
0189 };
0190 item_selector proc(key);
0191 m_pool.scan(conditionsProcessor(proc));
0192 for (auto c : proc.conditions ) m_currentWork->do_intersection(c->iov);
0193 return proc.conditions;
0194 }
0195 except("DependencyHandler",
0196 "Conditions bulk accesses are only possible during conditions resolution!");
0197 return std::vector<Condition>();
0198 }
0199
0200
0201 std::vector<dd4hep::Condition>
0202 ConditionsDependencyHandler::get(Condition::detkey_type det_key) {
0203 if ( m_state == RESOLVED ) {
0204 ConditionKey::KeyMaker lower(det_key, Condition::FIRST_ITEM_KEY);
0205 ConditionKey::KeyMaker upper(det_key, Condition::LAST_ITEM_KEY);
0206 std::vector<Condition> conditions = m_pool.get(lower.hash, upper.hash);
0207 for (auto c : conditions ) m_currentWork->do_intersection(c->iov);
0208 return conditions;
0209 }
0210 except("DependencyHandler",
0211 "Conditions bulk accesses are only possible during conditions resolution!");
0212 return std::vector<Condition>();
0213 }
0214
0215
0216 dd4hep::Condition
0217 ConditionsDependencyHandler::get(Condition::key_type key, bool throw_if_not) {
0218 return this->get(key, nullptr, throw_if_not);
0219 }
0220
0221
0222 dd4hep::Condition
0223 ConditionsDependencyHandler::get(Condition::key_type key,
0224 const ConditionDependency* dependency,
0225 bool throw_if_not)
0226 {
0227
0228 Condition c = m_pool.get(key);
0229 if ( c.isValid() ) {
0230 m_currentWork->do_intersection(c->iov);
0231 return c;
0232 }
0233 auto i = m_todo.find(key);
0234 if ( i != m_todo.end() ) {
0235 Work* w = i->second;
0236 if ( w->state == RESOLVED ) {
0237 return w->condition;
0238 }
0239 else if ( w->state == CREATED ) {
0240 return w->resolve(m_currentWork);
0241 }
0242 else if ( w->state == INVALID ) {
0243 do_callback(w);
0244 if ( w->condition && w->state == RESOLVED )
0245 return w->condition;
0246 else if ( w->condition )
0247 return w->resolve(m_currentWork);
0248 }
0249 }
0250 if ( throw_if_not ) {
0251 if ( dependency ) {
0252
0253 std::string de_path = dependency->detector.path();
0254 #if defined(DD4HEP_CONDITIONS_HAVE_NAME)
0255 std::string cond_from = dependency->target.name;
0256 std::string cond_to = "UNKNOWN";
0257 for(const auto& d : dependency->dependencies) {
0258 if ( d.hash == key ) {
0259 cond_to = d.name;
0260 break;
0261 }
0262 }
0263 printout(ERROR,"DependencyHandler",
0264 "Failed to resolve conditon:%016lX for DetElement: %s",
0265 key, de_path.c_str());
0266 printout(ERROR,"DependencyHandler",
0267 "Condition: %s dependent on missing condition: %s",
0268 cond_from.c_str(), cond_to.c_str());
0269 #else
0270 if ( detail::have_condition_item_inventory(-1) ) {
0271 std::string item_from = detail::get_condition_item_name(dependency->target.hash);
0272 std::string item_to = detail::get_condition_item_name(key);
0273 printout(ERROR,"DependencyHandler",
0274 "Failed to resolve conditon:%016lX for DetElement: %s",
0275 key, de_path.c_str());
0276 printout(ERROR,"DependencyHandler",
0277 "Condition: %s#%s dependent on missing condition item: %s",
0278 de_path.c_str(), item_from.c_str(), item_to.c_str());
0279 }
0280 #endif
0281 except("DependencyHandler",
0282 "Failed to resolve conditon:%016lX for DetElement: %s",
0283 key,de_path.c_str());
0284 }
0285 except("ConditionsDependencyHandler","Failed to resolve conditon:%016lX",key);
0286 }
0287 return Condition();
0288 }
0289
0290
0291 void ConditionsDependencyHandler::do_callback(Work* work) {
0292 const ConditionDependency* dep = work->context.dependency;
0293 try {
0294 Work* previous = m_currentWork;
0295 m_currentWork = work;
0296 if ( work->callstack > 0 ) {
0297
0298
0299
0300
0301 except("DependencyHandler",
0302 "++ Handler caught in infinite recursion loop. Key:%s %c%s%c",
0303 work->context.dependency->target.toString().c_str(),
0304 #if defined(DD4HEP_CONDITIONS_DEBUG)
0305 '[',work->context.dependency->detector.path().c_str(),']'
0306 #else
0307 ' ',"",' '
0308 #endif
0309 );
0310 }
0311 ++work->callstack;
0312 work->condition = (*dep->callback)(dep->target, work->context).ptr();
0313 --work->callstack;
0314 m_currentWork = previous;
0315 if ( work->condition ) {
0316 if ( !work->iov ) {
0317 work->_iov = IOV(m_iovType,IOV::Key(IOV::MIN_KEY, IOV::MAX_KEY));
0318 work->iov = &work->_iov;
0319 }
0320 if ( previous ) {
0321 previous->do_intersection(work->iov);
0322 }
0323 work->condition->iov = work->iov;
0324 work->condition->hash = dep->target.hash;
0325 work->condition->setFlag(Condition::DERIVED);
0326 work->state = CREATED;
0327 ++num_callback;
0328 }
0329 else {
0330 printout(ERROR,"DependencyHandler",
0331 "+++ Callback handler returned invalid condition. Key:%s %c%s%c",
0332 work->context.dependency->target.toString().c_str(),
0333 #if defined(DD4HEP_CONDITIONS_DEBUG)
0334 '[',work->context.dependency->detector.path().c_str(),']'
0335 #else
0336 ' ',"",' '
0337 #endif
0338 );
0339 throw std::runtime_error("Invalid derived condition callback");
0340 }
0341 return;
0342 }
0343 catch(const std::exception& e) {
0344 printout(ERROR,"DependencyHandler",
0345 "+++ Exception while creating dependent Condition %s:",
0346 dependency_name(dep).c_str());
0347 printout(ERROR,"DependencyHandler","\t\t%s", e.what());
0348 }
0349 catch(...) {
0350 printout(ERROR,"DependencyHandler",
0351 "+++ UNKNOWN exception while creating dependent Condition %s.",
0352 dependency_name(dep).c_str());
0353 }
0354 m_pool.print("*");
0355 except("DependencyHandler",
0356 "++ Exception while creating dependent Condition %s.",
0357 dependency_name(dep).c_str());
0358 }