diff --git a/DDAlign/include/DDAlign/AlignmentsCalib.h b/DDAlign/include/DDAlign/AlignmentsCalib.h index ec236622310c8c619a55c4d5da348cafdb18f91b..648f16cfc7a12d9547fc2bf9c24cfc7c9d83477b 100644 --- a/DDAlign/include/DDAlign/AlignmentsCalib.h +++ b/DDAlign/include/DDAlign/AlignmentsCalib.h @@ -14,6 +14,7 @@ #define DD4HEP_DDALIGN_ALIGNMENTCALIB_H // Framework includes +#include "DD4hep/Printout.h" #include "DD4hep/Detector.h" #include "DD4hep/Conditions.h" #include "DD4hep/Alignments.h" @@ -84,21 +85,20 @@ namespace DD4hep { typedef std::map<DetElement,UsedEntry> UsedDetectors; public: + enum CommitMode { + DIRECT = 1, + NORMAL = 2 + }; LCDD& lcdd; /// Reference to the alignment manager object Slice& slice; UsedConditions used; AlignmentsManager alignManager; AlignmentsUpdateCall* derivationCall = 0; + DD4hep::PrintLevel printLevel = DD4hep::DEBUG; protected: - /// Propagate all Delta parameters to the source conditions - bool propagateDeltas(); - /// Update Dependencies between the source conditions and the computations - bool updateDependencies(); - /// Compute all dependent conditions from the Delta parameters - AlignmentsManager::Result computeDependencies(); - + /// Implementation: Add a new entry to the transaction list std::pair<key_type,Entry*> _insert(const std::pair<Condition::key_type,Entry*>& e); /// Implementation: Register newly created condition to user-pool, slice and manager @@ -106,12 +106,12 @@ namespace DD4hep { /// Implementation: Add a new raw(delta)-condition to the transaction stack. Condition _create_source(key_type key, const std::string& nam) const; /// Implementation: Add a new alignment-condition to the transaction stack. - Condition _create_target(DetElement detector, key_type key, const std::string& nam) const; + Condition _create_target(DetElement det, key_type key, const std::string& nam) const; /// Implementation: Add a new entry to the transaction stack. - std::pair<key_type,Entry*> _use(DetElement detector, AlignmentCondition alignment); + std::pair<key_type,Entry*> _use(DetElement det, AlignmentCondition alignment); /// Implementation: Add a new entry to the transaction stack. - std::pair<key_type,Entry*> _use(DetElement detector, const std::string& alignment); + std::pair<key_type,Entry*> _use(DetElement det, const std::string& alignment); public: @@ -142,7 +142,7 @@ namespace DD4hep { * * The resulting alignment key is returned to the client. If NULL: Failure */ - key_type use(DetElement detector, Alignment alignment); + key_type use(DetElement det, Alignment alignment); /// (2) Add a new entry to an existing DetElement structure. /** @@ -178,28 +178,28 @@ namespace DD4hep { * * The resulting alignment key is returned to the client. If NULL: Failure */ - key_type use(DetElement detector, const std::string& name); + key_type use(DetElement det, const std::string& name); /// (3) Add a new entry to an existing DetElement structure. /** * Shortcut call equivalent to: - * key_type use(detector, detector.path()+"#alignment") + * key_type use(det, det.path()+"#alignment") * * The alignment key is returned to the client. If NULL: Failure */ - key_type use(DetElement detector); + key_type use(DetElement det); /// (4) Add a new entry to an existing DetElement structure. /** * The alignment key is returned to the client. If NULL: Failure */ - key_type use(const std::string& detector, const std::string& name); + key_type use(const std::string& path, const std::string& name); /// (5) Add a new entry to an existing DetElement structure. /** * The alignment key is returned to the client. If NULL: Failure */ - key_type use(const std::string& detector); + key_type use(const std::string& path); /// Complete the setup procedure bool start(); @@ -221,8 +221,11 @@ namespace DD4hep { /// We clear the entire cached stack of used entries. void clear(); + /// Convenience only: Access detector element by path + DetElement detector(const std::string& path) const; + /// Commit all pending transactions. Returns number of altered entries - AlignmentsManager::Result commit(); + AlignmentsManager::Result commit(CommitMode mode=NORMAL); }; } /* End namespace Alignments */ diff --git a/DDAlign/include/DDAlign/AlignmentsManager.h b/DDAlign/include/DDAlign/AlignmentsManager.h index 764e70d2ae3eb6390372aceb12a71306e1f868e0..6a54d29792e740b7ac18e700d3d96636e45c25f6 100644 --- a/DDAlign/include/DDAlign/AlignmentsManager.h +++ b/DDAlign/include/DDAlign/AlignmentsManager.h @@ -106,6 +106,9 @@ namespace DD4hep { Result compute(Slice& slice) const; /// Compute all alignment conditions of the internal dependency list Result compute(Slice& slice, const Dependencies& dependencies) const; + /// Compute all alignment conditions of the dependency list + /** Assume that source and target conditions were updated externally. */ + Result computeDirect(Slice& slice, const Dependencies& dependencies) const; /// Register new updated derived alignment during the computation step static void newEntry(const Context& parameter, const Dependency* dep, @@ -139,10 +142,13 @@ namespace DD4hep { AlignmentsManagerObject(); /// Default destructor virtual ~AlignmentsManagerObject(); - /// Compute all alignment conditions of the internal dependency list + /// Compute all alignment conditions. Dependency list created from slice information Result compute(Slice& slice) const; - /// Compute all alignment conditions of the internal dependency list + /// Compute all alignment conditions of the dependency list Result compute(Slice& slice, const Dependencies& dependencies) const; + /// Compute all alignment conditions of the dependency list + /** Assume that source and target conditions were updated externally. */ + Result computeDirect(Slice& slice, const Dependencies& dependencies) const; }; } /* End namespace Geometry */ diff --git a/DDAlign/src/AlignmentsCalib.cpp b/DDAlign/src/AlignmentsCalib.cpp index 839154cb793bc158ac683e84527c5e6ed03daaf2..e912401fdfeb36e7e16d9e7d5ff0dc761147d45a 100644 --- a/DDAlign/src/AlignmentsCalib.cpp +++ b/DDAlign/src/AlignmentsCalib.cpp @@ -62,32 +62,21 @@ namespace { } }; - struct ConnectChildren : public CalibCallback { - /// Standard constructor - ConnectChildren(AlignmentsCalib& c, Entry& e) : CalibCallback(c,e) { } - /// Dump method. - virtual int operator()(DetElement de,int /* level */) { - if ( entry.detector.ptr() == de.parent().ptr() ) { - Entry* child = 0;///TODO - entry.children.insert(child); - } - return 1; - } - }; - - struct Callback_SetDirty : public CalibCallback { - /// Standard constructor - Callback_SetDirty(AlignmentsCalib& c, Entry& e) : CalibCallback(c,e) { } - /// Dump method. - virtual int operator()(DetElement de,int /* level */) { - if ( entry.detector.ptr() == de.ptr() ) { + void set_children_dirty(PrintLevel lvl, AlignmentsCalib::Entry* entry) { + for ( auto& e : entry->children ) { + if ( !e->dirty ) + set_children_dirty(lvl,e); + if ( e->dirty ) { + printout(lvl,"SetDirty"," detector: %s --> %s", + entry->detector.path().c_str(), e->detector.name()); } - return 1; + e->dirty = 1; } - - }; + } + } // ====================================================================================== +#define TAG "AlignmentsCalib" /// Initializing constructor AlignmentsCalib::AlignmentsCalib(LCDD& l, Slice& s) : lcdd(l), slice(s), derivationCall(0) @@ -99,6 +88,12 @@ AlignmentsCalib::AlignmentsCalib(LCDD& l, Slice& s) : lcdd(l), slice(s), derivat AlignmentsCalib::~AlignmentsCalib() { } +/// Convenience only: Access detector element by path +AlignmentsCalib::DetElement AlignmentsCalib::detector(const std::string& path) const { + DetElement det(Geometry::DetectorTools::findElement(lcdd,path)); + return det; +} + /// Add a new entry to the transaction list pair<AlignmentsCalib::key_type,AlignmentsCalib::Entry*> AlignmentsCalib::_insert(const pair<Condition::key_type,Entry*>& e) { @@ -117,22 +112,18 @@ AlignmentsCalib::_use(DetElement detector, AlignmentCondition alignment_conditio } dd4hep_ptr<Entry> entry(new Entry()); - UserPool* pool = slice.pool.get(); - Condition cc(alignment_condition); - printout(INFO,"Ex","Check key: %p %p -> %s",(void*)alignment_condition.key(),(void*)cc.key(), - alignment_condition.name()); + UserPool* pool = slice.pool.get(); /// This may be the derived condition: check presence - cc = pool->get(tar_key); AlignmentCondition align_cond = pool->get(tar_key); if ( !align_cond.isValid() ) { - except("AlignmentsCalib","++ The DERIVED alignment condition [%p] is invalid.",(void*)tar_key); + except(TAG,"++ The DERIVED alignment condition [%016llX] is invalid.",tar_key); } - key_type src_key = align_cond->source_key; + key_type src_key = align_cond->source_key; Condition src_cond = pool->get(src_key); if ( !src_cond.isValid() ) { - except("AlignmentsCalib","++ The SOURCE alignment condition [%p] for %s is invalid.", - (void*)src_key, align_cond.name()); + except(TAG,"++ The SOURCE alignment condition [%016llX] for %s is invalid.", + src_key, align_cond.name()); } /// Check for the source data entry Proxy::const_iterator is = slice.conditions().find(src_key); @@ -142,22 +133,22 @@ AlignmentsCalib::_use(DetElement detector, AlignmentCondition alignment_conditio } entry->source = (*is).second; /// Check for the derived conditions entry + /// We ensure it is out callback, which is installed! Proxy::const_iterator ip = slice.derived().find(tar_key); - if ( ip == slice.derived().end() && derivationCall ) { + if ( ip != slice.derived().end() ) { + slice.remove((*ip).second->dependency); + } + + if ( derivationCall ) { ConditionKey key(align_cond.name(),align_cond.key()); Conditions::DependencyBuilder b(key,derivationCall,detector); b.add(ConditionKey(src_cond.name(),src_cond.key())); slice.insert(b.release()); ip = slice.derived().find(tar_key); } - else if ( derivationCall ) { - UpdateCall* call = (*ip).second->dependency->callback; - if ( call ) call->release(); - (*ip).second->dependency->callback = derivationCall->addRef(); - } else { - except("AlignmentsCalib","++ The dependency rule for [%p] %s cannot be added [no callback].", - (void*)tar_key, align_cond.name()); + except(TAG,"++ The dependency rule for [%016llX] %s cannot be added [no callback].", + tar_key, align_cond.name()); } entry->target = (*ip).second; entry->detector = detector; @@ -184,8 +175,8 @@ AlignmentsCalib::_use(DetElement detector,const string& src_nam) { src_cond = _create_source(src_key, src_nam); /// Now check again if we succeeded. if ( !src_cond.isValid() ) { - except("AlignmentsCalib","++ The SOURCE alignment condition [%p]: %s is invalid.", - (void*)src_key, src_nam.c_str()); + except(TAG,"++ The SOURCE alignment condition [%016llX]: %s is invalid.", + src_key, src_nam.c_str()); } // Add the conditons keys to the detector element: Conditions::DetConditions conditions(detector); @@ -200,8 +191,8 @@ AlignmentsCalib::_use(DetElement detector,const string& src_nam) { align_cond = _create_target(detector, tar_key, tar_nam); /// Now check again if we succeeded. if ( !align_cond.isValid() ) { - except("AlignmentsCalib","++ The DERIVED alignment condition [%p]: %s is invalid.", - (void*)tar_key, tar_nam.c_str()); + except(TAG,"++ The DERIVED alignment condition [%016llX]: %s is invalid.", + tar_key, tar_nam.c_str()); } // Add the conditons keys to the detector element: Conditions::DetConditions conditions(detector); @@ -236,7 +227,8 @@ Condition AlignmentsCalib::_register(Condition cond) const { ConditionKey key(cond.name(),cond.key()); slice.insert(key,slice.loadInfo(cond.address())); slice.insert(cond); - printout(INFO,"Ex","Inserted key: %p -> %s",(void*)key.hash,key.name.c_str()); + printout(DEBUG,TAG,"++ Inserted key: %016llX -> %s", + key.hash,key.name.c_str()); return cond; } invalidHandleError<Condition>(); @@ -250,7 +242,6 @@ Condition AlignmentsCalib::_create_source(key_type key, Condition cond(nam,"alignment"); cond.bind<Delta>(); cond->setFlag(Condition::ALIGNMENT); - //cond->validate(); cond->hash = key; return _register(cond); } @@ -264,54 +255,35 @@ Condition AlignmentsCalib::_create_target(DetElement detector, AlignmentData& data = Condition(cond).get<AlignmentData>(); data.detector = detector; cond->setFlag(Condition::ALIGNMENT_DERIVED); - //cond->invalidate(); cond->hash = key; return _register(cond); } /// (1) Add a new entry to the transaction stack. -AlignmentsCalib::key_type AlignmentsCalib::use(DetElement detector, Alignment alignment) { - AlignmentCondition cond = alignment.condition(); - detector.access(); // Throw exception if invalid. - cond.access(); // Throw exception if invalid. - return _use(detector, cond).first; +AlignmentsCalib::key_type AlignmentsCalib::use(DetElement det, Alignment alignment) { + AlignmentCondition condition = alignment.condition(); + return _use(det.access(), condition.access()).first; } /// (2) Add a new entry to an existing DetElement structure. -AlignmentsCalib::key_type -AlignmentsCalib::use(DetElement detector,const string& src_nam) { - return _use(detector, src_nam).first; +AlignmentsCalib::key_type AlignmentsCalib::use(DetElement det,const string& src_nam) { + return _use(det.access(), src_nam).first; } /// (3) Add a new entry to an existing DetElement structure. -AlignmentsCalib::key_type AlignmentsCalib::use(DetElement detector) { - if ( detector.isValid() ) { - string name = detector.path()+"#alignment"; - return use(detector,name); - } - invalidHandleError<DetElement>(); - return 0; +AlignmentsCalib::key_type AlignmentsCalib::use(DetElement det) { + string name = det.path()+"#alignment"; + return use(det.access(), name); } /// (4) Add a new entry to an existing DetElement structure. -AlignmentsCalib::key_type -AlignmentsCalib::use(const std::string& detector, const string& src_nam) { - DetElement det(Geometry::DetectorTools::findElement(lcdd,detector)); - if ( det.isValid() ) { - return use(det, src_nam); - } - invalidHandleError<DetElement>(); - return 0; +AlignmentsCalib::key_type AlignmentsCalib::use(const string& path, const string& src_nam) { + return use(detector(path).access(), src_nam); } /// (5) Add a new entry to an existing DetElement structure. -AlignmentsCalib::key_type AlignmentsCalib::use(const std::string& detector) { - DetElement det(Geometry::DetectorTools::findElement(lcdd,detector)); - if ( det.isValid() ) { - return use(det); - } - invalidHandleError<DetElement>(); - return 0; +AlignmentsCalib::key_type AlignmentsCalib::use(const string& path) { + return use(detector(path).access()); } /// Update Dependencies between the source conditions and the computations @@ -361,7 +333,7 @@ bool AlignmentsCalib::setDelta(Condition::key_type key_val, const Delta& delta) (*i).second->dirty = 1; return true; } - except("AlignmentsCalib","++ FAILED setDelta: invalid entry id: %p",(void*)key_val); + except(TAG,"++ FAILED setDelta: invalid entry id: %016llX",key_val); return false; } @@ -370,61 +342,38 @@ bool AlignmentsCalib::setDelta(const ConditionKey& key, const Delta& delta) { return setDelta(key.hash, delta); } -/// Propagate all Delta parameters to the source conditions -bool AlignmentsCalib::propagateDeltas() { +/// Commit all pending transactions. Returns number of altered entries +AlignmentsManager::Result AlignmentsCalib::commit(CommitMode mode) { UserPool* pool = slice.pool.get(); + ConditionsDependencyCollection deps; + + /// 1) Propagate the Delta values to the source conditions for ( auto& entry : used ) { Entry* e = entry.second; if ( e->dirty ) { /// Update the source condition with the new delta value Condition src_cond = pool->get(e->source->key.hash); if ( !src_cond.isValid() ) { - except("AlignmentsCalib","++ The SOURCE alignment condition [%p]: %s is invalid.", - (void*)e->source->key.hash, e->source->key.name.c_str()); + except(TAG,"++ The SOURCE alignment condition [%016llX]: %s is invalid.", + e->source->key.hash, e->source->key.name.c_str()); } src_cond.get<Delta>() = e->delta; } } - return true; -} - -void set_children_dirty(AlignmentsCalib::Entry* entry) { - for ( auto& e : entry->children ) { - if ( !e->dirty ) - set_children_dirty(e); - if ( e->dirty ) - printout(INFO,"SetDirty"," detector: %s --> %s",entry->detector.path().c_str(), e->detector.name()); - e->dirty = 1; - } -} - -/// Update Dependencies between the source conditions and the computations -bool AlignmentsCalib::updateDependencies() { - // To optimize the lookup we have to enable the parent chain for the entries - for ( auto& e : used ) { - if ( e.second->dirty ) - set_children_dirty(e.second); + /// 2) Update the dirty dependencies between the source conditions and the computations + for ( auto& entry : used ) { + if ( entry.second->dirty ) + set_children_dirty(printLevel, entry.second); } - return true; -} - -/// Compute all dependent conditions from the Delta parameters -AlignmentsManager::Result AlignmentsCalib::computeDependencies() { - ConditionsDependencyCollection deps; - for ( auto& e : used ) { - if ( e.second->dirty ) { - deps.insert(e.second->target->dependency); + /// 3) Setup dependency collection + for ( auto& entry : used ) { + Entry* e = entry.second; + if ( e->dirty ) { + deps.insert(e->target->dependency); } } - return alignManager.compute(slice, deps); -} - -/// Commit all pending transactions. Returns number of altered entries -AlignmentsManager::Result AlignmentsCalib::commit() { - if ( propagateDeltas() ) { - if ( updateDependencies() ) { - return computeDependencies(); - } + if ( mode == NORMAL ) { + return alignManager.compute(slice, deps); } - return AlignmentsManager::Result(); + return alignManager.computeDirect(slice, deps); } diff --git a/DDAlign/src/AlignmentsForward.cpp b/DDAlign/src/AlignmentsForward.cpp index f6ba2318c293a3c269bf0cef4d2689ab88c8ee3e..e80659afadc6d2e710b9933d221433efdac54d3f 100644 --- a/DDAlign/src/AlignmentsForward.cpp +++ b/DDAlign/src/AlignmentsForward.cpp @@ -25,7 +25,7 @@ using namespace DD4hep::Alignments; /// Initializing constructor AlignmentsForward::AlignmentsForward(Slice& s, AlignmentsUpdateCall* c) - : slice(s), updateCall(c), extension("#alignment/Tranformations"), + : slice(s), updateCall(c), extension("#alignment/Transformations"), alias("Alignment"), haveAlias(true), printLevel(DEBUG) { } diff --git a/DDAlign/src/AlignmentsManager.cpp b/DDAlign/src/AlignmentsManager.cpp index f6d5e52dd900799f8402fbdeebc876d1dbfce7e4..9fa76618947543a314960b5e1c7997b04277cff9 100644 --- a/DDAlign/src/AlignmentsManager.cpp +++ b/DDAlign/src/AlignmentsManager.cpp @@ -26,6 +26,8 @@ using namespace DD4hep; using namespace DD4hep::Alignments; +using Conditions::Condition; +using Conditions::ConditionKey; using Conditions::ConditionsSlice; using Conditions::ConditionDependency; using Conditions::ConditionsDependencyCollection; @@ -97,8 +99,8 @@ namespace DD4hep { DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentsManagerObject); -//static PrintLevel s_PRINT = WARNING; -static PrintLevel s_PRINT = INFO; +static PrintLevel s_PRINT = WARNING; +//static PrintLevel s_PRINT = INFO; /// Initializing constructor AlignmentsManagerObject::AlignmentsManagerObject() : NamedObject() { @@ -218,44 +220,6 @@ static void computeDelta(AlignmentCondition cond, TGeoHMatrix& tr_delta) { } } -/// Compute all alignment conditions of the internal dependency list -AlignmentsManager::Result -AlignmentsManagerObject::compute(Slice& slice, const Dependencies& dependencies) const { - Result result; - AlignContext new_alignments; - new_alignments.entries.reserve(slice.derived().size()); - // - // This here is the main difference compared to other derived conditions: - // ---------------------------------------------------------------------- - // - // We enforce here that all computations, which require an update of the corresponding - // alignment matrices are stored in "new_alignments", since the update callback registers - // all new entries using this user parameter when calling AlignmentsManager::newEntry. - // For this reason also ALL specific update calls must base themself in the - // Alignment update callback. - // - slice.pool->compute(dependencies, &new_alignments, true); - for(auto i=new_alignments.entries.begin(); i != new_alignments.entries.end(); ++i) { - Result r = compute(new_alignments, *slice.pool, (*i).det); - result.computed += r.computed; - result.missing += r.missing; - } - return result; -} - -/// Compute all alignment conditions of the specified dependency list -AlignmentsManager::Result -AlignmentsManagerObject::compute(Slice& slice) const { - ConditionsDependencyCollection deps; - for(const auto& d : slice.derived() ) { - ConditionDependency* dep = d.second->dependency; - if ( dep ) { - deps.insert(dep); - } - } - return compute(slice, deps); -} - /// Compute all alignment conditions of the lower levels AlignmentsManager::Result AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& pool, DetElement det) const { @@ -272,11 +236,8 @@ AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& pool, D TGeoHMatrix tr_delta; AlignmentCondition cond = ent->cond; AlignmentData& align = cond.data(); - if ( s_PRINT <= INFO ) { - printout(INFO,"ComputeAlignment", - "============================== Compute transformation of %s ============================== ", - det.path().c_str()); - } + printout(DEBUG,"ComputeAlignment", + "============================== Compute transformation of %s",det.path().c_str()); ent->valid = 1; computeDelta(cond, tr_delta); align.worldDelta = tr_delta; @@ -330,6 +291,79 @@ AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& pool, D return result; } + +/// Compute all alignment conditions of the internal dependency list +AlignmentsManager::Result +AlignmentsManagerObject::computeDirect(Slice& slice, const Dependencies& dependencies) const { + Result result; + AlignContext context; + context.entries.reserve(dependencies.size()); + + for ( const auto& i : dependencies ) { + Dependency* dep = i.second.get(); + const ConditionKey& src_key = *(dep->dependencies.begin()); + Condition src_cond = slice.pool->get(src_key.hash); + AlignmentCondition tar_cond = slice.pool->get(dep->key()); + + /// Update the source condition with the new delta value + if ( !src_cond.isValid() ) { + except("AlignmentsManager","++ The SOURCE alignment condition [%p]: %s is invalid.", + (void*)src_key.hash, src_key.name.c_str()); + } + /// Update the source condition with the new delta value + if ( !tar_cond.isValid() ) { + except("AlignmentsManager","++ The TARGET alignment condition [%p]: %s is invalid.", + (void*)dep->key(), dep->name()); + } + tar_cond.data().delta = src_cond.get<Delta>(); + context.newEntry(dep, tar_cond.ptr()); + } + for ( const auto& i : context.entries ) { + Result r = compute(context, *slice.pool, i.det); + result.computed += r.computed; + result.missing += r.missing; + } + return result; +} + +/// Compute all alignment conditions of the internal dependency list +AlignmentsManager::Result +AlignmentsManagerObject::compute(Slice& slice, const Dependencies& dependencies) const { + Result result; + AlignContext context; + context.entries.reserve(slice.derived().size()); + // + // This here is the main difference compared to other derived conditions: + // ---------------------------------------------------------------------- + // + // We enforce here that all computations, which require an update of the corresponding + // alignment matrices are stored in "context", since the update callback registers + // all new entries using this user parameter when calling AlignmentsManager::newEntry. + // For this reason also ALL specific update calls must base themself in the + // Alignment update callback. + // + slice.pool->compute(dependencies, &context, true); + for(auto i=context.entries.begin(); i != context.entries.end(); ++i) { + Result r = compute(context, *slice.pool, (*i).det); + result.computed += r.computed; + result.missing += r.missing; + } + return result; +} + +/// Compute all alignment conditions of the specified dependency list +AlignmentsManager::Result +AlignmentsManagerObject::compute(Slice& slice) const { + ConditionsDependencyCollection deps; + for(const auto& d : slice.derived() ) { + ConditionDependency* dep = d.second->dependency; + if ( dep ) { + deps.insert(dep); + } + } + return compute(slice, deps); +} + /// Initializing constructor AlignmentsManager::AlignmentsManager(const std::string& nam) { assign(new AlignmentsManagerObject(), nam, "alignmentmanager"); @@ -356,6 +390,12 @@ AlignmentsManager::compute(Slice& slice, const Dependencies& dependencies) cons return access()->compute(slice, dependencies); } +/// Compute all alignment conditions of the internal dependency list +AlignmentsManager::Result +AlignmentsManager::computeDirect(Slice& slice, const Dependencies& dependencies) const { + return access()->computeDirect(slice, dependencies); +} + /// Register new updated derived alignment during the computation step void AlignmentsManager::newEntry(const Context& context, const Dependency* dep, diff --git a/DDAlign/src/AlignmentsRegister.cpp b/DDAlign/src/AlignmentsRegister.cpp index 439ca4e0b40b1c2fbae8dddf1713ff4aa0a06374..2d18f4eea7db0cce15cbafc0c6a1b97c0958f0b5 100644 --- a/DDAlign/src/AlignmentsRegister.cpp +++ b/DDAlign/src/AlignmentsRegister.cpp @@ -28,7 +28,7 @@ using Conditions::Condition; /// Initializing constructor AlignmentsRegister::AlignmentsRegister(Slice& s, AlignmentsUpdateCall* c) - : slice(s), updateCall(c), extension("/Tranformations"), + : slice(s), updateCall(c), extension("/Transformations"), alias("Alignment"), haveAlias(true), printLevel(DEBUG) { } diff --git a/DDAlign/src/AlignmentsReset.cpp b/DDAlign/src/AlignmentsReset.cpp index 7d3f629384e84fa65d3247448120b7b176d63753..721c72eaed566d7ace3f92536a93da4938f8188a 100644 --- a/DDAlign/src/AlignmentsReset.cpp +++ b/DDAlign/src/AlignmentsReset.cpp @@ -28,7 +28,7 @@ using Conditions::Condition; /// Initializing constructor AlignmentsReset::AlignmentsReset(Slice& s, AlignmentsUpdateCall* c) - : slice(s), updateCall(c), extension("/Tranformations"), + : slice(s), updateCall(c), extension("/Transformations"), alias("Alignment"), haveAlias(true), printLevel(DEBUG) { } diff --git a/DDAlign/src/DDAlignForwardCall.cpp b/DDAlign/src/DDAlignForwardCall.cpp index cbb5094348461e48707fd9720f0efdce0eb819e8..09a4722ef15e063ed8d129db4ed5fd1f72530a39 100644 --- a/DDAlign/src/DDAlignForwardCall.cpp +++ b/DDAlign/src/DDAlignForwardCall.cpp @@ -26,7 +26,7 @@ Alignments::DDAlignForwardCall::operator()(const ConditionKey& key, const Update Data::Delta delta; DetElement det = context.dependency.detector; Condition c = AlignmentsUpdateCall::handle(key, context, 0, delta); - printout(INFO,"DDAlignForward","++ Building child alignment condition: %s Detector [%d]: %s [%p]", + printout(printLevel,"DDAlignForward","++ Building child alignment condition: %s Detector [%d]: %s [%p]", key.name.c_str(), det.level(), det.path().c_str(), c.ptr()); return c; } diff --git a/DDCond/include/DDCond/ConditionsDependencyCollection.h b/DDCond/include/DDCond/ConditionsDependencyCollection.h index 023fc1cf3ead3fc78ef01c69e91d30273052bfff..183bd0f6ee779f34c34642ebf37c3a9e400b24dd 100644 --- a/DDCond/include/DDCond/ConditionsDependencyCollection.h +++ b/DDCond/include/DDCond/ConditionsDependencyCollection.h @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCond/include/DDCond/ConditionsSlice.h b/DDCond/include/DDCond/ConditionsSlice.h index 0429fe84db03180dedeeb7d41f046f76d1ade55e..a3a91925180ad53fe8e4337bcdbb2b4a2b6a7ec0 100644 --- a/DDCond/include/DDCond/ConditionsSlice.h +++ b/DDCond/include/DDCond/ConditionsSlice.h @@ -127,8 +127,12 @@ namespace DD4hep { virtual const std::type_info& type() const { return typeid(T); } virtual const void* ptr() const { return &info; } }; - template <typename T> static LoadInfo<T> loadInfo(const T& t) - { return LoadInfo<T>(t); } + /// Concrete class for NO data loading information. + /** + * \author M.Frank + * \version 1.0 + * \date 31/03/2016 + */ struct NoLoadInfo : public ConditionsLoadInfo { NoLoadInfo() = default; NoLoadInfo(const NoLoadInfo& i) = default; @@ -218,16 +222,16 @@ namespace DD4hep { void clear(); /// Clear the conditions access and the user pool. void reset(); + /// Remove a new shared conditions dependency + bool remove(Dependency* dependency); + /// Remove a condition from the slice + bool remove(Condition condition); + /// Add a new conditions dependency collection void insert(const ConditionsDependencyCollection& deps); /// Add a new shared conditions dependency bool insert(Dependency* dependency); - /// Create slice entry for external usage - template <typename T> static - Descriptor* createDescriptor(const ConditionKey& key, const T& loadinfo) { - Descriptor* e = new ConditionsLoaderDescriptor<T>(key,loadinfo); - return e; - } + /// Add a new conditions key. T must inherot from class ConditionsSlice::Info template <typename T> bool insert(const ConditionKey& key, const T& loadinfo) { @@ -240,6 +244,15 @@ namespace DD4hep { bool insert(Condition condition) { return insert_condition(condition); } + /// Create load-info object + template <typename T> static LoadInfo<T> loadInfo(const T& t) { return LoadInfo<T>(t); } + + /// Create slice entry for external usage + template <typename T> static + Descriptor* createDescriptor(const ConditionKey& key, const T& loadinfo) { + Descriptor* e = new ConditionsLoaderDescriptor<T>(key,loadinfo); + return e; + } }; /// Populate the conditions slice from the conditions manager (convenience) diff --git a/DDCond/src/ConditionsSlice.cpp b/DDCond/src/ConditionsSlice.cpp index ac7c14584e18c1525a917d1ae4136fa35f50e27c..d09f7cc5a00f5ebe28371c1a19d3da2e7ff28bb0 100644 --- a/DDCond/src/ConditionsSlice.cpp +++ b/DDCond/src/ConditionsSlice.cpp @@ -82,6 +82,32 @@ void ConditionsSlice::reset() { if ( pool.get() ) pool->clear(); } +/// Remove a new shared conditions dependency +bool ConditionsSlice::remove(Dependency* dependency) { + if ( dependency ) { + ConditionsProxy::iterator i = m_derived.find(dependency->key()); + if ( i != m_derived.end() ) { + delete (*i).second; + m_derived.erase(i); + return true; + } + } + return false; +} + +/// Remove a new shared condition +bool ConditionsSlice::remove(Condition condition) { + if ( condition.isValid() ) { + ConditionsProxy::iterator i = m_conditions.find(condition->hash); + if ( i != m_conditions.end() ) { + delete (*i).second; + m_conditions.erase(i); + return true; + } + } + return false; +} + /// Add a new conditions dependency collection void ConditionsSlice::insert(const ConditionsDependencyCollection& deps) { for ( const auto& d : deps ) this->insert(d.second.get()); diff --git a/DDCond/src/plugins/ConditionsUserPool.cpp b/DDCond/src/plugins/ConditionsUserPool.cpp index 058cb07546a61c81403f70c2b4113bae05eba184..69aa3de7a6eaa9909cf7250ea7bbde47b273003b 100644 --- a/DDCond/src/plugins/ConditionsUserPool.cpp +++ b/DDCond/src/plugins/ConditionsUserPool.cpp @@ -194,7 +194,13 @@ ConditionsMappedUserPool<MAPPING>::i_findCondition(key_type key) const { template<typename MAPPING> inline bool ConditionsMappedUserPool<MAPPING>::i_insert(Condition::Object* o) { - return m_conditions.insert(make_pair(o->hash,o)).second; + int ret = m_conditions.insert(make_pair(o->hash,o)).second; +#if 0 + printout(INFO,"UserPool","++ %s condition [%016llX]: %s.", + ret ? "Successfully inserted" : "FAILED to insert", + o->hash, o->name.c_str()); +#endif + return ret; } /// Total entry count diff --git a/DDCore/include/DD4hep/LCDD.h b/DDCore/include/DD4hep/LCDD.h index fc07419809075985ada95bb82276dc5e16212eb2..75f8f6deb0b9f63721ffe05144a6c367f215f32d 100644 --- a/DDCore/include/DD4hep/LCDD.h +++ b/DDCore/include/DD4hep/LCDD.h @@ -17,9 +17,13 @@ #define DD4HEP_MAJOR_VERSION 0 #define DD4HEP_MINOR_VERSION 19 -#define DD4HEP_VERSION_GE( MAJV , MINV ) ( ( DD4HEP_MAJOR_VERSION > MAJV ) || ( (DD4HEP_MAJOR_VERSION==MAJV) && ( DD4HEP_MINOR_VERSION >= MINV ) ) ) +#define DD4HEP_VERSION_GE(MAJV,MINV) ( ( DD4HEP_MAJOR_VERSION > MAJV ) || \ + ( (DD4HEP_MAJOR_VERSION == MAJV ) && \ + (DD4HEP_MINOR_VERSION >= MINV ) ) ) -#define DD4HEP_VERSION_GT( MAJV , MINV ) ( ( DD4HEP_MAJOR_VERSION > MAJV ) || ( (DD4HEP_MAJOR_VERSION==MAJV) && ( DD4HEP_MINOR_VERSION > MINV ) ) ) +#define DD4HEP_VERSION_GT(MAJV,MINV) ( ( DD4HEP_MAJOR_VERSION > MAJV ) || \ + ( (DD4HEP_MAJOR_VERSION == MAJV ) && \ + (DD4HEP_MINOR_VERSION > MINV ) ) ) // Framework includes @@ -48,11 +52,7 @@ class TGeoManager; namespace DD4hep { /// return a string with the current DD4hep version in the form vXX-YY. - inline std::string versionString(){ - std::string vs("vXX-YY") ; - std::sprintf( &vs[0] , "v%2.2d-%2.2d", DD4HEP_MAJOR_VERSION, DD4HEP_MINOR_VERSION ) ; - return vs ; - } + std::string versionString(); // Foward declarations class NamedObject; diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp index 2cfc84009b6eef6fb5231213b752f977d6ea79f0..f307b843544949898d242d7fde9d2156741352c8 100644 --- a/DDCore/src/LCDDImp.cpp +++ b/DDCore/src/LCDDImp.cpp @@ -67,23 +67,29 @@ namespace { void lcdd_unexpected() { try { throw; - } catch( std::exception& e){ - std::cout << "\n" - << "**************************************************** \n" - << "* A runtime error has occured : \n" - << "* " << e.what() << std::endl - << "* the program will have to be terminated - sorry. \n" - << "**************************************************** \n" - << std::endl ; - - std::set_unexpected( std::unexpected ) ; - std::set_terminate( std::terminate ) ; + } catch( exception& e ) { + cout << "\n" + << "**************************************************** \n" + << "* A runtime error has occured : \n" + << "* " << e.what() << endl + << "* the program will have to be terminated - sorry. \n" + << "**************************************************** \n" + << endl ; + + set_unexpected(std::unexpected); + set_terminate(std::terminate); // this provokes ROOT seg fault and stack trace (comment out to avoid it) exit(1) ; } } } +string DD4hep::versionString(){ + string vs("vXX-YY") ; + sprintf( &vs[0] , "v%2.2d-%2.2d", DD4HEP_MAJOR_VERSION, DD4HEP_MINOR_VERSION ) ; + return vs; +} + LCDD& LCDD::getInstance() { if (!s_lcdd) s_lcdd = new LCDDImp(); @@ -101,8 +107,8 @@ void LCDD::destroyInstance() { LCDDImp::LCDDImp() : LCDDData(), LCDDLoad(this), m_buildType(BUILD_NONE) { - std::set_unexpected( lcdd_unexpected ) ; - std::set_terminate( lcdd_unexpected ) ; + set_unexpected( lcdd_unexpected ) ; + set_terminate( lcdd_unexpected ) ; InstanceCount::increment(this); if (0 == gGeoManager) { @@ -149,22 +155,22 @@ void LCDDImp::imp_loadVolumeManager() { } /// Add an extension object to the LCDD instance -void* LCDDImp::addUserExtension(void* ptr, const std::type_info& info, void (*destruct)(void*)) { +void* LCDDImp::addUserExtension(void* ptr, const type_info& info, void (*destruct)(void*)) { return m_extensions.addExtension(ptr,info,destruct); } /// Remove an existing extension object from the LCDD instance -void* LCDDImp::removeUserExtension(const std::type_info& info, bool destroy) { +void* LCDDImp::removeUserExtension(const type_info& info, bool destroy) { return m_extensions.removeExtension(info,destroy); } /// Access an existing extension object from the LCDD instance -void* LCDDImp::userExtension(const std::type_info& info, bool alert) const { +void* LCDDImp::userExtension(const type_info& info, bool alert) const { return m_extensions.extension(info,alert); } /// Register new mother volume using the detector name. -void LCDDImp::declareMotherVolume(const std::string& detector_name, const Volume& vol) { +void LCDDImp::declareMotherVolume(const string& detector_name, const Volume& vol) { if ( !detector_name.empty() ) { if ( vol.isValid() ) { HandleMap::const_iterator i = m_motherVolumes.find(detector_name); @@ -240,7 +246,7 @@ LCDD& LCDDImp::addConstant(const Ref_t& x) { } /// Retrieve a constant by it's name from the detector description -Constant LCDDImp::constant(const std::string& name) const { +Constant LCDDImp::constant(const string& name) const { if ( !m_inhibitConstants ) { return getRefChild(m_define, name); } @@ -540,7 +546,7 @@ void LCDDImp::fromXML(const string& xmlfile, LCDDBuildType build_type) { } /// Read any geometry description or alignment file with external XML entity resolution -void LCDDImp::fromXML(const std::string& fname, UriReader* entity_resolver, LCDDBuildType build_type) { +void LCDDImp::fromXML(const string& fname, UriReader* entity_resolver, LCDDBuildType build_type) { TypePreserve build_type_preserve(m_buildType = build_type); processXML(fname,entity_resolver); } diff --git a/examples/AlignDet/src/AlignmentExample_align_telescope.cpp b/examples/AlignDet/src/AlignmentExample_align_telescope.cpp new file mode 100644 index 0000000000000000000000000000000000000000..17f6732623aa7f4edf6f74fa020a944014d67b5e --- /dev/null +++ b/examples/AlignDet/src/AlignmentExample_align_telescope.cpp @@ -0,0 +1,191 @@ +//========================================================================== +// 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: + + A ideal detector may be worked on with: + geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_align_telescope \ + -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml \ + -setup file:${DD4hep_DIR}/examples/Conditions/data/manager.xml \ + -direct -end_plugin -print INFO + + To work an already loaded alignments use: + + geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_align_telescope \ + -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml \ + -setup file:${DD4hep_DIR}/examples/Conditions/data/repository.xml \ + -direct -end_plugin -print INFO + +*/ +// Framework include files +#include "AlignmentExampleObjects.h" +#include "DDAlign/AlignmentsCalib.h" +#include "DDAlign/DDAlignUpdateCall.h" +#include "DD4hep/Factories.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::AlignmentExamples; + +using Alignments::DDAlignUpdateCall; +using Alignments::AlignmentsCalib; +using Alignments::Delta; +using Geometry::Position; + +static void print_world_trafo(AlignmentsCalib& calib, const std::string& path) { + DetAlign d(calib.detector(path)); + Alignment a = d.alignments().get("Alignment",*calib.slice.pool); + printout(INFO,"Example","++ World transformation of: %s", path.c_str()); + a->worldTransformation().Print(); +} + +/// Plugin function: Alignment program example +/** + * Factory: DD4hep_AlignmentExample_align_telescope + * + * \author M.Frank + * \version 1.0 + * \date 01/12/2016 + */ +static int AlignmentExample_align_telescope (Geometry::LCDD& lcdd, int argc, char** argv) { + string input, setup; + bool arg_error = false, dump = false, direct = false; + + for(int i=0; i<argc && argv[i]; ++i) { + if ( 0 == ::strncmp("-input",argv[i],4) ) + input = argv[++i]; + else if ( 0 == ::strncmp("-setups",argv[i],5) ) + setup = argv[++i]; + else if ( 0 == ::strncmp("-dump",argv[i],5) ) + dump = true; + else if ( 0 == ::strncmp("-direct",argv[i],5) ) + direct = true; + else + arg_error = true; + } + if ( arg_error || input.empty() || setup.empty() ) { + /// Help printout describing the basic command line interface + cout << + "Usage: -plugin <name> -arg [-arg] \n" + " name: factory name DD4hep_AlignmentExample_align_telescope \n" + " -input <string> Geometry file \n" + " -setups <string> Alignment setups (Conditions, etc) \n" + " -dump Dump conditions user pool before and afterwards.\n" + " -direct Perform realignment in DIRECT mode. \n" + " (no ConditionsManager callbacks) \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* setup_args[] = {setup.c_str(), 0}; // Better zero-terminate + + lcdd.apply("DD4hep_ConditionsXMLRepositoryParser",1,(char**)setup_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 cres = condMgr.prepare(req_iov,*slice); + + // ++++++++++++++++++++++++ We need a valid set of conditions to do this! + registerAlignmentCallbacks(lcdd,*slice); + + // ++++++++++++++++++++++++ Compute the tranformation matrices + AlignmentsManager::Result ares = alignMgr.compute(*slice); + printout(INFO,"Example", + "Setup %ld/%ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) (A:%ld,M:%ld) for IOV:%-12s", + slice->conditions().size(), + cres.total(), cres.selected, cres.loaded, cres.computed, cres.missing, + ares.computed, ares.missing, iov_typ->str().c_str()); + + printout(INFO,"Example","========================================================="); + printout(INFO,"Example","==== Alignment transformation BEFORE manipulation ====="); + printout(INFO,"Example","========================================================="); + if ( dump ) slice->pool->print("*"); + + + AlignmentsCalib calib(lcdd,*slice); + calib.derivationCall = new DDAlignUpdateCall(); + + try { // These are only valid if alignments got pre-loaded! + print_world_trafo(calib,"/world/Telescope"); + print_world_trafo(calib,"/world/Telescope/module_1"); + print_world_trafo(calib,"/world/Telescope/module_1/sensor"); + + print_world_trafo(calib,"/world/Telescope/module_3"); + print_world_trafo(calib,"/world/Telescope/module_3/sensor"); + + print_world_trafo(calib,"/world/Telescope/module_5"); + print_world_trafo(calib,"/world/Telescope/module_5/sensor"); + print_world_trafo(calib,"/world/Telescope/module_8/sensor"); + } + catch(...) { + } + + // Alignments setup + Alignment::key_type key_tel = calib.use("/world/Telescope"); + Alignment::key_type key_m1 = calib.use("/world/Telescope/module_1"); + Alignment::key_type key_m3 = calib.use("/world/Telescope/module_3"); + calib.start(); // Necessary to compute dependencies! + + /// Let's change something: + Delta delta(Position(333.0,0,0)); + calib.setDelta(key_tel,Delta(Position(55.0,0,0))); + calib.setDelta(key_m1,delta); + calib.setDelta(key_m3,delta); + + if ( direct ) + calib.commit(AlignmentsCalib::DIRECT); + else + calib.commit(); + + printout(INFO,"Example","========================================================="); + printout(INFO,"Example","==== Alignment transformation AFTER manipulation ====="); + printout(INFO,"Example","========================================================="); + if ( dump ) slice->pool->print("*"); + + print_world_trafo(calib,"/world/Telescope"); + print_world_trafo(calib,"/world/Telescope/module_1"); + print_world_trafo(calib,"/world/Telescope/module_1/sensor"); + print_world_trafo(calib,"/world/Telescope/module_2/sensor"); + + print_world_trafo(calib,"/world/Telescope/module_3"); + print_world_trafo(calib,"/world/Telescope/module_3/sensor"); + print_world_trafo(calib,"/world/Telescope/module_4/sensor"); + + print_world_trafo(calib,"/world/Telescope/module_5"); + print_world_trafo(calib,"/world/Telescope/module_5/sensor"); + print_world_trafo(calib,"/world/Telescope/module_6/sensor"); + print_world_trafo(calib,"/world/Telescope/module_7/sensor"); + print_world_trafo(calib,"/world/Telescope/module_8/sensor"); + + + //Alignments::AlignedVolumePrinter printer(slice->pool.get(),"Example"); + //Scanner().scan(printer,lcdd.world()); + + return 1; +} + +// first argument is the type from the xml file +DECLARE_APPLY(DD4hep_AlignmentExample_align_telescope,AlignmentExample_align_telescope) diff --git a/examples/AlignDet/src/Alignment_to_Condition.cpp b/examples/AlignDet/src/Alignment_to_Condition.cpp index 5a327fd5001b038aae652777ff33ddf79c1f8b39..290b211086cf786146cce18dcb77001db7bb2d5b 100644 --- a/examples/AlignDet/src/Alignment_to_Condition.cpp +++ b/examples/AlignDet/src/Alignment_to_Condition.cpp @@ -62,21 +62,21 @@ static int Alignment_to_Condition (Geometry::LCDD& , int argc, char** argv) { AlignmentCondition ac("alignment"); ac->hash = ConditionKey::hashCode(ac.name()); - printout(INFO,"Example","Alignment condition: \"%s\" Key:%p",ac.name(),(void*)ac->hash); - printout(INFO,"Example","Alignment condition ptr: %p",(void*)ac.ptr()); + printout(INFO,"Example","Alignment condition: \"%s\" Key:%016llX",ac.name(),ac->hash); + printout(INFO,"Example","Alignment condition ptr: %p",ac.ptr()); Condition con(ac); AlignmentData& data = ac.data(); printout(INFO,"Example","Alignment condition data: %p",(void*)&data); printout(INFO,"Example","Condition opaque pointer: %p",(void*)con.data().ptr()); printout(INFO,"Example","Offset to opaque pointer: %uld",con->offset()); - printout(INFO,"Example","Computed Pointer: %p",((char*)con.ptr()+con->offset())); - printout(INFO,"Example","Computed payload pointer: %p",con->payload()); + printout(INFO,"Example","Computed Pointer: %p",(void*)((char*)con.ptr()+con->offset())); + printout(INFO,"Example","Computed payload pointer: %p",(void*)con->payload()); Alignment align(&data); - printout(INFO,"Example","Alignment object pointer: %p",align.ptr()); - printout(INFO,"Example","Alignment key: %p",(void*)align.key()); - printout(INFO,"Example","Condition key: %p",(void*)con.key()); + printout(INFO,"Example","Alignment object pointer: %p",(void*)align.ptr()); + printout(INFO,"Example","Alignment key: %016llX",align.key()); + printout(INFO,"Example","Condition key: %016llX",con.key()); Condition c(data.condition); printout(INFO,"Example","Condition ptr from alignment: %p",(void*)c.ptr()); diff --git a/examples/ClientTests/compact/IronCylinder.xml b/examples/ClientTests/compact/IronCylinder.xml index 99d248d088c1981ce144282262b7d7d7f0b34975..66c5087ef6456815a6ff129f37ecf5fd981dc988 100644 --- a/examples/ClientTests/compact/IronCylinder.xml +++ b/examples/ClientTests/compact/IronCylinder.xml @@ -61,7 +61,8 @@ <readouts> <readout name="HcalBarrelHits"> - <id>system:8,barrel:3,module:7,layer:5,slice:10</id> + <id>system:8,barrel:3,module:7,layer:5,slice:10,eta:10,phi:5</id> + <segmentation type="GridPhiEta" grid_size_eta="0.1*cm" phi_bins="10" /> </readout> <readout name="ContainmentHits"> <id>system:8,barrel:3</id>