From 9ea7185399121137ba7cb917697a80a774144800 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Thu, 2 Feb 2017 22:10:12 +0100 Subject: [PATCH] Evolve alignments and conditions -- not backwards compatible! --- DDAlign/include/DDAlign/AlignmentsForward.h | 15 +- DDAlign/include/DDAlign/AlignmentsManager.h | 18 +- DDAlign/include/DDAlign/AlignmentsRegister.h | 16 +- DDAlign/include/DDAlign/AlignmentsReset.h | 81 +++++ DDAlign/include/DDAlign/DDAlignResetCall.h | 44 +++ DDAlign/src/AlignmentsForward.cpp | 13 +- DDAlign/src/AlignmentsManager.cpp | 142 ++++---- DDAlign/src/AlignmentsRegister.cpp | 15 +- DDAlign/src/AlignmentsReset.cpp | 94 ++++++ DDAlign/src/AlignmentsUpdateCall.cpp | 6 +- DDAlign/src/DDAlignResetCall.cpp | 40 +++ DDAlign/src/DDAlignUpdateCall.cpp | 1 + DDAlign/src/GlobalAlignmentCache.cpp | 3 +- DDAlign/src/GlobalAlignmentWriter.cpp | 13 +- DDAlign/src/plugins/AlignmentsPlugins.cpp | 34 +- DDAlign/src/plugins/GlobalAlignmentParser.cpp | 7 +- DDCond/include/DDCond/ConditionsPool.h | 4 +- DDCond/src/plugins/ConditionsPlugins.cpp | 7 +- .../plugins/ConditionsRepositoryParser.cpp | 132 +++++--- .../plugins/ConditionsRepositoryWriter.cpp | 303 ++++++++++++++++++ DDCond/src/plugins/ConditionsUserPool.cpp | 25 +- DDCore/include/DD4hep/Conditions.h | 21 +- DDCore/include/DD4hep/DD4hepUI.h | 10 +- DDCore/include/DD4hep/Detector.h | 19 +- DDCore/include/DD4hep/Handle.h | 4 +- DDCore/include/DD4hep/Handle.inl | 2 + .../DD4hep/objects/AlignmentsInterna.h | 4 +- .../DD4hep/objects/ConditionsInterna.h | 9 +- .../include/DD4hep/objects/DetectorInterna.h | 6 - DDCore/include/XML/DocumentHandler.h | 4 + DDCore/src/Alignments.cpp | 64 +--- DDCore/src/AlignmentsInterna.cpp | 10 + DDCore/src/Conditions.cpp | 62 +--- DDCore/src/DD4hepUI.cpp | 19 ++ DDCore/src/Detector.cpp | 54 +--- DDCore/src/DetectorInterna.cpp | 47 +-- DDCore/src/Primitives.cpp | 3 +- DDCore/src/XML/DocumentHandler.cpp | 25 +- DDCore/src/plugins/LCDDConverter.cpp | 39 +-- DDCore/src/plugins/LCDDHelperTest.cpp | 1 - DDCore/src/plugins/LCDDSegmentations.cpp | 1 - DDCore/src/plugins/PandoraConverter.cpp | 16 +- DDCore/src/plugins/StandardPlugins.cpp | 73 +++-- DDDB/src/DDDBAlignmentTest.cpp | 31 +- DDDB/src/DDDBAlignmentTestEx.cpp | 2 +- UtilityApps/src/run_plugin.h | 2 +- examples/AlignDet/compact/AlephTPC_reset.xml | 2 + .../AlignDet/compact/AlephTPC_reset_all.xml | 12 + .../AlignDet/src/AlignmentExampleObjects.cpp | 54 +++- .../AlignDet/src/AlignmentExampleObjects.h | 59 +++- .../src/AlignmentExample_populate.cpp | 2 +- .../src/AlignmentExample_read_xml.cpp | 4 +- .../src/AlignmentExample_recompute.cpp | 122 +++++++ .../AlignDet/src/AlignmentExample_stress.cpp | 2 +- examples/DDDB/CMakeLists.txt | 2 +- 55 files changed, 1272 insertions(+), 528 deletions(-) create mode 100644 DDAlign/include/DDAlign/AlignmentsReset.h create mode 100644 DDAlign/include/DDAlign/DDAlignResetCall.h create mode 100644 DDAlign/src/AlignmentsReset.cpp create mode 100644 DDAlign/src/DDAlignResetCall.cpp create mode 100644 DDCond/src/plugins/ConditionsRepositoryWriter.cpp create mode 100644 examples/AlignDet/compact/AlephTPC_reset_all.xml create mode 100644 examples/AlignDet/src/AlignmentExample_recompute.cpp diff --git a/DDAlign/include/DDAlign/AlignmentsForward.h b/DDAlign/include/DDAlign/AlignmentsForward.h index 892293987..26271e948 100644 --- a/DDAlign/include/DDAlign/AlignmentsForward.h +++ b/DDAlign/include/DDAlign/AlignmentsForward.h @@ -18,11 +18,16 @@ #include "DD4hep/Conditions.h" #include "DD4hep/Detector.h" #include "DD4hep/Printout.h" -#include "DDAlign/AlignmentsManager.h" /// Namespace for the AIDA detector description toolkit namespace DD4hep { + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + // Forward declarations + class ConditionsSlice; + } + /// Namespace for the geometry part of the AIDA detector description toolkit namespace Alignments { @@ -48,9 +53,13 @@ namespace DD4hep { * \ingroup DD4HEP_DDALIGN */ class AlignmentsForward : public DetElement::Processor { + public: + /// Shortcut the ConditionsSlice type + typedef Conditions::ConditionsSlice Slice; + public: /// Reference to the alignment manager object - AlignmentsManager alignmentMgr; + Slice& slice; /// The callback to be registered for the update mechanism AlignmentsUpdateCall* updateCall; /// Conditions pool used to access the basic conditions object @@ -65,7 +74,7 @@ namespace DD4hep { PrintLevel printLevel; /// Initializing constructor - AlignmentsForward(AlignmentsManager m, AlignmentsUpdateCall* c, UserPool* p); + AlignmentsForward(Slice& slice, AlignmentsUpdateCall* c); /// Default destructor virtual ~AlignmentsForward(); /// Callback to output conditions information diff --git a/DDAlign/include/DDAlign/AlignmentsManager.h b/DDAlign/include/DDAlign/AlignmentsManager.h index 1e558c7e7..185c112ba 100644 --- a/DDAlign/include/DDAlign/AlignmentsManager.h +++ b/DDAlign/include/DDAlign/AlignmentsManager.h @@ -55,8 +55,6 @@ namespace DD4hep { typedef Conditions::ConditionUpdateContext Context; /// Alignments re-use conditions dependency definition from the conditions manager 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 /** @@ -102,18 +100,16 @@ namespace DD4hep { AlignmentsManager& operator=(const AlignmentsManager& mgr) = default; /// Delete the manager. Be careful: this affects all referencing handles! void destroy(); - /// Adopy alignment dependency for later recalculation - bool adoptDependency(Dependency* dependency) const; - /// Access all known dependencies - const Dependencies& knownDependencies() const; /// Compute all alignment conditions of the internal dependency list Result compute(Slice& slice) const; +#if 0 /// Compute all alignment conditions of the specified dependency list Result compute(Slice& slice, const Dependencies& deps) const; /// Compute all alignment conditions of the internal dependency list Result compute(Pool& pool) const; /// Compute all alignment conditions of the specified dependency list Result compute(Pool& pool, const Dependencies& deps) const; +#endif /// Register new updated derived alignment during the computation step static void newEntry(const Context& parameter, DetElement& det, @@ -133,13 +129,11 @@ namespace DD4hep { class AlignmentsManagerObject : public NamedObject { public: typedef AlignmentsManager::Pool Pool; + typedef AlignmentsManager::Slice Slice; typedef AlignmentsManager::Result Result; - typedef AlignmentsManager::Dependencies Dependencies; - /// Full list of alignment dependencies - Dependencies* dependencies; /// References to all alignment possibilities known - AlignContext* all_alignments; + //AlignContext* all_alignments; protected: /// Compute the transformation from the closest detector element of the alignment to the world system @@ -153,9 +147,9 @@ namespace DD4hep { /// Default destructor virtual ~AlignmentsManagerObject(); /// Compute all alignment conditions of the internal dependency list - Result compute(Pool& pool) const; + Result compute(Slice& slice) const; /// Compute all alignment conditions of the specified dependency list - Result 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 51046caf9..9946e4980 100644 --- a/DDAlign/include/DDAlign/AlignmentsRegister.h +++ b/DDAlign/include/DDAlign/AlignmentsRegister.h @@ -18,11 +18,16 @@ #include "DD4hep/Conditions.h" #include "DD4hep/Detector.h" #include "DD4hep/Printout.h" -#include "DDAlign/AlignmentsManager.h" /// Namespace for the AIDA detector description toolkit namespace DD4hep { + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + // Forward declarations + class ConditionsSlice; + } + /// Namespace for the geometry part of the AIDA detector description toolkit namespace Alignments { @@ -61,13 +66,14 @@ namespace DD4hep { * \ingroup DD4HEP_DDALIGN */ class AlignmentsRegister : public DetElement::Processor { + public: + /// Shortcut the ConditionsSlice type + typedef Conditions::ConditionsSlice Slice; public: /// Reference to the alignment manager object - AlignmentsManager alignmentMgr; + Slice& slice; /// The callback to be registered for the update mechanism AlignmentsUpdateCall* updateCall; - /// Conditions pool used to access the basic conditions object - Conditions::UserPool* user_pool; /// Extension property to construct the name of the alignment condition std::string extension; /// Name of the alignment alias for the detector elements alignment object @@ -78,7 +84,7 @@ namespace DD4hep { PrintLevel printLevel; /// Initializing constructor - AlignmentsRegister(AlignmentsManager m, AlignmentsUpdateCall* c, UserPool* p); + AlignmentsRegister(Slice& slice, AlignmentsUpdateCall* c); /// Default destructor virtual ~AlignmentsRegister(); /// Callback to output conditions information diff --git a/DDAlign/include/DDAlign/AlignmentsReset.h b/DDAlign/include/DDAlign/AlignmentsReset.h new file mode 100644 index 000000000..448895252 --- /dev/null +++ b/DDAlign/include/DDAlign/AlignmentsReset.h @@ -0,0 +1,81 @@ +//========================================================================== +// 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_DDALIGN_ALIGNMENTRESET_H +#define DD4HEP_DDALIGN_ALIGNMENTRESET_H + +// Framework includes +#include "DD4hep/Alignments.h" +#include "DD4hep/Conditions.h" +#include "DD4hep/Detector.h" +#include "DD4hep/Printout.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + // Forward declarations + class ConditionsSlice; + } + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Alignments { + + // Forward declarations + class AlignmentsUpdateCall; + + /// Reset alignment dependencies from conditions + /** + * + * \author M.Frank + * \version 1.0 + * \date 31/03/2016 + * \ingroup DD4HEP_DDALIGN + */ + class AlignmentsReset : public DetElement::Processor { + public: + /// Shortcut the ConditionsSlice type + typedef Conditions::ConditionsSlice Slice; + public: + /// Reference to the alignment manager object + Slice& slice; + /// The callback to be registered for the update mechanism + AlignmentsUpdateCall* updateCall; + /// Extension property to construct the name of the alignment condition + std::string extension; + /// Name of the alignment alias for the detector elements alignment object + std::string alias; + /// Flag if an alias to the real alignment object should be registered + bool haveAlias; + /// Print level + PrintLevel printLevel; + + /// Initializing constructor + AlignmentsReset(Slice& slice, AlignmentsUpdateCall* call); + /// Default destructor + virtual ~AlignmentsReset(); + /// Callback to output conditions information + virtual int processElement(DetElement de); + /// Overloadable: call to construct the alignment conditions name. + /** + * Specialize for user defined implementation. + * + * Default implementation returns "cond.name()+extension". + * Please note, that the corrsponding implementation of + * 'AlignmentsForward::construct_name' must match + */ + virtual std::string construct_name(DetElement de, Conditions::Condition cond) const; + }; + } /* End namespace Alignments */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_DDALIGN_ALIGNMENTRESET_H */ diff --git a/DDAlign/include/DDAlign/DDAlignResetCall.h b/DDAlign/include/DDAlign/DDAlignResetCall.h new file mode 100644 index 000000000..d275d8805 --- /dev/null +++ b/DDAlign/include/DDAlign/DDAlignResetCall.h @@ -0,0 +1,44 @@ +//========================================================================== +// 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_DDALIGN_DDALIGNRESETCALL_H +#define DD4HEP_DDALIGN_DDALIGNRESETCALL_H + +// Framework includes +#include "DDAlign/AlignmentsUpdateCall.h" + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace of the DDAlign conversion stuff + namespace Alignments { + + /// Specialized conditions reset callback for DDAlign alignments + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_ALIGNMENT + */ + class DDAlignResetCall : public AlignmentsUpdateCall { + public: + /// Default constructor + DDAlignResetCall() = default; + /// Default destructor + virtual ~DDAlignResetCall() = default; + /// Interface to client Callback in order to reset the condition + virtual Condition operator()(const ConditionKey& key, const UpdateContext& context); + }; + + } /* End namespace Alignments */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_DDALIGN_DDALIGNRESETCALL_H */ diff --git a/DDAlign/src/AlignmentsForward.cpp b/DDAlign/src/AlignmentsForward.cpp index 9b71e12f2..c79df3961 100644 --- a/DDAlign/src/AlignmentsForward.cpp +++ b/DDAlign/src/AlignmentsForward.cpp @@ -12,19 +12,20 @@ //========================================================================== // Framework includes +#include "DDAlign/AlignmentsForward.h" +#include "DDAlign/AlignmentsUpdateCall.h" + #include "DD4hep/Printout.h" #include "DD4hep/DetAlign.h" #include "DD4hep/DetConditions.h" - -#include "DDAlign/AlignmentsForward.h" -#include "DDAlign/AlignmentsUpdateCall.h" +#include "DDCond/ConditionsSlice.h" using namespace DD4hep; using namespace DD4hep::Alignments; /// Initializing constructor -AlignmentsForward::AlignmentsForward(AlignmentsManager m, AlignmentsUpdateCall* c, UserPool* p) - : alignmentMgr(m), updateCall(c), user_pool(p), extension("#alignment/Tranformations"), +AlignmentsForward::AlignmentsForward(Slice& s, AlignmentsUpdateCall* c) + : slice(s), updateCall(c), extension("#alignment/Tranformations"), alias("Alignment"), haveAlias(true), printLevel(DEBUG) { } @@ -60,7 +61,7 @@ int AlignmentsForward::processElement(DetElement de) { // // Now add the dependency to the alignmant manager Conditions::DependencyBuilder b(k, updateCall, de); - bool result = alignmentMgr.adoptDependency(b.release()); + bool result = slice.insert(b.release()); if ( result ) { printout(printLevel,"AlignForward", "++ Added Alignment child dependency Cond:%s Key:%16llX", diff --git a/DDAlign/src/AlignmentsManager.cpp b/DDAlign/src/AlignmentsManager.cpp index 4f05dc6fd..16169a366 100644 --- a/DDAlign/src/AlignmentsManager.cpp +++ b/DDAlign/src/AlignmentsManager.cpp @@ -12,6 +12,8 @@ //========================================================================== // Framework include files +#include "DDAlign/AlignmentsManager.h" + #include "DD4hep/LCDD.h" #include "DD4hep/Handle.inl" #include "DD4hep/Printout.h" @@ -21,10 +23,12 @@ #include "DDCond/ConditionsPool.h" #include "DDCond/ConditionsSlice.h" #include "DDCond/ConditionsDependencyCollection.h" -#include "DDAlign/AlignmentsManager.h" using namespace DD4hep; using namespace DD4hep::Alignments; +using Conditions::ConditionsSlice; +using Conditions::ConditionDependency; +using Conditions::ConditionsDependencyCollection; /// Namespace for the AIDA detector description toolkit namespace DD4hep { @@ -91,19 +95,20 @@ namespace DD4hep { DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentsManagerObject); static PrintLevel s_PRINT = WARNING; +//static PrintLevel s_PRINT = INFO; /// Initializing constructor AlignmentsManagerObject::AlignmentsManagerObject() : NamedObject() { InstanceCount::increment(this); - all_alignments = new AlignContext(); - dependencies = new Dependencies(); + //all_alignments = new AlignContext(); + //dependencies = new Dependencies(); } /// Default destructor AlignmentsManagerObject::~AlignmentsManagerObject() { - dependencies->clear(); - deletePtr(dependencies); - deletePtr(all_alignments); + //dependencies->clear(); + //deletePtr(dependencies); + //deletePtr(all_alignments); InstanceCount::decrement(this); } @@ -131,17 +136,17 @@ AlignmentsManagerObject::to_world(AlignContext& new_alignments, AlignmentCondition cond(e.cond); AlignmentData& align = cond.data(); if ( s_PRINT <= INFO ) { - printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); - printf(" with ALIGN(world) %s :", par.path().c_str()); - align.worldDelta.Print(); + ::printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); + ::printf(" with ALIGN(world) %s :", par.path().c_str()); align.worldDelta.Print(); } delta_to_world.MultiplyLeft(&align.worldDelta); if ( s_PRINT <= INFO ) { - printf(" Result :"); delta_to_world.Print(); + ::printf(" Result :"); delta_to_world.Print(); } ++result.computed; return result; } +#if 0 // 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 // The parent's alignment condition by defintiion must be present in the pool, @@ -153,27 +158,27 @@ AlignmentsManagerObject::to_world(AlignContext& new_alignments, AlignmentCondition cond = pool.get(key); AlignmentData& align = cond.data(); if ( s_PRINT <= INFO ) { - printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); - printf(" with ALIGN(world) %s :", par.path().c_str()); - align.worldDelta.Print(); + ::printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); + ::printf(" with ALIGN(pool) %s :", par.path().c_str()); align.worldDelta.Print(); } delta_to_world.MultiplyLeft(&align.worldDelta); if ( s_PRINT <= INFO ) { - printf(" Result :"); delta_to_world.Print(); + ::printf(" Result :"); delta_to_world.Print(); } ++result.computed; return result; } +#endif // There is no special alignment for this detector element. // Hence to nominal (relative) transformation to the parent is valid if ( s_PRINT <= INFO ) { - printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); - printf(" with NOMINAL(det) %s :", par.path().c_str()); + ::printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta_to_world.Print(); + ::printf(" with NOMINAL(det) %s :", par.path().c_str()); par.nominal().detectorTransformation().Print(); } delta_to_world.MultiplyLeft(&par.nominal().detectorTransformation()); if ( s_PRINT <= INFO ) { - printf(" Result :"); delta_to_world.Print(); + ::printf(" Result :"); delta_to_world.Print(); } par = par.parent(); } @@ -181,35 +186,6 @@ AlignmentsManagerObject::to_world(AlignContext& new_alignments, return result; } -/// Compute all alignment conditions of the internal dependency list -AlignmentsManager::Result AlignmentsManagerObject::compute(Pool& pool) const { - return compute(pool, *dependencies); -} - -/// Compute all alignment conditions of the specified dependency list -AlignmentsManager::Result AlignmentsManagerObject::compute(Pool& pool, const Dependencies& deps) const { - Result result; - AlignContext new_alignments; - new_alignments.entries.reserve(deps.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. - // - pool.compute(deps, &new_alignments); - 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; - } - return result; -} - /// Compute the alignment delta for one detector element and it's alignment condition static void computeDelta(AlignmentCondition cond, TGeoHMatrix& tr_delta) { const AlignmentData& align = cond.data(); @@ -239,11 +215,50 @@ static void computeDelta(AlignmentCondition cond, TGeoHMatrix& tr_delta) { } } +#if 0 +/// Compute all alignment conditions of the internal dependency list +AlignmentsManager::Result AlignmentsManagerObject::compute(Pool& pool) const { + return compute(pool, *dependencies); +} +#endif + +/// Compute all alignment conditions of the specified dependency list +AlignmentsManager::Result AlignmentsManagerObject::compute(Slice& slice) const { + Result result; + AlignContext new_alignments; + ConditionsDependencyCollection deps; + + for(const auto& d : slice.derived() ) { + ConditionDependency* dep = d.second->dependency; + if ( dep ) { + deps.insert(dep); + } + } + 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(deps, &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 lower levels AlignmentsManager::Result AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& pool, DetElement det) const { Result result, temp; - auto k=new_alignments.keys.find(det.key()); + 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; @@ -272,15 +287,15 @@ AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& pool, D if ( s_PRINT <= INFO ) { 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()); + yes_no(has_cond), (long long int)cond.key(), cond.iov().str().c_str()); } if ( s_PRINT <= DEBUG ) { - printf("DetectorTrafo: '%s' -> '%s' ",det.path().c_str(), det.parent().path().c_str()); + ::printf("DetectorTrafo: '%s' -> '%s' ",det.path().c_str(), det.parent().path().c_str()); det.nominal().detectorTransformation().Print(); - printf("Delta: '%s' ",det.path().c_str()); tr_delta.Print(); - printf("World-Delta: '%s' ",det.path().c_str()); align.worldDelta.Print(); - printf("Nominal: '%s' ",det.path().c_str()); det.nominal().worldTransformation().Print(); - printf("Result: '%s' ",det.path().c_str()); align.worldTrafo.Print(); + ::printf("Delta: '%s' ",det.path().c_str()); tr_delta.Print(); + ::printf("World-Delta: '%s' ",det.path().c_str()); align.worldDelta.Print(); + ::printf("Nominal: '%s' ",det.path().c_str()); det.nominal().worldTransformation().Print(); + ::printf("Result: '%s' ",det.path().c_str()); align.worldTrafo.Print(); } } else { @@ -328,28 +343,13 @@ void AlignmentsManager::destroy() { deletePtr(m_element); } -/// Adopy alignment dependency for later recalculation -bool AlignmentsManager::adoptDependency(Dependency* dependency) const { - Object* o = access(); - auto res = o->dependencies->insert(dependency); - if ( res.second ) { - o->all_alignments->newEntry(dependency->detector, dependency, 0); - return res.second; - } - return false; -} - -/// Access all known dependencies -const AlignmentsManager::Dependencies& AlignmentsManager::knownDependencies() const { - return *(access()->dependencies); -} - /// Compute all alignment conditions of the internal dependency list AlignmentsManager::Result AlignmentsManager::compute(Slice& slice) const { Object* o = access(); - return o->compute(*slice.pool, *(o->dependencies)); + return o->compute(slice); } +#if 0 /// Compute all alignment conditions of the specified dependency list AlignmentsManager::Result AlignmentsManager::compute(Slice& slice, const Dependencies& deps) const { return access()->compute(*slice.pool, deps); @@ -365,7 +365,7 @@ AlignmentsManager::Result AlignmentsManager::compute(Pool& pool) const { AlignmentsManager::Result AlignmentsManager::compute(Pool& pool, const Dependencies& deps) const { return access()->compute(pool, deps); } - +#endif /// Register new updated derived alignment during the computation step void AlignmentsManager::newEntry(const Context& context, DetElement& det, diff --git a/DDAlign/src/AlignmentsRegister.cpp b/DDAlign/src/AlignmentsRegister.cpp index f3d47092a..439ca4e0b 100644 --- a/DDAlign/src/AlignmentsRegister.cpp +++ b/DDAlign/src/AlignmentsRegister.cpp @@ -12,12 +12,13 @@ //========================================================================== // Framework includes +#include "DDAlign/AlignmentsRegister.h" +#include "DDAlign/AlignmentsUpdateCall.h" + #include "DD4hep/Printout.h" #include "DD4hep/DetAlign.h" #include "DD4hep/DetConditions.h" - -#include "DDAlign/AlignmentsRegister.h" -#include "DDAlign/AlignmentsUpdateCall.h" +#include "DDCond/ConditionsSlice.h" using namespace DD4hep; using namespace DD4hep::Alignments; @@ -26,8 +27,8 @@ using Conditions::Condition; // ====================================================================================== /// Initializing constructor -AlignmentsRegister::AlignmentsRegister(AlignmentsManager m, AlignmentsUpdateCall* c, UserPool* p) - : alignmentMgr(m), updateCall(c), user_pool(p), extension("/Tranformations"), +AlignmentsRegister::AlignmentsRegister(Slice& s, AlignmentsUpdateCall* c) + : slice(s), updateCall(c), extension("/Tranformations"), alias("Alignment"), haveAlias(true), printLevel(DEBUG) { } @@ -55,7 +56,7 @@ int AlignmentsRegister::processElement(DetElement de) { "++ Processing DE %s hasConditions:%s [%d entries]", de.path().c_str(), yes_no(de.hasConditions()), int(cont.numKeys())); for ( const auto& c : cont.keys() ) { - Condition cond = cont.get(c.first, *user_pool); + Condition cond = cont.get(c.first, *slice.pool); printout(DEBUG,"AlignRegister", "++ Processing DE %s Cond:%s Key:%16llX flags:%d", de.path().c_str(), cond.name(), cond.key(), cond->flags); @@ -79,7 +80,7 @@ int AlignmentsRegister::processElement(DetElement de) { // Now add the dependency to the alignmant manager Conditions::DependencyBuilder b(k, updateCall, de); b.add(Conditions::ConditionKey(cond->name)); - bool result = alignmentMgr.adoptDependency(b.release()); + bool result = slice.insert(b.release()); if ( result ) { printout(printLevel,"AlignRegister", "++ Added Alignment dependency Cond:%s Key:%16llX flags:%d", diff --git a/DDAlign/src/AlignmentsReset.cpp b/DDAlign/src/AlignmentsReset.cpp new file mode 100644 index 000000000..7d3f62938 --- /dev/null +++ b/DDAlign/src/AlignmentsReset.cpp @@ -0,0 +1,94 @@ +//========================================================================== +// 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 includes +#include "DDAlign/AlignmentsReset.h" +#include "DDAlign/AlignmentsUpdateCall.h" + +#include "DD4hep/Printout.h" +#include "DD4hep/DetAlign.h" +#include "DD4hep/DetConditions.h" +#include "DDCond/ConditionsSlice.h" + +using namespace DD4hep; +using namespace DD4hep::Alignments; +using Conditions::Condition; + +// ====================================================================================== + +/// Initializing constructor +AlignmentsReset::AlignmentsReset(Slice& s, AlignmentsUpdateCall* c) + : slice(s), updateCall(c), extension("/Tranformations"), + alias("Alignment"), haveAlias(true), printLevel(DEBUG) +{ +} + +/// Default destructor +AlignmentsReset::~AlignmentsReset() { + releasePtr(updateCall); +} + +/// Overloadable: call to construct the alignment conditions name. Specialize for change +std::string +AlignmentsReset::construct_name(DetElement /* de */, Condition cond) const +{ + return cond.name()+extension; +} + +/// Callback to output conditions information +int AlignmentsReset::processElement(DetElement de) { + if ( de.isValid() ) { + printLevel = WARNING; + if ( de.hasConditions() ) { + DetAlign align(de); + Conditions::DetConditions conditions(de); + Conditions::Container cont = conditions.conditions(); + printout(DEBUG,"AlignReset", + "++ Processing DE %s hasConditions:%s [%d entries]", + de.path().c_str(), yes_no(de.hasConditions()), int(cont.numKeys())); + for ( const auto& c : cont.keys() ) { + Condition cond = cont.get(c.first, *slice.pool); + printout(DEBUG,"AlignReset", + "++ 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() ) { + Conditions::ConditionKey k(alignment_name); + // Now add the dependency to the alignmant manager + Conditions::DependencyBuilder b(k, updateCall, de); + b.add(Conditions::ConditionKey(cond->name)); + bool result = slice.insert(b.release()); + if ( result ) { + printout(printLevel,"AlignReset", + "++ Added Alignment dependency Cond:%s Key:%16llX flags:%d", + k.name.c_str(), k.hash, cond->flags); + continue; + } + printout(ERROR,"AlignReset", + "++ FAILED to add Alignment dependency Cond:%s Key:%16llX flags:%d", + k.name.c_str(), k.hash, cond->flags); + } + } + } + return 1; + } + printout(DEBUG,"AlignReset","++ Processing DE %s hasConditions:%s", + de.path().c_str(), yes_no(de.hasConditions())); + } + return 1; +} + diff --git a/DDAlign/src/AlignmentsUpdateCall.cpp b/DDAlign/src/AlignmentsUpdateCall.cpp index 932c69760..5902ee507 100644 --- a/DDAlign/src/AlignmentsUpdateCall.cpp +++ b/DDAlign/src/AlignmentsUpdateCall.cpp @@ -14,6 +14,9 @@ // Framework include files #include "DDAlign/AlignmentsUpdateCall.h" #include "DDAlign/AlignmentsManager.h" + +#include "DD4hep/objects/AlignmentsInterna.h" +#include "DD4hep/objects/ConditionsInterna.h" #include "DD4hep/ConditionsPrinter.h" #include "DD4hep/InstanceCount.h" #include "DD4hep/Printout.h" @@ -37,8 +40,8 @@ AlignmentsUpdateCall::handle(const ConditionKey& key, const UpdateContext& ctxt, AlignmentCondition target(key.name); AlignmentData& data = target.data(); data.delta = delta; - data.flag = AlignmentData::HAVE_NONE; data.detector = ctxt.dependency.detector; + target->setFlag(Condition::ALIGNMENT_DERIVED); // // This here is the main difference compared to other derived conditions: // ---------------------------------------------------------------------- @@ -70,6 +73,7 @@ AlignmentsUpdateCall::invalidDataType(const ConditionKey& key, const UpdateConte Alignments::AlignmentCondition target(key.name); Data& data = target.data(); data.detector = det; + data.flag = AlignmentData::HAVE_NONE; printout(ERROR,"AlignmentUpdate","++ Failed to access alignment-Delta for %s from %s", det.path().c_str(), cond->value.c_str()); printout(ERROR,"AlignmentUpdate","++ The true data type is: %s",typeName(cond.typeInfo()).c_str()); diff --git a/DDAlign/src/DDAlignResetCall.cpp b/DDAlign/src/DDAlignResetCall.cpp new file mode 100644 index 000000000..53ee9b09f --- /dev/null +++ b/DDAlign/src/DDAlignResetCall.cpp @@ -0,0 +1,40 @@ +//========================================================================== +// 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 includes +#include "DDAlign/DDAlignResetCall.h" +#include "DD4hep/ConditionsData.h" +#include "DD4hep/Printout.h" + +using namespace DD4hep; +using namespace DD4hep::Conditions; + +/// Interface to client Callback in order to reset the condition +Condition +Alignments::DDAlignResetCall::operator()(const ConditionKey& key, const UpdateContext& context) +{ + Condition cond = context.condition(0); + DetElement det = context.dependency.detector; + if ( cond.typeInfo() == typeid(Data::Delta) ) { + Data::Delta empty_delta; + Data::Delta& delta = cond.get<Data::Delta>(); + delta = empty_delta; + Condition c = AlignmentsUpdateCall::handle(key, context, empty_delta); + printLevel = INFO; + printout(printLevel,"DDAlignReset","++ Building dependent condition: %s Detector [%d]: %s [%p]", + key.name.c_str(), det.level(), det.path().c_str(), c.ptr()); + return c; + } + // Somehow the condition is not of type Data::Delta. This is an ERROR. + return invalidDataType(key, context); +} diff --git a/DDAlign/src/DDAlignUpdateCall.cpp b/DDAlign/src/DDAlignUpdateCall.cpp index 735866e3c..871d5acda 100644 --- a/DDAlign/src/DDAlignUpdateCall.cpp +++ b/DDAlign/src/DDAlignUpdateCall.cpp @@ -28,6 +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 = AlignmentsUpdateCall::handle(key, context, delta); + //printLevel = INFO; 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/GlobalAlignmentCache.cpp b/DDAlign/src/GlobalAlignmentCache.cpp index 8bae7d17d..1997d6160 100644 --- a/DDAlign/src/GlobalAlignmentCache.cpp +++ b/DDAlign/src/GlobalAlignmentCache.cpp @@ -74,7 +74,8 @@ int GlobalAlignmentCache::release() { GlobalAlignmentCache* GlobalAlignmentCache::install(LCDD& lcdd) { GlobalAlignmentCache* cache = lcdd.extension<GlobalAlignmentCache>(false); if ( !cache ) { - lcdd.addExtension<GlobalAlignmentCache>(new GlobalAlignmentCache(lcdd,"world",true)); + cache = new GlobalAlignmentCache(lcdd,"world",true); + lcdd.addExtension<GlobalAlignmentCache>(cache); } return cache; } diff --git a/DDAlign/src/GlobalAlignmentWriter.cpp b/DDAlign/src/GlobalAlignmentWriter.cpp index 53061e1ba..260c25188 100644 --- a/DDAlign/src/GlobalAlignmentWriter.cpp +++ b/DDAlign/src/GlobalAlignmentWriter.cpp @@ -125,19 +125,8 @@ XML::Element GlobalAlignmentWriter::scan(XML::Document doc, DetElement element) /// Dump the tree content into a XML document structure XML::Document GlobalAlignmentWriter::dump(DetElement top, bool enable_transactions) const { - const char comment[] = "\n" - " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" - " ++++ DD4hep generated alignment file using the ++++\n" - " ++++ DD4hep Detector description XML generator. ++++\n" - " ++++ ++++\n" - " ++++ Parser:" - XML_IMPLEMENTATION_TYPE - " ++++\n" - " ++++ ++++\n" - " ++++ M.Frank CERN/LHCb ++++\n" - " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n "; XML::DocumentHandler docH; - XML::Document doc = docH.create("alignment", comment); + XML::Document doc = docH.create("alignment", docH.defaultComment()); XML::Element elt(0), elements(0), root = doc.root(); root.append(elements = XML::Element(doc, _ALU(detelements))); if ( enable_transactions ) root.append(XML::Element(doc,_ALU(open_transaction))); diff --git a/DDAlign/src/plugins/AlignmentsPlugins.cpp b/DDAlign/src/plugins/AlignmentsPlugins.cpp index 30bf03116..f94206cbe 100644 --- a/DDAlign/src/plugins/AlignmentsPlugins.cpp +++ b/DDAlign/src/plugins/AlignmentsPlugins.cpp @@ -15,10 +15,13 @@ #include "DD4hep/Printout.h" #include "DD4hep/DetectorTools.h" #include "DD4hep/DetFactoryHelper.h" +#include "DDCond/ConditionsSlice.h" using namespace std; using namespace DD4hep; using namespace DD4hep::Alignments; +using Conditions::UserPool; +using Conditions::ConditionsSlice; // ====================================================================================== #include "DDAlign/AlignmentsManager.h" @@ -107,15 +110,21 @@ static void* create_DDAlignForwardCall(Geometry::LCDD& /* lcdd */, int /* argc * } DECLARE_LCDD_CONSTRUCTOR(DDAlign_ForwardCall, create_DDAlignForwardCall) +// ====================================================================================== +#include "DDAlign/DDAlignResetCall.h" +static void* create_DDAlignResetCall(Geometry::LCDD& /* lcdd */, int /* argc */, char** /* argv */) { + return (AlignmentsUpdateCall*)(new DDAlignResetCall()); +} +DECLARE_LCDD_CONSTRUCTOR(DDAlign_ResetCall, create_DDAlignResetCall) + // ====================================================================================== #include "DD4hep/PluginTester.h" #include "DDCond/ConditionsPool.h" static long compute_alignments(Geometry::LCDD& lcdd, int /* argc */, char** /* argv */) { AlignmentsManager mgr = AlignmentsManager::from(lcdd); PluginTester* tst = lcdd.extension<PluginTester>(); - dd4hep_ptr<UserPool> pool(tst->extension<UserPool>("ConditionsTestUserPool")); - mgr.compute(*pool); - pool.release(); + ConditionsSlice* slc = tst->extension<ConditionsSlice>("ConditionsTestSlice"); + mgr.compute(*slc); return 1; } DECLARE_APPLY(DDAlign_ComputeAlignments, compute_alignments) @@ -153,20 +162,13 @@ static void* ddalign_AlignmentsRegister(Geometry::LCDD& lcdd, int argc, char** a " Arguments to the 'prepare' plugin. \n" " -call ... args ... -call-end \n" " Arguments to the 'call' plugin, which \n" - " create the AlignmentsUpdateCall callback. \n" + " create the AlignmentsUpdateCall callback.\n" "\tArguments given: " << arguments(argc,argv) << endl << flush; ::exit(EINVAL); } PluginTester* test = lcdd.extension<PluginTester>(); - Conditions::UserPool* pool = (Conditions::UserPool*) - PluginService::Create<void*>((const char*)args_prepare[0],&lcdd, - int(args_prepare.size())-1, - (char**)&args_prepare[1]); - if ( 0 == pool ) { - except("AlignRegister","++ Failed to prepare conditions user-pool!"); - } - test->addExtension<Conditions::UserPool>(pool,"ConditionsTestUserPool"); + ConditionsSlice* slice = test->extension<ConditionsSlice>("ConditionsTestSlice"); AlignmentsUpdateCall* call = (AlignmentsUpdateCall*) PluginService::Create<void*>((const char*)args_call[0],&lcdd, int(args_call.size())-1, @@ -174,8 +176,7 @@ static void* ddalign_AlignmentsRegister(Geometry::LCDD& lcdd, int argc, char** a if ( 0 == call ) { except("AlignRegister","++ Failed to create update call!"); } - AlignmentsManager mgr = AlignmentsManager::from(lcdd); - AlignmentsRegister* obj = new AlignmentsRegister(mgr, call, pool); + AlignmentsRegister* obj = new AlignmentsRegister(*slice, call); return obj; } DECLARE_LCDD_CONSTRUCTOR(DDAlign_AlignmentsRegister,ddalign_AlignmentsRegister) @@ -213,7 +214,7 @@ static void* ddalign_AlignmentsForward(Geometry::LCDD& lcdd, int argc, char** ar } PluginTester* test = lcdd.extension<PluginTester>(); - Conditions::UserPool* pool = test->extension<Conditions::UserPool>("ConditionsTestUserPool"); + ConditionsSlice* slice = test->extension<ConditionsSlice>("ConditionsTestSlice"); AlignmentsUpdateCall* call = (AlignmentsUpdateCall*) PluginService::Create<void*>((const char*)args_call[0],&lcdd, int(args_call.size())-1, @@ -221,8 +222,7 @@ static void* ddalign_AlignmentsForward(Geometry::LCDD& lcdd, int argc, char** ar if ( 0 == call ) { except("AlignForward","++ Failed to create update call!"); } - AlignmentsManager mgr = AlignmentsManager::from(lcdd); - AlignmentsForward* obj = new AlignmentsForward(mgr, call, pool); + AlignmentsForward* obj = new AlignmentsForward(*slice, call); return obj; } DECLARE_LCDD_CONSTRUCTOR(DDAlign_AlignmentsForward,ddalign_AlignmentsForward) diff --git a/DDAlign/src/plugins/GlobalAlignmentParser.cpp b/DDAlign/src/plugins/GlobalAlignmentParser.cpp index 9f05c5eee..d3745b702 100644 --- a/DDAlign/src/plugins/GlobalAlignmentParser.cpp +++ b/DDAlign/src/plugins/GlobalAlignmentParser.cpp @@ -340,7 +340,7 @@ template <> void Converter<alignment>::operator()(xml_h e) const { static long setup_Alignment(lcdd_t& lcdd, const xml_h& e) { static dd4hep_mutex_t s_mutex; dd4hep_lock_t lock(s_mutex); - bool open_trans = e.hasChild(_ALU(close_transaction)); + bool open_trans = e.hasChild(_ALU(open_transaction)); bool close_trans = e.hasChild(_ALU(close_transaction)); GlobalAlignmentCache* cache = GlobalAlignmentCache::install(lcdd); @@ -351,6 +351,11 @@ static long setup_Alignment(lcdd_t& lcdd, const xml_h& e) { } GlobalAlignmentStack::create(); } + if ( !GlobalAlignmentStack::exists() ) { + printout(ERROR,"GlobalAlignment","Request process global alignments without cache."); + printout(ERROR,"GlobalAlignment","Call plugin DD4hep_GlobalAlignmentInstall first OR add XML tag <open_transaction/>"); + except("GlobalAlignment","Request process global alignments without cache."); + } GlobalAlignmentStack& stack = GlobalAlignmentStack::get(); (DD4hep::Converter<DD4hep::alignment>(lcdd,lcdd.world().ptr(),&stack))(e); if ( close_trans ) { diff --git a/DDCond/include/DDCond/ConditionsPool.h b/DDCond/include/DDCond/ConditionsPool.h index b2f4f3992..13f5bb44b 100644 --- a/DDCond/include/DDCond/ConditionsPool.h +++ b/DDCond/include/DDCond/ConditionsPool.h @@ -183,7 +183,9 @@ namespace DD4hep { void* user_param = 0) = 0; /// Evaluate and register all derived conditions from the dependency list - virtual size_t compute(const Dependencies& dependencies, void* user_param = 0) = 0; + virtual size_t compute(const Dependencies& dependencies, + void* user_param, + bool force) = 0; }; } /* End namespace Conditions */ } /* End namespace DD4hep */ diff --git a/DDCond/src/plugins/ConditionsPlugins.cpp b/DDCond/src/plugins/ConditionsPlugins.cpp index 2be2c2d7e..f6e06bee0 100644 --- a/DDCond/src/plugins/ConditionsPlugins.cpp +++ b/DDCond/src/plugins/ConditionsPlugins.cpp @@ -392,7 +392,6 @@ DECLARE_APPLY(DD4hep_ConditionsClean,ddcond_clean_conditions) #include "DD4hep/PluginTester.h" template <typename PRINTER> static void* create_printer(Geometry::LCDD& lcdd, int argc,char** argv) { - typedef typename PRINTER::pool_type pool_t; PrintLevel print_level = INFO; string prefix = "", name = ""; int flags = 0, have_pool = 0, arg_error = false; @@ -420,7 +419,7 @@ static void* create_printer(Geometry::LCDD& lcdd, int argc,char** argv) { " -prefix <string> Printout prefix for user customized output. \n" " -flags <number> Printout processing flags. \n" " -pool Attach conditions user pool from \n" - " PluginTester instance attached to LCDD. \n\n" + " PluginTester's slice instance attached. \n\n" " -print Printout level for the printer object. \n" "\tArguments given: " << arguments(argc,argv) << endl << flush; ::exit(EINVAL); @@ -431,9 +430,9 @@ static void* create_printer(Geometry::LCDD& lcdd, int argc,char** argv) { p->printLevel = print_level; if ( have_pool != 0 ) { PluginTester* test = lcdd.extension<PluginTester>(); - pool_t* pool = test->extension<pool_t>("ConditionsTestUserPool"); + ConditionsSlice* slice = test->extension<ConditionsSlice>("ConditionsTestSlice"); if ( !name.empty() ) p->name = name; - p->setPool(pool); + p->setPool(slice->pool.get()); } return (void*)dynamic_cast<DetElement::Processor*>(p); } diff --git a/DDCond/src/plugins/ConditionsRepositoryParser.cpp b/DDCond/src/plugins/ConditionsRepositoryParser.cpp index db7bfef90..9de2b653f 100644 --- a/DDCond/src/plugins/ConditionsRepositoryParser.cpp +++ b/DDCond/src/plugins/ConditionsRepositoryParser.cpp @@ -46,6 +46,8 @@ namespace DD4hep { class arbitrary; /// Conditions types class value; + class pressure; + class temperature; class mapping; class sequence; class alignment; @@ -62,6 +64,8 @@ namespace DD4hep { template <> void Converter<position>::operator()(xml_h e) const; template <> void Converter<pivot>::operator()(xml_h e) const; template <> void Converter<value>::operator()(xml_h e) const; + template <> void Converter<pressure>::operator()(xml_h e) const; + template <> void Converter<temperature>::operator()(xml_h e) const; template <> void Converter<sequence>::operator()(xml_h e) const; template <> void Converter<mapping>::operator()(xml_h e) const; template <> void Converter<alignment>::operator()(xml_h e) const; @@ -78,7 +82,7 @@ using Geometry::Translation3D; using Geometry::Position; using Geometry::DetElement; -/// Ananymous local stuff only used in this module +/// Anonymous local stuff only used in this module namespace { /// Module print level @@ -183,9 +187,11 @@ namespace { const std::string& type="") { xml_dim_t elt(e); - string typ = type.empty() ? elt.typeStr() : type; - string val = elt.hasAttr(_U(value)) ? elt.valueStr() : elt.text(); - Condition con = create_condition(det, e); + string typ = type.empty() ? elt.typeStr() : type; + string val = elt.hasAttr(_U(value)) ? elt.valueStr() : elt.text(); + Condition con = create_condition(det, e); + string unit = elt.hasAttr(_U(unit)) ? elt.attr<string>(_U(unit)) : string(""); + if ( !unit.empty() ) val += "*"+unit; con->value = val; OpaqueDataBinder::bind(bnd, con, typ, val); return con; @@ -255,64 +261,30 @@ namespace DD4hep { printout(s_parseLevel,"XMLConditions","++ Conditions Manager successfully initialized."); } - /// Convert rotation objects - /** - * <rotation x="0.5" y="0" z="0"/> - * - * \author M.Frank - * \version 1.0 - * \date 01/04/2014 - */ - template <> void Converter<rotation>::operator()(xml_h e) const { - xml_comp_t r(e); - RotationZYX* v = (RotationZYX*)param; - v->SetComponents(r.z(), r.y(), r.x()); - printout(s_parseLevel,"XMLConditions", - "++ Rotation: x=%9.3f y=%9.3f z=%9.3f phi=%7.4f psi=%7.4f theta=%7.4f", - r.x(), r.y(), r.z(), v->Phi(), v->Psi(), v->Theta()); - } - - /// Convert position objects + /// Convert conditions value objects (scalars) /** - * <position x="0.5" y="0" z="0"/> - * * \author M.Frank * \version 1.0 * \date 01/04/2014 */ - template <> void Converter<position>::operator()(xml_h e) const { - xml_comp_t p(e); - Position* v = (Position*)param; - v->SetXYZ(p.x(), p.y(), p.z()); - printout(s_parseLevel,"XMLConditions","++ Position: x=%9.3f y=%9.3f z=%9.3f", - v->X(), v->Y(), v->Z()); + template <> void Converter<value>::operator()(xml_h e) const { + ConversionArg* arg = _param<ConversionArg>(); + Condition con = bind_condition(ValueBinder(), arg->detector, e); + arg->manager.registerUnlocked(arg->pool, con); } - /// Convert pivot objects + /// Convert conditions pressure objects (scalars with unit) /** - * <pivot x="0.5" y="0" z="0"/> + * <pressure value="980" unit="hPa"/> * * \author M.Frank * \version 1.0 * \date 01/04/2014 */ - template <> void Converter<pivot>::operator()(xml_h e) const { - xml_comp_t p(e); - double x,y,z; - Translation3D* v = (Translation3D*)param; - v->SetXYZ(x=p.x(), y=p.y(), z=p.z()); - printout(s_parseLevel,"XMLConditions","++ Pivot: x=%9.3f y=%9.3f z=%9.3f",x,y,z); - } - - /// Convert conditions value objects (scalars) - /** - * \author M.Frank - * \version 1.0 - * \date 01/04/2014 - */ - template <> void Converter<value>::operator()(xml_h e) const { + template <> void Converter<pressure>::operator()(xml_h e) const { ConversionArg* arg = _param<ConversionArg>(); Condition con = bind_condition(ValueBinder(), arg->detector, e); + con->setFlag(Condition::PRESSURE); arg->manager.registerUnlocked(arg->pool, con); } @@ -372,6 +344,70 @@ namespace DD4hep { arg->manager.registerUnlocked(arg->pool, con); } + /// Convert conditions temperature objects (scalars with unit) + /** + * <temperature value="273.1" unit="kelvin"/> + * + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ + template <> void Converter<temperature>::operator()(xml_h e) const { + ConversionArg* arg = _param<ConversionArg>(); + Condition con = bind_condition(ValueBinder(), arg->detector, e); + con->setFlag(Condition::TEMPERATURE); + arg->manager.registerUnlocked(arg->pool, con); + } + + /// Convert rotation objects + /** + * <rotation x="0.5" y="0" z="0"/> + * + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ + template <> void Converter<rotation>::operator()(xml_h e) const { + xml_comp_t r(e); + RotationZYX* v = (RotationZYX*)param; + v->SetComponents(r.z(), r.y(), r.x()); + printout(s_parseLevel,"XMLConditions", + "++ Rotation: x=%9.3f y=%9.3f z=%9.3f phi=%7.4f psi=%7.4f theta=%7.4f", + r.x(), r.y(), r.z(), v->Phi(), v->Psi(), v->Theta()); + } + + /// Convert position objects + /** + * <position x="0.5" y="0" z="0"/> + * + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ + template <> void Converter<position>::operator()(xml_h e) const { + xml_comp_t p(e); + Position* v = (Position*)param; + v->SetXYZ(p.x(), p.y(), p.z()); + printout(s_parseLevel,"XMLConditions","++ Position: x=%9.3f y=%9.3f z=%9.3f", + v->X(), v->Y(), v->Z()); + } + + /// Convert pivot objects + /** + * <pivot x="0.5" y="0" z="0"/> + * + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ + template <> void Converter<pivot>::operator()(xml_h e) const { + xml_comp_t p(e); + double x,y,z; + Translation3D* v = (Translation3D*)param; + v->SetXYZ(x=p.x(), y=p.y(), z=p.z()); + printout(s_parseLevel,"XMLConditions","++ Pivot: x=%9.3f y=%9.3f z=%9.3f",x,y,z); + } + /// Convert alignment delta objects /** * A generic alignment transformation is defined by @@ -449,7 +485,9 @@ namespace DD4hep { xml_coll_t(e,_U(value)).for_each(Converter<value>(lcdd,param,optional)); xml_coll_t(e,_UC(mapping)).for_each(Converter<mapping>(lcdd,param,optional)); xml_coll_t(e,_UC(sequence)).for_each(Converter<sequence>(lcdd,param,optional)); + xml_coll_t(e,_UC(pressure)).for_each(Converter<pressure>(lcdd,param,optional)); xml_coll_t(e,_UC(alignment)).for_each(Converter<alignment>(lcdd,param,optional)); + xml_coll_t(e,_UC(temperature)).for_each(Converter<temperature>(lcdd,param,optional)); xml_coll_t(e,_UC(detelement)).for_each(Converter<detelement>(lcdd,param,optional)); } diff --git a/DDCond/src/plugins/ConditionsRepositoryWriter.cpp b/DDCond/src/plugins/ConditionsRepositoryWriter.cpp new file mode 100644 index 000000000..9805180e7 --- /dev/null +++ b/DDCond/src/plugins/ConditionsRepositoryWriter.cpp @@ -0,0 +1,303 @@ +//========================================================================== +// 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_DDCOND_CONDITIONSREPOSITORYWRITER_H +#define DD4HEP_DDCOND_CONDITIONSREPOSITORYWRITER_H + +// Framework include files +#include "DD4hep/LCDD.h" +#include "DDCond/ConditionsManager.h" +#include "XML/XMLElements.h" + +// C/C++ include files + + + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Conditions slice object. Defines which conditions should be loaded by the ConditionsManager. + /** + * Object contains set of required conditions keys to be loaded to the user pool. + * It alkso contains the load information for the required conditions (conditions addresses). + * The address objects depend on the actual loader mechanism and must be specified the user. + * The information is then chained through the calls and made availible to the loader object. + * + * On return it contains the individual condition load information. + * + * Referenced by: ConditonsUserPool, ConditionsManager + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsXMLRepositoryWriter { + ConditionsManager manager; + public: + /// Default constructor + ConditionsXMLRepositoryWriter() = delete; + /// Copy constructor (Special, partial copy only. Hence no assignment!) + ConditionsXMLRepositoryWriter(const ConditionsXMLRepositoryWriter& copy) = delete; + /// Initializing constructor + ConditionsXMLRepositoryWriter(ConditionsManager& mgr); + /// Default destructor. + virtual ~ConditionsXMLRepositoryWriter(); + + /// Dump the tree content into a XML document structure + size_t collectConditions(XML::Element root, + ConditionsSlice& slice, + DetElement detector) const; + /// Write the XML document structure to a file. + long write(XML::Document doc, const std::string& output) const; + /// Dump the tree content into a XML document structure + XML::Document dump(ConditionsSlice& slice, DetElement element) const; + }; + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_DDCOND_CONDITIONSREPOSITORYWRITER_H */ + + +//========================================================================== +// 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 "XML/XMLElements.h" +#include "XML/DocumentHandler.h" +#include "DD4hep/Printout.h" +#include "DD4hep/DetConditions.h" +#include "DD4hep/AlignmentData.h" +#include "DD4hep/OpaqueDataBinder.h" +#include "DD4hep/ConditionsKeyAssign.h" +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/objects/ConditionsInterna.h" + +#include "DDCond/ConditionsTags.h" +#include "DDCond/ConditionsSlice.h" +#include "DDCond/ConditionsManager.h" + +// C/C++ include files +#include <stdexcept> + +using std::string; +using namespace DD4hep; +using namespace DD4hep::Conditions; +using Geometry::RotationZYX; +using Geometry::Transform3D; +using Geometry::Translation3D; +using Geometry::Position; + +/// Anonymous local stuff only used in this module +namespace { + + /// Module print level + static PrintLevel s_printLevel = INFO; + + class condition; + class pressure; + class temperature; + class alignment; + class position; + class rotation; + class pivot; + + template <typename T> XML::Element _convert(XML::Element par, Condition c); + + XML::Element make(XML::Element e, Condition c) { + std::string nam = c.name(); + std::string cn = nam.substr(nam.find('#')+1); + e.setAttr(_U(name),cn); + return e; + } + XML::Element _convert(XML::Element par, const Translation3D& tr) { + XML::Element e = XML::Element(par.document(),_U(pivot)); + const Translation3D::Vector& v = tr.Vect(); + e.setAttr(_U(x),v.X()); + e.setAttr(_U(y),v.Y()); + e.setAttr(_U(z),v.Z()); + return e; + } + XML::Element _convert(XML::Element par, const Position& pos) { + XML::Element e = XML::Element(par.document(),_U(position)); + e.setAttr(_U(x),pos.X()); + e.setAttr(_U(y),pos.Y()); + e.setAttr(_U(z),pos.Z()); + return e; + } + XML::Element _convert(XML::Element par, const RotationZYX& rot) { + XML::Element e = XML::Element(par.document(),_U(rotation)); + double z, y, x; + rot.GetComponents(z,y,x); + e.setAttr(_U(x),x); + e.setAttr(_U(y),y); + e.setAttr(_U(z),z); + return e; + } + template <> XML::Element _convert<pressure>(XML::Element par, Condition c) { + XML::Element press = make(XML::Element(par.document(),_UC(pressure)),c); + press.setAttr(_U(value),c.get<float>()/(100e0*dd4hep::pascal)); + press.setAttr(_U(unit),"hPa"); + return press; + } + template <> XML::Element _convert<temperature>(XML::Element par, Condition c) { + XML::Element temp = make(XML::Element(par.document(),_UC(temperature)),c); + temp.setAttr(_U(value),c.get<float>()/dd4hep::kelvin); + temp.setAttr(_U(unit),"kelvin"); + return temp; + } + template <> XML::Element _convert<alignment>(XML::Element par, Condition c) { + using Alignments::Delta; + XML::Element align = make(XML::Element(par.document(),_UC(alignment)),c); + const Delta& delta = c.get<Delta>(); + if ( delta.flags&Delta::HAVE_TRANSLATION ) + align.append(_convert(align,delta.translation)); + if ( delta.flags&Delta::HAVE_ROTATION ) + align.append(_convert(align,delta.rotation)); + if ( delta.flags&Delta::HAVE_PIVOT ) + align.append(_convert(align,delta.pivot)); + return align; + } +} + +/// Initializing constructor +ConditionsXMLRepositoryWriter::ConditionsXMLRepositoryWriter(ConditionsManager& mgr) + : manager(mgr) +{ +} + +/// Default destructor. +ConditionsXMLRepositoryWriter::~ConditionsXMLRepositoryWriter() { +} + +/// Dump the tree content into a XML document structure +XML::Document ConditionsXMLRepositoryWriter::dump(ConditionsSlice& slice, DetElement element) const { + XML::DocumentHandler docH; + XML::Document doc = docH.create("conditions", docH.defaultComment()); + XML::Element root = doc.root(); + collectConditions(root,slice,element); + return doc; +} + +/// Dump the tree content into a XML document structure +size_t ConditionsXMLRepositoryWriter::collectConditions(XML::Element root, + ConditionsSlice& slice, + DetElement detector) const +{ + size_t count = 0; + if ( detector.isValid() ) { + if ( detector.hasConditions() ) { + DetConditions det(detector); + Container cont = det.conditions(); + if ( cont.numKeys() > 0 ) { + XML::Element conditions = XML::Element(root.document(),_U(detelement)); + conditions.setAttr(_U(path),detector.path()); + printout(s_printLevel,"Writer","++ Conditions of DE %s [%d entries]", + detector.path().c_str(), int(cont.keys().size())); + root.append(conditions); + for(const auto& k : cont.keys() ) { + if ( k.first == k.second.first ) { + Condition c = cont.get(k.first,*slice.pool); + std::string nam = c.name(); + std::string cn = nam.substr(nam.find('#')+1); + ReferenceBitMask<Condition::mask_type> msk(c->flags); + + printout(s_printLevel,"Writer","++ Condition %s [%16llX] -> %s", + cn.c_str(), k.first, c.name()); + if ( msk.isSet(Condition::TEMPERATURE) ) { + conditions.append(_convert<temperature>(conditions,c)); + } + else if ( msk.isSet(Condition::PRESSURE) ) { + conditions.append(_convert<pressure>(conditions,c)); + } + else if ( msk.isSet(Condition::ALIGNMENT) ) { + conditions.append(_convert<alignment>(conditions,c)); + } + else { + printout(ERROR,"Writer","Unknown data type of condition: %s [%16llX] -> %s Flags:0x%08X", + cn.c_str(), k.first, c.name(), c->flags); + } + } + } + } + } + for (const auto& i : detector.children()) + count += collectConditions(root,slice,i.second); + } + return count; +} + +/// Write the XML document structure to a file. +long ConditionsXMLRepositoryWriter::write(XML::Document doc, const string& output) const { + XML::DocumentHandler docH; + return docH.output(doc, output); +} + +/// Basic entry point to read alignment conditions files +/** + * \author M.Frank + * \version 1.0 + * \date 01/04/2014 + */ +static long write_repository_conditions(lcdd_t& lcdd, int argc, char** argv) { + ConditionsManager manager = ConditionsManager::from(lcdd); + const IOVType* iovtype = 0; + long iovvalue = -1; + string output; + + for(int i=0; i<argc; ++i) { + if ( ::strncmp(argv[i],"-iov_type",7) == 0 ) + iovtype = manager.iovType(argv[++i]); + else if ( ::strncmp(argv[i],"-iov_value",7) == 0 ) + iovvalue = ::atol(argv[++i]); + else if ( ::strncmp(argv[i],"-output",4) == 0 && argc>i+1) + output = argv[++i]; + else if ( ::strncmp(argv[i],"-help",2) == 0 ) { + printout(ALWAYS,"Plugin-Help","Usage: DD4hep_XMLConditionsRepositoryWriter --opt [--opt] "); + printout(ALWAYS,"Plugin-Help"," -output <string> Output file name. Default: stdout "); + printout(ALWAYS,"Plugin-Help"," -iov_type <string> IOV type to be selected. "); + printout(ALWAYS,"Plugin-Help"," -iov_value <string> IOV value to create the conditions snapshot."); + ::exit(EINVAL); + } + } + if ( 0 == iovtype ) + except("ConditionsPrepare","++ Unknown IOV type supplied."); + if ( 0 > iovvalue ) + except("ConditionsPrepare", + "++ Unknown IOV value supplied for iov type %s.",iovtype->str().c_str()); + + IOV iov(iovtype,iovvalue); + dd4hep_ptr<ConditionsSlice> slice(Conditions::createSlice(manager,*iovtype)); + ConditionsManager::Result cres = manager.prepare(iov, *slice); + printout(INFO,"Conditions", + "++ Selected conditions: %7ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) for IOV:%-12s", + cres.total(), cres.selected, cres.loaded, cres.computed, cres.missing, + iovtype ? iov.str().c_str() : "???"); + + ConditionsXMLRepositoryWriter writer(manager); + XML::Document doc = writer.dump(*slice,lcdd.world()); + writer.write(doc, output); + return 1; +} +DECLARE_APPLY(DD4hep_XMLConditionsRepositoryWriter,write_repository_conditions) diff --git a/DDCond/src/plugins/ConditionsUserPool.cpp b/DDCond/src/plugins/ConditionsUserPool.cpp index 33bbad547..058cb0754 100644 --- a/DDCond/src/plugins/ConditionsUserPool.cpp +++ b/DDCond/src/plugins/ConditionsUserPool.cpp @@ -94,7 +94,8 @@ namespace DD4hep { void* user_param); /// Evaluate and register all derived conditions from the dependency list virtual size_t compute(const Dependencies& dependencies, - void* user_param); + void* user_param, + bool force); }; } /* End namespace Conditions */ } /* End namespace DD4hep */ @@ -277,7 +278,8 @@ bool ConditionsMappedUserPool<MAPPING>::remove(key_type hash_key) { /// Evaluate and register all derived conditions from the dependency list template<typename MAPPING> size_t ConditionsMappedUserPool<MAPPING>::compute(const Dependencies& deps, - void* user_param) + void* user_param, + bool force) { size_t num_updates = 0; if ( !deps.empty() ) { @@ -287,15 +289,20 @@ size_t ConditionsMappedUserPool<MAPPING>::compute(const Dependencies& deps, for ( const auto& i : deps ) { typename MAPPING::iterator j = m_conditions.find(i.first); if ( j != m_conditions.end() ) { - Condition::Object* c = (*j).second; - // Remeber: key ist first, test is second! - if ( IOV::key_is_contained(m_iov.keyData,c->iov->keyData) ) { - /// This condition is no longer valid. remove it! - /// This condition will be added again by the handler. + if ( !force ) { + Condition::Object* c = (*j).second; + // Remeber: key ist first, test is second! + if ( IOV::key_is_contained(m_iov.keyData,c->iov->keyData) ) { + /// This condition is no longer valid. remove it! + /// This condition will be added again by the handler. + m_conditions.erase(j); + missing.push_back(i.second.get()); + } + continue; + } + else { m_conditions.erase(j); - missing.push_back(i.second.get()); } - continue; } missing.push_back(i.second.get()); } diff --git a/DDCore/include/DD4hep/Conditions.h b/DDCore/include/DD4hep/Conditions.h index d213d0f96..8b8ad1679 100644 --- a/DDCore/include/DD4hep/Conditions.h +++ b/DDCore/include/DD4hep/Conditions.h @@ -89,17 +89,18 @@ namespace DD4hep { NONE }; enum ConditionState { - INACTIVE = 0, - ACTIVE = 1<<0, - CHECKED = 1<<2, - DERIVED = 1<<3, - TEMPERATURE = 1<<4, - PRESSURE = 1<<5, - ALIGNMENT = 1<<6, - // Keep bit 7-15 for other generic types + INACTIVE = 0, + ACTIVE = 1<<0, + CHECKED = 1<<2, + DERIVED = 1<<3, + TEMPERATURE = 1<<4, + PRESSURE = 1<<5, + ALIGNMENT = 1<<6, + ALIGNMENT_DERIVED = 1<<7, + // Keep bit 8-15 for other generic types // Bit 16-31 is reserved for user classifications - USER_FLAGS_FIRST = 1<<16, - USER_FLAGS_LAST = 1<<31 + USER_FLAGS_FIRST = 1<<16, + USER_FLAGS_LAST = 1<<31 }; /// Abstract base for processing callbacks to conditions objects diff --git a/DDCore/include/DD4hep/DD4hepUI.h b/DDCore/include/DD4hep/DD4hepUI.h index d4f3850f3..76fe9e855 100644 --- a/DDCore/include/DD4hep/DD4hepUI.h +++ b/DDCore/include/DD4hep/DD4hepUI.h @@ -40,6 +40,8 @@ namespace DD4hep { virtual ~DD4hepUI(); /// Access to the LCDD instance Geometry::LCDD* instance() const; + /// Access to the LCDD instance + Geometry::LCDD* lcdd() const; /// Install the DD4hep conditions manager object Handle<NamedObject> conditionsMgr() const; @@ -48,13 +50,17 @@ namespace DD4hep { /// Install the DD4hep alignment manager object Handle<NamedObject> alignmentMgr() const; - - /// LCDD interface: Manipulate geometry using facroy converter + + /// LCDD interface: Manipulate geometry using factory converter virtual long apply(const char* factory, int argc, char** argv) const; /// LCDD interface: Read any geometry description or alignment file virtual void fromXML(const std::string& fname, LCDDBuildType type = BUILD_DEFAULT) const; /// LCDD interface: Re-draw the entire scene virtual void redraw() const; + /// Dump the volume tree + virtual long dumpVols(int argc=0, char** argv=0) const; + /// Dump the DetElement tree + virtual long dumpDet() const; }; } /* End namespace DD4hep */ diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h index f3dd69049..4a2601c65 100644 --- a/DDCore/include/DD4hep/Detector.h +++ b/DDCore/include/DD4hep/Detector.h @@ -356,7 +356,17 @@ namespace DD4hep { Volume volume() const; /// Access to the physical volume of this detector element + /** This is the current placement value of the detector eleemnt. + * A possible global re-alignment may alter the value. + * Hence, it should hence not be cached. + */ PlacedVolume placement() const; + /// Access to the ideal physical volume of this detector element + /** This is the original placement set in the detector constructor. + * A possible global re-alignment make this value different + * from the regular placement() call. + */ + PlacedVolume idealPlacement() const; /// Set the physical volumes of the detector element DetElement& setPlacement(const PlacedVolume& volume); /// The cached VolumeID of this subdetector element @@ -385,29 +395,20 @@ namespace DD4hep { // Deprecated functions to be removed soon: - /// Set detector element for reference transformations. Will delete existing reference trafo. - //DetElement& setReference(DetElement reference); - /// Create cached matrix to transform to world coordinates const TGeoHMatrix& worldTransformation() const; /// Create cached matrix to transform to parent coordinates const TGeoHMatrix& parentTransformation() const; - /// Create cached matrix to transform to reference coordinates - //const TGeoHMatrix& referenceTransformation() const; /// Transformation from local coordinates of the placed volume to the world system bool localToWorld(const Position& local, Position& global) const; /// Transformation from local coordinates of the placed volume to the parent system bool localToParent(const Position& local, Position& parent) const; - /// Transformation from local coordinates of the placed volume to arbitrary parent system set as reference - bool localToReference(const Position& local, Position& reference) const; /// Transformation from world coordinates of the local placed volume coordinates bool worldToLocal(const Position& global, Position& local) const; /// Transformation from world coordinates of the local placed volume coordinates bool parentToLocal(const Position& parent, Position& local) const; - /// Transformation from world coordinates of the local placed volume coordinates - bool referenceToLocal(const Position& reference, Position& local) const; }; } /* End namespace Geometry */ diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h index 506c0dfe5..0210babf5 100644 --- a/DDCore/include/DD4hep/Handle.h +++ b/DDCore/include/DD4hep/Handle.h @@ -161,7 +161,9 @@ namespace DD4hep { template <typename Q> Q& object() const { return *(Q*) m_element; } - /// Checked object access. Throws invalid handle runtime exception + /// Checked object access. Throws invalid handle runtime exception if invalid handle. + /** Very compact way to check the validity of a handle with exception thrown. + */ T* access() const; /// Verify the object type after a (re-)assignment void verifyObject() const; diff --git a/DDCore/include/DD4hep/Handle.inl b/DDCore/include/DD4hep/Handle.inl index deb942d5d..fffbb3f00 100644 --- a/DDCore/include/DD4hep/Handle.inl +++ b/DDCore/include/DD4hep/Handle.inl @@ -38,6 +38,8 @@ namespace DD4hep { } /// Checked object access. Throws invalid handle runtime exception + /** Very compact way to check the validity of a handle with exception thrown. + */ template <typename T> T* Handle<T>::access() const { if ( this->m_element ) return this->m_element; invalidHandleError(typeid(T)); diff --git a/DDCore/include/DD4hep/objects/AlignmentsInterna.h b/DDCore/include/DD4hep/objects/AlignmentsInterna.h index 860d7b2df..1220922f1 100644 --- a/DDCore/include/DD4hep/objects/AlignmentsInterna.h +++ b/DDCore/include/DD4hep/objects/AlignmentsInterna.h @@ -92,7 +92,9 @@ namespace DD4hep { { public: /// Cached pointer to the bound conditions data, since these may be accessed very frequently - AlignmentData* alignment_data; + AlignmentData* alignment_data = 0; + /// Accessor to the alignment data + AlignmentData& values(); /// Standard constructor AlignmentConditionObject(const std::string& nam,const std::string& tit=""); /// Standard Destructor diff --git a/DDCore/include/DD4hep/objects/ConditionsInterna.h b/DDCore/include/DD4hep/objects/ConditionsInterna.h index 143ac727d..82e1ae11d 100644 --- a/DDCore/include/DD4hep/objects/ConditionsInterna.h +++ b/DDCore/include/DD4hep/objects/ConditionsInterna.h @@ -133,10 +133,11 @@ namespace DD4hep { /// Access safely the IOV-type const IOVType* iovType() const; /// Check if object is already bound.... - bool is_bound() const { return data.is_bound(); } - bool is_traced() const { return true; } - void setFlag(int option) { flags |= option; } - void unFlag(int option) { flags &= ~option; } + bool is_bound() const { return data.is_bound(); } + bool is_traced() const { return true; } + void setFlag(int option) { flags |= option; } + void unFlag(int option) { flags &= ~option; } + bool testFlag(int option) const { return 0 != (flags&option); } }; /// The data class behind a conditions container handle. diff --git a/DDCore/include/DD4hep/objects/DetectorInterna.h b/DDCore/include/DD4hep/objects/DetectorInterna.h index bbe5c3128..0384bba15 100644 --- a/DDCore/include/DD4hep/objects/DetectorInterna.h +++ b/DDCore/include/DD4hep/objects/DetectorInterna.h @@ -139,8 +139,6 @@ namespace DD4hep { World privateWorld; /// Reference to the parent element DetElement parent; - /// Reference element for stored transformations - DetElement reference; /// The array of children Children children; /// Placeholder for structure with update callbacks @@ -173,8 +171,6 @@ namespace DD4hep { TGeoHMatrix worldTrafo; /// Intermediate buffer to store the transformation to the parent detector element //TGeoHMatrix parentTrafo; - /// Intermediate buffer for the transformation to an arbitrary DetElement - //TGeoHMatrix* referenceTrafo; //@} private: @@ -201,8 +197,6 @@ namespace DD4hep { const TGeoHMatrix& worldTransformation(); /// Create cached matrix to transform to parent coordinates const TGeoHMatrix& parentTransformation(); - /// Create cached matrix to transform to reference coordinates - //const TGeoHMatrix& referenceTransformation(); /// Remove callback from object void removeAtUpdate(unsigned int type, void* pointer); /// Trigger update callbacks diff --git a/DDCore/include/XML/DocumentHandler.h b/DDCore/include/XML/DocumentHandler.h index 4b9ba0053..4de508975 100644 --- a/DDCore/include/XML/DocumentHandler.h +++ b/DDCore/include/XML/DocumentHandler.h @@ -44,8 +44,12 @@ namespace DD4hep { DocumentHandler(); /// Default destructor virtual ~DocumentHandler(); + /// Default comment string + static std::string defaultComment(); // Create new XML document by parsing empty xml buffer Document create(const char* tag, const char* comment = 0) const; + // Create new XML document by parsing empty xml buffer + Document create(const std::string& tag, const std::string& comment) const; /// Load XML file and parse it. virtual Document load(const std::string& fname) const; /// Load XML file and parse it using URI resolver to read data. diff --git a/DDCore/src/Alignments.cpp b/DDCore/src/Alignments.cpp index 933df8547..0aad46671 100644 --- a/DDCore/src/Alignments.cpp +++ b/DDCore/src/Alignments.cpp @@ -144,23 +144,13 @@ AlignmentCondition::key_type AlignmentCondition::key() const { /// Data accessor for the use of decorators AlignmentCondition::Data& AlignmentCondition::data() { Object* o = access(); - if ( o->alignment_data ) - return *(o->alignment_data); - Conditions::Condition c(*this); - o->alignment_data = c.is_bound() ? &c.get<Data>() : &c.bind<Data>(); - o->alignment_data->condition = c; - return *(o->alignment_data); + return o->alignment_data ? *o->alignment_data : o->values(); } /// Data accessor for the use of decorators const AlignmentCondition::Data& AlignmentCondition::data() const { Object* o = access(); - if ( o->alignment_data ) - return *(o->alignment_data); - Conditions::Condition c(*this); - o->alignment_data = c.is_bound() ? &c.get<Data>() : &c.bind<Data>(); - o->alignment_data->condition = c; - return *(o->alignment_data); + return o->alignment_data ? *o->alignment_data : o->values(); } /// Check if object is already bound.... @@ -189,11 +179,7 @@ size_t Container::numKeys() const { /// Known keys of conditions in this container const Container::Keys& Container::keys() const { - Object* o = ptr(); - if ( !o ) { - invalidHandleError<Container>(); - } - return o->keys; + return access()->keys; } /// Add a new key to the alignments access map @@ -208,56 +194,20 @@ void Container::addKey(const string& key_val, const string& data_val) { /// Access to alignment objects Alignment Container::get(const string& alignment_key, const iov_type& iov) { - Object* o = ptr(); - if ( o ) { - Alignment c = o->get(alignment_key, iov); - if ( c.isValid() ) { - return c; - } - invalidHandleError<Alignment>(); - } - invalidHandleError<Container>(); - return Alignment(); + return Alignment(access()->get(alignment_key, iov).access()); } /// Access to alignment objects Alignment Container::get(key_type alignment_key, const iov_type& iov) { - Object* o = ptr(); - if ( o ) { - Alignment c = o->get(alignment_key, iov); - if ( c.isValid() ) { - return c; - } - invalidHandleError<Alignment>(); - } - invalidHandleError<Container>(); - return Alignment(); + return Alignment(access()->get(alignment_key, iov).access()); } /// Access to alignment objects Alignment Container::get(const string& alignment_key, const UserPool& pool) { - Object* o = ptr(); - if ( o ) { - Alignment c = o->get(alignment_key, pool); - if ( c.isValid() ) { - return c; - } - invalidHandleError<Alignment>(); - } - invalidHandleError<Container>(); - return Alignment(); + return Alignment(access()->get(alignment_key, pool).access()); } /// Access to alignment objects Alignment Container::get(key_type alignment_key, const UserPool& pool) { - Object* o = ptr(); - if ( o ) { - Alignment c = o->get(alignment_key, pool); - if ( c.isValid() ) { - return c; - } - invalidHandleError<Alignment>(); - } - invalidHandleError<Container>(); - return Alignment(); + return Alignment(access()->get(alignment_key, pool).access()); } diff --git a/DDCore/src/AlignmentsInterna.cpp b/DDCore/src/AlignmentsInterna.cpp index 574710aa7..b41506c7c 100644 --- a/DDCore/src/AlignmentsInterna.cpp +++ b/DDCore/src/AlignmentsInterna.cpp @@ -43,6 +43,16 @@ AlignmentConditionObject::~AlignmentConditionObject() { InstanceCount::decrement(this); } +/// Accessor to the alignment data +Alignment::Data& AlignmentConditionObject::values() { + if ( alignment_data ) + return *alignment_data; + Conditions::Condition c(this); + alignment_data = c.is_bound() ? &c.get<Alignment::Data>() : &c.bind<Alignment::Data>(); + alignment_data->condition = c; + return *alignment_data; +} + /// Clear data content on demand. void AlignmentConditionObject::clear() { AlignmentCondition a(this); diff --git a/DDCore/src/Conditions.cpp b/DDCore/src/Conditions.cpp index 5927f2d90..b1ca80174 100644 --- a/DDCore/src/Conditions.cpp +++ b/DDCore/src/Conditions.cpp @@ -142,20 +142,12 @@ Container::Processor::Processor() { /// Access the number of conditons keys available for this detector element size_t Container::numKeys() const { - Object* o = ptr(); - if ( !o ) { - invalidHandleError<Container>(); - } - return o->keys.size(); + return access()->keys.size(); } /// Known keys of conditions in this container const Container::Keys& Container::keys() const { - Object* o = ptr(); - if ( !o ) { - invalidHandleError<Container>(); - } - return o->keys; + return access()->keys; } /// Add a new key to the conditions access map @@ -170,58 +162,22 @@ void Container::addKey(const string& key_val, const string& data_val) { /// Access to condition objects Condition Container::get(const string& condition_key, const iov_type& iov) { - Object* o = ptr(); - if ( o ) { - Condition c = o->get(condition_key, iov); - if ( c.isValid() ) { - return c; - } - invalidHandleError<Condition>(); - } - invalidHandleError<Container>(); - return Condition(); + return Condition(access()->get(condition_key, iov).access()); } /// Access to condition objects Condition Container::get(key_type condition_key, const iov_type& iov) { - Object* o = ptr(); - if ( o ) { - Condition c = o->get(condition_key, iov); - if ( c.isValid() ) { - return c; - } - invalidHandleError<Condition>(); - } - invalidHandleError<Container>(); - return Condition(); + return Condition(access()->get(condition_key, iov).access()); } /// Access to condition objects Condition Container::get(const string& condition_key, const UserPool& pool) { - Object* o = ptr(); - if ( o ) { - Condition c = o->get(condition_key, pool); - if ( c.isValid() ) { - return c; - } - invalidHandleError<Condition>(); - } - invalidHandleError<Container>(); - return Condition(); + return Condition(access()->get(condition_key, pool).access()); } /// Access to condition objects Condition Container::get(key_type condition_key, const UserPool& pool) { - Object* o = ptr(); - if ( o ) { - Condition c = o->get(condition_key, pool); - if ( c.isValid() ) { - return c; - } - invalidHandleError<Condition>(); - } - invalidHandleError<Container>(); - return Condition(); + return Condition(access()->get(condition_key, pool).access()); } /// Default destructor. @@ -230,10 +186,8 @@ ConditionsSelect::~ConditionsSelect() { /// Access the key of the condition ConditionKey DD4hep::Conditions::make_key(Condition c) { - Condition::Object* p = c.ptr(); - if ( p ) return ConditionKey(p->name,p->hash); - invalidHandleError<Condition>(); - return ConditionKey(); + Condition::Object* p = c.access(); + return ConditionKey(p->name,p->hash); } /// Constructor from string diff --git a/DDCore/src/DD4hepUI.cpp b/DDCore/src/DD4hepUI.cpp index 5f7a2972a..fc45a17eb 100644 --- a/DDCore/src/DD4hepUI.cpp +++ b/DDCore/src/DD4hepUI.cpp @@ -32,6 +32,11 @@ LCDD* DD4hepUI::instance() const { return &m_lcdd; } +/// Access to the LCDD instance +LCDD* DD4hepUI::lcdd() const { + return &m_lcdd; +} + /// Install the DD4hep conditions manager object Handle<NamedObject> DD4hepUI::conditionsMgr() const { if ( !m_condMgr.isValid() ) { @@ -84,3 +89,17 @@ void DD4hepUI::fromXML(const std::string& fname, LCDDBuildType type) const { void DD4hepUI::redraw() const { m_lcdd.worldVolume()->Draw("oglsame"); } + +/// Dump the volume tree +long DD4hepUI::dumpVols(int argc, char** argv) const { + if ( argc==0 ) { + const void* av[] = {"-positions","-pointers",0}; + return m_lcdd.apply("DD4hepVolumeDump",2,(char**)av); + } + return m_lcdd.apply("DD4hepVolumeDump",argc,argv); +} + +/// Dump the DetElement tree +long DD4hepUI::dumpDet() const { + return m_lcdd.apply("DD4hepDetectorVolumeDump",0,0); +} diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp index 10281113c..0d1b6a3cc 100644 --- a/DDCore/src/Detector.cpp +++ b/DDCore/src/Detector.cpp @@ -102,8 +102,7 @@ string DetElement::type() const { /// Set the type of the sensitive detector DetElement& DetElement::setType(const string& typ) { - Object* o = access(); - o->SetTitle(typ.c_str()); + access()->SetTitle(typ.c_str()); return *this; } @@ -113,8 +112,7 @@ unsigned int DetElement::typeFlag() const { /// Set the type of the sensitive detector DetElement& DetElement::setTypeFlag(unsigned int types) { - Object* o = access(); - o->typeFlag = types ; + access()->typeFlag = types ; return *this; } @@ -278,13 +276,20 @@ DetElement DetElement::clone(const string& new_name, int new_id) const { return DetElement(o->clone(new_id, COPY_NONE), new_name, o->GetTitle()); } +/// Access to the ideal physical volume of this detector element +PlacedVolume DetElement::idealPlacement() const { + if (isValid()) { + Object& o = object<Object>(); + return o.idealPlace; + } + return PlacedVolume(); +} + /// Access to the physical volume of this detector element PlacedVolume DetElement::placement() const { if (isValid()) { Object& o = object<Object>(); - if (o.placement.isValid()) { - return o.placement; - } + return o.placement; } return PlacedVolume(); } @@ -338,41 +343,6 @@ DetElement& DetElement::setAttributes(const LCDD& lcdd, const Volume& vol, const const string& vis) { return setRegion(lcdd, region, vol).setLimitSet(lcdd, limits, vol).setVisAttributes(lcdd, vis, vol); } -#if 0 -/// Set detector element for reference transformations. Will delete existing reference trafo. -DetElement& DetElement::setReference(DetElement reference) { - Object& o = object<Object>(); - if (o.referenceTrafo) { - delete o.referenceTrafo; - o.referenceTrafo = 0; - } - object<Object>().reference = reference; - return *this; -} - -/// Create cached matrix to transform to reference coordinates -const TGeoHMatrix& DetElement::referenceTransformation() const { - return access()->referenceTransformation(); -} - -/// Transformation from local coordinates of the placed volume to arbitrary parent system set as reference -bool DetElement::localToReference(const Position& local, Position& global) const { - // If the path is unknown an exception will be thrown inside referenceTransformation() ! - Double_t master_point[3] = { 0, 0, 0 }, local_point[3] = { local.X(), local.Y(), local.Z() }; - referenceTransformation().LocalToMaster(local_point, master_point); - global.SetCoordinates(master_point); - return true; -} - -/// Transformation from arbitrary parent system coordinates of the local placed volume coordinates -bool DetElement::referenceToLocal(const Position& global, Position& local) const { - // If the path is unknown an exception will be thrown inside referenceTransformation() ! - Double_t master_point[3] = { global.X(), global.Y(), global.Z() }, local_point[3] = { 0, 0, 0 }; - referenceTransformation().MasterToLocal(master_point, local_point); - local.SetCoordinates(local_point); - return true; -} -#endif /// Create cached matrix to transform to world coordinates const TGeoHMatrix& DetElement::worldTransformation() const { diff --git a/DDCore/src/DetectorInterna.cpp b/DDCore/src/DetectorInterna.cpp index 1de83fb83..5d3829635 100644 --- a/DDCore/src/DetectorInterna.cpp +++ b/DDCore/src/DetectorInterna.cpp @@ -63,7 +63,7 @@ SensitiveDetectorObject::~SensitiveDetectorObject() { DetElementObject::DetElementObject() : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()), flag(0), id(0), combineHits(0), typeFlag(0), level(-1), key(0), path(), placementPath(), - idealPlace(), placement(), volumeID(0), parent(), reference(), children(), + idealPlace(), placement(), volumeID(0), parent(), children(), nominal(), survey(), alignments(), conditions(), worldTrafo() { printout(VERBOSE,"DetElementObject","+++ Created new anonymous DetElementObject()"); @@ -74,7 +74,7 @@ DetElementObject::DetElementObject() DetElementObject::DetElementObject(const std::string& nam, int ident) : NamedObject(), ObjectExtensions(typeid(DetElementObject)), magic(magic_word()), flag(0), id(ident), combineHits(0), typeFlag(0), level(-1), key(0), path(), placementPath(), - idealPlace(), placement(), volumeID(0), parent(), reference(), children(), + idealPlace(), placement(), volumeID(0), parent(), children(), nominal(), survey(), alignments(), conditions(), worldTrafo() { SetName(nam.c_str()); @@ -85,7 +85,6 @@ DetElementObject::DetElementObject(const std::string& nam, int ident) /// Internal object destructor: release extension object(s) DetElementObject::~DetElementObject() { destroyHandles(children); - //deletePtr (referenceTrafo); destroyHandle (conditions); conditions = ConditionsContainer(); destroyHandle (nominal); @@ -179,34 +178,6 @@ const TGeoHMatrix& DetElementObject::parentTransformation() { return DetElement(this).nominal().detectorTransformation(); } -#if 0 -/// Create cached matrix to transform to reference coordinates -const TGeoHMatrix& DetElementObject::referenceTransformation() { - if (!referenceTrafo) { - DetElement ref(reference); - DetElement self(this); - if ( ref.ptr() == self.ptr() ) { - referenceTrafo = new TGeoHMatrix(gGeoIdentity->Inverse()); - } - else if ( DetectorTools::isParentElement(ref,self) ) { - PlacementPath nodes; - DetectorTools::placementPath(ref,self,nodes); - DetectorTools::placementTrafo(nodes,false,referenceTrafo); - } - else if ( DetectorTools::isParentElement(self,ref) ) { - PlacementPath nodes; - DetectorTools::placementPath(self,ref,nodes); - DetectorTools::placementTrafo(nodes,false,referenceTrafo); - } - else { - throw runtime_error("DD4hep: referenceTransformation: No path from " + string(self.name()) + - " to reference element " + string(ref.name()) + " present!"); - } - } - return *referenceTrafo; -} -#endif - /// Revalidate the caches void DetElementObject::revalidate(TGeoHMatrix* parent_world_trafo) { PlacementPath par_path; @@ -227,8 +198,19 @@ void DetElementObject::revalidate(TGeoHMatrix* parent_world_trafo) { "DetElement","+++ Invalidate chache of %s -> %s Placement:%p --> %p %s", det.path().c_str(), DetectorTools::placementPath(par_path).c_str(), placement.ptr(), node.ptr(), (placement.ptr() == node.ptr()) ? "" : "[UPDATE]"); - + if ( idealPlace.ptr() != node.ptr() && 0 == node->GetUserExtension() ) { + auto ext = idealPlace->GetUserExtension(); + node->SetUserExtension(ext); + } + Volume node_vol = node.volume(); + Volume plac_vol = idealPlace.volume(); + if ( node_vol.ptr() != plac_vol.ptr() && 0 == node_vol->GetUserExtension() ) { + auto ext = plac_vol->GetUserExtension(); + node_vol->SetUserExtension(ext); + } + // Now we can assign the new placement to the object placement = node; + Alignments::Alignment::Data& data = det.nominal().data(); if ( have_trafo && print ) data.worldTransformation().Print(); @@ -252,7 +234,6 @@ void DetElementObject::revalidate(TGeoHMatrix* parent_world_trafo) { } if ( (flag&HAVE_PARENT_TRAFO) && print ) data.worldTrafo.Print(); - //deletePtr (referenceTrafo); /// Now iterate down the children.... for(const auto& i : children ) diff --git a/DDCore/src/Primitives.cpp b/DDCore/src/Primitives.cpp index 4637e3c95..f84da1cad 100644 --- a/DDCore/src/Primitives.cpp +++ b/DDCore/src/Primitives.cpp @@ -432,7 +432,7 @@ __dynamic_cast(const void* __src_ptr,// Starting object. const abi::__class_type_info* __dst_type,// Desired target type. ptrdiff_t __src2dst);// How src and dst are related. #endif - +#if 0 #ifndef __APPLE__ static inline void* cast_wrap(const void* p, const abi::__class_type_info* src, @@ -442,6 +442,7 @@ static inline void* cast_wrap(const void* p, return abi::__dynamic_cast(p,src,dst,src2dst); } #endif +#endif /// Apply cast using typeinfo instead of dynamic_cast void* DD4hep::ComponentCast::apply_dynCast(const ComponentCast& to, const void* ptr) const diff --git a/DDCore/src/XML/DocumentHandler.cpp b/DDCore/src/XML/DocumentHandler.cpp index 5b0fdd0b6..9ab407d48 100644 --- a/DDCore/src/XML/DocumentHandler.cpp +++ b/DDCore/src/XML/DocumentHandler.cpp @@ -465,9 +465,9 @@ Document DocumentHandler::load(const std::string& fname, UriReader* reader) cons doc->ErrorDesc()); printout(FATAL,"DocumentHandler","+++ Document:%s Location Line:%d Column:%d", doc->Value(), doc->ErrorRow(), doc->ErrorCol()); - throw runtime_error("DD4hep: file:"+clean+" error:"+doc->ErrorDesc()); + except("DD4hep: file:%s error:%s",clean.c_str(),doc->ErrorDesc().c_str()); } - throw runtime_error("DD4hep: Unknown error (TinyXML) while parsing:%s",fname.c_str()); + except("DD4hep: Unknown error (TinyXML) while parsing:%s",fname.c_str()); } } catch(exception& e) { @@ -556,6 +556,22 @@ DocumentHandler::DocumentHandler() {} /// Default destructor of a document handler using TiXml DocumentHandler::~DocumentHandler() {} +/// Default comment string +std::string DocumentHandler::defaultComment() { + const char comment[] = "\n" + " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" + " ++++ DD4hep generated alignment file using the ++++\n" + " ++++ DD4hep Detector description XML generator. ++++\n" + " ++++ ++++\n" + " ++++ Parser:" + XML_IMPLEMENTATION_TYPE + " ++++\n" + " ++++ ++++\n" + " ++++ M.Frank CERN/LHCb ++++\n" + " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n "; + return comment; +} + /// Load XML file and parse it. Document DocumentHandler::load(const std::string& fname) const { return load(fname, 0); @@ -604,6 +620,11 @@ Document DocumentHandler::create(const char* tag, const char* comment) const { return doc; } +// Create new XML document by parsing empty xml buffer +Document DocumentHandler::create(const std::string& tag, const std::string& comment) const { + return create(tag.c_str(), comment.c_str()); +} + /// Dump partial or full XML trees to stdout void DD4hep::XML::dump_tree(Handle_t elt) { dump_tree(elt,cout); diff --git a/DDCore/src/plugins/LCDDConverter.cpp b/DDCore/src/plugins/LCDDConverter.cpp index 9e981c89a..f3004766f 100644 --- a/DDCore/src/plugins/LCDDConverter.cpp +++ b/DDCore/src/plugins/LCDDConverter.cpp @@ -1110,19 +1110,8 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) { collect(top, geo); printout(ALWAYS,"LCDDConverter","++ ==> Converting in memory detector description to GDML format..."); - const char* comment = "\n" - " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" - " ++++ Linear collider detector description GDML in C++ ++++\n" - " ++++ DD4hep Detector description generator. ++++\n" - " ++++ ++++\n" - " ++++ Parser:" - XML_IMPLEMENTATION_TYPE - " ++++\n" - " ++++ ++++\n" - " ++++ M.Frank CERN/LHCb ++++\n" - " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n "; XML::DocumentHandler docH; - geo.doc = docH.create("gdml", comment); + geo.doc = docH.create("gdml", docH.defaultComment()); geo.doc_root = geo.doc.root(); geo.doc_root.setAttr(Unicode("xmlns:xs"), "http://www.w3.org/2001/XMLSchema-instance"); geo.doc_root.setAttr(Unicode("xs:noNamespaceSchemaLocation"), @@ -1177,20 +1166,9 @@ xml_doc_t LCDDConverter::createVis(DetElement top) { collect(top, geo); printout(ALWAYS,"LCDDConverter","++ ==> Dump visualisation attributes " "from in memory detector description..."); - const char comment[] = "\n" - " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" - " ++++ Linear collider detector description LCDD in C++ ++++\n" - " ++++ DD4hep Detector description generator. ++++\n" - " ++++ ++++\n" - " ++++ Parser:" - XML_IMPLEMENTATION_TYPE - " ++++\n" - " ++++ ++++\n" - " ++++ M.Frank CERN/LHCb ++++\n" - " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n "; XML::DocumentHandler docH; xml_elt_t elt(0); - geo.doc = docH.create("visualization", comment); + geo.doc = docH.create("visualization", docH.defaultComment()); geo.doc_root = geo.doc.root(); geo.doc_root.append(geo.doc_display = xml_elt_t(geo.doc, _U(display))); geo.doc_root.append(geo.doc_structure = xml_elt_t(geo.doc, _U(structure))); @@ -1211,21 +1189,10 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) { GeometryInfo& geo = *(m_dataPtr = new GeometryInfo); m_data->clear(); collect(top, geo); - const char comment[] = "\n" - " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" - " ++++ Linear collider detector description LCDD in C++ ++++\n" - " ++++ DD4hep Detector description generator. ++++\n" - " ++++ ++++\n" - " ++++ Parser:" - XML_IMPLEMENTATION_TYPE - " ++++\n" - " ++++ ++++\n" - " ++++ M.Frank CERN/LHCb ++++\n" - " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n "; XML::DocumentHandler docH; xml_elt_t elt(0); Volume world_vol = lcdd.worldVolume(); - geo.doc = docH.create("lcdd", comment); + geo.doc = docH.create("lcdd", docH.defaultComment()); geo.doc_root = geo.doc.root(); geo.doc_root.setAttr(Unicode("xmlns:lcdd"), "http://www.lcsim.org/schemas/lcdd/1.0"); geo.doc_root.setAttr(Unicode("xmlns:xs"), "http://www.w3.org/2001/XMLSchema-instance"); diff --git a/DDCore/src/plugins/LCDDHelperTest.cpp b/DDCore/src/plugins/LCDDHelperTest.cpp index c45adbfb1..60b41f430 100644 --- a/DDCore/src/plugins/LCDDHelperTest.cpp +++ b/DDCore/src/plugins/LCDDHelperTest.cpp @@ -1,4 +1,3 @@ -// $Id: $ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/plugins/LCDDSegmentations.cpp b/DDCore/src/plugins/LCDDSegmentations.cpp index 0a60bc95c..29ea51e44 100644 --- a/DDCore/src/plugins/LCDDSegmentations.cpp +++ b/DDCore/src/plugins/LCDDSegmentations.cpp @@ -1,4 +1,3 @@ -// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- diff --git a/DDCore/src/plugins/PandoraConverter.cpp b/DDCore/src/plugins/PandoraConverter.cpp index eec6d4500..57cbb9977 100644 --- a/DDCore/src/plugins/PandoraConverter.cpp +++ b/DDCore/src/plugins/PandoraConverter.cpp @@ -10,8 +10,6 @@ // Author : M.Frank // //========================================================================== - -// $Id$ #ifndef DD4HEP_GEOMETRY_PANDORACONVERTER_H #define DD4HEP_GEOMETRY_PANDORACONVERTER_H @@ -67,14 +65,18 @@ namespace DD4hep { } // End namespace DD4hep #endif // DD4HEP_GEOMETRY_PANDORACONVERTER_H -//==================================================================== +//========================================================================== // AIDA Detector description implementation for LCD -//-------------------------------------------------------------------- +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. // -// Author : M.Frank +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. // -//==================================================================== -// $Id$ +// Author : M.Frank +// +//========================================================================== // Framework includes #include "DD4hep/LCDD.h" diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp index 8d23343a7..62e45ba4a 100644 --- a/DDCore/src/plugins/StandardPlugins.cpp +++ b/DDCore/src/plugins/StandardPlugins.cpp @@ -91,14 +91,9 @@ DECLARE_APPLY(DD4hepGeometryDisplay,display) * \date 01/04/2014 */ static long run_interpreter(LCDD& /* lcdd */, int argc, char** argv) { - if ( argc > 0 ) { - pair<int, char**> a(argc,argv); - } - else { - pair<int, char**> a(0,0); - TRint app("DD4hep", &a.first, a.second); - app.Run(); - } + pair<int, char**> a(argc,argv); + TRint app("DD4hep", &a.first, a.second); + app.Run(); return 1; } DECLARE_APPLY(DD4hepRint,run_interpreter) @@ -537,17 +532,20 @@ static long dump_volume_tree(LCDD& lcdd, int argc, char** argv) { typedef PlacedVolume::VolID VID; typedef PlacedVolume::VolIDs VIDs; bool m_printVolIDs; + bool m_printPointers; bool m_printPositions; bool m_printSensitivesOnly; Actor(int ac, char** av) - : m_printVolIDs(false), m_printPositions(false), m_printSensitivesOnly(false) + : m_printVolIDs(false), m_printPointers(false), m_printPositions(false), m_printSensitivesOnly(false) { for(int i=0; i<ac; ++i) { char c = ::tolower(av[i][0]); - if ( c == '-' ) c = ::tolower(av[i][1]); - if ( c == 'v' ) m_printVolIDs = true; - else if ( c == 'p' ) m_printPositions = true; - else if ( c == 's' ) m_printSensitivesOnly = true; + char* p = av[i]; + if ( c == '-' ) { ++p; c = ::tolower(av[i][1]); } + if ( ::strncmp(p,"volume_ids",3)==0 ) m_printVolIDs = true; + else if ( ::strncmp(p,"positions",3)==0 ) m_printPositions = true; + else if ( ::strncmp(p,"pointers",3)==0 ) m_printPointers = true; + else if ( ::strncmp(p,"sensitive",3)==0 ) m_printSensitivesOnly = true; } } @@ -558,6 +556,13 @@ static long dump_volume_tree(LCDD& lcdd, int argc, char** argv) { bool sensitive = false; if ( m_printPositions || m_printVolIDs ) { stringstream log; + if ( m_printPointers ) { + if ( ideal != aligned ) + ::snprintf(fmt,sizeof(fmt),"Ideal:%p Aligned:%p ",(void*)ideal,(void*)aligned); + else + ::snprintf(fmt,sizeof(fmt),"Ideal:%p ",(void*)ideal); + log << fmt; + } // Top level volume! have no volume ids if ( m_printVolIDs && ideal && ideal->GetMotherVolume() ) { VIDs vid = pv.volIDs(); @@ -592,13 +597,25 @@ static long dump_volume_tree(LCDD& lcdd, int argc, char** argv) { TGeoVolume* volume = ideal->GetVolume(); if ( !m_printSensitivesOnly || (m_printSensitivesOnly && sensitive) ) { char sens = pv.volume().isSensitive() ? 'S' : ' '; - if ( ideal == aligned ) { - ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%-16s (%%s) \t[%p] %c %%s", - level+1,2*level+1,(void*)ideal, sens); + if ( m_printPointers ) { + if ( ideal == aligned ) { + ::snprintf(fmt,sizeof(fmt),"%03d [Ideal:%p] %%-%ds %%-16s (%%s) \t %c %%s", + level+1,(void*)ideal,2*level+1,sens); + } + else { + ::snprintf(fmt,sizeof(fmt),"%03d Ideal:%p Aligned:%p %%-%ds %%-16s (%%s) %c %%s", + level+1,(void*)ideal,(void*)aligned,2*level+1,sens); + } } else { - ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%-16s (%%s) Ideal:%p Aligned:%p %c %%s", - level+1,2*level+1,(void*)ideal,(void*)aligned, sens); + if ( ideal == aligned ) { + ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%-16s (%%s) \t %c %%s", + level+1,2*level+1,sens); + } + else { + ::snprintf(fmt,sizeof(fmt),"%03d Ideal:%p Aligned:%p %%-%ds %%-16s (%%s) %c %%s", + level+1,(void*)ideal,(void*)aligned,2*level+1,sens); + } } printout(INFO,"VolumeDump",fmt,"", aligned->GetName(), @@ -695,16 +712,28 @@ template <int flag> long dump_detelement_tree(LCDD& lcdd, int argc, char** argv) char fmt[128]; switch(value) { case 0: - ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%s NumDau:%%d VolID:%%08X Place:%%p %%c",level+1,2*level+1); + if ( de.placement() == de.idealPlacement() ) { + ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%s NumDau:%%d VolID:%%08X Place:%%p %%c",level+1,2*level+1); + printout(INFO,"DetectorDump",fmt,"",de.path().c_str(),int(c.size()), + (unsigned long)de.volumeID(), (void*)node, sens); + break; + } + ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds %%s NumDau:%%d VolID:%%08X Place:%%p [ideal:%%p aligned:%%p] %%c",level+1,2*level+1); printout(INFO,"DetectorDump",fmt,"",de.path().c_str(),int(c.size()), - (unsigned long)de.volumeID(), (void*)node, sens); + (unsigned long)de.volumeID(), (void*)de.idealPlacement().ptr(), (void*)node, sens); break; case 1: ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds Detector: %%s NumDau:%%d VolID:%%p",level+1,2*level+1); printout(INFO,"DetectorDump", fmt, "", de.path().c_str(), int(c.size()), (void*)de.volumeID()); - ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds Placement: %%s %%c",level+1,2*level+3); - printout(INFO,"DetectorDump",fmt,"", de.placementPath().c_str(), sens); + if ( de.placement() == de.idealPlacement() ) { + ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds Placement: %%s %%c",level+1,2*level+3); + printout(INFO,"DetectorDump",fmt,"", de.placementPath().c_str(), sens); + break; + } + ::snprintf(fmt,sizeof(fmt),"%03d %%-%ds Placement: %%s [ideal:%%p aligned:%%p] %%c",level+1,2*level+3); + printout(INFO,"DetectorDump",fmt,"", de.placementPath().c_str(), + (void*)de.idealPlacement().ptr(), (void*)node, sens); break; default: break; diff --git a/DDDB/src/DDDBAlignmentTest.cpp b/DDDB/src/DDDBAlignmentTest.cpp index d92dace53..8e518ca6c 100644 --- a/DDDB/src/DDDBAlignmentTest.cpp +++ b/DDDB/src/DDDBAlignmentTest.cpp @@ -51,6 +51,7 @@ namespace { */ class AlignmentSelector { public: + ConditionsDependencyCollection dependencies; ConditionUpdateCall* updateCall; LCDD& lcdd; string m_name; @@ -72,14 +73,14 @@ namespace { releasePtr(updateCall); } /// Recursive alignment collector - long collect(DetElement de, dd4hep_ptr<UserPool>& user_pool, AlignmentsManager& am, int level) + long collect(DetElement de, ConditionsSlice& slice, int level) { char fmt[64]; try { DDDB::Catalog* cat = de.extension<DDDB::Catalog>(); if ( !cat->condition.empty() ) { ConditionKey key(cat->condition); - Condition cond = user_pool->get(key.hash); + Condition cond = slice.pool->get(key.hash); if ( cond.isValid() ) { ConditionKey k(cat->condition+"/Tranformations"); // @@ -95,7 +96,9 @@ namespace { DependencyBuilder b(k, updateCall); b->detector = de; b.add(ConditionKey(cond->value)); - am.adoptDependency(b.release()); + ConditionDependency* dep = b.release(); + dependencies.insert(dep); + slice.insert(dep); ++m_installCount; } else { @@ -115,14 +118,14 @@ namespace { } const DetElement::Children& c = de.children(); for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i) - collect((*i).second, user_pool, am, level+1); + collect((*i).second, slice, level+1); return 1; } /// Initial collector call - long collect(ConditionsManager manager, AlignmentsManager& context, const IOV& iov) { + long collect(ConditionsManager manager, const IOV& iov) { dd4hep_ptr<ConditionsSlice> slice(createSlice(manager,*iov.iovType)); manager.prepare(iov, *slice); - int res = collect(lcdd.world(), slice->pool, context, 0); + int res = collect(lcdd.world(), *slice, 0); return res; } /// Compute dependent alignment conditions @@ -132,16 +135,17 @@ namespace { const IOV& iov) { slice.adopt(createSlice(conds,*iov.iovType)); + slice->insert(dependencies); TTimeStamp acc_start; ConditionsManager::Result cres = conds.prepare(iov, *slice); TTimeStamp acc_stop; acc_stat.Fill(acc_stop.AsDouble()-acc_start.AsDouble()); TTimeStamp comp_start; - AlignmentsManager::Result ares = align.compute(*slice->pool); + AlignmentsManager::Result ares = align.compute(*slice); TTimeStamp comp_stop; comp_stat.Fill(comp_stop.AsDouble()-comp_start.AsDouble()); printout(INFO,"DDDBAlign", - "++ AlignmentManager: %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) (A:%ld,M:%ld) for IOV:%-12s", + "++ AlignmentManager: %7ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) (A:%ld,M:%ld) for IOV:%-12s", cres.total(), cres.selected, cres.loaded, cres.computed, cres.missing, ares.computed, ares.missing, iov.str().c_str()); return 1; @@ -150,10 +154,10 @@ namespace { int access(ConditionsManager conds,AlignmentsManager align, const IOV& iov) { typedef ConditionsDependencyCollection Deps; dd4hep_ptr<ConditionsSlice> slice; - int ret = computeDependencies(slice, conds, align, iov); + int ret = computeDependencies(slice, conds, align, iov); if ( ret == 1 ) { - const Deps& deps = align.knownDependencies(); + const Deps& deps = dependencies; int count = 0; for(Deps::const_iterator i=deps.begin(); i!=deps.end(); ++i) { const ConditionDependency* d = (*i).second.get(); @@ -234,7 +238,7 @@ namespace { { TTimeStamp start; IOV iov(iovType, time); - ret = selec.collect(conds,align,iov); + ret = selec.collect(conds,iov); TTimeStamp stop; cr_stat.Fill(stop.AsDouble()-start.AsDouble()); } @@ -249,7 +253,7 @@ namespace { TTimeStamp stop; re_acc_stat.Fill(stop.AsDouble()-start.AsDouble()); printout(INFO,"DDDBAlign", - "++ REACCESS: %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) for IOV:%-12s", + "++ REACCESS: %7ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) for IOV:%-12s", cres.total(), cres.selected, cres.loaded, cres.computed, cres.missing, iov.str().c_str()); } } @@ -303,7 +307,7 @@ namespace { ConditionsManager conds(ConditionsManager::from(lcdd)); const IOVType* iovType = conds.iovType("epoch"); IOV iov(iovType, time); - int ret = selec.collect(conds,align,iov); + int ret = selec.collect(conds,iov); if ( ret == 1 ) { ret = selec.access(conds,align,iov); } @@ -312,3 +316,4 @@ namespace { } /* End anonymous namespace */ DECLARE_APPLY(DDDB_AlignmentsAccessTest,dddb_access_alignments) //========================================================================== + diff --git a/DDDB/src/DDDBAlignmentTestEx.cpp b/DDDB/src/DDDBAlignmentTestEx.cpp index d17f772b6..65b398df3 100644 --- a/DDDB/src/DDDBAlignmentTestEx.cpp +++ b/DDDB/src/DDDBAlignmentTestEx.cpp @@ -169,7 +169,7 @@ namespace { TTimeStamp acc_stop; acc_stat.Fill(acc_stop.AsDouble()-acc_start.AsDouble()); TTimeStamp comp_start; - AlignmentsManager::Result ares = align.compute(*slice->pool); + AlignmentsManager::Result ares = align.compute(*slice); TTimeStamp comp_stop; comp_stat.Fill(comp_stop.AsDouble()-comp_start.AsDouble()); printout(INFO,"DDDBAlign", diff --git a/UtilityApps/src/run_plugin.h b/UtilityApps/src/run_plugin.h index cfe5ddea8..245707614 100644 --- a/UtilityApps/src/run_plugin.h +++ b/UtilityApps/src/run_plugin.h @@ -267,7 +267,7 @@ namespace { LCDD& lcdd = dd4hep_instance(); // Load all compact files load_compact(lcdd, args); - if ( args.ui ) run_plugin(lcdd,"DD4hepROOTUI",0,0); + if ( args.ui ) run_plugin(lcdd,"DD4hepInteractiveUI",0,0); // Create volume manager and populate it required if ( args.volmgr ) run_plugin(lcdd,"DD4hepVolumeManager",0,0); diff --git a/examples/AlignDet/compact/AlephTPC_reset.xml b/examples/AlignDet/compact/AlephTPC_reset.xml index 98ea4111b..0aeb0e41e 100644 --- a/examples/AlignDet/compact/AlephTPC_reset.xml +++ b/examples/AlignDet/compact/AlephTPC_reset.xml @@ -8,8 +8,10 @@ --> <detelement path="TPC" reset="false"> <detelement path="/world/TPC/TPC_SideA" reset="true" reset_children="false"> +<!-- <position x="0" y="0" z="0"/> <rotation x="-0.25" y="0" z="0"/> +--> </detelement> <!-- <detelement path="/world/TPC/TPC_SideA/TPC_SideA_sector05" reset="true"/> diff --git a/examples/AlignDet/compact/AlephTPC_reset_all.xml b/examples/AlignDet/compact/AlephTPC_reset_all.xml new file mode 100644 index 000000000..c8a341956 --- /dev/null +++ b/examples/AlignDet/compact/AlephTPC_reset_all.xml @@ -0,0 +1,12 @@ +<global_alignment print="true"> + <open_transaction/> + <subdetectors> + <!-- + Note: The subdetector name MUST be in the list of top level + detector elements attached to the LCDD structure. + + --> + <detelement path="TPC" reset="true" reset_children="true"/> + </subdetectors> + <close_transaction/> +</global_alignment> diff --git a/examples/AlignDet/src/AlignmentExampleObjects.cpp b/examples/AlignDet/src/AlignmentExampleObjects.cpp index 5b49640ac..526a954da 100644 --- a/examples/AlignDet/src/AlignmentExampleObjects.cpp +++ b/examples/AlignDet/src/AlignmentExampleObjects.cpp @@ -12,15 +12,20 @@ //========================================================================== // Framework include files +#include "DD4hep/AlignmentsPrinter.h" #include "AlignmentExampleObjects.h" #include "DD4hep/DD4hepUnits.h" -#include "DD4hep/AlignmentsPrinter.h" +#include "DD4hep/Objects.h" + +#include "DDAlign/DDAlignResetCall.h" #include "DDAlign/DDAlignUpdateCall.h" #include "DDAlign/DDAlignForwardCall.h" #include "DDAlign/AlignmentsRegister.h" #include "DDAlign/AlignmentsForward.h" +#include "DDAlign/AlignmentsReset.h" #include "DDCond/ConditionsSlice.h" + using namespace std; using namespace DD4hep; using namespace DD4hep::AlignmentExamples; @@ -34,23 +39,33 @@ void DD4hep::AlignmentExamples::installManagers(LCDD& lcdd) { } /// Register the alignment callbacks -void DD4hep::AlignmentExamples::registerAlignmentCallbacks(LCDD& lcdd, - ConditionsSlice& slice, - AlignmentsManager alignMgr) +void DD4hep::AlignmentExamples::registerAlignmentCallbacks(LCDD& lcdd,ConditionsSlice& slice) { // 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(),slice.pool.get()); + Alignments::AlignmentsRegister reg(slice,new Alignments::DDAlignUpdateCall()); Scanner().scan(reg,lcdd.world()); // 2) Create child dependencies if higher level alignments exist - Alignments::AlignmentsForward fwd(alignMgr,new Alignments::DDAlignForwardCall(),slice.pool.get()); + Alignments::AlignmentsForward fwd(slice,new Alignments::DDAlignForwardCall()); + Scanner().scan(fwd,lcdd.world()); +} + +/// Register the alignment callbacks +void DD4hep::AlignmentExamples::registerResetCallbacks(LCDD& lcdd,ConditionsSlice& slice) +{ + // Let's register the callbacks to compute dependent conditions/alignments + // 1) Create dependencies for all deltas found in the conditions + Alignments::AlignmentsReset reg(slice,new Alignments::DDAlignResetCall()); + Scanner().scan(reg,lcdd.world()); + // 2) Create child dependencies if higher level alignments exist + Alignments::AlignmentsForward fwd(slice,new Alignments::DDAlignForwardCall()); 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(); + Alignments::Container container = a.alignments(); // Let's go for the deltas.... for(const auto& k : container.keys() ) { Alignment align = container.get(k.first,pool); @@ -63,6 +78,31 @@ int AlignmentDataAccess::processElement(DetElement de) { return 1; } +/// Callback to process a single detector element +int AlignmentReset::processElement(DetElement de) { + DetAlign a(de); // Use special facade... + Alignments::Container container = a.alignments(); + + for(const auto& k : container.keys() ) { + Alignment align = container.get(k.first,pool); + AlignmentData& data = align.data(); + Delta& delta = data.delta; + // Leave the flags to get the proper printout! + //delta.flags &= ~(Delta::HAVE_TRANSLATION|Delta::HAVE_ROTATION|Delta::HAVE_PIVOT); + delta.translation = Geometry::Position(); + delta.rotation = Geometry::RotationZYX(); + delta.pivot = Delta::Pivot(); + data.worldDelta = *Geometry::identityTransform(); + data.worldTrafo = *Geometry::identityTransform(); + data.detectorTrafo = *Geometry::identityTransform(); + data.trToWorld = Geometry::Transform3D(); + data.nodes.clear(); + } + printout(printLevel,"Example","++ Reset alignment deltas for %s [%d keys]", + de.path().c_str(), int(container.keys().size())); + return 1; +} + /// Callback to process a single detector element int AlignmentCreator::operator()(DetElement de, int) { if ( de.ptr() != de.world().ptr() ) { diff --git a/examples/AlignDet/src/AlignmentExampleObjects.h b/examples/AlignDet/src/AlignmentExampleObjects.h index 18299ecf6..e35ccee7e 100644 --- a/examples/AlignDet/src/AlignmentExampleObjects.h +++ b/examples/AlignDet/src/AlignmentExampleObjects.h @@ -51,6 +51,7 @@ namespace DD4hep { using Alignments::Delta; using Alignments::DetAlign; using Alignments::Alignment; + using Alignments::AlignmentData; using Alignments::AlignmentsManager; /// Example how to populate the detector description with alignment constants @@ -62,7 +63,9 @@ namespace DD4hep { * \date 01/04/2016 */ struct AlignmentCreator : public DetectorProcessor { + /// Reference to the conditions manager ConditionsManager manager; + /// Reference to the used conditions pool ConditionsPool* pool; /// Print level PrintLevel printLevel; @@ -73,7 +76,7 @@ namespace DD4hep { virtual int operator()(DetElement de, int level); }; - // This is important, otherwise the register and forward calls won't find them! + /// This is important, otherwise the register and forward calls won't find them! /** * \author M.Frank * \version 1.0 @@ -93,17 +96,34 @@ namespace DD4hep { * \date 01/04/2016 */ struct AlignmentDataAccess : public Alignments::AlignmentsProcessor { - UserPool& pool; + /// Reference to the used conditions pool + UserPool& pool; /// Print level - PrintLevel printLevel; + PrintLevel printLevel; /// Constructor - AlignmentDataAccess(UserPool& p) : AlignmentsProcessor(0), pool(p), - printLevel(DEBUG) { - } + AlignmentDataAccess(UserPool& p) : AlignmentsProcessor(0), pool(p), printLevel(DEBUG) {} /// Callback to process a single detector element int processElement(DetElement de); }; + /// Reset all alignment deltas of the detector elements scanned + /** + * \author M.Frank + * \version 1.0 + * \date 01/04/2016 + */ + struct AlignmentReset : public Alignments::AlignmentsProcessor { + /// Reference to the used conditions pool + UserPool& pool; + /// Print level + PrintLevel printLevel; + /// Constructor + AlignmentReset(UserPool& p,PrintLevel pr=INFO) + : AlignmentsProcessor(0), pool(p), printLevel(pr) {} + /// Callback to process a single detector element + virtual int processElement(DetElement de); + }; + /// Helper to run DetElement scans /** * \author M.Frank @@ -113,20 +133,29 @@ namespace DD4hep { 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; } + 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& scan(const Q& p, DetElement start) { + Scanner obj; + Q* q = const_cast<Q*>(&p); + obj.proc = q; + 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); + void registerAlignmentCallbacks(LCDD& lcdd, ConditionsSlice& slice); + /// Register the alignment callbacks + void registerResetCallbacks(LCDD& lcdd, ConditionsSlice& slice); } /* End namespace AlignmentExamples */ diff --git a/examples/AlignDet/src/AlignmentExample_populate.cpp b/examples/AlignDet/src/AlignmentExample_populate.cpp index 49df9efbf..1dde1c0b6 100644 --- a/examples/AlignDet/src/AlignmentExample_populate.cpp +++ b/examples/AlignDet/src/AlignmentExample_populate.cpp @@ -101,7 +101,7 @@ static int alignment_example (Geometry::LCDD& lcdd, int argc, char** argv) { // IOV iov(iov_typ,10+5); condMgr.prepare(iov,*slice); - registerAlignmentCallbacks(lcdd,*slice,alignMgr); + registerAlignmentCallbacks(lcdd,*slice); // ++++++++++++++++++++++++ Now compute the alignments for each of these IOVs for(int i=1; i<num_iov; ++i) { diff --git a/examples/AlignDet/src/AlignmentExample_read_xml.cpp b/examples/AlignDet/src/AlignmentExample_read_xml.cpp index fa882a6f3..227adf7b9 100644 --- a/examples/AlignDet/src/AlignmentExample_read_xml.cpp +++ b/examples/AlignDet/src/AlignmentExample_read_xml.cpp @@ -79,13 +79,13 @@ static int alignment_example (Geometry::LCDD& lcdd, int argc, char** argv) { ConditionsManager::Result cres = condMgr.prepare(req_iov,*slice); // ++++++++++++++++++++++++ We need a valid set of conditions to do this! - registerAlignmentCallbacks(lcdd,*slice,alignMgr); + registerAlignmentCallbacks(lcdd,*slice); // ++++++++++++++++++++++++ Compute the tranformation matrices AlignmentsManager::Result ares = alignMgr.compute(*slice); // What else ? let's access the data - Scanner().scan2(AlignmentDataAccess(*slice->pool),lcdd.world()); + Scanner().scan(AlignmentDataAccess(*slice->pool),lcdd.world()); // What else ? let's print the current selection Alignments::AlignedVolumePrinter printer(slice->pool.get(),"Example"); diff --git a/examples/AlignDet/src/AlignmentExample_recompute.cpp b/examples/AlignDet/src/AlignmentExample_recompute.cpp new file mode 100644 index 000000000..d9a6b6357 --- /dev/null +++ b/examples/AlignDet/src/AlignmentExample_recompute.cpp @@ -0,0 +1,122 @@ +//========================================================================== +// 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_recompute \ + -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_recompute + * + * \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_AlignmentExample_recompute \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_align(createSlice(condMgr,*iov_typ)); + ConditionsManager::Result cres_align = condMgr.prepare(req_iov,*slice_align); + + // ++++++++++++++++++++++++ We need a valid set of conditions to do this! + registerAlignmentCallbacks(lcdd,*slice_align); + + // ++++++++++++++++++++++++ Compute the tranformation matrices + AlignmentsManager::Result ares_align = alignMgr.compute(*slice_align); + + // What else ? let's access the data + Scanner().scan(AlignmentDataAccess(*slice_align->pool),lcdd.world()); + + // What else ? let's print the current selection + Alignments::AlignedVolumePrinter print_align(slice_align->pool.get(),"Example"); + Scanner().scan(print_align,lcdd.world()); + + // What else ? let's access the data + //Scanner().scan(AlignmentReset(*slice_align->pool,INFO),lcdd.world()); + // Print again the changed values + + // ++++++++++++++++++++++++ Compute the tranformation matrices + dd4hep_ptr<ConditionsSlice> slice_reset(createSlice(condMgr,*iov_typ)); + ConditionsManager::Result cres_reset = condMgr.prepare(req_iov,*slice_reset); + registerResetCallbacks(lcdd,*slice_reset); + AlignmentsManager::Result ares_reset = alignMgr.compute(*slice_reset); + Alignments::AlignedVolumePrinter print_reset(slice_reset->pool.get(),"Example"); + Scanner().scan(print_reset,lcdd.world()); + + printout(INFO,"Example", + "Setup %ld/%ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) (A:%ld,M:%ld) for IOV:%-12s", + slice_align->conditions().size(), + cres_align.total(), cres_align.selected, cres_align.loaded, cres_align.computed, cres_align.missing, + ares_align.computed, ares_align.missing, iov_typ->str().c_str()); + printout(INFO,"Example", + "Setup %ld/%ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) (A:%ld,M:%ld) for IOV:%-12s", + slice_reset->conditions().size(), + cres_reset.total(), cres_reset.selected, cres_reset.loaded, cres_reset.computed, cres_reset.missing, + ares_reset.computed, ares_reset.missing, iov_typ->str().c_str()); + + // ++++++++++++++++++++++++ All done. + return 1; +} + +// first argument is the type from the xml file +DECLARE_APPLY(DD4hep_AlignmentExample_recompute,alignment_example) diff --git a/examples/AlignDet/src/AlignmentExample_stress.cpp b/examples/AlignDet/src/AlignmentExample_stress.cpp index 113348170..009b57080 100644 --- a/examples/AlignDet/src/AlignmentExample_stress.cpp +++ b/examples/AlignDet/src/AlignmentExample_stress.cpp @@ -112,7 +112,7 @@ static int alignment_example (Geometry::LCDD& lcdd, int argc, char** argv) { // IOV iov(iov_typ,15); condMgr.prepare(iov,*slice); - registerAlignmentCallbacks(lcdd,*slice,alignMgr); + registerAlignmentCallbacks(lcdd,*slice); /******************** Compute alignments *******************************/ for(int i=0; i<num_iov; ++i) { diff --git a/examples/DDDB/CMakeLists.txt b/examples/DDDB/CMakeLists.txt index d5cccf8f3..83441d542 100644 --- a/examples/DDDB/CMakeLists.txt +++ b/examples/DDDB/CMakeLists.txt @@ -126,7 +126,7 @@ if (DD4HEP_USE_XERCESC) -config DD4hep_ConditionsManagerInstaller -config DD4hep_AlignmentsManagerInstaller -plugin DDDB_DerivedAlignmentsTest -print DEBUG - REGEX_PASS "AlignmentManager: 9353 conditions \\(S:0,L:9353,C:0,M:0\\) \\(A:2493,M:0\\)" ) + REGEX_PASS "AlignmentManager: 11848 conditions \\(S:0,L:9353,C:2495,M:0\\) \\(A:2493,M:0\\)" ) # #---Testing: Load the geometry + conditions + access derived alignments from DetElement structures dd4hep_add_test_reg( test_DDDB_alignment_access_LONGTEST -- GitLab