Back to home page

EIC code displayed by LXR

 
 

    


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

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  Markus Frank
0011 //  \date    2016-02-02
0012 //  \version 1.0
0013 //
0014 //==========================================================================
0015 //
0016 // DDDB is a detector description convention developed by the LHCb experiment.
0017 // For further information concerning the DTD, please see:
0018 // http://lhcb-comp.web.cern.ch/lhcb-comp/Frameworks/DetDesc/Documents/lhcbDtd.pdf
0019 //
0020 //==========================================================================
0021 
0022 // Framework include files
0023 #include "DDDB/DDDBConditionsLoader.h"
0024 #include "DDDB/DDDBReaderContext.h"
0025 #include "DDDB/DDDBHelper.h"
0026 
0027 // Other dd4hep includes
0028 #include "DD4hep/Printout.h"
0029 #include "DD4hep/Operators.h"
0030 #include "DDCond/ConditionsManagerObject.h"
0031 #include "DD4hep/detail/ConditionsInterna.h"
0032 
0033 // Forward declartions
0034 using namespace std;
0035 using namespace dd4hep;
0036 using namespace dd4hep::cond;
0037 using cond::ConditionsSlice;
0038 using cond::ConditionsListener;
0039 using cond::ConditionsDescriptor;
0040 using cond::ConditionsManagerObject;
0041 using cond::ConditionsLoadInfo;
0042 using DDDB::DDDBConditionsLoader;
0043 
0044 namespace {
0045   enum CMD {
0046     INSERT=1,
0047     REPLACE=2,
0048     NONE
0049   };
0050   typedef ConditionsDataLoader::RequiredItems Entries;
0051   typedef ConditionsDataLoader::LoadedItems   Loaded;
0052 
0053   /// Loader callback for Item loaders: load_single(...), load_range(...)
0054   /** 
0055    *  \author   M.Frank
0056    *  \version  1.0
0057    *  \ingroup  DD4HEP_CONDITIONS
0058    */
0059   struct ItemCollector : public ConditionsListener  {
0060   private:
0061     CMD                        cmd;
0062     Condition::key_type        key;
0063     RangeConditions&           rc;
0064     const IOV&                 req_iov;
0065 
0066   public:
0067     IOV                        iov;
0068 
0069   public:
0070     /// Initializing constructor
0071     ItemCollector(CMD c, Condition::key_type k, const IOV& i, RangeConditions& r)
0072       : cmd(c), key(k), rc(r), req_iov(i), iov(i.iovType)  {}
0073     /// ConditionsListener overload: onRegister new condition
0074     virtual void onRegisterCondition(Condition cond, void* param )  {
0075       Condition::Object* c = cond.ptr();
0076       if ( param == this && key == c->hash &&
0077            req_iov.iovType == c->iov->iovType &&
0078            IOV::key_is_contained(c->iov->keyData,req_iov.keyData) )
0079       {
0080         if ( cmd == REPLACE )  {
0081           auto i=std::find_if(rc.begin(),rc.end(),byName(cond));
0082           if ( i != rc.end() ) {
0083             (*i) = cond;
0084             printout(DEBUG,"DDDB","++ Got  MATCH: %-40s [%16llX] --> %s.",
0085                      cond.name(), cond.key(), c->address.c_str());
0086             iov.iov_intersection(*c->iov);
0087             return;
0088           }
0089           printout(INFO,"DDDB","++ Got update: %-40s [%16llX] --> %s.",
0090                    cond.name(), cond.key(), c->address.c_str());
0091         }
0092         else if (  cmd == INSERT )  {
0093           iov.iov_intersection(*c->iov);
0094           rc.insert(rc.end(),cond);
0095         }
0096       }
0097     }
0098   };
0099   
0100   /// Loader callback for Group loader: load_many(...)
0101   /** 
0102    *  \author   M.Frank
0103    *  \version  1.0
0104    *  \ingroup  DD4HEP_CONDITIONS
0105    */
0106   struct GroupCollector : public ConditionsListener  {
0107   private:
0108     Loaded&    loaded;
0109     const IOV& req_iov;
0110   public:
0111     /// Resulting IOV
0112     IOV iov;
0113   public:
0114     /// Initializing constructor
0115     GroupCollector(const IOV& i, Loaded& l)
0116       : loaded(l), req_iov(i), iov(req_iov.iovType)
0117     {
0118       iov.reset().invert();
0119     }
0120     /// ConditionsListener overload: onRegister new condition
0121     virtual void onRegisterCondition(Condition cond, void* param)  {
0122       Condition::Object* c = cond.ptr();
0123       if ( c && param == this &&
0124            req_iov.iovType == c->iov->iovType &&
0125            IOV::key_is_contained(req_iov.keyData,c->iov->keyData) )
0126       {
0127         loaded.insert(make_pair(c->hash,cond));
0128         /// This is not entirely correct:
0129         /// There may be more conditions loaded than required
0130         /// and hence the interval of the pool bigger.
0131         /// But we do not want to make another map-lookup!
0132         iov.iov_intersection(c->iov->keyData);
0133       }
0134     }
0135   };
0136 }
0137 
0138 /// Namespace for the AIDA detector description toolkit
0139 namespace dd4hep {
0140 
0141   /// Namespace for implementation details of the AIDA detector description toolkit
0142   namespace DDDB  {
0143     /// Plugin entry points.
0144     long load_dddb_conditions_from_uri(Detector& description, int argc, char** argv);
0145     long dddb_conditions_2_dd4hep(Detector& description, int argc, char** argv);
0146 
0147     long load_dddb_from_uri(Detector& description, int argc, char** argv);
0148     long dddb_2_dd4hep(Detector& description, int argc, char** argv);
0149   } /* End namespace DDDB                    */
0150 } /* End namespace dd4hep                    */
0151 
0152 
0153 /// Initializing constructor
0154 DDDBConditionsLoader::KeyCollector::KeyCollector() : call(this,0)   {
0155 }
0156 
0157 /// ConditionsListener overload: onRegister new condition
0158 void DDDBConditionsLoader::KeyCollector::onRegisterCondition(Condition cond, void*)  {
0159   Condition::Object* c = cond.ptr();
0160   // Register address key
0161   if ( (0==(c->flags&Condition::DERIVED)) && !c->address.empty() )   {
0162     KeyMap::const_iterator k = keys.find(c->hash);
0163     if ( k == keys.end() )   {
0164       const string& addr = c->address;
0165       size_t idx     = addr.find('@');
0166       string doc_nam = addr.substr(0,idx);
0167       string doc_url = addr.substr(idx+1);
0168       if ( (idx=doc_url.find('#')) != string::npos )
0169         doc_url = doc_url.substr(0,idx);
0170       keys.insert(make_pair(c->hash,make_pair(doc_url,doc_nam)));
0171     }
0172   }
0173 }
0174 
0175 /// Standard constructor, initializes variables
0176 DDDBConditionsLoader::DDDBConditionsLoader(Detector& description, ConditionsManager mgr, const string& nam) 
0177   : ConditionsDataLoader(description, mgr, nam)
0178 {
0179   DDDBHelper* helper = description.extension<DDDBHelper>(); // Ensures object existence!
0180   // It is UGLY to listen on conditions appearing to know from which file they origin
0181   // but we do not have a better way as of now....
0182   m_mgr->callOnRegister(m_keys.call,true);
0183   m_resolver = helper->xmlReader();
0184 }
0185 
0186 /// Default Destructor
0187 DDDBConditionsLoader::~DDDBConditionsLoader() {
0188   m_mgr->callOnRegister(m_keys.call,false);
0189 } 
0190 
0191 /// Load single conditions document
0192 void DDDBConditionsLoader::loadDocument(xml::UriContextReader& rdr, const Key& k)
0193 {
0194   loadDocument(rdr, k.first, k.second);
0195 }
0196 
0197 /// Load single conditions document
0198 void DDDBConditionsLoader::loadDocument(xml::UriContextReader& rdr, 
0199                                         const string& sys_id,
0200                                         const string& obj_id)
0201 {
0202   const void* argv_conddb[] = {&rdr, sys_id.c_str(), obj_id.c_str(), 0};
0203   long result = load_dddb_conditions_from_uri(m_detector, 3, (char**)argv_conddb);
0204   if ( 0 == result )  {
0205     except("DDDB","++ Failed to load conditions from URI:%s",sys_id.c_str());
0206   }
0207   const void* argv_dddb[] = {"conditions_only", 0};
0208   result = dddb_conditions_2_dd4hep(m_detector, 1, (char**)argv_dddb);
0209   if ( 0 == result )  {
0210     except("DDDBLoader","++ Failed to process conditions from URI:%s",sys_id.c_str());
0211   }
0212 }
0213 
0214 /// Load  a condition set given a Detector Element and the conditions name according to their validity
0215 size_t DDDBConditionsLoader::load_range(key_type key,
0216                                         const IOV& req_iov,
0217                                         RangeConditions& conditions)   {
0218   KeyMap::const_iterator k = m_keys.keys.find(key);
0219   if ( k != m_keys.keys.end() )   {
0220     size_t                      len = conditions.size();
0221     DDDBReaderContext           local;
0222     const Key&                  url_key = (*k).second;
0223     long                        start = req_iov.keyData.first;
0224     xml::UriContextReader       local_reader(m_resolver, &local);
0225     ItemCollector               listener(INSERT, key, req_iov, conditions);
0226 
0227     m_mgr->callOnRegister(make_pair(&listener,&listener), true);  
0228     while (start < req_iov.keyData.second )   {
0229       local.event_time  = start;
0230       local.valid_since = 0;
0231       local.valid_until = 0;
0232       listener.iov.reset().invert();
0233       loadDocument(local_reader, url_key);
0234       start = listener.iov.keyData.second+1;
0235     }
0236     m_mgr->callOnRegister(make_pair(&listener,&listener), false);
0237     return conditions.size() - len;
0238   }
0239   return 0;
0240 }
0241 
0242 /// Access single conditions from the persistent medium
0243 size_t DDDBConditionsLoader::load_single(key_type key,
0244                                          const IOV& req_iov,
0245                                          RangeConditions& conditions)  {
0246   KeyMap::const_iterator k = m_keys.keys.find(key);
0247   if ( k != m_keys.keys.end() )   {
0248     size_t                      len = conditions.size();
0249     DDDBReaderContext           local;
0250     ItemCollector               listener(INSERT, key, req_iov, conditions);
0251     xml::UriContextReader       local_reader(m_resolver, &local);
0252 
0253     local.valid_since = 0;
0254     local.valid_until = 0;
0255     local.event_time  = req_iov.keyData.first;
0256     m_mgr->callOnRegister(make_pair(&listener,&listener), true);  
0257     loadDocument(local_reader, (*k).second);
0258     m_mgr->callOnRegister(make_pair(&listener,&listener), false);
0259     return conditions.size() - len;
0260   }
0261   return 0;
0262 }
0263 
0264 /// Optimized update using conditions slice data
0265 size_t DDDBConditionsLoader::load_many(const IOV&      req_iov,
0266                                        RequiredItems&  work,
0267                                        LoadedItems&    loaded,
0268                                        IOV&            conditions_validity)
0269 {
0270   DDDBReaderContext  local;
0271   size_t len = loaded.size();
0272   map<std::string,std::string>   urls;
0273 
0274   local.event_time  = req_iov.keyData.first;
0275   local.valid_since = 0;
0276   local.valid_until = 0;
0277 
0278   xml::UriContextReader local_reader(m_resolver, &local);
0279 
0280   // First collect all required URIs which need loading.
0281   // Since one file contains many conditions, we have
0282   // to create a unique set
0283   for(const auto& i : work )  {
0284     ConditionsLoadInfo* e = i.second;
0285     std::string* addr = e->data<std::string>();
0286     if ( !addr )  {
0287       printout(INFO,"DDDBLoader","++ CANNOT update condition: [%16llX] [No load info]]",i.first);
0288       continue;
0289     }
0290     size_t idx     = addr->find('@');
0291     string doc_nam = addr->substr(0,idx);
0292     string doc_url = addr->substr(idx+1);
0293     if ( (idx=doc_url.find('#')) != string::npos )
0294       doc_url = doc_url.substr(0,idx);
0295     urls.insert(make_pair(doc_url,doc_nam));
0296   }
0297 
0298   // Now load all necessary URIs.
0299   // In the callbacks we can check if we got all required conditions
0300   GroupCollector listener(req_iov, loaded);
0301   try  {
0302     size_t loaded_len    = loaded.size();
0303     bool   print_results = isActivePrintLevel(DEBUG);
0304     m_mgr->callOnRegister(make_pair(&listener,&listener),true);
0305     listener.iov.reset().invert();
0306     for( const auto& url : urls )  {
0307       loadDocument(local_reader, url.first, url.second);
0308       if ( !print_results ) continue;
0309       printout(DEBUG,"DDDBLoader","++ Loaded %3ld conditions from %s.",loaded.size()-loaded_len,url.first.c_str());
0310       loaded_len = loaded.size();
0311     }
0312     if ( print_results )  {
0313       for( const auto& e : loaded )  {
0314         const Condition& cond = e.second;
0315         printout(INFO,"DDDBLoader","++ %16llX: %s -> %s",cond.key(),cond->value.c_str(),cond.name());
0316       }
0317     }
0318     conditions_validity = listener.iov;
0319   }
0320   catch( const exception& e )  {
0321     printout(ERROR,"DDDBLoader","+++ Load exception: %s",e.what());
0322     throw;
0323   }
0324   catch( ... )  {
0325     printout(ERROR,"DDDBLoader","+++ UNKNWON Load exception.");
0326     throw;    
0327   }
0328   m_mgr->callOnRegister(make_pair(&listener,&listener),false);
0329   return loaded.size()-len;
0330 }