From d3b421c53772bc63d630579c279cc4aa9bd70ba4 Mon Sep 17 00:00:00 2001 From: Marko Petric <marko.petric@cern.ch> Date: Fri, 21 Feb 2020 11:14:29 +0100 Subject: [PATCH] Revert "dropped unused DDCore/src/AlignmentsCalculator.cpp.old" This reverts commit df0a9367f562df1ae3582f803849be6ba7f512b0. --- DDCore/src/AlignmentsCalculator.cpp.old | 291 ++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 DDCore/src/AlignmentsCalculator.cpp.old diff --git a/DDCore/src/AlignmentsCalculator.cpp.old b/DDCore/src/AlignmentsCalculator.cpp.old new file mode 100644 index 000000000..682f13459 --- /dev/null +++ b/DDCore/src/AlignmentsCalculator.cpp.old @@ -0,0 +1,291 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// 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 "DD4hep/AlignmentsCalculator.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Conditions.h" +#include "DD4hep/ConditionsMap.h" +#include "DD4hep/InstanceCount.h" +#include "DD4hep/MatrixHelpers.h" +#include "DD4hep/detail/AlignmentsInterna.h" + +using namespace dd4hep; +using namespace dd4hep::align; +typedef AlignmentsCalculator::Result Result; + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the alignment part of the AIDA detector description toolkit + namespace align { + + /// Anonymous implementation classes + namespace { + static Delta identity_delta; + + /// Alignment calculator. + /** + * Uses internally the conditions mechanism to calculator the alignment conditions. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_ALIGNMENTS + */ + class Calculator { + public: + class Entry; + class Context; + + public: + /// Initializing constructor + Calculator() = default; + /// Default destructor + ~Calculator() = default; + /// Compute the alignment delta for one detector element and it's alignment condition + void computeDelta(const Delta& delta, TGeoHMatrix& tr_delta) const; + /// Compute the transformation from the closest detector element of the alignment to the world system + Result to_world(Context& context, DetElement det, TGeoHMatrix& mat) const; + /// Compute all alignment conditions of the lower levels + Result compute(Context& context, Entry& entry) const; + /// Resolve child dependencies for a given context + void resolve(Context& context, DetElement child) const; + }; + + class Calculator::Entry { + public: + DetElement::Object* det = 0; + const Delta* delta = 0; + AlignmentCondition::Object* cond = 0; + unsigned char key = 0, valid = 0, created = 0, _pad[1]; + Entry(DetElement d, const Delta* del) : det(d.ptr()), delta(del), key(d.key()) {} + }; + + class Calculator::Context { + public: + struct PathOrdering { + bool operator()(const DetElement& a, const DetElement& b) const + { return a.path() < b.path(); } + }; + typedef std::map<DetElement,size_t,PathOrdering> DetectorMap; + typedef std::map<unsigned int,size_t> Keys; + typedef std::vector<Entry> Entries; + + DetectorMap detectors; + Keys keys; + Entries entries; + ConditionsMap& mapping; + Context(ConditionsMap& m) : mapping(m) { + InstanceCount::increment(this); + } + ~Context() { + InstanceCount::decrement(this); + } + void insert(DetElement det, const Delta* delta) { + if ( det.isValid() ) { + Entry entry(det,delta); + detectors.insert(std::make_pair(det, entries.size())); + keys.insert(std::make_pair(entry.key, entries.size())); + entries.insert(entries.end(), entry); + return; + } + except("AlignContext","Failed to add entry: invalid detector handle!"); + } + }; + } + } /* End namespace align */ +} /* End namespace dd4hep */ + +static PrintLevel s_PRINT = WARNING; +//static PrintLevel s_PRINT = INFO; + +Result Calculator::to_world(Context& context, + DetElement det, + TGeoHMatrix& delta_to_world) const +{ + Result result; + DetElement par = det.parent(); + + while( par.isValid() ) { + // Mapping creation mode: + // If we find that the parent also got updated, directly take this transformation. + // Since we compute top-down, it is already valid! + Context::Keys::const_iterator i = context.keys.find(par.key()); + if ( i != context.keys.end() ) { + Entry& e = context.entries[(*i).second]; + // The parent entry is (not yet) valid. need to compute it first + if ( 0 == e.valid ) { + result += compute(context, e); + } + 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(); + } + delta_to_world.MultiplyLeft(&align.worldDelta); + if ( s_PRINT <= INFO ) { + ::printf(" Result :"); delta_to_world.Print(); + } + ++result.computed; + return result; + } + // Mapping update mode: + // Check if there is already a transformation in the cache. If yes, take it. + // We assume it is a good one, because higher level changes are already processed. + AlignmentCondition cond = context.mapping.get(par,Keys::alignmentKey); + if ( cond.isValid() ) { + 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(); + } + delta_to_world.MultiplyLeft(&align.worldDelta); + if ( s_PRINT <= INFO ) { + ::printf(" Result :"); delta_to_world.Print(); + } + ++result.computed; + return result; + } + // 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()); + par.nominal().detectorTransformation().Print(); + } + delta_to_world.MultiplyLeft(&par.nominal().detectorTransformation()); + if ( s_PRINT <= INFO ) { + ::printf(" Result :"); delta_to_world.Print(); + } + par = par.parent(); + } + ++result.computed; + return result; +} + +/// Compute the alignment delta for one detector element and it's alignment condition +void Calculator::computeDelta(const Delta& delta, + TGeoHMatrix& tr_delta) const +{ + const Position& pos = delta.translation; + const Translation3D& piv = delta.pivot; + const RotationZYX& rot = delta.rotation; + + switch(delta.flags) { + case Delta::HAVE_TRANSLATION+Delta::HAVE_ROTATION+Delta::HAVE_PIVOT: + detail::matrix::_transform(tr_delta, Transform3D(Translation3D(pos)*piv*rot*(piv.Inverse()))); + break; + case Delta::HAVE_TRANSLATION+Delta::HAVE_ROTATION: + detail::matrix::_transform(tr_delta, Transform3D(rot,pos)); + break; + case Delta::HAVE_ROTATION+Delta::HAVE_PIVOT: + detail::matrix::_transform(tr_delta, Transform3D(piv*rot*(piv.Inverse()))); + break; + case Delta::HAVE_ROTATION: + detail::matrix::_transform(tr_delta, rot); + break; + case Delta::HAVE_TRANSLATION: + detail::matrix::_transform(tr_delta, pos); + break; + default: + break; + } +} + +/// Compute all alignment conditions of the lower levels +Result Calculator::compute(Context& context, Entry& e) const { + Result result; + DetElement det = e.det; + + if ( e.valid == 1 ) { + printout(DEBUG,"ComputeAlignment","================ IGNORE %s (already valid)",det.path().c_str()); + return result; + } + AlignmentCondition c = context.mapping.get(e.det, Keys::alignmentKey); + AlignmentCondition cond = c.isValid() ? c : AlignmentCondition("alignment"); + AlignmentData& align = cond.data(); + const Delta* delta = e.delta ? e.delta : &identity_delta; + TGeoHMatrix tr_delta; + + printout(DEBUG,"ComputeAlignment", + "============================== Compute transformation of %s",det.path().c_str()); + e.valid = 1; + e.cond = cond.ptr(); + computeDelta(*delta, tr_delta); + align.delta = *delta; + align.worldDelta = tr_delta; + result += to_world(context, det, align.worldDelta); + align.worldTrafo = det.nominal().worldTransformation()*align.worldDelta; + align.detectorTrafo = det.nominal().detectorTransformation()*tr_delta; + align.trToWorld = detail::matrix::_transform(&align.worldDelta); + // Update mapping if the condition is freshly created + if ( !c.isValid() ) { + e.created = 1; + cond->hash = ConditionKey(e.det,Keys::alignmentKey).hash; + context.mapping.insert(e.det, Keys::alignmentKey, cond); + } + if ( s_PRINT <= INFO ) { + printout(INFO,"ComputeAlignment","Level:%d Path:%s DetKey:%08X: Cond:%s key:%16llX", + det.level(), det.path().c_str(), det.key(), + yes_no(e.delta != 0), (long long int)cond.key()); + if ( s_PRINT <= DEBUG ) { + ::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(); + } + } + return result; +} + +/// Resolve child dependencies for a given context +void Calculator::resolve(Context& context, DetElement detector) const { + auto children = detector.children(); + auto item = context.detectors.find(detector); + if ( item == context.detectors.end() ) context.insert(detector,0); + for(const auto& c : children ) + resolve(context, c.second); +} + +/// Compute all alignment conditions of the internal dependency list +Result AlignmentsCalculator::compute(const std::map<DetElement, Delta>& deltas, + ConditionsMap& alignments) const +{ + Result result; + Calculator obj; + Calculator::Context context(alignments); + // This is a tricky one. We absolutely need the detector elements ordered + // by their depth aka. the distance to /world. + // Unfortunately one cannot use the raw pointer of the DetElement here, + // But has to insert them in a map which is ordered by the DetElement path. + // + // Otherwise memory randomization gives us the wrong order and the + // corrections are calculated in the wrong order ie. not top -> down the + // hierarchy, but in "some" order depending on the pointer values! + // + std::map<DetElement,Delta,Calculator::Context::PathOrdering> ordered_deltas; + + for( const auto& i : deltas ) + ordered_deltas.insert(i); + + for( const auto& i : ordered_deltas ) + context.insert(i.first, &(i.second)); + for( const auto& i : ordered_deltas ) + obj.resolve(context,i.first); + for( auto& i : context.entries ) + result += obj.compute(context, i); + return result; +} -- GitLab