DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
AlignmentsCalculator.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 // Framework include files
15 #include <DD4hep/Printout.h>
16 #include <DD4hep/Conditions.h>
17 #include <DD4hep/ConditionsMap.h>
18 #include <DD4hep/InstanceCount.h>
19 #include <DD4hep/MatrixHelpers.h>
25 
26 using namespace dd4hep;
27 using namespace dd4hep::align;
29 
31 namespace dd4hep {
32 
34  namespace align {
35 
37  namespace {
38  static Delta identity_delta;
39 
41 
48  class Calculator {
49  public:
50  class Entry;
51  class Context;
52 
53  public:
55  Calculator() = default;
57  ~Calculator() = default;
59  Result compute(Context& context, Entry& entry) const;
61  void resolve(Context& context, DetElement child) const;
62  };
63 
64  class Calculator::Entry {
65  public:
67  const Delta* delta = 0;
69  unsigned char key = 0, valid = 0, created = 0, _pad[1] { 0 };
70  Entry(DetElement d, const Delta* del) : det(d.ptr()), delta(del), key(d.key()) {}
71  };
72 
73  class Calculator::Context {
74  public:
75  typedef std::map<DetElement,std::size_t,AlignmentsCalculator::PathOrdering> DetectorMap;
76  typedef std::map<unsigned int,std::size_t> Keys;
77  typedef std::vector<Entry> Entries;
78 
79  DetectorMap detectors;
81  Entries entries;
83  Context(ConditionsMap& m) : mapping(m) {
85  }
86  ~Context() {
88  }
89  void insert(DetElement det, const Delta* delta) {
90  if ( det.isValid() ) {
91  Entry entry(det,delta);
92  detectors.emplace(det, entries.size());
93  keys.emplace(entry.key, entries.size());
94  entries.emplace_back(entry);
95  return;
96  }
97  except("AlignContext","Failed to add entry: invalid detector handle!");
98  }
99  };
100  }
101  } /* End namespace align */
102 } /* End namespace dd4hep */
103 
104 //static PrintLevel s_PRINT = DEBUG;
105 //static PrintLevel s_PRINT = INFO;
106 static PrintLevel s_PRINT = WARNING;
107 
110  if ( de.isValid() ) {
112  Condition c = context.condition(key, false);
113  if ( c.isValid() ) {
114  const Delta& d = c.get<Delta>();
115  deltas.emplace(de,&d);
116  if ( iov ) iov->iov_intersection(c->iov->key());
117  }
118  return 1;
119  }
120  return 0;
121 }
122 
124 Result Calculator::compute(Context& context, Entry& e) const {
125  Result result;
126  DetElement det = e.det;
127 
128  if ( e.valid == 1 ) {
129  printout(DEBUG,"ComputeAlignment","================ IGNORE %s (already valid)",det.path().c_str());
130  return result;
131  }
132  AlignmentCondition c = context.mapping.get(det, Keys::alignmentKey);
133  AlignmentCondition cond = c.isValid() ? c : AlignmentCondition(det.path()+"#alignment");
134  AlignmentData& align = cond.data();
135  const Delta* delta = e.delta ? e.delta : &identity_delta;
136  TGeoHMatrix transform_for_delta;
137 
138  printout(DEBUG,"ComputeAlignment",
139  "============================== Compute transformation of %s",det.path().c_str());
140  e.valid = 1;
141  e.cond = cond.ptr();
142  align.delta = *delta;
143  delta->computeMatrix(transform_for_delta);
144  result.multiply += 2;
145 
146  DetElement parent_det = det.parent();
147  AlignmentCondition parent_cond = context.mapping.get(parent_det, Keys::alignmentKey);
148  TGeoHMatrix parent_transform;
149  if (parent_cond.isValid()) {
150  AlignmentData& parent_align = parent_cond.data();
151  parent_transform = parent_align.worldTrafo;
152  }
153  else if ( det.parent().isValid() ) {
154  parent_transform = parent_det.nominal().worldTransformation();
155  }
156  else {
157  // The tranformation from the "world" to its parent is non-existing i.e. unity
158  }
159 
160  align.detectorTrafo = det.nominal().detectorTransformation() * transform_for_delta;
161  align.worldTrafo = parent_transform * align.detectorTrafo;
163  ++result.computed;
164  result.multiply += 3;
165  // Update mapping if the condition is freshly created
166  if ( !c.isValid() ) {
167  e.created = 1;
169  cond->hash = ConditionKey(e.det,Keys::alignmentKey).hash;
170  context.mapping.insert(e.det, Keys::alignmentKey, cond);
171  }
172  if ( s_PRINT <= INFO ) {
173  printout(INFO,"ComputeAlignment","Level:%d Path:%s DetKey:%08X: Cond:%s key:%16llX",
174  det.level(), det.path().c_str(), det.key(),
175  yes_no(e.delta != 0), (long long int)cond.key());
176  if ( s_PRINT <= DEBUG ) {
177  ::printf("Nominal: '%s' ", det.path().c_str());
178  det.nominal().worldTransformation().Print();
179  ::printf("Parent: '%s' -> '%s' ", det.path().c_str(), parent_det.path().c_str());
180  parent_transform.Print();
181  ::printf("DetectorTrafo: '%s' -> '%s' ", det.path().c_str(), det.parent().path().c_str());
182  det.nominal().detectorTransformation().Print();
183  ::printf("Delta: '%s' ", det.path().c_str());
184  transform_for_delta.Print();
185  ::printf("Result: '%s' ", det.path().c_str());
186  align.worldTrafo.Print();
187  }
188  }
189  return result;
190 }
191 
193 void Calculator::resolve(Context& context, DetElement detector) const {
194  auto children = detector.children();
195  auto item = context.detectors.find(detector);
196  if ( item == context.detectors.end() ) context.insert(detector,0);
197  for(const auto& c : children )
198  resolve(context, c.second);
199 }
200 
203  ConditionsMap& alignments) const
204 {
205  Result result;
206  Calculator obj;
207  Calculator::Context context(alignments);
208  for( const auto& i : deltas )
209  context.insert(i.first, i.second);
210  for( const auto& i : deltas )
211  obj.resolve(context,i.first);
212  for( auto& i : context.entries )
213  result += obj.compute(context, i);
214  return result;
215 }
216 
218 Result AlignmentsCalculator::compute(const std::map<DetElement, Delta>& deltas,
219  ConditionsMap& alignments) const
220 {
221  Calculator::Context context(alignments);
222  // This is a tricky one. We absolutely need the detector elements ordered
223  // by their depth aka. the distance to /world.
224  // Unfortunately one cannot use the raw pointer of the DetElement here,
225  // But has to insert them in a map which is ordered by the DetElement path.
226  //
227  // Otherwise memory randomization gives us the wrong order and the
228  // corrections are calculated in the wrong order ie. not top -> down the
229  // hierarchy, but in "some" order depending on the pointer values!
230  //
231  OrderedDeltas ordered_deltas;
232  for( const auto& i : deltas )
233  ordered_deltas.emplace(i.first, &i.second);
234  return compute(ordered_deltas, alignments);
235 }
236 
238 Result AlignmentsCalculator::compute(const std::map<DetElement, const Delta*>& deltas,
239  ConditionsMap& alignments) const
240 {
241  Calculator::Context context(alignments);
242  // This is a tricky one. We absolutely need the detector elements ordered
243  // by their depth aka. the distance to /world.
244  // Unfortunately one cannot use the raw pointer of the DetElement here,
245  // But has to insert them in a map which is ordered by the DetElement path.
246  //
247  // Otherwise memory randomization gives us the wrong order and the
248  // corrections are calculated in the wrong order ie. not top -> down the
249  // hierarchy, but in "some" order depending on the pointer values!
250  //
251  OrderedDeltas ordered_deltas;
252  for( const auto& i : deltas )
253  ordered_deltas.insert(i);
254  return compute(ordered_deltas, alignments);
255 }
256 
259  ExtractContext& extract_context,
260  OrderedDeltas& deltas,
261  IOV* effective_iov) const
262 {
263  return extract_deltas(ctxt.world(), ctxt, extract_context, deltas, effective_iov);
264 }
265 
269  ExtractContext& extract_context,
270  OrderedDeltas& deltas,
271  IOV* effective_iov) const
272 {
273  if ( !extract_context.empty() ) {
274  struct DeltaScanner : public Condition::Processor {
275  OrderedDeltas& delta_conditions;
276  ExtractContext& extract_context;
277  IOV* effective_iov = 0;
279  DeltaScanner(OrderedDeltas& d, ExtractContext& e, IOV* eff_iov)
280  : delta_conditions(d), extract_context(e), effective_iov(eff_iov) {}
282  virtual int process(Condition c) const override {
283  ConditionKey::KeyMaker key_maker(c->hash);
284  if ( key_maker.values.item_key == align::Keys::deltaKey ) {
285  auto idd = extract_context.find(key_maker.values.det_key);
286  if ( idd != extract_context.end() ) {
287  const Delta& d = c.get<Delta>();
288  DetElement de = idd->second;
289  delta_conditions.emplace(de,&d);
290  if (effective_iov) effective_iov->iov_intersection(c->iov->key());
291  return 1;
292  }
293  // Fatal or not? Depends if the context should be re-usable or the projection
294  //except("extract_deltas","++ Inconsistency between extraction context and conditions content!!");
295  }
296  return 0;
297  }
298  };
299  DeltaScanner scanner(deltas,extract_context,effective_iov);
300  ctxt.resolver->conditionsMap().scan(scanner);
301  return deltas.size();
302  }
303  DetectorScanner().scan(AlignmentsCalculator::Scanner(ctxt,deltas,effective_iov),start);
304  for( const auto& d : deltas ) extract_context.emplace(d.first.key(), d.first);
305  return deltas.size();
306 }
307 
310  OrderedDeltas& deltas,
311  IOV* effective_iov) const
312 {
313  return extract_deltas(ctxt.world(), ctxt, deltas, effective_iov);
314 }
315 
316 
320  OrderedDeltas& deltas,
321  IOV* effective_iov) const
322 {
323  DetectorScanner().scan(AlignmentsCalculator::Scanner(ctxt,deltas,effective_iov),start);
324  return deltas.size();
325 }
326 
327 #include <DD4hep/GrammarUnparsed.h>
328 static auto s_registry = GrammarRegistry::pre_note<AlignmentsCalculator::OrderedDeltas>(1);
dd4hep::IOV::iov_intersection
void iov_intersection(const IOV &comparator)
Set the intersection of this IOV with the argument IOV.
Definition: IOV.cpp:99
dd4hep::DetElement::children
const Children & children() const
Access to the list of children.
Definition: DetElement.cpp:207
dd4hep::DetElement::path
const std::string & path() const
Path of the detector element (not necessarily identical to placement path!)
Definition: DetElement.cpp:158
Result
AlignmentsCalculator::Result Result
Definition: AlignmentsCalculator.cpp:28
AlignmentsCalculator.h
cond
AlignmentCondition::Object * cond
Definition: AlignmentsCalculator.cpp:68
dd4hep::DetectorScanner
Helper to run DetElement scans.
Definition: DetectorProcessor.h:173
DetectorProcessor.h
dd4hep::DetElement::key
unsigned int key() const
Access hash key of this detector element (Only valid once geometry is closed!)
Definition: DetElement.cpp:134
dd4hep::cond::ConditionResolver::conditionsMap
virtual ConditionsMap & conditionsMap() const =0
Accessor for the current conditons mapping.
dd4hep::Handle< DetElementObject >::Object
DetElementObject Object
Extern accessible definition of the contained element type.
Definition: Handle.h:88
MatrixHelpers.h
dd4hep::ConditionsMap::scan
virtual void scan(const Condition::Processor &processor) const =0
Interface to scan data content of the conditions mapping.
dd4hep::cond::ConditionUpdateContext::resolver
ConditionResolver * resolver
Internal reference to the resolver to access other conditions (Be careful)
Definition: ConditionDerived.h:139
dd4hep::AlignmentCondition
Main handle class to hold an alignment conditions object.
Definition: Alignments.h:68
dd4hep::align::AlignmentsCalculator::OrderedDeltas
std::map< DetElement, const Delta *, PathOrdering > OrderedDeltas
Definition: AlignmentsCalculator.h:75
created
unsigned char created
Definition: AlignmentsCalculator.cpp:69
dd4hep::align::AlignmentsCalculator::extract_deltas
size_t extract_deltas(cond::ConditionUpdateContext &context, OrderedDeltas &deltas, IOV *effective_iov=0) const
Helper: Extract all Delta-conditions from the conditions map.
Definition: AlignmentsCalculator.cpp:309
dd4hep::ConditionKey::hash
Condition::key_type hash
Hashed key representation.
Definition: Conditions.h:287
Entry
GlobalAlignmentStack::StackEntry Entry
Definition: GlobalAlignmentCache.cpp:25
delta
const Delta * delta
Definition: AlignmentsCalculator.cpp:67
dd4hep::align::AlignmentsCalculator::Scanner::context
cond::ConditionUpdateContext & context
Reference to the user pool taking into account IOV intersections.
Definition: AlignmentsCalculator.h:100
dd4hep::cond::ConditionUpdateContext::world
DetElement world() const
Access to the top level detector element.
Definition: ConditionDerived.cpp:30
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:128
dd4hep::detail::matrix::_transform
TGeoHMatrix * _transform(const Transform3D &trans)
Convert a Transform3D object to a newly created TGeoHMatrix.
Definition: MatrixHelpers.cpp:140
dd4hep::align::Keys
Alignment and Delta item key.
Definition: Alignments.h:47
dd4hep::InstanceCount::increment
static void increment(T *)
Increment count according to type information.
Definition: InstanceCount.h:98
dd4hep::ConditionKey
Key definition to optimize ans simplyfy the access to conditions entities.
Definition: Conditions.h:280
dd4hep::ConditionKey::KeyMaker
Helper union to interprete conditions keys.
Definition: Conditions.h:295
dd4hep::align::AlignmentsCalculator::Scanner::iov
IOV * iov
Resulting IOV.
Definition: AlignmentsCalculator.h:104
dd4hep::align::AlignmentsCalculator::Scanner
Scanner to find all alignment deltas in the detector hierarchy.
Definition: AlignmentsCalculator.h:97
dd4hep::Delta
Class describing an condition to re-adjust an alignment.
Definition: AlignmentData.h:38
dd4hep::align::AlignmentsCalculator::Result::multiply
size_t multiply
Definition: AlignmentsCalculator.h:49
entries
Entries entries
Definition: AlignmentsCalculator.cpp:81
dd4hep::Condition
Main condition object handle.
Definition: Conditions.h:51
dd4hep::IOV
Class describing the interval of validty.
Definition: IOV.h:67
dd4hep::cond::ConditionUpdateContext::condition
Condition condition(const ConditionKey &key_value) const
Access to condition object by dependency key.
Definition: ConditionDerived.cpp:51
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:188
dd4hep::DetectorScanner::scan
int scan(Q &p, DetElement start, int level=0, bool recursive=true) const
Detector element tree scanner using wrapped DetectorProcessor objects.
Definition: DetectorProcessor.h:194
dd4hep::align::Keys::alignmentKey
static const Condition::itemkey_type alignmentKey
Key value of an alignment condition object "alignment".
Definition: Alignments.h:56
dd4hep::AlignmentCondition::data
AlignmentData & data()
Data accessor for the use of decorators.
Definition: Alignments.cpp:157
dd4hep::align::Keys::deltaKey
static const Condition::itemkey_type deltaKey
Key value of a delta condition "alignment_delta".
Definition: Alignments.h:52
dd4hep::Alignment::worldTransformation
const TGeoHMatrix & worldTransformation() const
Create cached matrix to transform to world coordinates.
Definition: Alignments.cpp:68
dd4hep::AlignmentData::trToWorld
Transform3D trToWorld
Transformation from volume to the world.
Definition: AlignmentData.h:124
dd4hep::AlignmentData::delta
Delta delta
Alignment changes.
Definition: AlignmentData.h:116
dd4hep::InstanceCount::decrement
static void decrement(T *)
Decrement count according to type information.
Definition: InstanceCount.h:102
dd4hep::Delta::computeMatrix
void computeMatrix(TGeoHMatrix &tr_delta) const
Compute the alignment delta for one detector element and its alignment condition.
Definition: AlignmentData.cpp:60
keys
Keys keys
Definition: AlignmentsCalculator.cpp:80
dd4hep::align::GlobalAlignmentStack::StackEntry::delta
Delta delta
Delta transformation to be applied.
Definition: GlobalAlignmentStack.h:57
dd4hep::align::AlignmentsCalculator::Result
Object encapsulating the result of a computation call to the alignments calculator.
Definition: AlignmentsCalculator.h:45
dd4hep::AlignmentData
Derived condition data-object definition.
Definition: AlignmentData.h:98
dd4hep::DetElement::nominal
Alignment nominal() const
Access to the constant ideal (nominal) alignment information.
Definition: DetElement.cpp:185
dd4hep::align::AlignmentsCalculator::Scanner::operator()
int operator()(DetElement de, int) const
Callback to output alignments information.
Definition: AlignmentsCalculator.cpp:109
dd4hep::AlignmentData::detectorTrafo
TGeoHMatrix detectorTrafo
Intermediate buffer to store the transformation to the parent detector element.
Definition: AlignmentData.h:120
dd4hep::Condition::get
T & get()
Generic getter. Specify the exact type, not a polymorph type.
Definition: Conditions.h:258
dd4hep::align::AlignmentsCalculator::ExtractContext
std::map< Condition::key_type, DetElement > ExtractContext
Definition: AlignmentsCalculator.h:76
_pad
unsigned char _pad[1]
Definition: AlignmentsCalculator.cpp:69
Conditions.h
GrammarUnparsed.h
detectors
DetectorMap detectors
Definition: AlignmentsCalculator.cpp:79
dd4hep::IOV::key
Key key() const
Get the local key of the IOV.
Definition: IOV.h:115
dd4hep::Condition::key_type
unsigned long long int key_type
Forward definition of the key type.
Definition: Conditions.h:54
ConditionsMap.h
dd4hep::AlignmentData::worldTrafo
TGeoHMatrix worldTrafo
Intermediate buffer to store the transformation to the world coordination system.
Definition: AlignmentData.h:118
dd4hep::align::AlignmentsCalculator::Scanner::deltas
OrderedDeltas & deltas
Collection container.
Definition: AlignmentsCalculator.h:102
key
unsigned char key
Definition: AlignmentsCalculator.cpp:69
AlignmentsProcessor.h
ConditionDerived.h
dd4hep::ConditionKey::KeyMaker::det_key
Condition::detkey_type det_key
Definition: Conditions.h:303
mapping
ConditionsMap & mapping
Definition: AlignmentsCalculator.cpp:82
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::ConditionKey::KeyMaker::hash
Condition::key_type hash
Definition: Conditions.h:296
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::Condition::ALIGNMENT_DERIVED
@ ALIGNMENT_DERIVED
Definition: Conditions.h:87
dd4hep::align::AlignmentsCalculator::Result::computed
size_t computed
Definition: AlignmentsCalculator.h:47
AlignmentsInterna.h
InstanceCount.h
valid
unsigned char valid
Definition: AlignmentsCalculator.cpp:69
dd4hep::align::AlignmentsCalculator::compute
Result compute(const std::map< DetElement, Delta > &deltas, ConditionsMap &alignments) const
Compute all alignment conditions of the internal dependency list.
Definition: AlignmentsCalculator.cpp:218
dd4hep::ConditionKey::KeyMaker::values
struct dd4hep::ConditionKey::KeyMaker::@2 values
dd4hep::align::GlobalAlignmentStack::StackEntry
Stack entry definition.
Definition: GlobalAlignmentStack.h:52
dd4hep::Condition::Processor
Abstract base for processing callbacks to conditions objects.
Definition: Conditions.h:112
Printout.h
dd4hep::Condition::iov
const IOV & iov() const
Access the IOV block.
Definition: Conditions.cpp:139
dd4hep::cond::ConditionUpdateContext
ConditionUpdateContext class used by the derived conditions calculation mechanism.
Definition: ConditionDerived.h:136
dd4hep::ConditionsMap
ConditionsMap class.
Definition: ConditionsMap.h:59
dd4hep::align
Namespace for implementation details of the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:31
dd4hep::ConditionKey::KeyMaker::item_key
Condition::itemkey_type item_key
Definition: Conditions.h:302