Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:18:01

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 "DD4hep/Detector.h"
0022 #include "DD4hep/Path.h"
0023 #include "DD4hep/Plugins.h"
0024 #include "DD4hep/Printout.h"
0025 #include "DD4hep/Factories.h"
0026 #include "DD4hep/Alignments.h"
0027 #include "DD4hep/ConditionDerived.h"
0028 
0029 #include "DDCond/ConditionsSlice.h"
0030 #include "DDCond/ConditionsOperators.h"
0031 #include "DDCond/ConditionsManagerObject.h"
0032 
0033 #include "DDDB/DDDBReader.h"
0034 #include "DDDB/DDDBConversion.h"
0035 
0036 using namespace std;
0037 using namespace dd4hep;
0038 using namespace dd4hep::cond;
0039 
0040 using DDDB::DDDBDocument;
0041 
0042 /// Anonymous namespace for plugins
0043 namespace  {
0044 
0045   /// Helper containing shared context
0046   /**
0047    *  \author  M.Frank
0048    *  \version 1.0
0049    *  \ingroup DD4HEP_CONDITIONS
0050    */
0051   struct CallContext {
0052     long              numCall1 = 0;
0053     long              numCall2 = 0;
0054     long              numCall3 = 0;
0055     long              numFail1 = 0;
0056     long              numFail2 = 0;
0057     long              numFail3 = 0;
0058     long              numBuild1 = 0;
0059     long              numBuild2 = 0;
0060     long              numBuild3 = 0;
0061     long              numAlignments = 0;
0062     long              numNoCatalogs = 0;
0063     PrintLevel        level = INFO;
0064     CallContext() = default;
0065   };
0066   
0067   /// Specialized conditions update callback for alignments
0068   /**
0069    *  Used by clients to update a condition.
0070    *
0071    *  \author  M.Frank
0072    *  \version 1.0
0073    *  \ingroup DD4HEP_CONDITIONS
0074    */
0075   class ConditionUpdate1 : public ConditionUpdateCall {
0076   public:
0077     CallContext& context;
0078     ConditionUpdate1(CallContext& c) : context(c)  {
0079       ++context.numCall1;
0080     }
0081     virtual ~ConditionUpdate1() {    }
0082     /// Interface to client Callback in order to update the condition
0083     virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext& ) override final {
0084       printout(context.level,"ConditionUpdate1","++ Building dependent condition: %s",key.toString().c_str());
0085       Condition    target("","Alignment");
0086       target.bind<AlignmentData>();
0087       return target;
0088     }
0089     /// Interface to client Callback in order to update the condition
0090     void resolve(Condition target, ConditionUpdateContext& ctxt) override final {
0091       try  {
0092         AlignmentData& data = target.get<AlignmentData>();
0093         Condition    cond0  = ctxt.condition(ctxt.key(0));
0094         const Delta& delta  = cond0.get<Delta>();
0095         data.delta          = delta;
0096         data.flag           = AlignmentData::HAVE_NONE;
0097         ++context.numBuild1;
0098       }
0099       catch(const exception& exc)   {
0100         ++context.numFail1;
0101         printout(ERROR,"ConditionUpdate2","++ Failed to build condition %s: %s",
0102                  ctxt.key(0).toString().c_str(), exc.what());
0103       }
0104     }
0105   };
0106   /// Specialized conditions update callback for alignments
0107   /**
0108    *  Used by clients to update a condition.
0109    *
0110    *  \author  M.Frank
0111    *  \version 1.0
0112    *  \ingroup DD4HEP_CONDITIONS
0113    */
0114   class ConditionUpdate2 : public ConditionUpdateCall {
0115   public:
0116     CallContext& context;
0117     ConditionUpdate2(CallContext& c) : context(c)  {
0118       ++context.numCall2;
0119     }
0120     virtual ~ConditionUpdate2() {    }
0121     /// Interface to client Callback in order to update the condition
0122     virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext&)  override final  {
0123       printout(context.level,"ConditionUpdate2","++ Building dependent condition: %s",key.toString().c_str());
0124       Condition     target("","Alignment");
0125       target.bind<AlignmentData>();
0126       return target;
0127     }
0128     /// Interface to client Callback in order to update the condition
0129     void resolve(Condition target, ConditionUpdateContext& ctxt) override final {
0130       try  {
0131         AlignmentData& data  = target.get<AlignmentData>();
0132         Condition     cond0  = ctxt.condition(ctxt.key(0));
0133         const Delta&  delta0 = cond0.get<Delta>();
0134         const AlignmentData& data1  = ctxt.get<AlignmentData>(ctxt.key(1));
0135         data.delta           = delta0;
0136         data.delta           = data1.delta;
0137         data.flag            = AlignmentData::HAVE_NONE;
0138         ++context.numBuild2;
0139       }
0140       catch(const exception& exc)   {
0141         ++context.numFail2;
0142         printout(ERROR,"ConditionUpdate2","++ Failed to build condition %s: %s",
0143                  ctxt.key(0).toString().c_str(), exc.what());
0144       }
0145     }
0146   };
0147   /// Specialized conditions update callback for alignments
0148   /**
0149    *  Used by clients to update a condition.
0150    *
0151    *  \author  M.Frank
0152    *  \version 1.0
0153    *  \ingroup DD4HEP_CONDITIONS
0154    */
0155   class ConditionUpdate3 : public ConditionUpdateCall {
0156   public:
0157     CallContext& context;
0158     ConditionUpdate3(CallContext& c) : context(c)  {
0159       ++context.numCall3;
0160     }
0161     virtual ~ConditionUpdate3() {    }
0162     /// Interface to client Callback in order to update the condition
0163     virtual Condition operator()(const ConditionKey& key, ConditionUpdateContext&)  override final  {
0164       printout(context.level,"ConditionUpdate3","++ Building dependent condition: %s",key.toString().c_str());
0165       Condition    target("","Alignment");
0166       target.bind<AlignmentData>();
0167       return target;
0168     }
0169     /// Interface to client Callback in order to update the condition
0170     void resolve(Condition target, ConditionUpdateContext& ctxt) override final {
0171       try  {
0172         AlignmentData& data  = target.get<AlignmentData>();
0173         Condition     cond0 = ctxt.condition(ctxt.key(0));
0174         const Delta& delta0 = cond0.get<Delta>();
0175         const AlignmentData&  data1  = ctxt.get<AlignmentData>(ctxt.key(1));
0176         const AlignmentData&  data2  = ctxt.get<AlignmentData>(ctxt.key(2));
0177         data.delta          = delta0;
0178         data.delta          = data1.delta;
0179         data.delta          = data2.delta;
0180         data.flag           = AlignmentData::HAVE_NONE;
0181         ++context.numBuild3;
0182       }
0183       catch(const exception& exc)   {
0184         ++context.numFail3;
0185         printout(ERROR,"ConditionUpdate3","++ Failed to build condition %s: %s",
0186                  ctxt.key(0).toString().c_str(), exc.what());
0187       }
0188     }
0189   };
0190 
0191   /// DDDB Conditions analyser to select alignments.
0192   /**
0193    *   \author  M.Frank
0194    *   \version 1.0
0195    *   \date    31/03/2016
0196    *   \ingroup DD4HEP_DDDB
0197    */
0198   class ConditionsSelector  {
0199   public:
0200     typedef std::shared_ptr<ConditionsContent> Content;
0201     string            m_name;
0202     ConditionsManager m_manager;
0203     RangeConditions   m_allConditions;
0204     PrintLevel        m_level = INFO;
0205     CallContext       m_context;
0206     Content           content;
0207 
0208     /// Default constructor
0209     ConditionsSelector() = delete;
0210     /// Initializing constructor
0211     ConditionsSelector(const string& nam, ConditionsManager mgr, PrintLevel lvl)
0212       : m_name(nam), m_manager(mgr), m_level(lvl)
0213     {
0214       m_context.level = lvl;
0215       content.reset(new ConditionsContent());
0216       Operators::collectAllConditions(mgr, m_allConditions);
0217     }
0218     /// Default destructor
0219     virtual ~ConditionsSelector()   {
0220       printout(INFO,"Conditions","++ DDDB: Total number of conditions:   %ld", content->conditions().size());
0221       printout(INFO,"Conditions","++ DDDB: Total number of dependencies: %ld", content->derived().size());
0222       printout(INFO,"Conditions","++ DDDB: Number of Type1 instances:    %ld", m_context.numCall1);
0223       printout(INFO,"Conditions","++ DDDB: Number of Type1 callbacks:    %ld", m_context.numBuild1);
0224       printout(INFO,"Conditions","++ DDDB: Number of Type1 failures:     %ld", m_context.numFail1);
0225       printout(INFO,"Conditions","++ DDDB: Number of Type2 instances:    %ld", m_context.numCall2);
0226       printout(INFO,"Conditions","++ DDDB: Number of Type2 callbacks:    %ld", m_context.numBuild2);
0227       printout(INFO,"Conditions","++ DDDB: Number of Type2 failures:     %ld", m_context.numFail2);
0228       printout(INFO,"Conditions","++ DDDB: Number of Type3 instances:    %ld", m_context.numCall3);
0229       printout(INFO,"Conditions","++ DDDB: Number of Type3 callbacks:    %ld", m_context.numBuild3);
0230       printout(INFO,"Conditions","++ DDDB: Number of Type3 failures:     %ld", m_context.numFail3);
0231       printout(INFO,"Conditions","++ DDDB: Total Number of instances:    %ld",
0232                m_context.numCall1+m_context.numCall2+m_context.numCall3);
0233       printout(INFO,"Conditions","++ DDDB: Total Number of callbacks:    %ld",
0234                m_context.numBuild1+m_context.numBuild2+m_context.numBuild3);
0235       printout(INFO,"Conditions","++ DDDB: Total Number of failures:     %ld",
0236                m_context.numFail1+m_context.numFail2+m_context.numFail3);
0237       content.reset();
0238     }
0239 
0240     RangeConditions findCond(const string& match)   {
0241       RangeConditions result;
0242       if ( !match.empty() )  {
0243         for( Condition cond : m_allConditions )  {
0244           size_t idx = cond->value.find(match);
0245           if ( idx == 0 )  {
0246             if (cond->value.length() == match.length() )   {
0247               result.push_back(cond);
0248             }
0249             else if ( cond->value[match.length()] == '/' )  {
0250               size_t idq = cond->value.find('/',match.length()+1);
0251               if ( idq == string::npos )  {
0252                 result.push_back(cond);
0253               }
0254             }
0255           }
0256         }
0257       }
0258       return result;
0259     }
0260     long collectDependencies(DetElement de, int level)  {
0261       char fmt[64];
0262       DDDB::DDDBCatalog* cat = 0;
0263       const DetElement::Children& c = de.children();
0264 
0265       ::snprintf(fmt,sizeof(fmt),"%%-%ds-> ",2*level+5);
0266       try  {
0267         ::sprintf(fmt,"%03d %%-%ds Detector: %%s #Dau:%%d VolID:%%p",level+1,2*level+1);
0268         printout(m_level,m_name,fmt,"",de.path().c_str(),int(c.size()),(void*)de.volumeID());
0269         cat = de.extension<DDDB::DDDBCatalog>();
0270         ::sprintf(fmt,"%03d %%-%ds %%-20s -> %%s", level+1, 2*level+3);
0271         //
0272         // We use here the alignment entry from the DDDB catalog:
0273         // This ensures, that we are only bound by the name and not by any other means!
0274         //
0275         if ( !cat->condition.empty() )  {
0276           RangeConditions rc = findCond(cat->condition);
0277           printout(m_level,m_name,fmt,"","Alignment:    ", 
0278                    rc.empty() ? (cat->condition+"  !!!UNRESOLVED!!!").c_str() : cat->condition.c_str());
0279           if ( !rc.empty() )   {
0280             for( Condition cond : rc )  {
0281               ConditionKey key(de, cond->name);
0282               if ( key.hash == cond.key() && cond.typeInfo() == typeid(Delta) )  {
0283                 ConditionKey target1(de,cond->name+"/derived_1");
0284                 ConditionKey target2(de,cond->name+"/derived_2");
0285                 ConditionKey target3(de,cond->name+"/derived_3");
0286                 DependencyBuilder build_1(de, cond->name+"/derived_1", make_shared<ConditionUpdate1>(m_context));
0287                 DependencyBuilder build_2(de, cond->name+"/derived_2", make_shared<ConditionUpdate2>(m_context));
0288                 DependencyBuilder build_3(de, cond->name+"/derived_3", make_shared<ConditionUpdate3>(m_context));
0289                 build_1.add(key);
0290 
0291                 build_2.add(key);
0292                 build_2.add(target1);
0293 
0294                 build_3.add(key);
0295                 build_3.add(target1);
0296                 build_3.add(target2);
0297                 printout(m_context.level,m_name,"Build [%ld] cond.deps: %s [%s # %s] -> %016llX",
0298                          rc.size(), cat->condition.c_str(), de.path().c_str(), cond.name(), cond->hash);
0299                 content->addDependency(build_1.release());
0300                 content->addDependency(build_2.release());
0301                 content->addDependency(build_3.release());
0302               }
0303               else  { // These conditions cannot be handled....
0304                 printout(INFO,m_name,"Ignore condition: %s [%s # %s] -> Hash: %016llX Key: %016llX Type: %s",
0305                          cat->condition.c_str(), de.path().c_str(), cond.name(), cond->hash,
0306                          key.hash, cond.data().dataType().c_str());
0307               }
0308             }
0309           }
0310           ++m_context.numAlignments;
0311         }
0312       }
0313       catch(...)  {
0314         ::sprintf(fmt,"%03d %%-%ds %%s%%-20s -> %%s",level+1,2*level+3);
0315         printout(m_level,m_name, fmt, "", de.path().c_str(), "NO CATALOG availible!", "");
0316         ++m_context.numNoCatalogs;
0317       }
0318       for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i)
0319         collectDependencies((*i).second,level+1);
0320       return 1;
0321     }
0322 
0323     int computeDependencies(long time)  {
0324       const IOVType* iovType = m_manager.iovType("epoch");
0325       shared_ptr<ConditionsSlice> slice(new ConditionsSlice(m_manager,content));
0326       IOV  iov(iovType, IOV::Key(time,time));
0327       m_manager.prepare(iov, *slice);
0328       printout(m_level,"Conditions",
0329                "+++ ConditionsUpdate: Updated %ld conditions... IOV:%s",
0330                long(slice->pool->size()), iov.str().c_str());
0331       slice->pool->clear();
0332       return 1;
0333     }
0334   };
0335 
0336   //========================================================================
0337   /// Plugin function
0338   /// Load, compute and access derived conditions
0339   long dddb_derived_alignments(Detector& description, int argc, char** argv) {
0340     PrintLevel level = INFO;
0341     long time = detail::makeTime(2016,4,1,12);
0342     for(int i=0; i<argc; ++i)  {
0343       if ( ::strcmp(argv[i],"-time")==0 )  {
0344         time = detail::makeTime(argv[++i],"%d-%m-%Y %H:%M:%S");
0345         printout(level,"DDDB","Setting event time in %s to %s [%ld]",
0346                  Path(__FILE__).filename().c_str(), argv[i-1], time);
0347       }
0348       else if ( ::strcmp(argv[i],"-print")==0 )  {
0349         level = dd4hep::printLevel(argv[++i]);
0350         printout(level,"DDDB","Setting print level in %s to %s [%d]",
0351                  Path(__FILE__).filename().c_str(), argv[i-1], level);
0352       }
0353       else if ( ::strcmp(argv[i],"--help")==0 )      {
0354         printout(level,"Plugin-Help","Usage: DDDB_DerivedCondTest --opt [--opt]        ");
0355         printout(level,"Plugin-Help","  -time  <string>     Set event time Format: \"%%d-%%m-%%Y %%H:%%M:%%S\"");
0356         printout(level,"Plugin-Help","  -print <value>      Printlevel for output      ");
0357         printout(level,"Plugin-Help","  -help               Print this help message    ");
0358         ::exit(EINVAL);
0359       }
0360     }
0361 
0362     ConditionsSelector selector("DDDB_Derived",ConditionsManager::from(description), level);
0363     int ret = selector.collectDependencies(description.world(), 0);
0364     if ( ret == 1 )  {
0365       ret = selector.computeDependencies(time);
0366     }
0367     return ret;
0368   }
0369 } /* End anonymous namespace  */
0370 
0371 DECLARE_APPLY(DDDB_DerivedCondTest,dddb_derived_alignments)
0372 //==========================================================================