File indexing completed on 2025-01-18 09:13:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DDCond/Type1/Manager_Type1.h>
0016
0017 #include <DD4hep/Detector.h>
0018 #include <DD4hep/World.h>
0019 #include <DD4hep/Errors.h>
0020 #include <DD4hep/Plugins.h>
0021 #include <DD4hep/Printout.h>
0022 #include <DD4hep/Factories.h>
0023 #include <DD4hep/InstanceCount.h>
0024 #include <DD4hep/PluginCreators.h>
0025 #include <DD4hep/ConditionsListener.h>
0026 #include <DD4hep/detail/Handle.inl>
0027 #include <DD4hep/detail/DetectorInterna.h>
0028 #include <DD4hep/detail/ConditionsInterna.h>
0029
0030 #include <DDCond/ConditionsPool.h>
0031 #include <DDCond/ConditionsEntry.h>
0032 #include <DDCond/ConditionsCleanup.h>
0033 #include <DDCond/ConditionsManager.h>
0034 #include <DDCond/ConditionsIOVPool.h>
0035 #include <DDCond/ConditionsDataLoader.h>
0036
0037 using namespace dd4hep::cond;
0038
0039 typedef UpdatePool::UpdateEntries Updates;
0040 typedef dd4hep::RangeConditions RC;
0041
0042 DD4HEP_INSTANTIATE_HANDLE_NAMED(Manager_Type1);
0043
0044 static void* ddcond_create_manager_instance(dd4hep::Detector& description, int, char**) {
0045 return (ConditionsManagerObject*)new Manager_Type1(description);
0046 }
0047 DECLARE_DD4HEP_CONSTRUCTOR(DD4hep_ConditionsManager_Type1,ddcond_create_manager_instance)
0048
0049 #define NO_AGE 0
0050
0051 namespace {
0052 struct Range {};
0053 struct Discrete {};
0054
0055 int s_debug = dd4hep::INFO;
0056
0057
0058 template <typename T> const dd4hep::IOVType* check_iov_type(const Manager_Type1* o, const dd4hep::IOV* iov);
0059
0060
0061 template <> const dd4hep::IOVType* check_iov_type<void>(const Manager_Type1* o, const dd4hep::IOV* iov) {
0062 if ( iov ) {
0063 const dd4hep::IOVType* typ = iov->iovType ? iov->iovType : o->iovType(iov->type);
0064 if ( typ ) {
0065 if ( iov->type == typ->type ) {
0066 if ( typ->type < o->m_rawPool.size() ) {
0067 if ( o->m_rawPool[typ->type] != 0 ) {
0068 return typ;
0069 }
0070 }
0071 }
0072 }
0073 }
0074 return 0;
0075 }
0076
0077
0078 template <> const dd4hep::IOVType* check_iov_type<Discrete>(const Manager_Type1* o, const dd4hep::IOV* iov) {
0079 const dd4hep::IOVType* typ = check_iov_type<void>(o,iov);
0080 if ( typ && !iov->has_range() ) return typ;
0081 return 0;
0082 }
0083 #if 0
0084
0085 template <> const dd4hep::IOVType* check_iov_type<Range>(const Manager_Type1* o, const dd4hep::IOV* iov) {
0086 const dd4hep::IOVType* typ = check_iov_type<void>(o,iov);
0087 if ( typ && iov->has_range() ) return typ;
0088 return 0;
0089 }
0090 #endif
0091
0092 template <typename T> void __check_values__(const Manager_Type1* o, dd4hep::Condition::key_type key, const dd4hep::IOV* iov)
0093 {
0094 if ( !iov ) {
0095 dd4hep::except("ConditionsMgr","+++ Invalid IOV to access condition: %16llX. [Null-reference]",key);
0096 }
0097 const dd4hep::IOVType* typ = check_iov_type<T>(o,iov);
0098 if ( !typ ) {
0099
0100
0101 dd4hep::except("ConditionsMgr","+++ Invalid IOV type [%d] to access condition: %16llX.",
0102 iov->type, key);
0103 }
0104 }
0105
0106
0107 bool is_range_complete(const dd4hep::IOV& iov, const RC& conditions) {
0108 if ( !conditions.empty() ) {
0109
0110
0111 dd4hep::IOV::Key test=iov.keyData;
0112
0113
0114 for( std::size_t j = 0; j < conditions.size(); ++j ) {
0115 for(const auto& cond : conditions ) {
0116 const dd4hep::IOV::Key& k = cond->iov->key();
0117 if ( k.first <= test.first+1 && k.second >= test.first ) test.first = k.second;
0118 if ( k.first+1 <= test.second && k.second >= test.second ) test.second = k.first;
0119
0120 if ( test.first >= test.second ) return true;
0121 }
0122 if ( test.first <= iov.keyData.first && test.second >= iov.keyData.second ) return false;
0123 }
0124 }
0125 return false;
0126 }
0127
0128 template <typename PMF>
0129 void __callListeners(const Manager_Type1::Listeners& listeners, PMF pmf, dd4hep::Condition& cond) {
0130 for(const auto& listener : listeners )
0131 (listener.first->*pmf)(cond, listener.second);
0132 }
0133 }
0134
0135
0136 Manager_Type1::Manager_Type1(Detector& description_instance)
0137 : ConditionsManagerObject(description_instance), ObjectExtensions(typeid(Manager_Type1)),
0138 m_updateLock(), m_poolLock(), m_updatePool(), m_rawPool(), m_locked(0)
0139 {
0140 InstanceCount::increment(this);
0141 declareProperty("MaxIOVTypes", m_maxIOVTypes=32);
0142 declareProperty("PoolType", m_poolType = "");
0143 declareProperty("UpdatePoolType", m_updateType = "DD4hep_ConditionsLinearUpdatePool");
0144 declareProperty("UserPoolType", m_userType = "DD4hep_ConditionsMapUserPool");
0145 declareProperty("LoaderType", m_loaderType = "DD4hep_Conditions_multi_Loader");
0146 m_iovTypes.resize(m_maxIOVTypes,IOVType());
0147 m_rawPool.resize(m_maxIOVTypes,0);
0148 }
0149
0150
0151 Manager_Type1::~Manager_Type1() {
0152 for_each(m_rawPool.begin(), m_rawPool.end(), detail::DestroyObject<ConditionsIOVPool*>());
0153 InstanceCount::decrement(this);
0154 }
0155
0156 void Manager_Type1::initialize() {
0157 if ( !m_updatePool.get() ) {
0158 std::string typ = m_loaderType;
0159 const void* argv_loader[] = {"ConditionsDataLoader", this, 0};
0160 const void* argv_pool[] = {this, 0, 0};
0161 m_loader.reset(createPlugin<ConditionsDataLoader>(typ,m_detDesc,2,argv_loader));
0162 m_updatePool.reset(createPlugin<UpdatePool>(m_updateType,m_detDesc,2,argv_pool));
0163 if ( !m_updatePool.get() ) {
0164 except("ConditionsMgr","+++ The update pool of type %s cannot be created. [%s]",
0165 m_updateType.c_str(),Errors::noSys().c_str());
0166 }
0167 Ref_t ref(m_updatePool.get());
0168 ref->SetName("updates");
0169 ref->SetTitle("updates");
0170 }
0171 }
0172
0173
0174 std::pair<bool, const dd4hep::IOVType*>
0175 Manager_Type1::registerIOVType(std::size_t iov_index, const std::string& iov_name) {
0176 if ( iov_index<m_iovTypes.size() ) {
0177 IOVType& typ = m_iovTypes[iov_index];
0178 bool eq_type = typ.type == iov_index;
0179 bool eq_name = typ.name == iov_name;
0180 if ( eq_type && eq_name ) {
0181 return { false, &typ };
0182 }
0183 else if ( typ.type != 0 && eq_type && !eq_name ) {
0184 except("ConditionsMgr","Cannot register IOV %s. Type %d already in use!",
0185 iov_name.c_str(), iov_index);
0186 }
0187 typ.name = iov_name;
0188 typ.type = iov_index;
0189 m_rawPool[typ.type] = new ConditionsIOVPool(&typ);
0190 return { true, &typ };
0191 }
0192 except("ConditionsMgr","Cannot register IOV section %d of type %d. Value out of bounds: [%d,%d]",
0193 iov_name.c_str(), iov_index, 0, int(m_iovTypes.size()));
0194 return { false, nullptr };
0195 }
0196
0197
0198 const dd4hep::IOVType* Manager_Type1::iovType (size_t iov_index) const {
0199 if ( iov_index<m_iovTypes.size() ) {
0200 const IOVType& typ = m_iovTypes[iov_index];
0201 if ( typ.type == iov_index ) return &typ;
0202 }
0203 except("ConditionsMgr","Request to access an unregistered IOV type: %d.", iov_index);
0204 return 0;
0205 }
0206
0207
0208 const dd4hep::IOVType* Manager_Type1::iovType (const std::string& iov_name) const {
0209 for( const auto& i : m_iovTypes )
0210 if ( i.name == iov_name ) return &i;
0211 except("ConditionsMgr","Request to access an unregistered IOV type: %s.", iov_name.c_str());
0212 return 0;
0213 }
0214
0215
0216 ConditionsPool* Manager_Type1::registerIOV(const IOVType& typ, IOV::Key key) {
0217
0218 ConditionsIOVPool* pool = m_rawPool[typ.type];
0219 dd4hep_lock_t lock(m_poolLock);
0220 if ( !pool ) {
0221 m_rawPool[typ.type] = pool = new ConditionsIOVPool(&typ);
0222 }
0223 ConditionsIOVPool::Elements::const_iterator i = pool->elements.find(key);
0224 if ( i != pool->elements.end() ) {
0225 return (*i).second.get();
0226 }
0227 IOV* iov = new IOV(&typ);
0228 iov->type = typ.type;
0229 iov->keyData = key;
0230 const void* argv_pool[] = {this, iov, 0};
0231 std::shared_ptr<ConditionsPool> cond_pool(createPlugin<ConditionsPool>(m_poolType,m_detDesc,2,argv_pool));
0232 pool->elements.emplace(key,cond_pool);
0233 printout(INFO,"ConditionsMgr","Created IOV Pool for:%s",iov->str().c_str());
0234 return cond_pool.get();
0235 }
0236
0237
0238 ConditionsIOVPool* Manager_Type1::iovPool(const IOVType& iov_type) const {
0239 return m_rawPool[iov_type.type];
0240 }
0241
0242
0243 bool Manager_Type1::registerUnlocked(ConditionsPool& pool, Condition cond) {
0244 if ( cond.isValid() ) {
0245 cond->iov = pool.iov;
0246 cond->setFlag(Condition::ACTIVE);
0247 pool.insert(cond);
0248 #if !defined(DD4HEP_MINIMAL_CONDITIONS) && defined(DD4HEP_CONDITIONS_HAVE_NAME)
0249 printout(DEBUG,"ConditionsMgr","Register condition %016lX %s [%s] IOV:%s",
0250 cond.key(), cond.name(), cond->address.c_str(), pool.iov->str().c_str());
0251 #elif defined(DD4HEP_CONDITIONS_HAVE_NAME)
0252 printout(DEBUG,"ConditionsMgr","Register condition %016lX %s IOV:%s",
0253 cond.key(), cond.name(), pool.iov->str().c_str());
0254 #else
0255 printout(DEBUG,"ConditionsMgr","Register condition %016lX IOV:%s",
0256 cond.key(), pool.iov->str().c_str());
0257 #endif
0258 if ( !m_onRegister.empty() ) {
0259 __callListeners(m_onRegister, &ConditionsListener::onRegisterCondition, cond);
0260 }
0261 return true;
0262 }
0263 else if ( !cond.isValid() )
0264 except("ConditionsMgr","+++ Invalid condition objects may not be registered. [%s]",
0265 Errors::invalidArg().c_str());
0266 return false;
0267 }
0268
0269
0270 std::size_t Manager_Type1::blockRegister(ConditionsPool& pool, const std::vector<Condition>& cond) const {
0271 std::size_t result = 0;
0272 for(auto c : cond) {
0273 if ( c.isValid() ) {
0274 c->iov = pool.iov;
0275 c->setFlag(Condition::ACTIVE);
0276 pool.insert(c);
0277 if ( !m_onRegister.empty() ) {
0278 __callListeners(m_onRegister, &ConditionsListener::onRegisterCondition, c);
0279 }
0280 ++result;
0281 continue;
0282 }
0283 except("ConditionsMgr",
0284 "+++ Invalid condition objects may not be registered. [%s]",
0285 Errors::invalidArg().c_str());
0286 }
0287 return result;
0288 }
0289
0290
0291
0292 dd4hep::Condition Manager_Type1::__queue_update(cond::Entry* e) {
0293 if ( e ) {
0294 ConditionsPool* p = this->ConditionsManagerObject::registerIOV(e->validity);
0295 Condition condition(e->name,e->type);
0296 Condition::Object* c = condition.ptr();
0297 c->value = e->value;
0298 #if !defined(DD4HEP_MINIMAL_CONDITIONS)
0299 c->comment = "----";
0300 c->address = "----";
0301 c->validity = e->validity;
0302 #endif
0303 c->iov = p->iov;
0304 c->hash = ConditionKey::KeyMaker(e->detector,e->name).hash;
0305 p->insert(c);
0306 if ( s_debug > INFO ) {
0307 #if defined(DD4HEP_MINIMAL_CONDITIONS)
0308 ConditionKey::KeyMaker key(c->hash);
0309 printout(INFO,"Conditions","+++ Loaded condition: %s %08X.%08X to %s",
0310 e->detector.path().c_str(), key.values.det_key, key.values.item_key,
0311 c->value.c_str());
0312 #else
0313 printout(INFO,"Conditions","+++ Loaded condition: %s.%s to %s [%s] V: %s",
0314 e->detector.path().c_str(), c->name.c_str(),
0315 c->value.c_str(), c->type.c_str(), c->validity.c_str());
0316 #endif
0317 }
0318 return c;
0319 }
0320 return Condition();
0321 }
0322
0323
0324 void Manager_Type1::__get_checked_pool(const IOV& req_iov,
0325 std::unique_ptr<UserPool>& up)
0326 {
0327 const IOVType* typ = check_iov_type<Discrete>(this, &req_iov);
0328 if ( typ ) {
0329 ConditionsIOVPool* pool = m_rawPool[typ->type];
0330 if ( 0 == up.get() ) {
0331 const void* argv[] = {this, pool, 0};
0332 UserPool* p = createPlugin<UserPool>(m_userType,m_detDesc,2,argv);
0333 up.reset(p);
0334 }
0335 return;
0336 }
0337
0338 except("ConditionsMgr","+++ Unknown IOV type requested to enable conditions. [%s]",
0339 Errors::invalidArg().c_str());
0340 }
0341
0342
0343 void Manager_Type1::adoptCleanup(ConditionsCleanup* cleaner) {
0344 m_cleaner.reset(cleaner);
0345 }
0346
0347
0348 int Manager_Type1::clean(const IOVType* typ, int max_age) {
0349 int count = 0;
0350 dd4hep_lock_t lock(m_updateLock);
0351 ConditionsIOVPool* pool = m_rawPool[typ->type];
0352 if ( pool ) {
0353 count += pool->clean(max_age);
0354 }
0355 return count;
0356 }
0357
0358
0359 std::pair<int,int> Manager_Type1::clean(const ConditionsCleanup& cleaner) {
0360 std::pair<int,int> count(0,0);
0361 for( TypedConditionPool::iterator i=m_rawPool.begin(); i != m_rawPool.end(); ++i) {
0362 ConditionsIOVPool* p = *i;
0363 if ( p && cleaner(*p) ) {
0364 ++count.first;
0365 count.second += p->clean(cleaner);
0366 }
0367 }
0368 return count;
0369 }
0370
0371
0372 std::pair<int,int> Manager_Type1::clear() {
0373 std::pair<int,int> count(0,0);
0374 for( TypedConditionPool::iterator i=m_rawPool.begin(); i != m_rawPool.end(); ++i) {
0375 ConditionsIOVPool* p = *i;
0376 if ( p ) {
0377 ++count.first;
0378 count.second += p->clean(0);
0379 }
0380 }
0381 return count;
0382 }
0383
0384
0385 void Manager_Type1::pushUpdates() {
0386 Updates entries; {
0387 dd4hep_lock_t lock(m_updateLock);
0388 m_updatePool->popEntries(entries);
0389 }
0390
0391
0392 dd4hep_lock_t lock(m_poolLock);
0393 for(const auto& iov_iter : entries ) {
0394 const UpdatePool::ConditionEntries& ents = iov_iter.second;
0395 if ( !ents.empty() ) {
0396 for(Condition c : ents ) {
0397 c->setFlag(Condition::ACTIVE);
0398 except("ConditionsMgr",
0399 "+++ We should never end up here [%s]. FIXME!!!!",
0400 c.str(0).c_str());
0401
0402 }
0403 }
0404 }
0405 }
0406
0407
0408 bool Manager_Type1::select(Condition::key_type key,
0409 const IOV& req_validity,
0410 RangeConditions& conditions) {
0411 {
0412 ConditionsIOVPool* p = 0;
0413 dd4hep_lock_t locked_action(m_poolLock);
0414 p = m_rawPool[req_validity.type];
0415 p->select(key, req_validity, conditions);
0416 }
0417 {
0418 dd4hep_lock_t locked_action(m_updateLock);
0419 m_updatePool->select_range(key, req_validity, conditions);
0420 }
0421 return !conditions.empty();
0422 }
0423
0424
0425 bool Manager_Type1::select_range(Condition::key_type key,
0426 const IOV& req_validity,
0427 RangeConditions& conditions)
0428 {
0429 {
0430 ConditionsIOVPool* p = 0;
0431 dd4hep_lock_t locked_action(m_poolLock);
0432 p = m_rawPool[req_validity.type];
0433 p->selectRange(key, req_validity, conditions);
0434 }
0435 {
0436 dd4hep_lock_t locked_action(m_updateLock);
0437 m_updatePool->select_range(key, req_validity, conditions);
0438 }
0439 return is_range_complete(req_validity,conditions);
0440 }
0441 #if 0
0442
0443 Condition
0444 Manager_Type1::get(Condition::key_type key, const IOV& iov)
0445 {
0446 RC conditions;
0447 __check_values__<Discrete>(this, key, &iov);
0448 bool rc = select(key, iov, conditions);
0449 if ( !rc ) {
0450 dd4hep_lock_t locked_load(m_updateLock);
0451 m_loader->load_single(key, iov, conditions);
0452 }
0453 if ( conditions.size() == 1 ) {
0454 conditions[0]->flags |= Condition::ACTIVE;
0455 return conditions[0];
0456 }
0457 else if ( conditions.empty() ) {
0458 except("ConditionsMgr","+++ Condition %16llX for the requested IOV %s do not exist.",
0459 key, iov.str().c_str());
0460 }
0461 else if ( conditions.size() > 1 ) {
0462 RC::const_iterator start = conditions.begin();
0463 Condition first = *start;
0464 printout(ERROR,"ConditionsMgr","+++ Condition %s [%16llX] is ambiguous for IOV %s:",
0465 first.name(), key, iov.str().c_str());
0466 for(RC::const_iterator i=start; i!=conditions.end(); ++i) {
0467 Condition c = *i;
0468 printout(ERROR,"ConditionsMgr","+++ %s [%s] = %s",
0469 c.name(), c->iov->str().c_str(), c->value.c_str());
0470 }
0471 except("ConditionsMgr","+++ Condition %s [%16llX] is ambiguous for IOV %s:",
0472 first.name(), key, iov.str().c_str());
0473 }
0474 return Condition();
0475 }
0476
0477
0478 RangeConditions
0479 Manager_Type1::getRange(Condition::key_type key, const IOV& iov)
0480 {
0481 RC conditions;
0482 __check_values__<Range>(this, key, &iov);
0483 bool rc = select_range(key, iov, conditions);
0484 if ( rc ) {
0485 return conditions;
0486 }
0487 else {
0488 dd4hep_lock_t locked_load(m_updateLock);
0489 m_loader->load_range(key, iov, conditions);
0490 if ( conditions.empty() ) {
0491 except("ConditionsMgr","+++ Conditions %16llX for IOV %s do not exist.",
0492 key, iov.str().c_str());
0493 }
0494 conditions.clear();
0495 }
0496 rc = select_range(key, iov, conditions);
0497 if ( !rc ) {
0498 except("ConditionsMgr","+++ Conditions %16llX for IOV %s do not exist.",
0499 key, iov.str().c_str());
0500 }
0501 return conditions;
0502 }
0503 #endif
0504
0505
0506 ConditionsManager::Result
0507 Manager_Type1::prepare(const IOV& req_iov, ConditionsSlice& slice, ConditionUpdateUserContext* ctx)
0508 {
0509 __get_checked_pool(req_iov, slice.pool);
0510
0511 pushUpdates();
0512
0513 Result res = slice.pool->prepare(req_iov, slice, ctx);
0514
0515 if ( m_cleaner.get() ) {
0516 this->clean(*m_cleaner);
0517 }
0518 return res;
0519 }
0520
0521
0522 ConditionsManager::Result
0523 Manager_Type1::load(const IOV& req_iov, ConditionsSlice& slice, ConditionUpdateUserContext* ctx) {
0524 __get_checked_pool(req_iov, slice.pool);
0525
0526 pushUpdates();
0527
0528 Result res = slice.pool->load(req_iov, slice, ctx);
0529 return res;
0530 }
0531
0532
0533 ConditionsManager::Result
0534 Manager_Type1::compute(const IOV& req_iov, ConditionsSlice& slice, ConditionUpdateUserContext* ctx) {
0535 Result res = slice.pool->compute(req_iov, slice, ctx);
0536
0537 if ( m_cleaner.get() ) {
0538 this->clean(*m_cleaner);
0539 }
0540 return res;
0541 }
0542
0543
0544 std::unique_ptr<UserPool> Manager_Type1::createUserPool(const IOVType* iovT) const {
0545 if ( iovT ) {
0546 ConditionsIOVPool* p = m_rawPool[iovT->type];
0547 const void* argv[] = {this, p, 0};
0548 std::unique_ptr<UserPool> pool(createPlugin<UserPool>(m_userType,m_detDesc,2,argv));
0549 return pool;
0550 }
0551
0552 except("ConditionsMgr","+++ Unknown IOV type requested to enable conditions. [%s]",
0553 Errors::invalidArg().c_str());
0554 return std::unique_ptr<UserPool>();
0555 }
0556