File indexing completed on 2025-01-30 09:18:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
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
0043 namespace {
0044
0045
0046
0047
0048
0049
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
0068
0069
0070
0071
0072
0073
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
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
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
0107
0108
0109
0110
0111
0112
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
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
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
0148
0149
0150
0151
0152
0153
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
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
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
0192
0193
0194
0195
0196
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
0209 ConditionsSelector() = delete;
0210
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
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
0273
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 {
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
0338
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 }
0370
0371 DECLARE_APPLY(DDDB_DerivedCondTest,dddb_derived_alignments)
0372