Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:14:54

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 // DDDB is a detector description convention developed by the LHCb experiment.
0015 // For further information concerning the DTD, please see:
0016 // http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/DetDesc/Documents/lhcbDtd.pdf
0017 //
0018 //==========================================================================
0019 
0020 // Framework includes
0021 #include "DetService.h"
0022 #include "DD4hep/Plugins.h"
0023 #include "DD4hep/Printout.h"
0024 #include "DD4hep/Factories.h"
0025 
0026 using namespace std;
0027 using namespace gaudi;
0028 
0029 using dd4hep::except;
0030 using dd4hep::printout;
0031 using dd4hep::PrintLevel;
0032 
0033 typedef lock_guard<mutex> Lock;
0034 
0035 /// Initializing constructor
0036 DetService::DetService(ConditionsManager m) : m_manager(m)
0037 {
0038   declareProperty("AgeLimit", m_ageLimit=3);
0039 }
0040 
0041 /// Initialize the service
0042 int DetService::initialize()   {
0043   return 1;
0044 }
0045 
0046 /// Finalize the service
0047 int DetService::finalize()   {
0048   return 1;
0049 }
0050 
0051 /// Accessor: get refernece to the conditions manager
0052 DetService::ConditionsManager DetService::manager() const   {
0053   return m_manager;
0054 }
0055 
0056 /// Accessor: Access IOV Type from conditions manager
0057 const DetService::IOVType* DetService::iovType(const std::string& identifier)  const  {
0058   return m_manager.iovType(identifier);
0059 }
0060 
0061 /// Open content creation context and copy items from registered object
0062 DetService::Content DetService::getContent(const string& nam)   {
0063   Lock lock(m_contentLock);
0064   for(const auto& c : m_activeContents)   {
0065     if ( c.first == nam )
0066       return c.second;
0067   }
0068   for(const auto& c : m_openContents)   {
0069     if ( c.first == nam )
0070       return c.second;
0071   }
0072   return Content();
0073 }
0074 
0075 /// Open content creation context and copy items from registered object
0076 DetService::Content DetService::openContent(const string& nam)   {
0077   Content ptr = getContent(nam);
0078   if ( !ptr )   {
0079     Lock lock(m_contentLock);
0080     ptr.reset(new dd4hep::cond::ConditionsContent());
0081     m_openContents.insert(m_openContents.end(),make_pair(nam,ptr));
0082     return ptr;
0083   }
0084   except("DetService",
0085          "openContent FAILED. ConditionsContent object with name %s exists already.",
0086          nam.c_str());
0087   return Content();
0088 }
0089 
0090 /// Add a condition address to the content. Condition is identified by its global key
0091 bool DetService::_addContent(Content& content,
0092                              Condition::key_type key,
0093                              const std::string& address)    {
0094   if ( content )   {
0095     for(auto& c : m_openContents)    {
0096       if ( content == c.second )   {
0097         if ( c.second->addLocation(key, address).first )   {
0098           return true;
0099         }
0100       }
0101     }
0102   }
0103   return false;
0104 }
0105 
0106 /// Add a condition address to the content. Condition is identified by its global key
0107 void DetService::addContent(Content& content,
0108                             Condition::key_type key,
0109                             const std::string& address)    {
0110   /// Fast return if all fine:
0111   if ( _addContent(content, key, address) )
0112     return;
0113   /// Handle errors:
0114   if ( content )   {
0115     for(auto& c : m_openContents)    {
0116       if ( content == c.second )   {
0117         except("DetService","Attempt to insert item with duplicate key: %016lX", key);
0118       }
0119     }
0120     except("DetService","This content object is not availible for manipulation. Key:%016X", key);
0121   }
0122   except("DetService","This content object is INVALID and cannot be manipulated. Key:%016X", key);
0123 }
0124 
0125 /// Add a condition address to the content
0126 void DetService::addContent(Content& content,
0127                             DetElement det,
0128                             const string& item,
0129                             const string& address)   {
0130   dd4hep::ConditionKey key(det.key(), item);
0131   if ( _addContent(content, key.hash, address) )
0132     return;
0133   if ( content )   {
0134     for(auto& c : m_openContents)    {
0135       if ( content == c.second )   {
0136         except("DetService","Attempt to insert item with duplicate key:%s -> %s",
0137                det.path().c_str(), item.c_str());
0138       }
0139     }
0140     except("DetService","This content object is not availible for manipulation. %s -> %s",
0141            det.path().c_str(), item.c_str());
0142   }
0143   except("DetService","This content object is INVALID and cannot be manipulated. %s -> %s",
0144          det.path().c_str(), item.c_str());
0145 }
0146 
0147 /// Add a condition functor for a derived condition to the content
0148 void DetService::addContent(Content& content, Dependency* dep)
0149 {
0150   if ( content && dep )   {
0151     for(auto& c : m_openContents)  {
0152       if ( content == c.second && c.second->addDependency(dep->addRef()).first )   {
0153         return;
0154       }
0155       except("DetService","Attempt to insert dependency with duplicate key.");
0156     }
0157     except("DetService","This content object is not availible for manipulation.");
0158   }
0159   except("DetService","This content object is INVALID and cannot be manipulated.");
0160 }
0161 
0162 /// Open content creation context
0163 void DetService::closeContent(Content& content)   {
0164   if ( content )   {
0165     for(auto c=m_openContents.begin(); c!=m_openContents.end(); ++c)  {
0166       if ( content == (*c).second )   {
0167         Lock lock(m_contentLock);
0168         m_activeContents.insert(m_activeContents.end(),*c);
0169         m_openContents.erase(c);
0170         return;
0171       }
0172     }
0173     except("DetService","This content object is not availible for manipulation.");
0174   }
0175   except("DetService","This content object is INVALID and cannot be manipulated.");
0176 }
0177 
0178 /// Remove content from cache container
0179 bool DetService::_remove(CachedContents& cache, Content& content)   {
0180   for(auto c=cache.begin(); c!=cache.end(); ++c)  {
0181     if ( content == (*c).second )   {
0182       cache.erase(c);
0183       return true;
0184     }
0185   }
0186   return false;
0187 }
0188 
0189 /// Close content creation context
0190 bool DetService::removeContent(Content& cont)   {
0191   Lock lock(m_contentLock);
0192   if ( cont )   {
0193     bool ret = _remove(m_activeContents,cont)  ? true : _remove(m_openContents,cont);
0194     if ( ret ) cont.reset();
0195     return ret;
0196   }
0197   return false;
0198 }
0199 
0200 /// Age all slices and check for slices which have expired.
0201 void DetService::_age()  {
0202   CachedSlices tmp = m_cache;
0203   m_cache.clear();
0204   m_cache.reserve(tmp.size());
0205   for( size_t i=0; i<tmp.size(); ++i ) {
0206     if ( ++tmp[i]->age > m_ageLimit && tmp[i]->slice.unique() ) continue;
0207     m_cache.push_back(tmp[i]);
0208     tmp[i] = 0;
0209   }
0210   for(auto* cc : tmp)   {
0211     if ( cc ) delete cc;
0212   }
0213 }
0214 
0215 /// Find an existing cached slice
0216 DetService::Slice DetService::_find(Content& content,
0217                                     const IOVType* typ,
0218                                     EventStamp stamp)
0219 {
0220   // When we are here we know that all arguments make sense.
0221   // No need here for any further checks
0222   dd4hep::IOV req_iov(typ,stamp);
0223   // First scan the cache: maybe we do not have to do anything.....
0224   for(CacheEntry* c : m_cache)    {
0225     if ( c->iov.iovType != typ ) continue;
0226     if ( content != c->slice->content ) continue;
0227     if ( dd4hep::IOV::key_is_contained(req_iov.keyData,c->iov.keyData) )  {
0228       c->age = 0;
0229       _age();
0230       c->age = 0;
0231       return c->slice;
0232     }
0233   }
0234   return  Slice();
0235 }
0236 
0237 /// Project a newly created conditions slice.
0238 DetService::Slice DetService::_create(Content& content,
0239                                       Context *ctx,
0240                                       const IOVType* typ,
0241                                       EventStamp stamp)
0242 {
0243   dd4hep::IOV req_iov(typ, stamp);
0244   unique_ptr<CacheEntry> e(new CacheEntry());
0245   e->slice.reset(new dd4hep::cond::ConditionsSlice(m_manager,content));
0246   m_manager.prepare(req_iov, *e->slice, ctx);
0247   m_cache.push_back(e.release());
0248   return m_cache.back()->slice;
0249 }
0250 
0251 /// Project a new conditions slice. If a free cached slice is availible, it shall be re-used
0252 DetService::Slice DetService::_project(Content& content,
0253                                        Context *ctx,
0254                                        const IOVType* typ,
0255                                        EventStamp stamp)   {
0256   Slice ptr;
0257   if ( content )  {
0258     Lock lock(m_sliceLock);
0259     if ( !(ptr=_find(content, typ, stamp)) )   {
0260       return _create(content, ctx, typ, stamp);
0261     }
0262     except("DetService","Invalid conditions content give. Cannot create slice.");
0263   }
0264   return ptr;
0265 }
0266 
0267 /// Project a new conditions slice. If a free cached slice is availible, it shall be re-used
0268 DetService::Slice DetService::project(Content& content,
0269                                       Context *ctx,
0270                                       const IOVType* typ,
0271                                       EventStamp stamp)   {
0272   /// Check if the givem IOV type is correct
0273   auto used_types = m_manager.iovTypesUsed();
0274   for(const auto* i : used_types)  {
0275     if ( i == typ )   {
0276       return _project(content, ctx, i, stamp);
0277     }
0278   }
0279   dd4hep::except("DetService",
0280                  "Request to project a conditions slice for an unknown IOV type.");
0281   return Slice();
0282 }
0283 
0284 /// Project a new conditions slice. If a free cached slice is availible, it shall be re-used
0285 DetService::Slice DetService::project(Content& content,
0286                                       Context *ctx,
0287                                       const string& typ,
0288                                       EventStamp stamp)   {
0289   /// Check if the givem IOV type is correct
0290   const IOVType* iovType = m_manager.iovType(typ);
0291   if ( iovType )  {
0292     return _project(content, ctx, iovType, stamp);
0293   }
0294   dd4hep::except("DetService",
0295                  "Request to project a conditions slice for an unknown IOV type: %s",
0296                  typ.c_str());
0297   return Slice();
0298 }
0299 
0300 /// Project a new conditions slice. If a free cached slice is availible, it shall be re-used
0301 DetService::Slice DetService::project(const string& content,
0302                                       Context *ctx,
0303                                       const string& typ,
0304                                       EventStamp stamp)   {
0305   Content cont(getContent(content));
0306   if ( cont )   {
0307     return project(cont, ctx, typ, stamp);
0308   }
0309   dd4hep::except("DetService",
0310                  "Request to project a conditions slice for unknown content: %s",
0311                  content.c_str());
0312   return Slice();
0313 }
0314 
0315 /// Invoke slice cleanup
0316 void DetService::cleanup(const Cleanup &cleaner)   {
0317   m_manager.clean(cleaner);
0318 }