diff --git a/DDAlign/include/DDAlign/AlignmentUpdateCall.h b/DDAlign/include/DDAlign/AlignmentUpdateCall.h index b0d7226483ba3aee8d6422e3cd8e19e620ac8287..8f5bae5da42d999fed69e743f4e4ff7b77c96671 100644 --- a/DDAlign/include/DDAlign/AlignmentUpdateCall.h +++ b/DDAlign/include/DDAlign/AlignmentUpdateCall.h @@ -17,6 +17,7 @@ #include "DD4hep/ConditionDerived.h" #include "DD4hep/AlignmentData.h" #include "DD4hep/Alignments.h" +#include "DD4hep/Printout.h" /// Namespace for the AIDA detector description toolkit namespace DD4hep { @@ -50,6 +51,9 @@ namespace DD4hep { typedef Alignments::AlignmentData Data; typedef Alignments::AlignmentData::Delta Delta; + /// adjustable printout level for informative messages + PrintLevel printLevel; + public: /// Default constructor AlignmentUpdateCall(); diff --git a/DDAlign/include/DDAlign/AlignmentsForward.h b/DDAlign/include/DDAlign/AlignmentsForward.h index 34e2c7350a0b12afd71622e3ba3ff8eb942942fd..7782d49a74fa99f561a8e58d114bdfb4363ead58 100644 --- a/DDAlign/include/DDAlign/AlignmentsForward.h +++ b/DDAlign/include/DDAlign/AlignmentsForward.h @@ -17,6 +17,7 @@ #include "DD4hep/Alignments.h" #include "DD4hep/Conditions.h" #include "DD4hep/Detector.h" +#include "DD4hep/Printout.h" #include "DDAlign/AlignmentsManager.h" /// Namespace for the AIDA detector description toolkit @@ -36,6 +37,11 @@ namespace DD4hep { * This class has the same interface like AlignmentsRegister. * Please see AlignmentsRegister.h for further information. * + * Note: We have to load one set of conditions in order to auto-populate + * because we need to see if a detector element actually has alignment + * conditions. For this we must access the conditions data. + * Unfortunate, but unavoidable. + * * \author M.Frank * \version 1.0 * \date 31/03/2016 @@ -55,7 +61,9 @@ namespace DD4hep { std::string alias; /// Flag if an alias to the real alignment object should be registered bool haveAlias; - + /// Print level + PrintLevel printLevel; + /// Initializing constructor AlignmentsForward(AlignmentsManager m, AlignmentUpdateCall* c, UserPool* p); /// Default destructor diff --git a/DDAlign/include/DDAlign/AlignmentsManager.h b/DDAlign/include/DDAlign/AlignmentsManager.h index 4d9a1df8553ea1d1eef63ea166f2d2dba9a8de4f..1e558c7e7b58fb2bd60438b4e9075077030dd123 100644 --- a/DDAlign/include/DDAlign/AlignmentsManager.h +++ b/DDAlign/include/DDAlign/AlignmentsManager.h @@ -57,7 +57,23 @@ namespace DD4hep { typedef Conditions::ConditionDependency Dependency; /// Alignments re-use conditions dependency container def from the conditions manager typedef Conditions::ConditionsDependencyCollection Dependencies; - + + /// Result of a computation call to the alignments manager + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class Result { + public: + size_t computed = 0; + size_t missing = 0; + Result() = default; + Result(const Result& result) = default; + Result& operator=(const Result& result) = default; + size_t total() const { return computed+missing; } + }; + public: /// Static accessor if installed as an extension @@ -91,13 +107,13 @@ namespace DD4hep { /// Access all known dependencies const Dependencies& knownDependencies() const; /// Compute all alignment conditions of the internal dependency list - void compute(Slice& slice) const; + Result compute(Slice& slice) const; /// Compute all alignment conditions of the specified dependency list - void compute(Slice& slice, const Dependencies& deps) const; + Result compute(Slice& slice, const Dependencies& deps) const; /// Compute all alignment conditions of the internal dependency list - void compute(Pool& pool) const; + Result compute(Pool& pool) const; /// Compute all alignment conditions of the specified dependency list - void compute(Pool& pool, const Dependencies& deps) const; + Result compute(Pool& pool, const Dependencies& deps) const; /// Register new updated derived alignment during the computation step static void newEntry(const Context& parameter, DetElement& det, @@ -117,6 +133,7 @@ namespace DD4hep { class AlignmentsManagerObject : public NamedObject { public: typedef AlignmentsManager::Pool Pool; + typedef AlignmentsManager::Result Result; typedef AlignmentsManager::Dependencies Dependencies; /// Full list of alignment dependencies @@ -126,9 +143,9 @@ namespace DD4hep { protected: /// Compute the transformation from the closest detector element of the alignment to the world system - void to_world(AlignContext& new_alignments, Pool& pool, DetElement det, TGeoHMatrix& mat) const; + Result to_world(AlignContext& new_alignments, Pool& pool, DetElement det, TGeoHMatrix& mat) const; /// Compute all alignment conditions of the lower levels - void compute(AlignContext& new_alignments, Pool& pool, DetElement child) const; + Result compute(AlignContext& new_alignments, Pool& pool, DetElement child) const; public: /// Initializing constructor @@ -136,9 +153,9 @@ namespace DD4hep { /// Default destructor virtual ~AlignmentsManagerObject(); /// Compute all alignment conditions of the internal dependency list - void compute(Pool& pool) const; + Result compute(Pool& pool) const; /// Compute all alignment conditions of the specified dependency list - void compute(Pool& pool, const Dependencies& deps) const; + Result compute(Pool& pool, const Dependencies& deps) const; }; } /* End namespace Geometry */ diff --git a/DDAlign/include/DDAlign/AlignmentsRegister.h b/DDAlign/include/DDAlign/AlignmentsRegister.h index c2f06e0f31ea4895529f0b0688a1287ee2c02b1a..401d5e4b5330095b036394e60a24dd532e0e9bd2 100644 --- a/DDAlign/include/DDAlign/AlignmentsRegister.h +++ b/DDAlign/include/DDAlign/AlignmentsRegister.h @@ -17,6 +17,7 @@ #include "DD4hep/Alignments.h" #include "DD4hep/Conditions.h" #include "DD4hep/Detector.h" +#include "DD4hep/Printout.h" #include "DDAlign/AlignmentsManager.h" /// Namespace for the AIDA detector description toolkit @@ -49,6 +50,11 @@ namespace DD4hep { * The way to register the alignments with the detector element * strongly depend on the surrounding experiment framework. * + * Note: We have to load one set of conditions in order to auto-populate + * because we need to see if a detector element actually has alignment + * conditions. For this we must access the conditions data. + * Unfortunate, but unavoidable. + * * \author M.Frank * \version 1.0 * \date 31/03/2016 @@ -68,6 +74,8 @@ namespace DD4hep { std::string alias; /// Flag if an alias to the real alignment object should be registered bool haveAlias; + /// Print level + PrintLevel printLevel; /// Initializing constructor AlignmentsRegister(AlignmentsManager m, AlignmentUpdateCall* c, UserPool* p); diff --git a/DDAlign/src/AlignmentUpdateCall.cpp b/DDAlign/src/AlignmentUpdateCall.cpp index 815f9add4eb7cbc86b26168859964b2bcffd8690..c0a0951ccf2aacbedc53af73408010c6c0267cca 100644 --- a/DDAlign/src/AlignmentUpdateCall.cpp +++ b/DDAlign/src/AlignmentUpdateCall.cpp @@ -21,7 +21,8 @@ using namespace DD4hep::Alignments; /// Default constructor -AlignmentUpdateCall::AlignmentUpdateCall() : DD4hep::Conditions::ConditionUpdateCall() +AlignmentUpdateCall::AlignmentUpdateCall() + : DD4hep::Conditions::ConditionUpdateCall(), printLevel(DEBUG) { InstanceCount::increment(this); } diff --git a/DDAlign/src/AlignmentsForward.cpp b/DDAlign/src/AlignmentsForward.cpp index 0aad284e33b474716c80cf3f057c11cab91f5bee..98a0a8646939743ed9665913b4df0dc6a758c66f 100644 --- a/DDAlign/src/AlignmentsForward.cpp +++ b/DDAlign/src/AlignmentsForward.cpp @@ -24,7 +24,8 @@ using namespace DD4hep::Alignments; /// Initializing constructor AlignmentsForward::AlignmentsForward(AlignmentsManager m, AlignmentUpdateCall* c, UserPool* p) - : alignmentMgr(m), updateCall(c), user_pool(p), extension("#alignment/Tranformations"), alias("Alignment"), haveAlias(true) + : alignmentMgr(m), updateCall(c), user_pool(p), extension("#alignment/Tranformations"), + alias("Alignment"), haveAlias(true), printLevel(DEBUG) { } @@ -61,13 +62,13 @@ int AlignmentsForward::processElement(DetElement de) { Conditions::DependencyBuilder b(k, updateCall->addRef(), de); bool result = alignmentMgr.adoptDependency(b.release()); if ( result ) { - printout(INFO,"AlignForward", - "++ Added Alignment child dependency Cond:%s Key:%08X", + printout(printLevel,"AlignForward", + "++ Added Alignment child dependency Cond:%s Key:%16llX", k.name.c_str(), k.hash); return 1; } printout(ERROR,"AlignForward", - "++ FAILED to add Alignment dependency Cond:%s Key:%08X", + "++ FAILED to add Alignment dependency Cond:%s Key:%16llX", k.name.c_str(), k.hash); } } diff --git a/DDAlign/src/AlignmentsManager.cpp b/DDAlign/src/AlignmentsManager.cpp index 91596ea9d62734462ee13ee36d97717635922e8c..78eb9669e123d7209a873ca31116c337d8f175e5 100644 --- a/DDAlign/src/AlignmentsManager.cpp +++ b/DDAlign/src/AlignmentsManager.cpp @@ -107,12 +107,14 @@ AlignmentsManagerObject::~AlignmentsManagerObject() { InstanceCount::decrement(this); } -void AlignmentsManagerObject::to_world(AlignContext& new_alignments, - UserPool& pool, - DetElement det, - TGeoHMatrix& delta_to_world) const +AlignmentsManager::Result +AlignmentsManagerObject::to_world(AlignContext& new_alignments, + UserPool& pool, + DetElement det, + TGeoHMatrix& delta_to_world) const { using Conditions::Condition; + Result result; DetElement par = det.parent(); while( par.isValid() ) { // If we find that the parent also got updated, directly take this transformation. @@ -122,7 +124,9 @@ void AlignmentsManagerObject::to_world(AlignContext& new_alignments, const AlignContext::Entry& e = new_alignments.entries[(*i).second]; // The parent entry is (not yet) valid. need to compute it first if ( 0 == e.valid ) { - compute(new_alignments, pool, par); + Result r = compute(new_alignments, pool, par); + result.missing += r.missing; + result.computed += r.computed; } AlignmentCondition cond(e.cond); AlignmentData& align = cond.data(); @@ -135,7 +139,8 @@ void AlignmentsManagerObject::to_world(AlignContext& new_alignments, if ( s_PRINT <= INFO ) { printf(" Result :"); delta_to_world.Print(); } - return; + ++result.computed; + return result; } // The parent did not get updated: We have to search the conditions pool if // there is a still valid condition, which we can use to build the world transformation @@ -156,7 +161,8 @@ void AlignmentsManagerObject::to_world(AlignContext& new_alignments, if ( s_PRINT <= INFO ) { printf(" Result :"); delta_to_world.Print(); } - return; + ++result.computed; + return result; } // There is no special alignment for this detector element. // Hence to nominal (relative) transformation to the parent is valid @@ -171,45 +177,27 @@ void AlignmentsManagerObject::to_world(AlignContext& new_alignments, } par = par.parent(); } + ++result.computed; + return result; } /// Compute all alignment conditions of the internal dependency list -void AlignmentsManagerObject::compute(Pool& pool) const { - compute(pool, *dependencies); +AlignmentsManager::Result AlignmentsManagerObject::compute(Pool& pool) const { + return compute(pool, *dependencies); } /// Compute all alignment conditions of the specified dependency list -void AlignmentsManagerObject::compute(Pool& pool, const Dependencies& deps) const { +AlignmentsManager::Result AlignmentsManagerObject::compute(Pool& pool, const Dependencies& deps) const { + Result result; AlignContext new_alignments; new_alignments.entries.reserve(deps.size()); pool.compute(deps, &new_alignments); - for(auto i=new_alignments.entries.begin(); i != new_alignments.entries.end(); ++i) - compute(new_alignments, pool, (*i).det); -#if 0 - std::string prev = "-----"; - for(auto i=new_alignments.detectors.begin(); i!=new_alignments.detectors.end(); ++i) { - AlignContext::Entry& e = new_alignments.entries[(*i).second]; - DetElement det = e.det; - const std::string& p = det.path(); - size_t idx = p.find(prev); - if ( idx == 0 ) { - continue; - } - prev = p; - printout(s_PRINT,"Alignment","Update top Node: Lvl:%d Key:%08X: %s", det.level(), det.key(), p.c_str()); - e.top = 1; - } - // We got now the top nodes of the new_alignments. From the top nodes we have to - // recursively calculate all changes downwards the lower levels! - // Note: The upper levels are already correct and do not need to be updated! - printout(INFO,"Alignment","Working down the tree...."); - for(auto i=new_alignments.detectors.begin(); i != new_alignments.detectors.end(); ++i) { - AlignContext::Entry& e = new_alignments.entries[(*i).second]; - if ( e.top ) { - compute(new_alignments, pool, e.det); - } + for(auto i=new_alignments.entries.begin(); i != new_alignments.entries.end(); ++i) { + Result r = compute(new_alignments, pool, (*i).det); + result.computed += r.computed; + result.missing += r.missing; } -#endif + return result; } /// Compute the alignment delta for one detector element and it's alignment condition @@ -242,14 +230,16 @@ static void computeDelta(AlignmentCondition cond, TGeoHMatrix& tr_delta) { } /// Compute all alignment conditions of the lower levels -void AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& pool, DetElement det) const { +AlignmentsManager::Result +AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& pool, DetElement det) const { + Result result, temp; auto k=new_alignments.keys.find(det.key()); bool has_cond = (k != new_alignments.keys.end()); AlignContext::Entry* ent = has_cond ? &new_alignments.entries[(*k).second] : 0; if ( ent && ent->valid == 1 ) { printout(DEBUG,"ComputeAlignment","================ IGNORE %s (already valid)",det.path().c_str()); - return; + return result; } if ( ent && ent->valid == 0 ) { TGeoHMatrix tr_delta; @@ -263,12 +253,14 @@ void AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& po ent->valid = 1; computeDelta(cond, tr_delta); align.worldDelta = tr_delta; - to_world(new_alignments, pool, det, align.worldDelta); + temp = to_world(new_alignments, pool, det, align.worldDelta); + result.computed += temp.computed; + result.missing += temp.missing; align.worldTrafo = det.nominal().worldTransformation()*align.worldDelta; align.detectorTrafo = det.nominal().detectorTransformation()*tr_delta; align.trToWorld = Geometry::_transform(&align.worldDelta); if ( s_PRINT <= INFO ) { - printout(INFO,"ComputeAlignment","Level:%d Path:%s DetKey:%08X: Cond:%s key:%08X IOV:%s", + printout(INFO,"ComputeAlignment","Level:%d Path:%s DetKey:%08X: Cond:%s key:%16llX IOV:%s", det.level(), det.path().c_str(), det.key(), yes_no(has_cond), cond.key(), cond.iov().str().c_str()); } @@ -304,8 +296,11 @@ void AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& po const DetElement::Children& children = det.children(); for(auto c=children.begin(); c!=children.end(); ++c) { DetElement child = (*c).second; - compute(new_alignments, pool, child); + temp = compute(new_alignments, pool, child); + result.computed += temp.computed; + result.missing += temp.missing; } + return result; } /// Initializing constructor @@ -340,25 +335,25 @@ const AlignmentsManager::Dependencies& AlignmentsManager::knownDependencies() c } /// Compute all alignment conditions of the internal dependency list -void AlignmentsManager::compute(Slice& slice) const { +AlignmentsManager::Result AlignmentsManager::compute(Slice& slice) const { Object* o = access(); - o->compute(*slice.pool(), *(o->dependencies)); + return o->compute(*slice.pool(), *(o->dependencies)); } /// Compute all alignment conditions of the specified dependency list -void AlignmentsManager::compute(Slice& slice, const Dependencies& deps) const { - access()->compute(*slice.pool(), deps); +AlignmentsManager::Result AlignmentsManager::compute(Slice& slice, const Dependencies& deps) const { + return access()->compute(*slice.pool(), deps); } /// Compute all alignment conditions of the internal dependency list -void AlignmentsManager::compute(Pool& pool) const { +AlignmentsManager::Result AlignmentsManager::compute(Pool& pool) const { Object* o = access(); - o->compute(pool, *(o->dependencies)); + return o->compute(pool, *(o->dependencies)); } /// Compute all alignment conditions of the specified dependency list -void AlignmentsManager::compute(Pool& pool, const Dependencies& deps) const { - access()->compute(pool, deps); +AlignmentsManager::Result AlignmentsManager::compute(Pool& pool, const Dependencies& deps) const { + return access()->compute(pool, deps); } /// Register new updated derived alignment during the computation step diff --git a/DDAlign/src/AlignmentsRegister.cpp b/DDAlign/src/AlignmentsRegister.cpp index 134bed08e6d4990a787e00d9148c019238070a46..85778dd5e987009ca61334afc011f4cd21ff56bf 100644 --- a/DDAlign/src/AlignmentsRegister.cpp +++ b/DDAlign/src/AlignmentsRegister.cpp @@ -27,7 +27,8 @@ using Conditions::Condition; /// Initializing constructor AlignmentsRegister::AlignmentsRegister(AlignmentsManager m, AlignmentUpdateCall* c, UserPool* p) - : alignmentMgr(m), updateCall(c), user_pool(p), extension("/Tranformations"), alias("Alignment"), haveAlias(true) + : alignmentMgr(m), updateCall(c), user_pool(p), extension("/Tranformations"), + alias("Alignment"), haveAlias(true), printLevel(DEBUG) { } @@ -56,8 +57,11 @@ int AlignmentsRegister::processElement(DetElement de) { for ( const auto& c : cont.keys() ) { Condition cond = cont.get(c.first, *user_pool); printout(DEBUG,"AlignRegister", - "++ Processing DE %s Cond:%s Key:%08X flags:%d", + "++ Processing DE %s Cond:%s Key:%16llX flags:%d", de.path().c_str(), cond.name(), cond.key(), cond->flags); + // + // Due to this very check we have to load the condition..... + // if ( (cond->flags&Condition::ALIGNMENT) ) { std::string alignment_name = construct_name(de, cond); if ( !alignment_name.empty() ) { @@ -77,13 +81,13 @@ int AlignmentsRegister::processElement(DetElement de) { b.add(Conditions::ConditionKey(cond->name)); bool result = alignmentMgr.adoptDependency(b.release()); if ( result ) { - printout(INFO,"AlignRegister", - "++ Added Alignment dependency Cond:%s Key:%08X flags:%d", + printout(printLevel,"AlignRegister", + "++ Added Alignment dependency Cond:%s Key:%16llX flags:%d", k.name.c_str(), k.hash, cond->flags); continue; } printout(ERROR,"AlignRegister", - "++ FAILED to add Alignment dependency Cond:%s Key:%08X flags:%d", + "++ FAILED to add Alignment dependency Cond:%s Key:%16llX flags:%d", k.name.c_str(), k.hash, cond->flags); } } diff --git a/DDAlign/src/DDAlignUpdateCall.cpp b/DDAlign/src/DDAlignUpdateCall.cpp index e8a7e2a196e9e04628e1578860134601952abe5a..75ddf5f0571de7ca492f27e051a202899812dbbe 100644 --- a/DDAlign/src/DDAlignUpdateCall.cpp +++ b/DDAlign/src/DDAlignUpdateCall.cpp @@ -28,7 +28,7 @@ Alignments::DDAlignUpdateCall::operator()(const ConditionKey& key, const UpdateC if ( cond.typeInfo() == typeid(Data::Delta) ) { const Data::Delta& delta = cond.get<Data::Delta>(); Condition c = AlignmentUpdateCall::handle(key, context, delta); - printout(INFO,"DDAlignUpdate","++ Building dependent condition: %s Detector [%d]: %s [%p]", + printout(printLevel,"DDAlignUpdate","++ Building dependent condition: %s Detector [%d]: %s [%p]", key.name.c_str(), det.level(), det.path().c_str(), c.ptr()); return c; } diff --git a/DDAlign/src/plugins/AlignmentDependencyTest.cpp b/DDAlign/src/plugins/AlignmentDependencyTest.cpp index f476764e8751490c329fbdf33038cb97e4d77a31..0764fbf8ba00acf1b3545f3977057d87e06d551e 100644 --- a/DDAlign/src/plugins/AlignmentDependencyTest.cpp +++ b/DDAlign/src/plugins/AlignmentDependencyTest.cpp @@ -72,7 +72,7 @@ int access(ConditionsManager conds,AlignmentsManager align,long time) { { Alignments::Alignment a = c.get(k.hash,p); const Alignments::Delta& D = a.data().delta; - printout(INFO,"Alignment","++ [%08X] (%11s-%8s-%5s) Cond:%p '%s'", k.hash, + printout(INFO,"Alignment","++ [%16llX] (%11s-%8s-%5s) Cond:%p '%s'", k.hash, D.hasTranslation() ? "Translation" : "", D.hasRotation() ? "Rotation" : "", D.hasPivot() ? "Pivot" : "", @@ -83,7 +83,7 @@ int access(ConditionsManager conds,AlignmentsManager align,long time) { { Alignments::Alignment a = c.get("Alignment",p); const Alignments::Delta& D = a.data().delta; - printout(INFO,"Alignment","++ [%08X] (%11s-%8s-%5s) Cond:%p 'Alignment'", k.hash, + printout(INFO,"Alignment","++ [%16llX] (%11s-%8s-%5s) Cond:%p 'Alignment'", k.hash, D.hasTranslation() ? "Translation" : "", D.hasRotation() ? "Rotation" : "", D.hasPivot() ? "Pivot" : "", diff --git a/DDCond/include/DDCond/ConditionsDependencyCollection.h b/DDCond/include/DDCond/ConditionsDependencyCollection.h index c886940168f33f83117c9cbea96adac84eb446a9..023fc1cf3ead3fc78ef01c69e91d30273052bfff 100644 --- a/DDCond/include/DDCond/ConditionsDependencyCollection.h +++ b/DDCond/include/DDCond/ConditionsDependencyCollection.h @@ -56,11 +56,11 @@ namespace DD4hep { }; /// Forward definition of the dependency container type - typedef std::map<unsigned int,Holder> Dependencies; - typedef Dependencies::const_iterator const_iterator; - typedef Dependencies::iterator iterator; - typedef Dependencies::key_type key_type; - typedef Dependencies::mapped_type mapped_type; + typedef std::map<Condition::key_type,Holder> Dependencies; + typedef Dependencies::const_iterator const_iterator; + typedef Dependencies::iterator iterator; + typedef Dependencies::key_type key_type; + typedef Dependencies::mapped_type mapped_type; /// Functor base to create views /** diff --git a/DDCond/include/DDCond/ConditionsDependencyHandler.h b/DDCond/include/DDCond/ConditionsDependencyHandler.h index e59002db6209e06edab440eb91fc217d05d6ac9f..be74653fd2b1ea20f764f4ccd21bc0d54f3261f0 100644 --- a/DDCond/include/DDCond/ConditionsDependencyHandler.h +++ b/DDCond/include/DDCond/ConditionsDependencyHandler.h @@ -53,7 +53,12 @@ namespace DD4hep { ConditionsPool* m_iovPool; /// User defined optional processing parameter void* m_userParam; - + + public: + /// Number of callbacks to the handler for monitoring + mutable size_t num_callback; + + protected: /// Internal call to trigger update callback Condition::Object* do_callback(const ConditionDependency& dep) const; @@ -74,7 +79,7 @@ namespace DD4hep { /// ConditionResolver implementation: Interface to access conditions. virtual Condition get(const ConditionKey& key) const { return get(key.hash); } /// ConditionResolver implementation: Interface to access conditions - virtual Condition get(unsigned int key) const; + virtual Condition get(Condition::key_type key) const; /// Handler callback to process multiple derived conditions Condition::Object* operator()(const ConditionDependency* dep) const; }; diff --git a/DDCond/include/DDCond/ConditionsManager.h b/DDCond/include/DDCond/ConditionsManager.h index baa7142cfbfb6d73523417ab046a46666f35b4d0..6f651c5a0efadeda2e9bd8901cf546a734f59f9c 100644 --- a/DDCond/include/DDCond/ConditionsManager.h +++ b/DDCond/include/DDCond/ConditionsManager.h @@ -48,6 +48,24 @@ namespace DD4hep { typedef ConditionsDataLoader Loader; typedef std::vector<IOVType> IOVTypes; + /// Result of a prepare call to the conditions manager + /** + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class Result { + public: + size_t selected = 0; + size_t loaded = 0; + size_t computed = 0; + size_t missing = 0; + Result() = default; + Result(const Result& result) = default; + Result& operator=(const Result& result) = default; + size_t total() const { return selected+computed+loaded; } + }; + public: /// Static accessor if installed as an extension @@ -133,8 +151,8 @@ namespace DD4hep { void clear() const; /// Prepare all updates to the clients with the defined IOV - long prepare(const IOV& required_validity, - ConditionsSlice& slice) const; + Result prepare(const IOV& required_validity, + ConditionsSlice& slice) const; }; } /* End namespace Conditions */ } /* End namespace DD4hep */ diff --git a/DDCond/include/DDCond/ConditionsManagerObject.h b/DDCond/include/DDCond/ConditionsManagerObject.h index abc8f42d677fedfe767b5d74825970695c6979b6..f9e6a671543eb7e828ce2168b1bd75786be1295e 100644 --- a/DDCond/include/DDCond/ConditionsManagerObject.h +++ b/DDCond/include/DDCond/ConditionsManagerObject.h @@ -17,9 +17,8 @@ #include "DD4hep/Memory.h" #include "DD4hep/Conditions.h" #include "DD4hep/NamedObject.h" -#include "DDCond/ConditionsSlice.h" -#include "DD4hep/ComponentProperties.h" #include "DDCond/ConditionsPool.h" +#include "DDCond/ConditionsSlice.h" // C/C++ include files #include <vector> @@ -35,10 +34,9 @@ namespace DD4hep { namespace Conditions { // Forward declarations - class ConditionsPool; + class ConditionsIOVPool; class ConditionsListener; class ConditionsDataLoader; - class ConditionsIOVPool; /// Basic conditions manager implementation /** @@ -61,6 +59,7 @@ namespace DD4hep { typedef std::pair<ConditionsListener*,void*> Listener; typedef std::set<Listener> Listeners; typedef dd4hep_ptr<ConditionsDataLoader> Loader; + typedef ConditionsManager::Result Result; protected: /// Reference to main detector description object @@ -139,8 +138,7 @@ namespace DD4hep { virtual bool registerUnlocked(ConditionsPool* pool, Condition cond) = 0; /// Prepare all updates to the clients with the defined IOV - virtual UserPool::Result prepare(const IOV& req_iov, - ConditionsSlice& slice) = 0; + virtual Result prepare(const IOV& req_iov, ConditionsSlice& slice) = 0; /// Clean conditions, which are above the age limit. /** @return Number of conditions cleaned/removed from the IOV pool of the given type */ diff --git a/DDCond/include/DDCond/ConditionsPool.h b/DDCond/include/DDCond/ConditionsPool.h index 3e2184d6667f97646a91828695bdb99c09964c9f..fad04760a6a30aa45ee8634b40fabccda20aafcc 100644 --- a/DDCond/include/DDCond/ConditionsPool.h +++ b/DDCond/include/DDCond/ConditionsPool.h @@ -142,14 +142,8 @@ namespace DD4hep { typedef std::set<ConditionKey> ConditionKeys; typedef ConditionDependency Dependency; typedef ConditionsDependencyCollection Dependencies; - class Result { - public: - size_t selected = 0; - size_t missing = 0; - Result() = default; - Result(const Result& result) = default; - Result& operator=(const Result& result) = default; - }; + typedef ConditionsManager::Result Result; + protected: /// The pool's interval of validity IOV m_iov; diff --git a/DDCond/include/DDCond/Type1/Manager_Type1.h b/DDCond/include/DDCond/Type1/Manager_Type1.h index a562833401d2221719ff9fc408195d2dfd5612f7..46b7533ed46dc07876c722ff97c19c19a2966b0e 100644 --- a/DDCond/include/DDCond/Type1/Manager_Type1.h +++ b/DDCond/include/DDCond/Type1/Manager_Type1.h @@ -164,8 +164,7 @@ namespace DD4hep { * * @return */ - UserPool::Result prepare(const IOV& req_validity, - ConditionsSlice& slice); + Result prepare(const IOV& req_iov, ConditionsSlice& slice); }; } /* End namespace Conditions */ diff --git a/DDCond/src/ConditionsDependencyHandler.cpp b/DDCond/src/ConditionsDependencyHandler.cpp index 47466b95bc3e56ea50aa837b74095033b2988316..809aa4c331a2107b22516a5eb19e30f566dba632 100644 --- a/DDCond/src/ConditionsDependencyHandler.cpp +++ b/DDCond/src/ConditionsDependencyHandler.cpp @@ -24,7 +24,8 @@ ConditionsDependencyHandler::ConditionsDependencyHandler(ConditionsManager mgr, UserPool& pool, const Dependencies& dependencies, void* user_param) - : m_manager(mgr.access()), m_pool(pool), m_dependencies(dependencies), m_userParam(user_param) + : m_manager(mgr.access()), m_pool(pool), m_dependencies(dependencies), + m_userParam(user_param), num_callback(0) { const IOV& iov = m_pool.validity(); m_iovPool = m_manager->registerIOV(*iov.iovType, iov.keyData); @@ -40,7 +41,7 @@ LCDD& ConditionsDependencyHandler::lcdd() const { } /// ConditionResolver implementation: Interface to access conditions -Condition ConditionsDependencyHandler::get(unsigned int key) const { +Condition ConditionsDependencyHandler::get(Condition::key_type key) const { Condition c = m_pool.get(key); if ( c.isValid() ) { Condition::Object* obj = c.ptr(); @@ -77,6 +78,7 @@ ConditionsDependencyHandler::do_callback(const ConditionDependency& dep) const cond->setFlag(Condition::DERIVED); cond->iov = m_pool.validityPtr(); // Must IMMEDIATELY insert to handle inter-dependencies. + ++num_callback; m_pool.insert(cond); m_manager->registerUnlocked(m_iovPool, cond); } diff --git a/DDCond/src/ConditionsManager.cpp b/DDCond/src/ConditionsManager.cpp index 44c7d95ceeea275ac50f497449f34842d62a4c4f..1117a63f691f4ae5f0bd4d230989f7c89b4192a2 100644 --- a/DDCond/src/ConditionsManager.cpp +++ b/DDCond/src/ConditionsManager.cpp @@ -236,7 +236,7 @@ void ConditionsManager::clear() const { } /// Prepare all updates to the clients with the defined IOV -long ConditionsManager::prepare(const IOV& req_iov, - ConditionsSlice& slice) const { - return access()->prepare(req_iov, slice).missing; +ConditionsManager::Result +ConditionsManager::prepare(const IOV& req_iov, ConditionsSlice& slice) const { + return access()->prepare(req_iov, slice); } diff --git a/DDCond/src/ConditionsRepository.cpp b/DDCond/src/ConditionsRepository.cpp index 20b9bda2a7d8352b52b9d02fe38fa00aed50fc07..ccb7a6550a46a1aff6fa8836f964a3672269fbf8 100644 --- a/DDCond/src/ConditionsRepository.cpp +++ b/DDCond/src/ConditionsRepository.cpp @@ -63,7 +63,7 @@ namespace { for(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i) { char text[32]; Condition c = (*i).second; - ::snprintf(text,sizeof(text),"0x%08X",c.key()); + ::snprintf(text,sizeof(text),"0x%16llX",c.key()); root.append(cond = xml_elt_t(doc, _U(ref))); cond.setAttr(_U(key), text); cond.setAttr(_U(name), c.name()); @@ -88,7 +88,7 @@ namespace { string key = element.attr<string>(_U(key)); size_t cap = data.capacity(); ConditionsRepository::Entry e; - ::sscanf(key.c_str(),"0x%08X",&e.key); + ::sscanf(key.c_str(),"0x%16llX",&e.key); e.name = element.attr<string>(_U(name)); e.address = element.attr<string>(_U(ref)); if ( data.size() == cap ) data.reserve(cap+500); @@ -111,7 +111,7 @@ namespace { output.c_str(), errno, ::strerror(errno)); } else if ( sep ) { - ::snprintf(fmt,sizeof(fmt),"%%08X%c%%s%c%%s%c",sep,sep,sep); + ::snprintf(fmt,sizeof(fmt),"%%16llX%c%%s%c%%s%c",sep,sep,sep); } else { for(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i) { @@ -123,7 +123,7 @@ namespace { if ( siz_tot < (siz_n+siz_a) ) siz_tot = siz_n+siz_a; } siz_tot += 8+2+1; - ::snprintf(fmt,sizeof(fmt),"%%08X %%-%lds %%-%lds",long(siz_nam),long(siz_add)); + ::snprintf(fmt,sizeof(fmt),"%%16llX %%-%lds %%-%lds",long(siz_nam),long(siz_add)); } out << "dd4hep." << char(sep ? sep : '-') << "." << long(siz_nam) @@ -176,7 +176,7 @@ namespace { e.address[idx] = 0; } size_t cap = data.capacity(); - ::sscanf(text,"%08X",&e.key); + ::sscanf(text,"%16llX",&e.key); if ( data.size() == cap ) data.reserve(cap+500); data.push_back(e); } diff --git a/DDCond/src/ConditionsTextRepository.cpp b/DDCond/src/ConditionsTextRepository.cpp index d9f7cffb01e4b2fa3fc085921131374c61028cd0..75ece0c8ec8d5eff6dfb49ce9d44314cebe4203e 100644 --- a/DDCond/src/ConditionsTextRepository.cpp +++ b/DDCond/src/ConditionsTextRepository.cpp @@ -62,7 +62,7 @@ namespace { for(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i) { char text[32]; Condition c = (*i).second; - ::snprintf(text,sizeof(text),"0x%08X",c.key()); + ::snprintf(text,sizeof(text),"0x%16llX",c.key()); root.append(cond = xml_elt_t(doc, _U(ref))); cond.setAttr(_U(key), text); cond.setAttr(_U(name), c.name()); @@ -87,7 +87,7 @@ namespace { string key = element.attr<string>(_U(key)); size_t cap = data.capacity(); ConditionsTextRepository::Entry e; - ::sscanf(key.c_str(),"0x%08X",&e.key); + ::sscanf(key.c_str(),"0x%16llX",&e.key); e.name = element.attr<string>(_U(name)); e.address = element.attr<string>(_U(ref)); if ( data.size() == cap ) data.reserve(cap+500); @@ -110,7 +110,7 @@ namespace { output.c_str(), errno, ::strerror(errno)); } else if ( sep ) { - ::snprintf(fmt,sizeof(fmt),"%%08X%c%%s%c%%s%c",sep,sep,sep); + ::snprintf(fmt,sizeof(fmt),"%%16llX%c%%s%c%%s%c",sep,sep,sep); } else { for(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i) { @@ -122,7 +122,7 @@ namespace { if ( siz_tot < (siz_n+siz_a) ) siz_tot = siz_n+siz_a; } siz_tot += 8+2+1; - ::snprintf(fmt,sizeof(fmt),"%%08X %%-%lds %%-%lds",long(siz_nam),long(siz_add)); + ::snprintf(fmt,sizeof(fmt),"%%16llX %%-%lds %%-%lds",long(siz_nam),long(siz_add)); } out << "dd4hep." << char(sep ? sep : '-') << "." << long(siz_nam) @@ -175,7 +175,7 @@ namespace { e.address[idx]=0; } size_t cap = data.capacity(); - ::sscanf(text,"%08X",&e.key); + ::sscanf(text,"%16llX",&e.key); if ( data.size() == cap ) data.reserve(cap+500); data.push_back(e); } diff --git a/DDCond/src/Type1/Manager_Type1.cpp b/DDCond/src/Type1/Manager_Type1.cpp index 436d4114e8e8be22ee9edc0d20db11e44fc1afce..193ec54345b14fcb0cc2a6219e5dd34f66188751 100644 --- a/DDCond/src/Type1/Manager_Type1.cpp +++ b/DDCond/src/Type1/Manager_Type1.cpp @@ -95,13 +95,13 @@ namespace { template <typename T> void __check_values__(const Manager_Type1* o, Condition::key_type key, const IOV* iov) { if ( !iov ) { - except("ConditionsManager","+++ Invalid IOV to access condition: %08X. [Null-reference]",key); + except("ConditionsManager","+++ Invalid IOV to access condition: %16llX. [Null-reference]",key); } const IOVType* typ = check_iov_type<T>(o,iov); if ( !typ ) { // Severe: We have an unknown IOV type. This is not allowed, // because we do not known hot to handle it..... - except("ConditionsManager","+++ Invalid IOV type [%d] to access condition: %08X.", + except("ConditionsManager","+++ Invalid IOV type [%d] to access condition: %16llX.", iov->type, key); } } @@ -411,20 +411,20 @@ Manager_Type1::get(Condition::key_type key, const Condition::iov_type& iov) return conditions[0]; } else if ( conditions.empty() ) { - except("ConditionsManager","+++ Condition %08X for the requested IOV %s do not exist.", + except("ConditionsManager","+++ Condition %16llX for the requested IOV %s do not exist.", key, iov.str().c_str()); } else if ( conditions.size() > 1 ) { RC::const_iterator start = conditions.begin(); Condition first = *start; - printout(ERROR,"ConditionsManager","+++ Condition %s [%08X] is ambiguous for IOV %s:", + printout(ERROR,"ConditionsManager","+++ Condition %s [%16llX] is ambiguous for IOV %s:", first.name(), key, iov.str().c_str()); for(RC::const_iterator i=start; i!=conditions.end(); ++i) { Condition c = *i; printout(ERROR,"ConditionsManager","+++ %s [%s] = %s", c.name(), c->iov->str().c_str(), c->value.c_str()); } - except("ConditionsManager","+++ Condition %s [%08X] is ambiguous for IOV %s:", + except("ConditionsManager","+++ Condition %s [%16llX] is ambiguous for IOV %s:", first.name(), key, iov.str().c_str()); } return Condition(); @@ -444,23 +444,22 @@ Manager_Type1::getRange(Condition::key_type key, const Condition::iov_type& iov) dd4hep_lock_t locked_load(m_updateLock); m_loader->load_range(key, iov, conditions); if ( conditions.empty() ) { - except("ConditionsManager","+++ Conditions %08X for IOV %s do not exist.", + except("ConditionsManager","+++ Conditions %16llX for IOV %s do not exist.", key, iov.str().c_str()); } conditions.clear(); } rc = select_range(key, iov, conditions); if ( !rc ) { - except("ConditionsManager","+++ Conditions %08X for IOV %s do not exist.", + except("ConditionsManager","+++ Conditions %16llX for IOV %s do not exist.", key, iov.str().c_str()); } return conditions; } /// Prepare all updates for the given keys to the clients with the defined IOV -UserPool::Result -Manager_Type1::prepare(const IOV& req_iov, - ConditionsSlice& slice) +ConditionsManager::Result +Manager_Type1::prepare(const IOV& req_iov, ConditionsSlice& slice) { dd4hep_ptr<UserPool>& up = slice.pool(); __get_checked_pool(req_iov, up); diff --git a/DDCond/src/plugins/ConditionsLinearPool.cpp b/DDCond/src/plugins/ConditionsLinearPool.cpp index cdceec670137910c96641141efd5fa557ff2e79f..7e1e0b5bb477ee941d01a65acd653e0709a75c24 100644 --- a/DDCond/src/plugins/ConditionsLinearPool.cpp +++ b/DDCond/src/plugins/ConditionsLinearPool.cpp @@ -18,6 +18,8 @@ #include "DDCond/ConditionsManager.h" #include "DDCond/ConditionsSelectors.h" +#include "DD4hep/Printout.h" + // C/C++ include files #include <list> @@ -189,7 +191,6 @@ namespace DD4hep { // Framework include files //#include "DDCond/ConditionsLinearPool.h" -#include "DD4hep/Printout.h" #include "DD4hep/InstanceCount.h" using DD4hep::Handle; diff --git a/DDCond/src/plugins/ConditionsMappedPool.cpp b/DDCond/src/plugins/ConditionsMappedPool.cpp index 28c6a5425e3c7f92ee5e75250ac1641cc6e6fb4f..d865315d200a60920e04d7d8bbe9cb8fc1fc3b75 100644 --- a/DDCond/src/plugins/ConditionsMappedPool.cpp +++ b/DDCond/src/plugins/ConditionsMappedPool.cpp @@ -14,7 +14,9 @@ #define DDCOND_CONDITIONSMAPPEDPOOL_H // Framework include files +#include "DD4hep/Printout.h" #include "DD4hep/objects/ConditionsInterna.h" + #include "DDCond/ConditionsPool.h" #include "DDCond/ConditionsSelectors.h" @@ -71,8 +73,15 @@ namespace DD4hep { /// Register a new condition to this pool virtual bool insert(Condition condition) { Condition::Object* c = condition.access(); - return m_entries.insert(std::make_pair(c->hash,c)).second; - } + bool result = m_entries.insert(std::make_pair(c->hash,c)).second; + if ( result ) return true; + auto i = m_entries.find(c->hash); + Condition present = (*i).second; + + printout(ERROR,"MappedPool","ConditionsClash: %s %08llX <> %08llX %s", + present.name(), present.key(), condition.key(), condition.name()); + return false; + } /// Register a new condition to this pool. May overload for performance reasons. virtual void insert(RangeConditions& new_entries) { @@ -203,7 +212,6 @@ namespace DD4hep { // Framework include files //#include "DDCond/ConditionsMappedPool.h" -#include "DD4hep/Printout.h" #include "DD4hep/InstanceCount.h" using DD4hep::Handle; diff --git a/DDCond/src/plugins/ConditionsPlugins.cpp b/DDCond/src/plugins/ConditionsPlugins.cpp index b58d955aac45e9088116f6a7bc8e009beb626508..102deb1c6cec70283bbc79357598ad7c42562b98 100644 --- a/DDCond/src/plugins/ConditionsPlugins.cpp +++ b/DDCond/src/plugins/ConditionsPlugins.cpp @@ -510,7 +510,7 @@ static long ddcond_dump_repository(lcdd_t& /* lcdd */, int argc, char** argv) const ConditionsRepository::Entry& e = *i; string add = e.address; if ( add.length() > 80 ) add = e.address.substr(0,60) + "..."; - printout(INFO,"Repository","%08X %s",e.key,e.name.c_str()); + printout(INFO,"Repository","%16llX %s",e.key,e.name.c_str()); printout(INFO,"Repository"," -> %s",e.address.c_str()); } } diff --git a/DDCond/src/plugins/ConditionsUserPool.cpp b/DDCond/src/plugins/ConditionsUserPool.cpp index 5120172bcf0a0aa9d41e1b46e8f17316c55c3403..3d05bc6503ebbe2edebbbfac758400b37deda935 100644 --- a/DDCond/src/plugins/ConditionsUserPool.cpp +++ b/DDCond/src/plugins/ConditionsUserPool.cpp @@ -234,7 +234,7 @@ void ConditionsMappedUserPool<MAPPING>::print(const std::string& opt) const { if ( opt == "*" ) { for( const auto& i : m_conditions ) { Condition c = i.second; - printout(INFO,"UserPool","++ %08X/%08X Val:%s %s",i.first, c->hash, c->value.c_str(), c.str().c_str()); + printout(INFO,"UserPool","++ %16llX/%16llX Val:%s %s",i.first, c->hash, c->value.c_str(), c.str().c_str()); } } } @@ -274,7 +274,7 @@ Condition ConditionsMappedUserPool<MAPPING>::get(const ConditionKey& key) const template<typename MAPPING> bool ConditionsMappedUserPool<MAPPING>::insert(Condition cond) { bool result = i_insert(cond.ptr()); - //printout(INFO,"UserPool","++ INSERT: %08X Name:%s",cond->hash, cond.name()); + //printout(INFO,"UserPool","++ INSERT: %16llX Name:%s",cond->hash, cond.name()); if ( result ) return true; except("UserPool","++ Attempt to double insert condition: %s", cond.name()); return false; @@ -350,6 +350,7 @@ ConditionsMappedUserPool<MAPPING>::prepare_VSN_1(const IOV& require typedef vector<pair<key_type,SliceEntry*> > _Missing; Result result; IOV pool_iov(required.iovType); + size_t len = m_conditions.size(); const auto& slice_cond = slice.conditions(); const auto& slice_calc = slice.derived(); @@ -357,19 +358,21 @@ ConditionsMappedUserPool<MAPPING>::prepare_VSN_1(const IOV& require pool_iov.reset().invert(); m_iovPool->select(required, Operators::mapConditionsSelect(m_conditions), pool_iov); m_iov = pool_iov; - _Missing cond_missing(slice_cond.size()), calc_missing(slice_cond.size()); + _Missing cond_missing(len+slice_cond.size()), calc_missing(len+slice_calc.size()); _Missing::iterator cond_last = set_difference(slice_cond.begin(), slice_cond.end(), m_conditions.begin(), m_conditions.end(), cond_missing.begin(), _compare); int num_cond_miss = int(cond_last-cond_missing.begin()); - printout(INFO,"UserPool","Found %ld missing conditions out of %ld conditions.", + printout(num_cond_miss==0 ? DEBUG : INFO,"UserPool", + "Found %ld missing conditions out of %ld conditions.", num_cond_miss, m_conditions.size()); _Missing::iterator calc_last = set_difference(slice_calc.begin(), slice_calc.end(), m_conditions.begin(), m_conditions.end(), calc_missing.begin(), _compare); int num_calc_miss = int(calc_last-calc_missing.begin()); - printout(INFO,"UserPool","Found %ld missing derived conditions out of %ld conditions.", + printout(num_cond_miss==0 ? DEBUG : INFO,"UserPool", + "Found %ld missing derived conditions out of %ld conditions.", int(calc_last-calc_missing.begin()), m_conditions.size()); result.selected = m_conditions.size(); @@ -381,7 +384,7 @@ ConditionsMappedUserPool<MAPPING>::prepare_VSN_1(const IOV& require vector<pair<key_type,SliceEntry*> > loaded, missing; size_t updates = m_loader->load_many(required, cond_missing, loaded, missing, pool_iov); for_each(loaded.begin(),loaded.end(),Inserter<MAPPING>(m_conditions,&m_iov)); - result.selected += updates; + result.loaded = updates; result.missing -= updates; if ( !missing.empty() ) { // ERROR! @@ -389,22 +392,23 @@ ConditionsMappedUserPool<MAPPING>::prepare_VSN_1(const IOV& require } // // Now we update the already existing dependencies, which have expired + // if ( int(calc_last-calc_missing.begin()) > 0 ) { ConditionsDependencyCollection deps(calc_missing.begin(), calc_last, _to_dep); - ConditionsDependencyHandler h(m_manager, *this, deps, user_param); + ConditionsDependencyHandler handler(m_manager, *this, deps, user_param); for(auto i=begin(deps); i != end(deps); ++i) { const ConditionDependency* d = (*i).second.get(); typename MAPPING::iterator j = m_conditions.find(d->key()); // If we would know, that dependencies are only ONE level, we could skip this search.... if ( j == m_conditions.end() ) { - Condition::Object* c = h(d); - ( c != 0 ) ? ++result.selected : ++result.missing; + handler(d); continue; } // printout(INFO,"UserPool","Already calcluated: %s",d->name()); - ++result.selected; continue; } + result.computed = handler.num_callback; + result.missing -= handler.num_callback; } return result; } diff --git a/DDCore/include/DD4hep/Alignments.h b/DDCore/include/DD4hep/Alignments.h index a434a421e1ba9c5a53555e3eb8c57f653a570539..3bfb92aaf3fe472adff4a84988b4d5b16fbf3918 100644 --- a/DDCore/include/DD4hep/Alignments.h +++ b/DDCore/include/DD4hep/Alignments.h @@ -91,7 +91,7 @@ namespace DD4hep { /// Forward definition of the alignment delta data typedef Alignments::Delta Delta; /// Forward definition of the key type - typedef unsigned int key_type; + typedef unsigned long long int key_type; /// Forward definition of the iov type typedef IOV iov_type; @@ -125,11 +125,11 @@ namespace DD4hep { /// Hash code generation from input string inline Alignment::key_type Alignment::hashCode(const char* value) - { return hash32(value); } + { return hash64(value); } /// Hash code generation from input string inline Alignment::key_type Alignment::hashCode(const std::string& value) - { return hash32(value); } + { return hash64(value); } /// Main handle class to hold an alignment conditions object /** diff --git a/DDCore/include/DD4hep/AlignmentsPrinter.h b/DDCore/include/DD4hep/AlignmentsPrinter.h index 1bba8f208061297400979d2d44bfa0af17c3c02e..cabf92a780732762a520b369826cca9bcd9802aa 100644 --- a/DDCore/include/DD4hep/AlignmentsPrinter.h +++ b/DDCore/include/DD4hep/AlignmentsPrinter.h @@ -44,10 +44,10 @@ namespace DD4hep { int m_flag; public: - /// Initializing constructor - AlignmentsPrinter(const std::string& prefix="",int flags=0); /// Initializing constructor AlignmentsPrinter(UserPool* pool, const std::string& prefix="",int flags=0); + /// Initializing constructor + AlignmentsPrinter(const std::string& prefix="",int flags=0); /// Default destructor virtual ~AlignmentsPrinter() = default; /// Set name for printouts diff --git a/DDCore/include/DD4hep/AlignmentsProcessor.h b/DDCore/include/DD4hep/AlignmentsProcessor.h index 725d0bc88cf7e451957103dd5dede1b76f742045..6f811ccfa51dfaa227d516412f5d712fe4178043 100644 --- a/DDCore/include/DD4hep/AlignmentsProcessor.h +++ b/DDCore/include/DD4hep/AlignmentsProcessor.h @@ -40,9 +40,9 @@ namespace DD4hep { * \ingroup DD4HEP_ALIGNMENTS */ class AlignmentsProcessor : - virtual public Alignment::Processor, - virtual public Container::Processor, - virtual public Geometry::DetElement::Processor + public Alignment::Processor, + public Container::Processor, + public Geometry::DetElement::Processor { public: /// Self type definition diff --git a/DDCore/include/DD4hep/ConditionDerived.h b/DDCore/include/DD4hep/ConditionDerived.h index 142e8257d01dfbea623367b6920bb993a731a5e1..67f3f7ee51e85dd201b17fe865bf8088e721e42c 100644 --- a/DDCore/include/DD4hep/ConditionDerived.h +++ b/DDCore/include/DD4hep/ConditionDerived.h @@ -45,7 +45,7 @@ namespace DD4hep { /// Interface to access conditions by conditions key virtual Condition get(const ConditionKey& key) const = 0; /// Interface to access conditions by hash value - virtual Condition get(unsigned int key) const = 0; + virtual Condition get(Condition::key_type key) const = 0; /// Access to the conditions manager virtual Ref_t manager() const = 0; /// Access to the detector description instance diff --git a/DDCore/include/DD4hep/Conditions.h b/DDCore/include/DD4hep/Conditions.h index 7ef0dfee572a3df169e9b11629b71a660e0614c2..78f720998befb8afc84bdcdbda03bf1c28442a6f 100644 --- a/DDCore/include/DD4hep/Conditions.h +++ b/DDCore/include/DD4hep/Conditions.h @@ -71,7 +71,7 @@ namespace DD4hep { /// Standard object type typedef Interna::ConditionObject Object; /// Forward definition of the key type - typedef unsigned int key_type; + typedef unsigned long long int key_type; /// Forward definition of the iov type typedef IOV iov_type; /// Forward definition of the object properties @@ -412,11 +412,11 @@ namespace DD4hep { /// Hash code generation from input string inline ConditionKey::key_type ConditionKey::hashCode(const char* value) - { return hash32(value); } + { return hash64(value); } /// Hash code generation from input string inline ConditionKey::key_type ConditionKey::hashCode(const std::string& value) - { return hash32(value); } + { return hash64(value); } /// Equality operator using key object inline bool ConditionKey::operator==(const ConditionKey& compare) const diff --git a/DDCore/include/DD4hep/ConditionsPrinter.h b/DDCore/include/DD4hep/ConditionsPrinter.h index 24979431ab98542139c87c643e0c22b9e60be8e8..5ba9d6e40ba40f16f5b5047fafa2ceeeb09abb2a 100644 --- a/DDCore/include/DD4hep/ConditionsPrinter.h +++ b/DDCore/include/DD4hep/ConditionsPrinter.h @@ -45,6 +45,9 @@ namespace DD4hep { public: /// Initializing constructor + ConditionsPrinter(UserPool* pool, const std::string& prefix="", + int flag=Condition::NO_NAME|Condition::WITH_IOV|Condition::WITH_ADDRESS); + /// Initializing constructor ConditionsPrinter(const std::string& prefix="", int flag=Condition::NO_NAME|Condition::WITH_IOV|Condition::WITH_ADDRESS); /// Default destructor diff --git a/DDCore/include/DD4hep/ConditionsProcessor.h b/DDCore/include/DD4hep/ConditionsProcessor.h index cc46848e6f4cd634f2fc2c01555386a8e0a5b02e..8c539069554f346f8582bd568b0848c2d9708ab9 100644 --- a/DDCore/include/DD4hep/ConditionsProcessor.h +++ b/DDCore/include/DD4hep/ConditionsProcessor.h @@ -23,6 +23,9 @@ namespace DD4hep { /// Namespace for the AIDA detector description toolkit supporting XML utilities namespace Conditions { + // Forward declarations + class UserPool; + /// Generic Conditions processor /** * Please note that the principle of locality applies: @@ -40,9 +43,9 @@ namespace DD4hep { * \ingroup DD4HEP_CONDITIONS */ class ConditionsProcessor : - virtual public Condition::Processor, - virtual public Container::Processor, - virtual public Geometry::DetElement::Processor + public Condition::Processor, + public Container::Processor, + public Geometry::DetElement::Processor { public: /// Self type definition diff --git a/DDCore/include/DD4hep/DetectorProcessor.h b/DDCore/include/DD4hep/DetectorProcessor.h index 2fa421a577664d367ebe4b99ba983c894ced6010..c2794a827aad37b3fb38035ba6426274e804eefb 100644 --- a/DDCore/include/DD4hep/DetectorProcessor.h +++ b/DDCore/include/DD4hep/DetectorProcessor.h @@ -74,7 +74,10 @@ namespace DD4hep { /// Default destructor virtual ~DetElementProcessor() = default; }; - + /// Instantiation helper + template <typename T> DetElementProcessor<T> detectorProcessor(T* proc) + { return DetElementProcessor<T>(proc); } + /// Generic Condition object collector /** * Please see the documentation of the diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h index 3fa86764daab16ca1e843ab030046ae5a0959562..b757b92481a971d813a75bca47ada2450b594a4f 100644 --- a/DDCore/include/DD4hep/Primitives.h +++ b/DDCore/include/DD4hep/Primitives.h @@ -34,7 +34,11 @@ namespace DD4hep { typedef long long int CellID; typedef long long int VolumeID; } - + + /// We need it so often: one-at-time 64 bit hash function + unsigned long long int hash64(const char* key); + unsigned long long int hash64(const std::string& key); + /// We need it so often: one-at-time 32 bit hash function inline unsigned int hash32(const char* key) { unsigned int hash = 0; diff --git a/DDCore/src/AlignmentsInterna.cpp b/DDCore/src/AlignmentsInterna.cpp index 4c9cda82ab2df5ab3bdc02e45b914b33c43fb37e..574710aa77a07fd56ea705c6ce54da97e46943fd 100644 --- a/DDCore/src/AlignmentsInterna.cpp +++ b/DDCore/src/AlignmentsInterna.cpp @@ -70,7 +70,7 @@ AlignmentContainer::~AlignmentContainer() { void AlignmentContainer::addKey(const string& key_val) { key_type hash = Alignment::hashCode(key_val); if ( !keys.insert(make_pair(hash,make_pair(hash,key_val))).second ) { - except("AlignmentContainer","++ Key[%08X]: %s already present. " + except("AlignmentContainer","++ Key[%16llX]: %s already present. " "Duplicate insertions inhibited!",hash, key_val.c_str()); } } @@ -80,7 +80,7 @@ void AlignmentContainer::addKey(const string& key_val, const string& data_val) key_type key_hash = Alignment::hashCode(key_val); key_type val_hash = Alignment::hashCode(data_val); if ( !keys.insert(make_pair(key_hash,make_pair(val_hash,data_val))).second ) { - except("AlignmentContainer","++ Key[%08X]: %s already present. " + except("AlignmentContainer","++ Key[%16llX]: %s already present. " "Duplicate insertions inhibited!",key_hash, key_val.c_str()); } } diff --git a/DDCore/src/AlignmentsPrinter.cpp b/DDCore/src/AlignmentsPrinter.cpp index c9183a740ff2752115f18f58c53e1da77437dcff..a7b538536f91e7246d4bb94493803e3b9e0c5ca7 100644 --- a/DDCore/src/AlignmentsPrinter.cpp +++ b/DDCore/src/AlignmentsPrinter.cpp @@ -85,12 +85,12 @@ void DD4hep::Alignments::printContainer(const string& prefix, Container containe for(const auto& k : container.keys() ) { try { Alignment align = container.get(k.first,*pool); - printout(INFO,tag,"++ %s Alignment [%08X] -> [%08X] %s", + printout(INFO,tag,"++ %s Alignment [%16llX] -> [%16llX] %s", prefix.c_str(), k.first, k.second.first, k.second.second.c_str()); printAlignment(prefix,align); } catch(...) { - printout(ERROR,tag,"++ %s %s [%08X] -> [%08X]", + printout(ERROR,tag,"++ %s %s [%16llX] -> [%16llX]", prefix.c_str(), "FAILED Alignment:", k.first, k.second.first); } } @@ -245,11 +245,11 @@ void DD4hep::Alignments::printElementPlacement(const string& prefix, DetElement const Alignment::Data& align_data = align.data(); Conditions::Condition align_cond = align_data.condition; if ( k.first != k.second.first ) { - printout(INFO,tag,"++ Alignment %p [%08X] -> [%08X] %s (SYNONYM) ignored.", + printout(INFO,tag,"++ Alignment %p [%16llX] -> [%16llX] %s (SYNONYM) ignored.", a.ptr(), k.first, k.second.first, k.second.second.c_str()); continue; } - printout(INFO,tag,"++ Alignment %p [%08X] -> [%08X] %s", + printout(INFO,tag,"++ Alignment %p [%16llX] -> [%16llX] %s", a.ptr(), k.first, k.second.first, k.second.second.c_str()); if ( k.second.second != align_cond.name() ) { printout(INFO,prefix,"++ \tPath:%s [%p]", align_cond.name(), a.ptr()); @@ -257,7 +257,7 @@ void DD4hep::Alignments::printElementPlacement(const string& prefix, DetElement printAlignmentEx(tag,"ALIGNMENT",de,align); } catch(...) { - printout(ERROR,tag,"++ %s %s [%08X] -> [%08X]", + printout(ERROR,tag,"++ %s %s [%16llX] -> [%16llX]", prefix.c_str(), "FAILED Alignment:", k.first, k.second.first); } } diff --git a/DDCore/src/ConditionsInterna.cpp b/DDCore/src/ConditionsInterna.cpp index 0dd09506b92c24c4bae6b35600af14ccc81da9a2..af348ea48a6c667ebc106e825cd82194bb6b385f 100644 --- a/DDCore/src/ConditionsInterna.cpp +++ b/DDCore/src/ConditionsInterna.cpp @@ -75,7 +75,9 @@ Interna::ConditionContainer::~ConditionContainer() { void Interna::ConditionContainer::addKey(const string& key_val) { key_type hash = ConditionKey::hashCode(key_val); if ( !keys.insert(make_pair(hash,make_pair(hash,key_val))).second ) { - except("ConditionContainer","++ Key[%08X]: %s already present. Duplicate insertions inhibited!",hash, key_val.c_str()); + except("ConditionContainer", + "++ Key[%16llX]: %s already present. Duplicate insertions inhibited!", + hash, key_val.c_str()); } } @@ -84,7 +86,9 @@ void Interna::ConditionContainer::addKey(const string& key_val, const string& da key_type key_hash = ConditionKey::hashCode(key_val); key_type val_hash = ConditionKey::hashCode(data_val); if ( !keys.insert(make_pair(key_hash,make_pair(val_hash,data_val))).second ) { - except("ConditionContainer","++ Key[%08X]: %s already present. Duplicate insertions inhibited!",key_hash, key_val.c_str()); + except("ConditionContainer", + "++ Key[%16llX]: %s already present. Duplicate insertions inhibited!", + key_hash, key_val.c_str()); } } diff --git a/DDCore/src/ConditionsPrinter.cpp b/DDCore/src/ConditionsPrinter.cpp index 1253a6d55858b52de92fd657b705e8401f94d48e..122065f8c53878c62c8673149c48a6b631aa4351 100644 --- a/DDCore/src/ConditionsPrinter.cpp +++ b/DDCore/src/ConditionsPrinter.cpp @@ -20,6 +20,12 @@ using namespace DD4hep; using namespace DD4hep::Conditions; +/// Initializing constructor +ConditionsPrinter::ConditionsPrinter(UserPool* p, const std::string& pref, int flg) + : ConditionsProcessor(p), name("Condition"), prefix(pref), m_flag(flg) +{ +} + /// Initializing constructor ConditionsPrinter::ConditionsPrinter(const std::string& pref, int flg) : ConditionsProcessor(0), name("Condition"), prefix(pref), m_flag(flg) @@ -39,7 +45,7 @@ int ConditionsPrinter::operator()(Condition cond) { if ( values.length() > 132 ) values = values.substr(0,130)+"..."; std::string new_prefix = prefix; new_prefix.assign(prefix.length(),' '); - printout(INFO,name,"++ %s \tPath:%s Key:%08X Type:%s", + printout(INFO,name,"++ %s \tPath:%s Key:%16llX Type:%s", new_prefix.c_str(), cond.name(), cond.key(), data.dataType().c_str()); printout(INFO,name,"++ %s \tData:%s", new_prefix.c_str(), values.c_str()); } @@ -56,7 +62,7 @@ int ConditionsPrinter::operator()(Container container) { std::string nam = c.name(); std::string cn = nam.substr(nam.find('#')+1); Condition::key_type key = ConditionKey::hashCode(cn); - printout(INFO,name,"++ %s %s %s [%08X] -> %s [%08X]", + printout(INFO,name,"++ %s %s %s [%16llX] -> %s [%16llX]", prefix.c_str(), "Condition:", cn.c_str(), key==k.first ? key : k.first, c.name(), k.second.first); (*this)(c); diff --git a/DDCore/src/Primitives.cpp b/DDCore/src/Primitives.cpp index 32eb287bbb9386852904d8f407b4ceb26bae2fcd..acc8bbcb59f411d95f396fbca281920ac1138a0f 100644 --- a/DDCore/src/Primitives.cpp +++ b/DDCore/src/Primitives.cpp @@ -18,6 +18,7 @@ // C/C++ include files #include <stdexcept> +#include <cstdint> #include <cstring> #include <map> @@ -28,6 +29,113 @@ typedef abi::__class_type_info class_t; using abi::__dynamic_cast; #endif #endif +//----------------------------------------------------------------------------- +// MurmurHash2, 64-bit versions, by Austin Appleby + +// The same caveats as 32-bit MurmurHash2 apply here - beware of alignment +// and endian-ness issues if used across multiple platforms. +static inline uint64_t murmur_hash_64 ( const void * key, int len) { +#define seed 0xFEEDBABE + const unsigned int * data = (const unsigned int *)key; +#if INTPTR_MAX == INT32_MAX + const unsigned int m = 0x5bd1e995; + const int r = 24; + + unsigned int h1 = seed ^ len; + unsigned int h2 = 0; + + while(len >= 8) + { + unsigned int k1 = *data++; + k1 *= m; k1 ^= k1 >> r; k1 *= m; + h1 *= m; h1 ^= k1; + len -= 4; + + unsigned int k2 = *data++; + k2 *= m; k2 ^= k2 >> r; k2 *= m; + h2 *= m; h2 ^= k2; + len -= 4; + } + + if(len >= 4) + { + unsigned int k1 = *data++; + k1 *= m; k1 ^= k1 >> r; k1 *= m; + h1 *= m; h1 ^= k1; + len -= 4; + } + + switch(len) + { + case 3: h2 ^= ((unsigned char*)data)[2] << 16; + case 2: h2 ^= ((unsigned char*)data)[1] << 8; + case 1: h2 ^= ((unsigned char*)data)[0]; + h2 *= m; + }; + + h1 ^= h2 >> 18; h1 *= m; + h2 ^= h1 >> 22; h2 *= m; + h1 ^= h2 >> 17; h1 *= m; + h2 ^= h1 >> 19; h2 *= m; + + uint64_t h = h1; + + h = (h << 32) | h2; +#elif INTPTR_MAX == INT64_MAX + const uint64_t m = 0xc6a4a7935bd1e995; + const int r = 47; + + uint64_t h = seed ^ (len * m); + + const uint64_t * data = (const uint64_t *)key; + const uint64_t * end = data + (len/8); + + while(data != end) + { + uint64_t k = *data++; + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + h *= m; + } + + const unsigned char * data2 = (const unsigned char*)data; + + switch(len & 7) + { + case 7: h ^= uint64_t(data2[6]) << 48; + case 6: h ^= uint64_t(data2[5]) << 40; + case 5: h ^= uint64_t(data2[4]) << 32; + case 4: h ^= uint64_t(data2[3]) << 24; + case 3: h ^= uint64_t(data2[2]) << 16; + case 2: h ^= uint64_t(data2[1]) << 8; + case 1: h ^= uint64_t(data2[0]); + h *= m; + }; + + h ^= h >> r; + h *= m; + h ^= h >> r; + +#else +#error "Environment not 32 or 64-bit." +#endif + + return h; +} + + +/// We need it so often: one-at-time 64 bit hash function +unsigned long long int DD4hep::hash64(const char* key) { + return murmur_hash_64(key, strlen(key)); +} + +unsigned long long int DD4hep::hash64(const std::string& key) { + return murmur_hash_64(key.data(), key.length()); +} long int DD4hep::makeTime(int year, int month, int day, int hour, int minutes, int seconds) diff --git a/DDDB/src/DDDBAlignmentTest.cpp b/DDDB/src/DDDBAlignmentTest.cpp index ff26b1dd93413da04d5883253d4b7189b7e8268d..fd46ef24deab617a95490b32e86919cfd66cf6d3 100644 --- a/DDDB/src/DDDBAlignmentTest.cpp +++ b/DDDB/src/DDDBAlignmentTest.cpp @@ -119,10 +119,10 @@ namespace { const IOVType* iovType = conds.iovType("epoch"); IOV iov(iovType, IOV::Key(time,time)); slice.adopt(createSlice(conds,*iovType)); - long num_expired = conds.prepare(iov, *slice); + ConditionsManager::Result res = conds.prepare(iov, *slice); printout(INFO,"Conditions", - "+++ ConditionsUpdate: Updated %ld conditions... IOV:%s", - num_expired, iov.str().c_str()); + "+++ ConditionsUpdate: Total of %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) ... IOV:%s", + res.total(), res.selected, res.loaded, res.computed, res.missing, iov.str().c_str()); align.compute(*(slice->pool())); return 1; } @@ -144,7 +144,7 @@ namespace { { Alignments::Alignment a = c.get(k.hash,p); const Alignments::Delta& D = a.data().delta; - printout(INFO,"Alignment","++ [%08X] (%11s-%8s-%5s) Cond:%p '%s'", k.hash, + printout(INFO,"Alignment","++ [%16llX] (%11s-%8s-%5s) Cond:%p '%s'", k.hash, D.hasTranslation() ? "Translation" : "", D.hasRotation() ? "Rotation" : "", D.hasPivot() ? "Pivot" : "", @@ -155,7 +155,7 @@ namespace { { Alignments::Alignment a = c.get("Alignment",p); const Alignments::Delta& D = a.data().delta; - printout(INFO,"Alignment","++ [%08X] (%11s-%8s-%5s) Cond:%p 'Alignment'", k.hash, + printout(INFO,"Alignment","++ [%16llX] (%11s-%8s-%5s) Cond:%p 'Alignment'", k.hash, D.hasTranslation() ? "Translation" : "", D.hasRotation() ? "Rotation" : "", D.hasPivot() ? "Pivot" : "", diff --git a/DDDB/src/DDDBConditionPrinter.cpp b/DDDB/src/DDDBConditionPrinter.cpp index 53b30cb45b3aa805b69efb19998c4e37292a01b7..550df60e8767740090aea19c8cbbb4e7ddaf1de7 100644 --- a/DDDB/src/DDDBConditionPrinter.cpp +++ b/DDDB/src/DDDBConditionPrinter.cpp @@ -106,17 +106,18 @@ int ConditionPrinter::operator()(Condition cond) { } /// Plugin function -static void* create_dddb_conditions_printer(Geometry::LCDD& /* lcdd */, int argc,char** argv) { +static void* create_dddb_conditions_printer(Geometry::LCDD& /* lcdd */, int argc, char** argv) { string prefix = ""; - int flags = 0; + int flags = 0; for(int i=0; i<argc && argv[i]; ++i) { if ( 0 == ::strncmp("-prefix",argv[i],4) ) prefix = argv[++i]; else if ( 0 == ::strncmp("-flags",argv[i],2) ) flags = ::atol(argv[++i]); } - if ( flags ) - return new DDDB::ConditionPrinter(prefix,flags); - return new DDDB::ConditionPrinter(prefix); + DetElement::Processor* proc = flags + ? new DDDB::ConditionPrinter(prefix,flags) + : new DDDB::ConditionPrinter(prefix); + return proc; } DECLARE_LCDD_CONSTRUCTOR(DDDB_ConditionsPrinter,create_dddb_conditions_printer) diff --git a/DDDB/src/DDDBConditionsLoader.cpp b/DDDB/src/DDDBConditionsLoader.cpp index 413ff4c6db50a6106c11a6a698425ef8e12eddd4..9ea7af5c70b49369adc76735fa57f12b0e92ec65 100644 --- a/DDDB/src/DDDBConditionsLoader.cpp +++ b/DDDB/src/DDDBConditionsLoader.cpp @@ -214,7 +214,7 @@ size_t DDDBConditionsLoader::update(const iov_type& req_validity, size_t idx = c->address.find('#'); string url = (idx == string::npos) ? c->address : c->address.substr(0,idx); #if 0 - printout(INFO,"DDDB","++ Need to update: %-40s [%08X] --> %s", + printout(INFO,"DDDB","++ Need to update: %-40s [%16llX] --> %s", c->name.c_str(), c->hash, url.c_str()); #endif urls.insert(make_pair(url,c)); @@ -257,7 +257,7 @@ size_t DDDBConditionsLoader::load_many(const iov_type& /* req_validity */, size_t idx = c->address.find('#'); string url = (idx == string::npos) ? c->address : c->address.substr(0,idx); #if 0 - printout(INFO,"DDDB","++ Need to update: %-40s [%08X] --> %s", + printout(INFO,"DDDB","++ Need to update: %-40s [%16llX] --> %s", c->name.c_str(), c->hash, url.c_str()); #endif urls.insert(make_pair(url,c)); @@ -287,12 +287,12 @@ void DDDBConditionsLoader::onRegisterCondition(Condition cond, void* param) { RC::iterator i=std::find_if(r.begin(),r.end(),byName(cond)); if ( i != r.end() ) { (*i) = cond; - printout(DEBUG,"DDDB","++ Got MATCH: %-40s [%08X] --> %s.", + printout(DEBUG,"DDDB","++ Got MATCH: %-40s [%16llX] --> %s.", c->name.c_str(), c->hash, c->address.c_str()); arg->iov.iov_intersection(cond.iov()); return; } - printout(INFO,"DDDB","++ Got update: %-40s [%08X] --> %s.", + printout(INFO,"DDDB","++ Got update: %-40s [%16llX] --> %s.", c->name.c_str(), c->hash, c->address.c_str()); } else if ( arg->cmd == INSERT && arg->key == c->hash ) { diff --git a/DDDB/src/DDDBPlugins.cpp b/DDDB/src/DDDBPlugins.cpp index 29ac0eb395497257aab4d4732242dd0e319fdfaa..338eda3e27e3e3914aae2d7c432c9fc6f785a85f 100644 --- a/DDDB/src/DDDBPlugins.cpp +++ b/DDDB/src/DDDBPlugins.cpp @@ -162,10 +162,10 @@ namespace { const AbstractMap& data = cond.get<AbstractMap>(); const DDDB::Document* doc = data.option<DDDB::Document>(); if ( doc ) - printout(INFO,m_name,"++ Usage: %d Cond: %s/%s -> %s [%08X]", + printout(INFO,m_name,"++ Usage: %d Cond: %s/%s -> %s [%16llX]", ic.first, doc->name.c_str(), cond->name.c_str(), cond->value.c_str(), cond->hash); else - printout(INFO,m_name,"++ Usage: %d Cond: ---/%s -> %s [%08X]", + printout(INFO,m_name,"++ Usage: %d Cond: ---/%s -> %s [%16llX]", ic.first, cond->name.c_str(), cond->value.c_str(), cond->hash); } #endif @@ -241,7 +241,7 @@ namespace { if ( (with_keys || with_values) && de.hasConditions() ) { Conditions::DetConditions dc(de); Conditions::Container cont = dc.conditions(); - ::sprintf(fmt,"%03d %%-%ds Key: %%08X -> %%08X -> %%s",level+1,2*level+3); + ::sprintf(fmt,"%03d %%-%ds Key: %%16llX -> %%16llX -> %%s",level+1,2*level+3); for(const auto& i : cont->keys ) { if ( with_keys ) { printout(INFO,m_name,fmt,"",i.first,i.second.first, i.second.second.c_str()); diff --git a/examples/AlignDet/CMakeLists.txt b/examples/AlignDet/CMakeLists.txt index 9bb443d5314e7027d74d6af38379e86791421400..3d59dca9eed549a46803dfea99943eafcbce4577 100644 --- a/examples/AlignDet/CMakeLists.txt +++ b/examples/AlignDet/CMakeLists.txt @@ -33,10 +33,18 @@ dd4hep_add_test_reg( test_AlignDet_Telescope_dump_geometry -plugin DD4hepDetectorDump REGEX_PASS "/world/Telescope/module_9 NumDau\\:1 VolID\\:00000903 Place") # -#---Testing: Load Telescope geometry and read conditions ------------------ -dd4hep_add_test_reg( test_AlignDet_Telescope_dump_alignments +#---Testing: Load Telescope geometry and read and print alignments -------- +dd4hep_add_test_reg( test_AlignDet_Telescope_populate + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" + EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_populate + -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml + -deltas file:${DD4hep_DIR}/examples/Conditions/data/repository.xml + REGEX_PASS "\\[E42813AA\\] -> \\[E42813AA\\] /world/Telescope/module_9/sensor#alignment/Tranformations") +# +#---Testing: Load Telescope geometry and read and print alignments -------- +dd4hep_add_test_reg( test_AlignDet_Telescope_read_xml COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" - EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample + EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_read_xml -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml -deltas file:${DD4hep_DIR}/examples/Conditions/data/repository.xml REGEX_PASS "\\[E42813AA\\] -> \\[E42813AA\\] /world/Telescope/module_9/sensor#alignment/Tranformations") diff --git a/examples/AlignDet/src/AlignmentExample.cpp b/examples/AlignDet/src/AlignmentExample.cpp deleted file mode 100644 index e6e76f9bd39b74779551c641a7bf1be98c6715a4..0000000000000000000000000000000000000000 --- a/examples/AlignDet/src/AlignmentExample.cpp +++ /dev/null @@ -1,160 +0,0 @@ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== -/* - Plugin invocation: - ================== - This plugin behaves like a main program. - Invoke the plugin with something like this: - - geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample \ - -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml \ - -delta file:${DD4hep_DIR}/examples/Conditions/data/repository.xml - -*/ -// Framework include files -#include "DD4hep/LCDD.h" -#include "DD4hep/Printout.h" -#include "DD4hep/Conditions.h" -#include "DD4hep/Alignments.h" -#include "DD4hep/DetectorProcessor.h" -#include "DD4hep/AlignmentsPrinter.h" -#include "DD4hep/Factories.h" -#include "DD4hep/DetAlign.h" - -#include "DDCond/ConditionsSlice.h" -#include "DDAlign/AlignmentsManager.h" -#include "DDAlign/DDAlignUpdateCall.h" -#include "DDAlign/DDAlignForwardCall.h" -#include "DDAlign/AlignmentsRegister.h" -#include "DDAlign/AlignmentsForward.h" - -using namespace std; -using namespace DD4hep; -using namespace DD4hep::Alignments; - -// Don't clutter global namespace -namespace { - - /// Example how to access the alignment constants from a detector element - /** - * \author M.Frank - * \version 1.0 - * \date 01/04/2016 - */ - struct AlignmentDataAccess : public AlignmentsProcessor { - Conditions::UserPool* pool; - AlignmentDataAccess(Conditions::UserPool* p) : AlignmentsProcessor(0), pool(p) {} - int processElement(DetElement de) { - DetAlign a(de); // Use special facade... - Container container = a.alignments(); - // Let's go for the deltas.... - for(const auto& k : container.keys() ) { - Alignment align = container.get(k.first,*pool); - const Delta& delta = align.data().delta; - if ( delta.hasTranslation() || delta.hasPivot() || delta.hasRotation() ) {} - } - // Keep it simple. To know how to access stuff, - // simply look in DDDCore/src/AlignmentsPrinter.cpp... - printElementPlacement("Example",de,pool); - return 1; - } - }; - struct Proc : public Geometry::DetectorProcessor { - DetElement::Processor* proc; - virtual int operator()(DetElement de, int) - { return proc->processElement(de); } - template <typename Q> Proc& scan(Q& p, DetElement start) - { Proc obj; obj.proc = &p; obj.process(start, 0, true); return *this; } - }; -} - -/// Plugin function: Alignment program example -/** - * Factory: DD4hep_AlignmentExample - * - * \author M.Frank - * \version 1.0 - * \date 01/04/2016 - */ -static int alignment_example (Geometry::LCDD& lcdd, int argc, char** argv) { - - string input, delta; - bool arg_error = false; - for(int i=0; i<argc && argv[i]; ++i) { - if ( 0 == ::strncmp("-input",argv[i],4) ) - input = argv[++i]; - else if ( 0 == ::strncmp("-deltas",argv[i],5) ) - delta = argv[++i]; - else - arg_error = true; - } - if ( arg_error || input.empty() || delta.empty() ) { - /// Help printout describing the basic command line interface - cout << - "Usage: -plugin <name> -arg [-arg] \n" - " name: factory name DD4hep_AlignmentExample \n" - " -input <string> Geometry file \n" - " -deltas <string> Alignment deltas (Conditions \n" - "\tArguments given: " << arguments(argc,argv) << endl << flush; - ::exit(EINVAL); - } - - // First we load the geometry - lcdd.fromXML(input); - // Now we instantiate the conditions manager - lcdd.apply("DD4hep_ConditionsManagerInstaller",0,(char**)0); - // Now we instantiate the alignments manager - lcdd.apply("DD4hep_AlignmentsManagerInstaller",0,(char**)0); - - Conditions::ConditionsManager condMgr = Conditions::ConditionsManager::from(lcdd); - AlignmentsManager alignMgr = AlignmentsManager::from(lcdd); - const void* delta_args[] = {delta.c_str(), 0}; // Better zero-terminate - - lcdd.apply("DD4hep_ConditionsXMLRepositoryParser",1,(char**)delta_args); - // Now the deltas are stored in the conditions manager in the proper IOV pools - const IOVType* iov_typ = condMgr.iovType("run"); - if ( 0 == iov_typ ) { - except("ConditionsPrepare","++ Unknown IOV type supplied."); - } - IOV req_iov(iov_typ,1500); // IOV goes from run 1000 ... 2000 - dd4hep_ptr<Conditions::ConditionsSlice> slice(Conditions::createSlice(condMgr,*iov_typ)); - dd4hep_ptr<Conditions::UserPool>& pool = slice->pool(); - long num_updated = condMgr.prepare(req_iov,*slice); - printout(DEBUG,"Example","Updated %ld conditions of type %s.",num_updated, iov_typ->str().c_str()); - - printout(INFO,"Example","Updated %ld [%ld] conditions of type %s.", - num_updated, slice->conditions().size(), iov_typ->str().c_str()); - - AlignmentsRegister reg(alignMgr,new DDAlignUpdateCall(),pool.get()); - AlignmentsForward fwd(alignMgr,new DDAlignForwardCall(),pool.get()); - // Let's register the callbacks to compute dependent conditions/alignments - Proc() - .scan(reg,lcdd.world()) // Create dependencies for all deltas found in the conditions - .scan(fwd,lcdd.world()); // Create child dependencies if higher level alignments exist - - // ++++++++++++++++++++++++ Now the registration is finished. - - // ++++++++++++++++++++++++ The following has to be done for each new IOV.... - // Let's compute the tranformation matrices - alignMgr.compute(*slice); - - // What else ? let's access the data - AlignmentDataAccess access(pool.get()); - Proc().scan(access,lcdd.world()); - - // All done. - return 1; -} - -// first argument is the type from the xml file -DECLARE_APPLY(DD4hep_AlignmentExample,alignment_example) diff --git a/examples/AlignDet/src/AlignmentExampleObjects.cpp b/examples/AlignDet/src/AlignmentExampleObjects.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6df52ac89d82a48f44141c313d81c322183bf224 --- /dev/null +++ b/examples/AlignDet/src/AlignmentExampleObjects.cpp @@ -0,0 +1,91 @@ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "AlignmentExampleObjects.h" +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/AlignmentsPrinter.h" +#include "DDAlign/DDAlignUpdateCall.h" +#include "DDAlign/DDAlignForwardCall.h" +#include "DDAlign/AlignmentsRegister.h" +#include "DDAlign/AlignmentsForward.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::AlignmentExamples; + +/// Install the consitions and the alignment manager +void DD4hep::AlignmentExamples::installManagers(LCDD& lcdd) { + // Now we instantiate the conditions manager + lcdd.apply("DD4hep_ConditionsManagerInstaller",0,(char**)0); + // Now we instantiate the alignments manager + lcdd.apply("DD4hep_AlignmentsManagerInstaller",0,(char**)0); +} + +/// Register the alignment callbacks +void DD4hep::AlignmentExamples::registerAlignmentCallbacks(LCDD& lcdd, + ConditionsSlice& slice, + AlignmentsManager alignMgr) +{ + dd4hep_ptr<UserPool>& pool = slice.pool(); + // Let's register the callbacks to compute dependent conditions/alignments + // 1) Create dependencies for all deltas found in the conditions + Alignments::AlignmentsRegister reg(alignMgr,new Alignments::DDAlignUpdateCall(),pool.get()); + Scanner().scan(reg,lcdd.world()); + // 2) Create child dependencies if higher level alignments exist + Alignments::AlignmentsForward fwd(alignMgr,new Alignments::DDAlignForwardCall(),pool.get()); + Scanner().scan(fwd,lcdd.world()); +} + +/// Callback to process a single detector element +int AlignmentDataAccess::processElement(DetElement de) { + DetAlign a(de); // Use special facade... + Alignments::Container container = a.alignments(); + // Let's go for the deltas.... + for(const auto& k : container.keys() ) { + Alignment align = container.get(k.first,*pool); + const Delta& delta = align.data().delta; + if ( delta.hasTranslation() || delta.hasPivot() || delta.hasRotation() ) {} + } + // Keep it simple. To know how to access stuff, + // simply look in DDDCore/src/AlignmentsPrinter.cpp... + Alignments::printElementPlacement("Example",de,pool); + return 1; +} + +/// Callback to process a single detector element +int AlignmentCreator::operator()(DetElement de, int) { + if ( de.ptr() != de.world().ptr() ) { + DetConditions dc(de); + Condition cond(de.path()+"#alignment", "alignment"); + Delta& delta = cond.bind<Delta>(); + cond->hash = ConditionKey::hashCode(cond->name); + cond->setFlag(Condition::ACTIVE|Condition::ALIGNMENT); + /// Simply move everything by 1 mm in z. Not physical, but this is just an example... + delta.translation.SetZ(delta.translation.Z()+0.1*dd4hep::cm); + delta.rotation = RotationZYX(0.999,1.001,0.999); + delta.flags |= Delta::HAVE_TRANSLATION|Delta::HAVE_ROTATION; + manager.registerUnlocked(pool, cond); + printout(printLevel,"Example","++ Adding manually alignments for %s",de.path().c_str()); + } + return 1; +} + +/// Callback to process a single detector element +int AlignmentKeys::operator()(DetElement de, int) { + if ( de.ptr() != de.world().ptr() ) { + DetConditions dc(de); + dc.conditions().addKey(de.path()+"#alignment"); + } + return 1; +} diff --git a/examples/AlignDet/src/AlignmentExampleObjects.h b/examples/AlignDet/src/AlignmentExampleObjects.h new file mode 100644 index 0000000000000000000000000000000000000000..bf4fa17b46f20f8b807343495907130ff77e53e7 --- /dev/null +++ b/examples/AlignDet/src/AlignmentExampleObjects.h @@ -0,0 +1,134 @@ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_ALIGNDET_ALIGNMENTEXAMPLEOBJECTS_H +#define DD4HEP_ALIGNDET_ALIGNMENTEXAMPLEOBJECTS_H + +// Framework include files +#include "DD4hep/LCDD.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Conditions.h" +#include "DD4hep/Alignments.h" +#include "DD4hep/AlignmentData.h" +#include "DD4hep/DetAlign.h" +#include "DD4hep/DetConditions.h" +#include "DD4hep/DetectorProcessor.h" +#include "DD4hep/AlignmentsProcessor.h" +#include "DD4hep/AlignedVolumePrinter.h" + +#include "DDCond/ConditionsSlice.h" +#include "DDCond/ConditionsManager.h" +#include "DDAlign/AlignmentsManager.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for alignment examples + namespace AlignmentExamples { + + using Geometry::LCDD; + using Geometry::RotationZYX; + using Geometry::DetElement; + using Geometry::DetectorProcessor; + + using Conditions::UserPool; + using Conditions::Condition; + using Conditions::ConditionKey; + using Conditions::ConditionsPool; + using Conditions::ConditionsSlice; + using Conditions::ConditionsManager; + using Conditions::DetConditions; + + using Alignments::Delta; + using Alignments::DetAlign; + using Alignments::Alignment; + using Alignments::AlignmentsManager; + + /// Example how to populate the detector description with alignment constants + /** + * This is simply a DetElement crawler... + * + * \author M.Frank + * \version 1.0 + * \date 01/04/2016 + */ + struct AlignmentCreator : public DetectorProcessor { + ConditionsManager manager; + ConditionsPool* pool; + /// Print level + PrintLevel printLevel; + /// Constructor + AlignmentCreator(ConditionsManager m,ConditionsPool* p) + : manager(m), pool(p), printLevel(DEBUG) {} + /// Callback to process a single detector element + virtual int operator()(DetElement de, int level); + }; + + // This is important, otherwise the register and forward calls won't find them! + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2016 + */ + struct AlignmentKeys : public DetectorProcessor { + /// Constructor + AlignmentKeys() = default; + /// Callback to process a single detector element + virtual int operator()(DetElement de, int level); + }; + + /// Example how to access the alignment constants from a detector element + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2016 + */ + struct AlignmentDataAccess : public Alignments::AlignmentsProcessor { + UserPool* pool; + /// Print level + PrintLevel printLevel; + /// Constructor + AlignmentDataAccess(UserPool* p) : AlignmentsProcessor(0), pool(p), + printLevel(DEBUG) { + } + /// Callback to process a single detector element + int processElement(DetElement de); + }; + + /// Helper to run DetElement scans + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2016 + */ + struct Scanner : public DetectorProcessor { + DetElement::Processor* proc; + /// Callback to process a single detector element + virtual int operator()(DetElement de, int) + { return proc->processElement(de); } + template <typename Q> Scanner& scan(Q& p, DetElement start) + { Scanner obj; obj.proc = &p; obj.process(start, 0, true); return *this; } + template <typename Q> Scanner& scan2(const Q& p, DetElement start) + { Scanner obj; obj.proc = const_cast<Q*>(&p); obj.process(start, 0, true); return *this; } + }; + + /// Install the consitions and the alignment manager + void installManagers(LCDD& lcdd); + /// Register the alignment callbacks + void registerAlignmentCallbacks(LCDD& lcdd, + ConditionsSlice& slice, + Alignments::AlignmentsManager alignMgr); + + + } /* End namespace AlignmentExamples */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_ALIGNDET_ALIGNMENTEXAMPLEOBJECTS_H */ diff --git a/examples/AlignDet/src/AlignmentExample_populate.cpp b/examples/AlignDet/src/AlignmentExample_populate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..770a6bd5c4b45e1fbf65ef5b1ca0c686db51014c --- /dev/null +++ b/examples/AlignDet/src/AlignmentExample_populate.cpp @@ -0,0 +1,127 @@ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +/* + Plugin invocation: + ================== + This plugin behaves like a main program. + Invoke the plugin with something like this: + + geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_populate \ + -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml + + Populate the conditions store by hand for a set of IOVs. + Then compute the corresponding alignment entries.... + +*/ +// Framework include files +#include "AlignmentExampleObjects.h" +#include "DD4hep/Factories.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::AlignmentExamples; + +/// Plugin function: Alignment program example +/** + * Factory: DD4hep_AlignmentExample_populate + * + * \author M.Frank + * \version 1.0 + * \date 01/12/2016 + */ +static int alignment_example (Geometry::LCDD& lcdd, int argc, char** argv) { + + string input; + int num_iov = 10; + bool arg_error = false; + for(int i=0; i<argc && argv[i]; ++i) { + if ( 0 == ::strncmp("-input",argv[i],4) ) + input = argv[++i]; + else if ( 0 == ::strncmp("-iovs",argv[i],4) ) + num_iov = ::atol(argv[++i]); + else + arg_error = true; + } + if ( arg_error || input.empty() ) { + /// Help printout describing the basic command line interface + cout << + "Usage: -plugin <name> -arg [-arg] \n" + " name: factory name DD4hep_AlignmentExample1 \n" + " -input <string> Geometry file \n" + " -iovs <number> Number of parallel IOV slots for processing. \n" + "\tArguments given: " << arguments(argc,argv) << endl << flush; + ::exit(EINVAL); + } + + // First we load the geometry + lcdd.fromXML(input); + installManagers(lcdd); + + /******************** Initialize the conditions manager *****************/ + ConditionsManager condMgr = ConditionsManager::from(lcdd); + condMgr["PoolType"] = "DD4hep_ConditionsLinearPool"; + condMgr["UserPoolType"] = "DD4hep_ConditionsMapUserPool"; + condMgr["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool"; + condMgr.initialize(); + + AlignmentsManager alignMgr = AlignmentsManager::from(lcdd); + const IOVType* iov_typ = condMgr.registerIOVType(0,"run").second; + if ( 0 == iov_typ ) { + except("ConditionsPrepare","++ Unknown IOV type supplied."); + } + AlignmentKeys keys; + keys.process(lcdd.world(),0,true); + /******************** Populate the conditions store *********************/ + // Have 10 run-slices [1001,2000] .... [9001,10000] + for(int i=1; i<num_iov; ++i) { + IOV iov(iov_typ, IOV::Key(1+i*10,(i+1)*10)); + ConditionsPool* iov_pool = condMgr.registerIOV(*iov.iovType, iov.key()); + AlignmentCreator creator(condMgr, iov_pool); // Use a generic creator + creator.process(lcdd.world(),0,true); // Create conditions with all deltas + } + + /******************** Now as usual: create the slice ********************/ + dd4hep_ptr<ConditionsSlice> slice(Conditions::createSlice(condMgr,*iov_typ)); + dd4hep_ptr<UserPool>& pool = slice->pool(); + + /******************** Register alignments *******************************/ + // Note: We have to load one set of conditions in order to auto-populate + // because we need to see if a detector element actually has alignment + // conditions. For this we must access the conditions data. + // Unfortunate, but unavoidable. + // + IOV iov(iov_typ,10+5); + condMgr.prepare(iov,*slice); + registerAlignmentCallbacks(lcdd,*slice,alignMgr); + + // ++++++++++++++++++++++++ Now compute the alignments for each of these IOVs + for(int i=1; i<num_iov; ++i) { + IOV req_iov(iov_typ,i*10+5); + // Attach the proper set of conditions to the user pool + ConditionsManager::Result res = condMgr.prepare(req_iov,*slice); + // Now compute the tranformation matrices + alignMgr.compute(*slice); + printout(INFO,"Prepare","Total %ld/%ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) of type %s.", + slice->conditions().size(), res.total(), res.selected, res.loaded, + res.computed, res.missing, iov_typ->str().c_str()); + } + // What else ? let's access/print the current selection + Alignments::AlignedVolumePrinter printer(pool.get(),"Example"); + Scanner().scan(printer,lcdd.world()); + + // All done. + return 1; +} + +// first argument is the type from the xml file +DECLARE_APPLY(DD4hep_AlignmentExample_populate,alignment_example) diff --git a/examples/AlignDet/src/AlignmentExample_read_xml.cpp b/examples/AlignDet/src/AlignmentExample_read_xml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3a2cc6e9bd6ce8dbb63f3254cd46267cf4cc3996 --- /dev/null +++ b/examples/AlignDet/src/AlignmentExample_read_xml.cpp @@ -0,0 +1,98 @@ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +/* + Plugin invocation: + ================== + This plugin behaves like a main program. + Invoke the plugin with something like this: + + geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_read_xml \ + -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml \ + -delta file:${DD4hep_DIR}/examples/Conditions/data/repository.xml + +*/ +// Framework include files +#include "AlignmentExampleObjects.h" +#include "DD4hep/Factories.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::AlignmentExamples; + +/// Plugin function: Alignment program example +/** + * Factory: DD4hep_AlignmentExample_read_xml + * + * \author M.Frank + * \version 1.0 + * \date 01/12/2016 + */ +static int alignment_example (Geometry::LCDD& lcdd, int argc, char** argv) { + + string input, delta; + bool arg_error = false; + for(int i=0; i<argc && argv[i]; ++i) { + if ( 0 == ::strncmp("-input",argv[i],4) ) + input = argv[++i]; + else if ( 0 == ::strncmp("-deltas",argv[i],5) ) + delta = argv[++i]; + else + arg_error = true; + } + if ( arg_error || input.empty() || delta.empty() ) { + /// Help printout describing the basic command line interface + cout << + "Usage: -plugin <name> -arg [-arg] \n" + " name: factory name DD4hep_AlignmentExample2 \n" + " -input <string> Geometry file \n" + " -deltas <string> Alignment deltas (Conditions \n" + "\tArguments given: " << arguments(argc,argv) << endl << flush; + ::exit(EINVAL); + } + + // First we load the geometry + lcdd.fromXML(input); + installManagers(lcdd); + + ConditionsManager condMgr = ConditionsManager::from(lcdd); + AlignmentsManager alignMgr = AlignmentsManager::from(lcdd); + const void* delta_args[] = {delta.c_str(), 0}; // Better zero-terminate + + lcdd.apply("DD4hep_ConditionsXMLRepositoryParser",1,(char**)delta_args); + // Now the deltas are stored in the conditions manager in the proper IOV pools + const IOVType* iov_typ = condMgr.iovType("run"); + if ( 0 == iov_typ ) { + except("ConditionsPrepare","++ Unknown IOV type supplied."); + } + IOV req_iov(iov_typ,1500); // IOV goes from run 1000 ... 2000 + dd4hep_ptr<ConditionsSlice> slice(createSlice(condMgr,*iov_typ)); + ConditionsManager::Result res = condMgr.prepare(req_iov,*slice); + printout(INFO,"Prepare","Total %ld/%ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) of type %s.", + slice->conditions().size(), res.total(), res.selected, res.loaded, + res.computed, res.missing, iov_typ->str().c_str()); + + // ++++++++++++++++++++++++ We need a valid set of conditions to do this! + registerAlignmentCallbacks(lcdd,*slice,alignMgr); + + // ++++++++++++++++++++++++ Compute the tranformation matrices + alignMgr.compute(*slice); + + // What else ? let's access the data + Scanner().scan2(AlignmentDataAccess(slice->pool().get()),lcdd.world()); + + // ++++++++++++++++++++++++ All done. + return 1; +} + +// first argument is the type from the xml file +DECLARE_APPLY(DD4hep_AlignmentExample_read_xml,alignment_example) diff --git a/examples/AlignDet/src/AlignmentExample_stress.cpp b/examples/AlignDet/src/AlignmentExample_stress.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ded4f2cc3817cd181e2192380039a2d11fa4d6e5 --- /dev/null +++ b/examples/AlignDet/src/AlignmentExample_stress.cpp @@ -0,0 +1,160 @@ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +/* + Plugin invocation: + ================== + This plugin behaves like a main program. + Invoke the plugin with something like this: + + geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_stress \ + -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml + + Populate the conditions store by hand for a set of IOVs. + Then compute the corresponding alignment entries.... + +*/ +// Framework include files +#include "AlignmentExampleObjects.h" +#include "DD4hep/Factories.h" +#include "TStatistic.h" +#include "TTimeStamp.h" +#include "TRandom3.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::AlignmentExamples; + +/// Plugin function: Alignment program example +/** + * Factory: DD4hep_AlignmentExample_stress + * + * \author M.Frank + * \version 1.0 + * \date 01/12/2016 + */ +static int alignment_example (Geometry::LCDD& lcdd, int argc, char** argv) { + + string input; + int num_iov = 10, num_runs = 10; + bool arg_error = false; + for(int i=0; i<argc && argv[i]; ++i) { + if ( 0 == ::strncmp("-input",argv[i],4) ) + input = argv[++i]; + else if ( 0 == ::strncmp("-iovs",argv[i],4) ) + num_iov = ::atol(argv[++i]); + else if ( 0 == ::strncmp("-runs",argv[i],4) ) + num_runs = ::atol(argv[++i]); + else + arg_error = true; + } + if ( arg_error || input.empty() ) { + /// Help printout describing the basic command line interface + cout << + "Usage: -plugin <name> -arg [-arg] \n" + " name: factory name DD4hep_AlignmentExample_stress \n" + " -input <string> Geometry file \n" + " -iovs <number> Number of parallel IOV slots for processing. \n" + " -runs <number> Number of collision loads to be performed. \n" + "\tArguments given: " << arguments(argc,argv) << endl << flush; + ::exit(EINVAL); + } + + // First we load the geometry + lcdd.fromXML(input); + installManagers(lcdd); + + /******************** Initialize the conditions manager *****************/ + ConditionsManager condMgr = ConditionsManager::from(lcdd); + condMgr["PoolType"] = "DD4hep_ConditionsLinearPool"; + condMgr["UserPoolType"] = "DD4hep_ConditionsMapUserPool"; + condMgr["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool"; + condMgr.initialize(); + + AlignmentsManager alignMgr = AlignmentsManager::from(lcdd); + const IOVType* iov_typ = condMgr.registerIOVType(0,"run").second; + if ( 0 == iov_typ ) { + except("ConditionsPrepare","++ Unknown IOV type supplied."); + } + AlignmentKeys keys; + keys.process(lcdd.world(),0,true); + TStatistic cr_stat("Creation"), comp_stat("Computation"), access_stat("Access"); + + /******************** Populate the conditions store *********************/ + // Have num_iov possible run-slices [11,20] .... [n*10+1,(n+1)*10] + for(int i=0; i<num_iov; ++i) { + TTimeStamp start; + IOV iov(iov_typ, IOV::Key(1+i*10,(i+1)*10)); + ConditionsPool* iov_pool = condMgr.registerIOV(*iov.iovType, iov.key()); + AlignmentCreator creator(condMgr, iov_pool); // Use a generic creator + creator.process(lcdd.world(),0,true); // Create conditions with all deltas + TTimeStamp stop; + cr_stat.Fill(stop.AsDouble()-start.AsDouble()); + } + + /******************** Now as usual: create the slice ********************/ + dd4hep_ptr<ConditionsSlice> slice(Conditions::createSlice(condMgr,*iov_typ)); + + /******************** Register alignments *******************************/ + // Note: We have to load one set of conditions in order to auto-populate + // because we need to see if a detector element actually has alignment + // conditions. For this we must access the conditions data. + // Unfortunate, but unavoidable. + // + IOV iov(iov_typ,15); + condMgr.prepare(iov,*slice); + registerAlignmentCallbacks(lcdd,*slice,alignMgr); + + /******************** Compute alignments *******************************/ + for(int i=0; i<num_iov; ++i) { + TTimeStamp start; + IOV req_iov(iov_typ,1+i*10); + ConditionsManager::Result cres = condMgr.prepare(req_iov,*slice); + // Now compute the tranformation matrices + AlignmentsManager::Result ares = alignMgr.compute(*slice); + TTimeStamp stop; + comp_stat.Fill(stop.AsDouble()-start.AsDouble()); + printout(INFO,"ComputedDerived", + "Setup %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) (A:%ld,M:%ld) for IOV:%-12s [%8.3f sec]", + cres.total(), cres.selected, cres.loaded, cres.computed, cres.missing, + ares.computed, ares.missing, req_iov.str().c_str(), stop.AsDouble()-start.AsDouble()); + } + + // ++++++++++++++++++++++++ Now access the conditions for every IOV.... + TRandom3 random; + for(int i=0; i<num_runs; ++i) { + TTimeStamp start; + unsigned int rndm = 1+random.Integer(num_iov*10); + IOV req_iov(iov_typ,rndm); + // Attach the proper set of conditions to the user pool + ConditionsManager::Result res = condMgr.prepare(req_iov,*slice); + TTimeStamp stop; + access_stat.Fill(stop.AsDouble()-start.AsDouble()); + printout(INFO,"Setup slice: ", + "Total %ld conditions (S:%6ld,L:%6ld,C:%4ld,M:%ld) for random %4d of type %s. [%8.4f sec]", + res.total(), res.selected, res.loaded, res.computed, res.missing, rndm, + iov_typ->str().c_str(), stop.AsDouble()-start.AsDouble()); + } + printout(INFO,"Statistics","+======================================================================="); + printout(INFO,"Statistics","+ %-12s: %11.5g +- %11.4g RMS = %11.5g N = %lld", + cr_stat.GetName(), cr_stat.GetMean(), cr_stat.GetMeanErr(), cr_stat.GetRMS(), cr_stat.GetN()); + printout(INFO,"Statistics","+ %-12s: %11.5g +- %11.4g RMS = %11.5g N = %lld", + comp_stat.GetName(), comp_stat.GetMean(), comp_stat.GetMeanErr(), comp_stat.GetRMS(), comp_stat.GetN()); + printout(INFO,"Statistics","+ %-12s: %11.5g +- %11.4g RMS = %11.5g N = %lld", + access_stat.GetName(), access_stat.GetMean(), access_stat.GetMeanErr(), access_stat.GetRMS(), access_stat.GetN()); + printout(INFO,"Statistics","+======================================================================="); + // All done. + return 1; +} + +// first argument is the type from the xml file +DECLARE_APPLY(DD4hep_AlignmentExample_stress,alignment_example) diff --git a/examples/Conditions/src/ConditionExampleObjects.cpp b/examples/Conditions/src/ConditionExampleObjects.cpp new file mode 100644 index 0000000000000000000000000000000000000000..26a7228d6406d2ad178bf3450c57b1c46977f782 --- /dev/null +++ b/examples/Conditions/src/ConditionExampleObjects.cpp @@ -0,0 +1,208 @@ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include "ConditionExampleObjects.h" +#include "DD4hep/DD4hepUnits.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::ConditionExamples; +using Conditions::DependencyBuilder; + +/// Install the consitions and the alignment manager +void DD4hep::ConditionExamples::installManagers(LCDD& lcdd) { + // Now we instantiate the conditions manager + lcdd.apply("DD4hep_ConditionsManagerInstaller",0,(char**)0); +} + +/// Interface to client Callback in order to update the condition +Condition ConditionUpdate1::operator()(const ConditionKey& key, const Context& context) { + printout(printLevel,"ConditionUpdate1","++ Building dependent condition: %s",key.name.c_str()); + Condition target(key.name,"derived"); + vector<int>& data = target.bind<vector<int> >(); + Condition cond0 = context.condition(0); + data.push_back(cond0.get<int>()); + data.push_back(cond0.get<int>()*2); + return target; +} + +/// Interface to client Callback in order to update the condition +Condition ConditionUpdate2::operator()(const ConditionKey& key, const Context& context) { + printout(printLevel,"ConditionUpdate2","++ Building dependent condition: %s",key.name.c_str()); + Condition target(key.name,"derived"); + vector<int>& data = target.bind<vector<int> >(); + Condition cond0 = context.condition(0); + Condition cond1 = context.condition(1); + + data.push_back(cond0.get<int>()); + data.push_back(cond0.get<int>()*2); + vector<int>& c1 = cond1.get<vector<int> >(); + data.insert(data.end(), c1.begin(), c1.end()); + return target; +} + +/// Interface to client Callback in order to update the condition +Condition ConditionUpdate3::operator()(const ConditionKey& key, const Context& context) { + printout(printLevel,"ConditionUpdate3","++ Building dependent condition: %s",key.name.c_str()); + Condition target(key.name,"derived"); + vector<int>& data = target.bind<vector<int> >(); + Condition cond0 = context.condition(0); + Condition cond1 = context.condition(1); + Condition cond2 = context.condition(2); + + data.push_back(cond0.get<int>()); + data.push_back(cond0.get<int>()*2); + vector<int>& c1 = cond1.get<vector<int> >(); + data.insert(data.end(), c1.begin(), c1.end()); + + vector<int>& c2 = cond2.get<vector<int> >(); + data.insert(data.end(), c2.begin(), c2.end()); + return target; +} + + +ConditionsDependencyCreator::ConditionsDependencyCreator(ConditionsSlice& s,PrintLevel p) + : slice(s), printLevel(p) +{ + call1 = new ConditionUpdate1(printLevel); + call2 = new ConditionUpdate2(printLevel); + call3 = new ConditionUpdate3(printLevel); +} + +/// Callback to process a single detector element +int ConditionsDependencyCreator::operator()(DetElement de, int) { + DetConditions dc(de); + ConditionKey key(de.path()+"#derived_data"); + ConditionKey target1(key.name+"/derived_1"); + ConditionKey target2(key.name+"/derived_2"); + ConditionKey target3(key.name+"/derived_3"); + DependencyBuilder build_1(target1, call1->addRef()); + DependencyBuilder build_2(target2, call2->addRef()); + DependencyBuilder build_3(target3, call3->addRef()); + + // Compute the derived stuff + build_1.add(key); + + build_2.add(key); + build_2.add(target1); + + build_3.add(key); + build_3.add(target1); + build_3.add(target2); + + slice.insert(build_1.release()); + slice.insert(build_2.release()); + slice.insert(build_3.release()); + + /// Add the conditions keys to the container + dc.conditions().addKey(target1.name); + dc.conditions().addKey(target2.name); + dc.conditions().addKey(target3.name); + /// Add conditions aliases to the container + dc.conditions().addKey("derived_1",target1.name); + dc.conditions().addKey("derived_2",target2.name); + dc.conditions().addKey("derived_3",target3.name); + printout(printLevel,"Example","++ Added derived conditions dependencies for %s",de.path().c_str()); + return 1; +} + +/// Callback to process a single detector element +int ConditionsDataAccess::processElement(DetElement de) { + DetConditions dc(de); // Use special facade... + string path = de.path(); + ConditionKey key_temperature (path+"#temperature"); + ConditionKey key_pressure (path+"#pressure"); + ConditionKey key_double_table(path+"#double_table"); + ConditionKey key_int_table (path+"#int_table"); + ConditionKey key_derived_data(path+"#derived_data"); + ConditionKey key_derived1 (path+"#derived_data/derived_1"); + ConditionKey key_derived2 (path+"#derived_data/derived_2"); + ConditionKey key_derived3 (path+"#derived_data/derived_3"); + Conditions::Container container = dc.conditions(); + int result = 0; + // Let's go for the deltas.... + for(const auto& k : container.keys() ) { + Condition cond = container.get(k.first,*pool); + if ( k.first == key_temperature.hash ) { + result += int(cond.get<double>()); + } + else if ( k.first == key_pressure.hash ) { + result += int(cond.get<double>()); + } + else if ( k.first == key_double_table.hash ) { + result += int(cond.get<vector<double> >().size()); + } + else if ( k.first == key_int_table.hash ) { + result += int(cond.get<vector<int> >().size()); + } + else if ( k.first == key_derived_data.hash ) { + result += int(cond.get<int>()); + } + else if ( k.first == key_derived1.hash ) { + result += int(cond.get<vector<int> >().size()); + } + else if ( k.first == key_derived2.hash ) { + result += int(cond.get<vector<int> >().size()); + } + else if ( k.first == key_derived3.hash ) { + result += int(cond.get<vector<int> >().size()); + } + } + return result; +} + +template<typename T> Condition make_condition(DetElement de, const string& name, T val) { + Condition cond(de.path()+"#"+name, name); + T& value = cond.bind<T>(); + value = val; + cond->hash = ConditionKey::hashCode(cond->name); + cond->setFlag(Condition::ACTIVE); + return cond; +} + +/// Destructor +ConditionsCreator::~ConditionsCreator() { + printout(printLevel,"Creator","++ Added a total of %d conditions",conditionCount); +} + +/// Callback to process a single detector element +int ConditionsCreator::operator()(DetElement de, int) { + DetConditions dc(de); + Condition temperature = make_condition<double>(de,"temperature",1.222); + Condition pressure = make_condition<double>(de,"pressure",888.88); + Condition derived = make_condition<int> (de,"derived_data",100); + Condition dbl_table = make_condition<vector<double> >(de,"double_table",{1.,2.,3.,4.,5.,6.,7.,8.,9.}); + Condition int_table = make_condition<vector<int> > (de,"int_table",{10,20,30,40,50,60,70,80,90}); + + manager.registerUnlocked(pool, temperature); + manager.registerUnlocked(pool, pressure); + manager.registerUnlocked(pool, derived); + manager.registerUnlocked(pool, dbl_table); + manager.registerUnlocked(pool, int_table); + printout(printLevel,"Creator","++ Adding manually conditions for %s",de.path().c_str()); + conditionCount += 5; + return 1; +} + +/// Callback to process a single detector element +int ConditionsKeys::operator()(DetElement de, int) { + DetConditions dc(de); + dc.conditions().addKey(de.path()+"#temperature"); + dc.conditions().addKey(de.path()+"#pressure"); + dc.conditions().addKey(de.path()+"#double_table"); + dc.conditions().addKey(de.path()+"#int_table"); + dc.conditions().addKey(de.path()+"#derived_data"); + dc.conditions().addKey("derived",de.path()+"#derived_data"); + return 1; +} diff --git a/examples/Conditions/src/ConditionExampleObjects.h b/examples/Conditions/src/ConditionExampleObjects.h new file mode 100644 index 0000000000000000000000000000000000000000..8f29551bbbdd5a103dbd9de756b14b0308ae1da3 --- /dev/null +++ b/examples/Conditions/src/ConditionExampleObjects.h @@ -0,0 +1,210 @@ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DD4HEP_CONDITIONS_CONDITIONSEXAMPLEOBJECTS_H +#define DD4HEP_CONDITIONS_CONDITIONSEXAMPLEOBJECTS_H + +// Framework include files +#include "DD4hep/LCDD.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Conditions.h" +#include "DD4hep/DetConditions.h" +#include "DD4hep/ConditionDerived.h" +#include "DD4hep/ConditionsPrinter.h" +#include "DD4hep/DetectorProcessor.h" +#include "DD4hep/ConditionsProcessor.h" + +#include "DDCond/ConditionsSlice.h" +#include "DDCond/ConditionsManager.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for conditions examples + namespace ConditionExamples { + + using Geometry::LCDD; + using Geometry::RotationZYX; + using Geometry::DetElement; + using Geometry::DetectorProcessor; + + using Conditions::UserPool; + using Conditions::Condition; + using Conditions::ConditionKey; + using Conditions::DetConditions; + using Conditions::ConditionsPool; + using Conditions::ConditionsSlice; + using Conditions::ConditionsPrinter; + using Conditions::ConditionsManager; + using Conditions::ConditionUpdateCall; + + /// Specialized conditions update callback + /** + * Used by clients to update a condition. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionUpdate1 : public ConditionUpdateCall { + /// Output level + PrintLevel printLevel; + public: + /// Initializing constructor + ConditionUpdate1(PrintLevel p) : printLevel(p) { } + /// Default destructor + virtual ~ConditionUpdate1() { } + /// Interface to client Callback in order to update the condition + virtual Condition operator()(const ConditionKey& key, const Context& context); + }; + + /// Specialized conditions update callback + /** + * Used by clients to update a condition. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionUpdate2 : public ConditionUpdateCall { + /// Output level + PrintLevel printLevel; + public: + /// Initializing constructor + ConditionUpdate2(PrintLevel p) : printLevel(p) { } + /// Default destructor + virtual ~ConditionUpdate2() { } + /// Interface to client Callback in order to update the condition + virtual Condition operator()(const ConditionKey& key, const Context& context); + }; + + /// Specialized conditions update callback + /** + * Used by clients to update a condition. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionUpdate3 : public ConditionUpdateCall { + /// Output level + PrintLevel printLevel; + public: + /// Initializing constructor + ConditionUpdate3(PrintLevel p) : printLevel(p) { } + /// Default destructor + virtual ~ConditionUpdate3() { } + /// Interface to client Callback in order to update the condition + virtual Condition operator()(const ConditionKey& key, const Context& context); + }; + + /// Example how to populate the detector description with conditions constants + /** + * This is simply a DetElement crawler... + * + * \author M.Frank + * \version 1.0 + * \date 01/04/2016 + */ + struct ConditionsCreator : public DetectorProcessor { + /// reference to the conditions manager + ConditionsManager manager; + /// Reference to the conditiosn user pool + ConditionsPool* pool; + /// Counter + unsigned int conditionCount; + /// Print level + PrintLevel printLevel; + /// Constructor + ConditionsCreator(ConditionsManager& m,ConditionsPool* p,PrintLevel l) + : manager(m), pool(p), conditionCount(0), printLevel(l) { } + /// Destructor + virtual ~ConditionsCreator(); + /// Callback to process a single detector element + virtual int operator()(DetElement de, int level); + }; + + /// Example how to populate the detector description with derived conditions + /** + * This is simply a DetElement crawler... + * + * \author M.Frank + * \version 1.0 + * \date 01/04/2016 + */ + struct ConditionsDependencyCreator : public DetectorProcessor { + /// Reference to the conditiosn user pool + ConditionsSlice& slice; + /// Print level + PrintLevel printLevel; + /// Three different update call types + ConditionUpdateCall *call1, *call2, *call3; + /// Constructor + ConditionsDependencyCreator(ConditionsSlice& s,PrintLevel p); + /// Callback to process a single detector element + virtual int operator()(DetElement de, int level); + }; + + /// This is important, otherwise the register and forward calls won't find them! + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2016 + */ + struct ConditionsKeys : public DetectorProcessor { + /// Print level + PrintLevel printLevel; + /// Constructor + ConditionsKeys(PrintLevel p) : printLevel(p) {} + /// Callback to process a single detector element + virtual int operator()(DetElement de, int level); + }; + + /// Example how to access the conditions constants from a detector element + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2016 + */ + struct ConditionsDataAccess : public Conditions::ConditionsProcessor { + UserPool* pool; + /// Print level + PrintLevel printLevel; + /// Constructor + ConditionsDataAccess(UserPool* p) : + ConditionsProcessor(0), pool(p), printLevel(DEBUG) { } + /// Callback to process a single detector element + int processElement(DetElement de); + }; + + /// Helper to run DetElement scans + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2016 + */ + struct Scanner : public DetectorProcessor { + DetElement::Processor* proc; + /// Callback to process a single detector element + virtual int operator()(DetElement de, int) + { return proc->processElement(de); } + template <typename Q> Scanner& scan(Q& p, DetElement start) + { Scanner obj; obj.proc = &p; obj.process(start, 0, true); return *this; } + template <typename Q> Scanner& scan2(const Q& p, DetElement start) + { Scanner obj; obj.proc = const_cast<Q*>(&p); obj.process(start, 0, true); return *this; } + }; + + /// Install the consitions and the conditions manager + void installManagers(LCDD& lcdd); + } /* End namespace ConditionsExamples */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_CONDITIONS_CONDITIONSEXAMPLEOBJECTS_H */ diff --git a/examples/Conditions/src/ConditionExample_populate.cpp b/examples/Conditions/src/ConditionExample_populate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..02ce748a01e962578ce0cdc1fb13238fd31e7264 --- /dev/null +++ b/examples/Conditions/src/ConditionExample_populate.cpp @@ -0,0 +1,114 @@ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +/* + Plugin invocation: + ================== + This plugin behaves like a main program. + Invoke the plugin with something like this: + + geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_populate \ + -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml + + Populate the conditions store by hand for a set of IOVs. + Then compute the corresponding alignment entries.... + +*/ +// Framework include files +#include "ConditionExampleObjects.h" +#include "DD4hep/Factories.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::ConditionExamples; + +/// Plugin function: Condition program example +/** + * Factory: DD4hep_ConditionExample_populate + * + * \author M.Frank + * \version 1.0 + * \date 01/12/2016 + */ +static int condition_example (Geometry::LCDD& lcdd, int argc, char** argv) { + + string input; + int num_iov = 10; + bool arg_error = false; + for(int i=0; i<argc && argv[i]; ++i) { + if ( 0 == ::strncmp("-input",argv[i],4) ) + input = argv[++i]; + else if ( 0 == ::strncmp("-iovs",argv[i],4) ) + num_iov = ::atol(argv[++i]); + else + arg_error = true; + } + if ( arg_error || input.empty() ) { + /// Help printout describing the basic command line interface + cout << + "Usage: -plugin <name> -arg [-arg] \n" + " name: factory name DD4hep_ConditionExample_populate \n" + " -input <string> Geometry file \n" + " -iovs <number> Number of parallel IOV slots for processing. \n" + "\tArguments given: " << arguments(argc,argv) << endl << flush; + ::exit(EINVAL); + } + + // First we load the geometry + lcdd.fromXML(input); + installManagers(lcdd); + + /******************** Initialize the conditions manager *****************/ + ConditionsManager condMgr = ConditionsManager::from(lcdd); + condMgr["PoolType"] = "DD4hep_ConditionsLinearPool"; + condMgr["UserPoolType"] = "DD4hep_ConditionsMapUserPool"; + condMgr["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool"; + condMgr.initialize(); + + const IOVType* iov_typ = condMgr.registerIOVType(0,"run").second; + if ( 0 == iov_typ ) { + except("ConditionsPrepare","++ Unknown IOV type supplied."); + } + + /******************** Now as usual: create the slice ********************/ + dd4hep_ptr<ConditionsSlice> slice(Conditions::createSlice(condMgr,*iov_typ)); + ConditionsKeys(INFO).process(lcdd.world(),0,true); + ConditionsDependencyCreator(*slice,INFO).process(lcdd.world(),0,true); + + /******************** Populate the conditions store *********************/ + // Have 10 run-slices [11,20] .... [91,100] + for(int i=0; i<num_iov; ++i) { + IOV iov(iov_typ, IOV::Key(1+i*10,(i+1)*10)); + ConditionsPool* iov_pool = condMgr.registerIOV(*iov.iovType, iov.key()); + ConditionsCreator creator(condMgr, iov_pool, INFO); // Use a generic creator + creator.process(lcdd.world(),0,true); // Create conditions with all deltas + } + + // ++++++++++++++++++++++++ Now compute the conditions for each of these IOVs + for(int i=0; i<num_iov; ++i) { + IOV req_iov(iov_typ,i*10+5); + // Attach the proper set of conditions to the user pool + ConditionsManager::Result r = condMgr.prepare(req_iov,*slice); + // Now compute the tranformation matrices + printout(INFO,"Prepare","Total %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) of type %s", + r.total(), r.selected, r.loaded, r.computed, r.missing, iov_typ->str().c_str()); + } + // What else ? let's access/print the current selection + ConditionsPrinter printer(slice->pool().get(),"Example"); + Scanner().scan(printer,lcdd.world()); + + // All done. + return 1; +} + +// first argument is the type from the xml file +DECLARE_APPLY(DD4hep_ConditionExample_populate,condition_example) diff --git a/examples/Conditions/src/ConditionExample_stress.cpp b/examples/Conditions/src/ConditionExample_stress.cpp new file mode 100644 index 0000000000000000000000000000000000000000..70a5cb04654f95c2f3fb9bbba4d45902a70596c8 --- /dev/null +++ b/examples/Conditions/src/ConditionExample_stress.cpp @@ -0,0 +1,134 @@ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +/* + Plugin invocation: + ================== + This plugin behaves like a main program. + Invoke the plugin with something like this: + + geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_stress \ + -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml + + Populate the conditions store by hand for a set of IOVs. + Then compute the corresponding alignment entries.... + +*/ +// Framework include files +#include "ConditionExampleObjects.h" +#include "DD4hep/Factories.h" +#include "TStatistic.h" +#include "TTimeStamp.h" +#include "TRandom3.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::ConditionExamples; + +/// Plugin function: Condition program example +/** + * Factory: DD4hep_ConditionExample_stress + * + * \author M.Frank + * \version 1.0 + * \date 01/12/2016 + */ +static int condition_example (Geometry::LCDD& lcdd, int argc, char** argv) { + string input; + int num_iov = 10, num_runs = 10; + bool arg_error = false; + for(int i=0; i<argc && argv[i]; ++i) { + if ( 0 == ::strncmp("-input",argv[i],4) ) + input = argv[++i]; + else if ( 0 == ::strncmp("-iovs",argv[i],4) ) + num_iov = ::atol(argv[++i]); + else if ( 0 == ::strncmp("-runs",argv[i],4) ) + num_runs = ::atol(argv[++i]); + else + arg_error = true; + } + if ( arg_error || input.empty() ) { + /// Help printout describing the basic command line interface + cout << + "Usage: -plugin <name> -arg [-arg] \n" + " name: factory name DD4hep_AlignmentExample1 \n" + " -input <string> Geometry file \n" + " -iovs <number> Number of parallel IOV slots for processing. \n" + " -runs <number> Number of collision loads to be performed. \n" + "\tArguments given: " << arguments(argc,argv) << endl << flush; + ::exit(EINVAL); + } + + // First we load the geometry + lcdd.fromXML(input); + installManagers(lcdd); + + /******************** Initialize the conditions manager *****************/ + ConditionsManager condMgr = ConditionsManager::from(lcdd); + condMgr["PoolType"] = "DD4hep_ConditionsMappedPool"; + condMgr["UserPoolType"] = "DD4hep_ConditionsMapUserPool"; + condMgr["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool"; + condMgr.initialize(); + + const IOVType* iov_typ = condMgr.registerIOVType(0,"run").second; + if ( 0 == iov_typ ) { + except("ConditionsPrepare","++ Unknown IOV type supplied."); + } + + /******************** Now as usual: create the slice ********************/ + dd4hep_ptr<ConditionsSlice> slice(Conditions::createSlice(condMgr,*iov_typ)); + ConditionsKeys(DEBUG).process(lcdd.world(),0,true); + ConditionsDependencyCreator(*slice,DEBUG).process(lcdd.world(),0,true); + + TStatistic cr_stat("Creation"), acc_stat("Access"); + /******************** Populate the conditions store *********************/ + // Have 10 run-slices [11,20] .... [91,100] + for(int i=0; i<num_iov; ++i) { + TTimeStamp start; + IOV iov(iov_typ, IOV::Key(1+i*10,(i+1)*10)); + ConditionsPool* iov_pool = condMgr.registerIOV(*iov.iovType, iov.key()); + ConditionsCreator creator(condMgr, iov_pool, DEBUG); // Use a generic creator + creator.process(lcdd.world(),0,true); // Create conditions with all deltas + TTimeStamp stop; + cr_stat.Fill(stop.AsDouble()-start.AsDouble()); + printout(INFO,"Example", "Setup %ld conditions for IOV:%s [%8.3f sec]", + creator.conditionCount, iov.str().c_str(), + stop.AsDouble()-start.AsDouble()); + } + + // ++++++++++++++++++++++++ Now compute the conditions for each of these IOVs + TRandom3 random; + for(int i=0; i<num_runs; ++i) { + TTimeStamp start; + unsigned int rndm = 1+random.Integer(num_iov*10); + IOV req_iov(iov_typ,rndm); + // Attach the proper set of conditions to the user pool + ConditionsManager::Result res = condMgr.prepare(req_iov,*slice); + TTimeStamp stop; + acc_stat.Fill(stop.AsDouble()-start.AsDouble()); + // Now compute the tranformation matrices + printout(INFO,"Prepare","Total %ld conditions (S:%6ld,L:%6ld,C:%6ld,M:%ld) of type %s [%8.3f sec]", + res.total(), res.selected, res.loaded, res.computed, res.missing, + req_iov.str().c_str(), stop.AsDouble()-start.AsDouble()); + } + printout(INFO,"Statistics","+======================================================================="); + printout(INFO,"Statistics","+ %-12s: %11.5g +- %11.4g RMS = %11.5g N = %lld", + cr_stat.GetName(), cr_stat.GetMean(), cr_stat.GetMeanErr(), cr_stat.GetRMS(), cr_stat.GetN()); + printout(INFO,"Statistics","+ %-12s: %11.5g +- %11.4g RMS = %11.5g N = %lld", + acc_stat.GetName(), acc_stat.GetMean(), acc_stat.GetMeanErr(), acc_stat.GetRMS(), acc_stat.GetN()); + printout(INFO,"Statistics","+======================================================================="); + // All done. + return 1; +} + +// first argument is the type from the xml file +DECLARE_APPLY(DD4hep_ConditionExample_stress,condition_example) diff --git a/examples/Conditions/src/ConditionExample_stress2.cpp b/examples/Conditions/src/ConditionExample_stress2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3281870ab147a3748ff2de58c46bb04cbcb76369 --- /dev/null +++ b/examples/Conditions/src/ConditionExample_stress2.cpp @@ -0,0 +1,126 @@ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +/* + Plugin invocation: + ================== + This plugin behaves like a main program. + Invoke the plugin with something like this: + + geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_stress \ + -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml + + Populate the conditions store by hand for a set of IOVs. + Then compute the corresponding alignment entries.... + +*/ +// Framework include files +#include "ConditionExampleObjects.h" +#include "DD4hep/Factories.h" +#include "TStatistic.h" +#include "TTimeStamp.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::ConditionExamples; + +/// Plugin function: Condition program example +/** + * Factory: DD4hep_ConditionExample_stress2 + * + * \author M.Frank + * \version 1.0 + * \date 01/12/2016 + */ +static int condition_example (Geometry::LCDD& lcdd, int argc, char** argv) { + string input; + int num_iov = 10; + bool arg_error = false; + for(int i=0; i<argc && argv[i]; ++i) { + if ( 0 == ::strncmp("-input",argv[i],4) ) + input = argv[++i]; + else if ( 0 == ::strncmp("-iovs",argv[i],4) ) + num_iov = ::atol(argv[++i]); + else + arg_error = true; + } + if ( arg_error || input.empty() ) { + /// Help printout describing the basic command line interface + cout << + "Usage: -plugin <name> -arg [-arg] \n" + " name: factory name DD4hep_ConditionExample_stress2 \n" + " -input <string> Geometry file \n" + " -iovs <number> Number of collision loads to be performed. \n" + "\tArguments given: " << arguments(argc,argv) << endl << flush; + ::exit(EINVAL); + } + + // First we load the geometry + lcdd.fromXML(input); + installManagers(lcdd); + + /******************** Initialize the conditions manager *****************/ + ConditionsManager condMgr = ConditionsManager::from(lcdd); + condMgr["PoolType"] = "DD4hep_ConditionsMappedPool"; + condMgr["UserPoolType"] = "DD4hep_ConditionsMapUserPool"; + condMgr["UpdatePoolType"] = "DD4hep_ConditionsLinearUpdatePool"; + condMgr.initialize(); + + const IOVType* iov_typ = condMgr.registerIOVType(0,"run").second; + if ( 0 == iov_typ ) { + except("ConditionsPrepare","++ Unknown IOV type supplied."); + } + + /******************** Now as usual: create the slice ********************/ + dd4hep_ptr<ConditionsSlice> slice(Conditions::createSlice(condMgr,*iov_typ)); + ConditionsKeys(DEBUG).process(lcdd.world(),0,true); + ConditionsDependencyCreator(*slice,DEBUG).process(lcdd.world(),0,true); + + TStatistic cr_stat("Creation"), acc_stat("Access"); + // ++++++++++++++++++++++++ Now compute the conditions for each of these IOVs + for(int i=0; i<num_iov; ++i) { + { + TTimeStamp start; + IOV iov(iov_typ, IOV::Key(1+i*10,(i+1)*10)); + ConditionsPool* iov_pool = condMgr.registerIOV(*iov.iovType, iov.key()); + ConditionsCreator creator(condMgr, iov_pool, DEBUG); // Use a generic creator + creator.process(lcdd.world(),0,true); // Create conditions with all deltas + TTimeStamp stop; + cr_stat.Fill(stop.AsDouble()-start.AsDouble()); + printout(INFO,"Creating", "Setup %-6ld conditions for IOV:%-60s [%8.3f sec]", + creator.conditionCount, iov.str().c_str(), + stop.AsDouble()-start.AsDouble()); + } { + TTimeStamp start; + IOV req_iov(iov_typ,i*10+5); + // Attach the proper set of conditions to the user pool + ConditionsManager::Result res = condMgr.prepare(req_iov,*slice); + TTimeStamp stop; + acc_stat.Fill(stop.AsDouble()-start.AsDouble()); + // Now compute the tranformation matrices + printout(INFO,"Compute","Total %-6ld conditions (S:%6ld,L:%6ld,C:%6ld,M:%4ld) of type %-25s [%8.3f sec]", + res.total(), res.selected, res.loaded, res.computed, res.missing, + req_iov.str().c_str(), stop.AsDouble()-start.AsDouble()); + } + } + printout(INFO,"Statistics","+======================================================================="); + printout(INFO,"Statistics","+ %-12s: %11.5g +- %11.4g RMS = %11.5g N = %lld", + cr_stat.GetName(), cr_stat.GetMean(), cr_stat.GetMeanErr(), cr_stat.GetRMS(), cr_stat.GetN()); + printout(INFO,"Statistics","+ %-12s: %11.5g +- %11.4g RMS = %11.5g N = %lld", + acc_stat.GetName(), acc_stat.GetMean(), acc_stat.GetMeanErr(), acc_stat.GetRMS(), acc_stat.GetN()); + printout(INFO,"Statistics","+======================================================================="); + // All done. + return 1; +} + +// first argument is the type from the xml file +DECLARE_APPLY(DD4hep_ConditionExample_stress2,condition_example)