Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:28

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 // Framework include files
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   /// Helper: IOV Check function declaration
0058   template <typename T> const dd4hep::IOVType* check_iov_type(const Manager_Type1* o, const dd4hep::IOV* iov);
0059 
0060   /// Helper: Specialized IOV check
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   /// Helper: Specialized IOV check for discrete IOV values
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   /// Helper: Specialized IOV check for range IOV values
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   /// Helper: Check conditions result for consistency
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       // Severe: We have an unknown IOV type. This is not allowed, 
0100       // because we do not known hot to handle it.....
0101       dd4hep::except("ConditionsMgr","+++ Invalid IOV type [%d] to access condition: %16llX.",
0102                      iov->type, key);
0103     }
0104   }
0105 
0106   /// Helper: Check if the conditions range covers the entire IOV span
0107   bool is_range_complete(const dd4hep::IOV& iov, const RC& conditions)  {
0108     if ( !conditions.empty() )  {
0109       // We need to check if the entire range is covered.
0110       // For every key.second we must find a key.first, which is at least as big
0111       dd4hep::IOV::Key test=iov.keyData;
0112       // The range may be returned unordered. Hence, 
0113       // we have to try to match at most conditions.size() times until we really know
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           //printout(INFO,"Test","IOV: %ld,%ld --> %ld,%ld",k.first,k.second, test.first, test.second);
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 /// Standard constructor
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 /// Default destructor
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 /// Register new IOV type if it does not (yet) exist.
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 /// Access IOV by its type
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 /// Access IOV by its name
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 /// Register IOV with type and key
0216 ConditionsPool* Manager_Type1::registerIOV(const IOVType& typ, IOV::Key key)   {
0217   // IOV read and checked. Now register it, but always locked!
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 /// Access conditions multi IOV pool by iov type
0238 ConditionsIOVPool* Manager_Type1::iovPool(const IOVType& iov_type)  const    {
0239   return m_rawPool[iov_type.type];
0240 }
0241 
0242 /// Register new condition with the conditions store. Unlocked version, not multi-threaded
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 /// Register a whole block of conditions with identical IOV.
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 /// Set a single conditions value to be managed.
0291 /// Requires external lock on update pool!
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 /// Helper to check iov and user pool and create user pool if not present
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   // Invalid IOV type. Throw exception
0338   except("ConditionsMgr","+++ Unknown IOV type requested to enable conditions. [%s]",
0339          Errors::invalidArg().c_str());
0340 }
0341 
0342 /// Adopt cleanup handler. If a handler is registered, it is invoked at every "prepare" step
0343 void Manager_Type1::adoptCleanup(ConditionsCleanup* cleaner)     {
0344   m_cleaner.reset(cleaner);
0345 }
0346 
0347 /// Clean conditions, which are above the age limit.
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 /// Invoke cache cleanup with user defined policy
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 /// Full cleanup of all managed conditions.
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 /// Push all pending updates to the conditions store
0385 void Manager_Type1::pushUpdates()   {
0386   Updates entries;  {
0387     dd4hep_lock_t lock(m_updateLock);
0388     m_updatePool->popEntries(entries);
0389   }
0390   // Lock global pool so that no other updates happen in the meanwhile
0391   // which could kill the pool's containers
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         //c->pool->insert(c);
0402       }
0403     }
0404   }
0405 }
0406 
0407 /// Retrieve  a condition set given a Detector Element and the conditions name according to their validity
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]; // Existence already checked by caller!
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 /// Retrieve  a condition set given a Detector Element and the conditions name according to their validity
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]; // Existence alread checked by caller!
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 /// Retrieve a condition given a Detector Element and the conditions name
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 /// Retrieve a condition given a Detector Element and the conditions name
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 /// Prepare all updates for the given keys to the clients with the defined IOV
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   /// First push any pending updates and register them to pending pools...
0511   pushUpdates();
0512   /// Now update/fill the user pool
0513   Result res = slice.pool->prepare(req_iov, slice, ctx);
0514   /// Invoke auto cleanup if registered
0515   if ( m_cleaner.get() )   {
0516     this->clean(*m_cleaner);
0517   }
0518   return res;
0519 }
0520 
0521 /// Load all updates to the clients with the defined IOV (1rst step of prepare)
0522 ConditionsManager::Result
0523 Manager_Type1::load(const IOV& req_iov, ConditionsSlice& slice, ConditionUpdateUserContext* ctx)    {
0524   __get_checked_pool(req_iov, slice.pool);
0525   /// First push any pending updates and register them to pending pools...
0526   pushUpdates();
0527   /// Now update/fill the user pool
0528   Result res = slice.pool->load(req_iov, slice, ctx);
0529   return res;
0530 }
0531 
0532 /// Compute all derived conditions with the defined IOV (2nd step of prepare)
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   /// Invoke auto cleanup if registered
0537   if ( m_cleaner.get() )   {
0538     this->clean(*m_cleaner);
0539   }
0540   return res;
0541 }
0542 
0543 /// Create empty user pool object
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   // Invalid IOV type. Throw exception
0552   except("ConditionsMgr","+++ Unknown IOV type requested to enable conditions. [%s]",
0553          Errors::invalidArg().c_str());
0554   return std::unique_ptr<UserPool>();
0555 }
0556