DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AlignmentOperators.cpp
Go to the documentation of this file.
1 // $Id: $
2 //==========================================================================
3 // AIDA Detector description implementation for LCD
4 //--------------------------------------------------------------------------
5 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
6 // All rights reserved.
7 //
8 // For the licensing terms see $DD4hepINSTALL/LICENSE.
9 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
10 //
11 // Author : M.Frank
12 //
13 //==========================================================================
14 
15 // Framework include files
16 #include "DD4hep/LCDD.h"
17 #include "DD4hep/Printout.h"
21 
22 // C/C++ include files
23 #include <stdexcept>
24 
25 using namespace std;
26 using namespace DD4hep;
27 using namespace DD4hep::Alignments;
28 
29 void AlignmentOperator::insert(GlobalAlignment alignment) const {
30  if ( !cache.insert(alignment) ) {
31  // Error
32  }
33 }
34 
35 void AlignmentSelector::operator()(Entries::value_type e) const {
36  TGeoPhysicalNode* pn = 0;
37  nodes.insert(make_pair(e->path,make_pair(pn,e)));
38 }
39 
40 void AlignmentSelector::operator()(const Cache::value_type& entry) const {
41  TGeoPhysicalNode* pn = entry.second;
42  for(Entries::const_iterator j=entries.begin(); j != entries.end(); ++j) {
43  Entries::value_type e = (*j);
44  if ( e->needsReset() || e->hasMatrix() ) {
45  const char* p = pn->GetName();
46  bool reset_children = e->resetChildren();
47  if ( reset_children && ::strstr(p,e->path.c_str()) == p ) {
48  nodes.insert(make_pair(p,make_pair(pn,e)));
49  break;
50  }
51  else if ( e->path == p ) {
52  nodes.insert(make_pair(p,make_pair(pn,e)));
53  break;
54  }
55  }
56  }
57 }
58 
60  printout(ALWAYS,"GlobalAlignmentCache","++++++++++++++++++++++++ Summary ++++++++++++++++++++++++");
61 }
62 
63 template <> void AlignmentActor<DDAlign_standard_operations::node_print>::operator()(Nodes::value_type& n) const {
64  TGeoPhysicalNode* p = n.second.first;
65  Entry* e = n.second.second;
66  printout(ALWAYS,"GlobalAlignmentCache","Need to reset entry:%s - %s [needsReset:%s, hasMatrix:%s]",
67  p->GetName(),e->path.c_str(),yes_no(e->needsReset()),yes_no(e->hasMatrix()));
68 }
69 
70 template <> void AlignmentActor<DDAlign_standard_operations::node_delete>::operator()(Nodes::value_type& n) const {
71  delete n.second.second;
72  n.second.second = 0;
73 }
74 
75 template <> void AlignmentActor<DDAlign_standard_operations::node_reset>::operator()(Nodes::value_type& n) const {
76  TGeoPhysicalNode* p = n.second.first;
77  string np;
78  if ( p->IsAligned() ) {
79  for (Int_t i=0, nLvl=p->GetLevel(); i<=nLvl; i++) {
80  TGeoNode* node = p->GetNode(i);
81  TGeoMatrix* mm = node->GetMatrix(); // Node's relative matrix
82  np += string("/")+node->GetName();
83  if ( !mm->IsIdentity() && i > 0 ) { // Ignore the 'world', is identity anyhow
84  GlobalAlignment a = cache.get(np);
85  if ( a.isValid() ) {
86  printout(ALWAYS,"AlignmentActor<reset>","Correct path:%s leaf:%s",p->GetName(),np.c_str());
87  TGeoHMatrix* glob = p->GetMatrix(i-1);
88  if ( a.isValid() && i!=nLvl ) {
89  *mm = *(a->GetOriginalMatrix());
90  }
91  else if ( i==nLvl ) {
92  TGeoHMatrix* hm = dynamic_cast<TGeoHMatrix*>(mm);
93  TGeoMatrix* org = p->GetOriginalMatrix();
94  hm->SetTranslation(org->GetTranslation());
95  hm->SetRotation(org->GetRotationMatrix());
96  }
97  *glob *= *mm;
98  }
99  }
100  }
101  }
102 }
103 
104 template <> void AlignmentActor<DDAlign_standard_operations::node_align>::operator()(Nodes::value_type& n) const {
105  Entry& e = *n.second.second;
106  bool overlap = e.overlapDefined();
107  DetElement det = e.detector;
108 
109  if ( !det->global_alignment.isValid() && !e.hasMatrix() ) {
110  printout(WARNING,"AlignmentActor","++++ SKIP Alignment %s DE:%s Valid:%s Matrix:%s",
111  e.path.c_str(),det.placementPath().c_str(),
112  yes_no(det->global_alignment.isValid()), yes_no(e.hasMatrix()));
113  return;
114  }
115  if ( GlobalDetectorAlignment::debug() ) {
116  printout(INFO,"AlignmentActor","++++ %s DE:%s Matrix:%s",
117  e.path.c_str(),det.placementPath().c_str(),yes_no(e.hasMatrix()));
118  }
119  // Need to care about optional arguments 'check_overlaps' and 'overlap'
120  GlobalDetectorAlignment ad(det);
121  GlobalAlignment align;
122  Transform3D trafo;
123  bool no_vol = e.path == det.placementPath();
124  double ovl_val = e.overlapValue();
125  const Delta& delta = e.delta;
126 
127  if ( delta.checkFlag(Delta::HAVE_ROTATION|Delta::HAVE_PIVOT|Delta::HAVE_TRANSLATION) )
128  trafo = Transform3D(Translation3D(delta.translation)*delta.pivot*delta.rotation*(delta.pivot.Inverse()));
129  else if ( delta.checkFlag(Delta::HAVE_ROTATION|Delta::HAVE_TRANSLATION) )
130  trafo = Transform3D(delta.rotation,delta.translation);
131  else if ( delta.checkFlag(Delta::HAVE_ROTATION|Delta::HAVE_PIVOT) )
132  trafo = Transform3D(delta.pivot*delta.rotation*(delta.pivot.Inverse()));
133  else if ( delta.checkFlag(Delta::HAVE_ROTATION) )
134  trafo = Transform3D(delta.rotation);
135  else if ( delta.checkFlag(Delta::HAVE_TRANSLATION) )
136  trafo = Transform3D(delta.translation);
137 
138  if ( e.checkOverlap() && overlap )
139  align = no_vol ? ad.align(trafo,ovl_val,e.overlap) : ad.align(e.path,trafo,ovl_val,e.overlap);
140  else if ( e.checkOverlap() )
141  align = no_vol ? ad.align(trafo,ovl_val) : ad.align(e.path,trafo,ovl_val);
142  else
143  align = no_vol ? ad.align(trafo) : ad.align(e.path,trafo);
144 
145  if ( align.isValid() ) {
146  insert(align);
147  return;
148  }
149  except("AlignmentActor","Failed to apply alignment for "+e.path);
150 }
151 
152 #if 0
153 void alignment_reset_dbg(const string& path, const GlobalAlignment& a) {
154  TGeoPhysicalNode* n = a.ptr();
155  cout << " +++++++++++++++++++++++++++++++ " << path << endl;
156  cout << " +++++ Misaligned physical node: " << endl;
157  n->Print();
158  string np;
159  if ( n->IsAligned() ) {
160  for (Int_t i=0; i<=n->GetLevel(); i++) {
161  TGeoMatrix* mm = n->GetNode(i)->GetMatrix();
162  np += "/";
163  np += n->GetNode(i)->GetName();
164  if ( mm->IsIdentity() ) continue;
165  if ( i == 0 ) continue;
166 
167  TGeoHMatrix* glob = n->GetMatrix(i-1);
168  NodeMap::const_iterator j=original_matrices.find(np);
169  if ( j != original_matrices.end() && i!=n->GetLevel() ) {
170  cout << " +++++ Patch Level: " << i << np << endl;
171  *mm = *((*j).second);
172  }
173  else {
174  if ( i==n->GetLevel() ) {
175  cout << " +++++ Level: " << i << np << " --- Original matrix: " << endl;
176  n->GetOriginalMatrix()->Print();
177  cout << " +++++ Level: " << i << np << " --- Local matrix: " << endl;
178  mm->Print();
179  TGeoHMatrix* hm = dynamic_cast<TGeoHMatrix*>(mm);
180  hm->SetTranslation(n->GetOriginalMatrix()->GetTranslation());
181  hm->SetRotation(n->GetOriginalMatrix()->GetRotationMatrix());
182  cout << " +++++ Level: " << i << np << " --- New local matrix" << endl;
183  mm->Print();
184  }
185  else {
186  cout << " +++++ Level: " << i << np << " --- Keep matrix " << endl;
187  mm->Print();
188  }
189  }
190  cout << " +++++ Level: " << i << np << " --- Global matrix: " << endl;
191  glob->Print();
192  *glob *= *mm;
193  cout << " +++++ Level: " << i << np << " --- New global matrix: " << endl;
194  glob->Print();
195  }
196  }
197  cout << "\n\n\n +++++ physical node (full): " << np << endl;
198  n->Print();
199  cout << " +++++ physical node (global): " << np << endl;
200  n->GetMatrix()->Print();
201 }
202 #endif
Act on selected alignment entries.
bool overlapDefined() const
Check if the overlap flag checking is enabled.
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:124
bool checkFlag(unsigned int mask) const
Check a given flag.
Definition: AlignmentData.h:90
Main handle class to hold a TGeo alignment object of type TGeoPhysicalNode.
GlobalDetectorAlignment. DetElement Handle supporting alignment operations.
const char * yes_no(bool value)
Helper function to print booleans in format YES/NO.
Definition: Printout.h:295
DetElement detector
Reference to the detector element.
Delta delta
Delta transformation to be applied.
return e
Definition: Volumes.cpp:297
double overlap
Parameter for overlap checking.
int except(const std::string &src, const std::string &fmt,...)
Calls the display action with ERROR and throws an std::runtime_error exception.
Definition: Printout.cpp:217
T * ptr() const
Access to the held object.
Definition: Handle.h:149
bool hasMatrix() const
Check if this alignment entry has a non unitary transformation matrix.
bool needsReset() const
Check flag if the node location should be reset.
Class describing an condition to re-adjust an alignment.
Definition: AlignmentData.h:49
std::string path
Path to the misaligned volume.
bool checkOverlap() const
Check if the overlap flag checking is enabled.
Handle class describing a detector element.
Definition: Detector.h:172
ROOT::Math::Translation3D Translation3D
Definition: Objects.h:112
Stack entry definition.
static const double mm
Definition: DD4hepUnits.h:69
int printout(PrintLevel severity, const char *src, const char *fmt,...)
Calls the display action with a given severity level.
Definition: Printout.cpp:111
ROOT::Math::Transform3D Transform3D
Definition: Objects.h:110
bool overlapValue() const
Check if the overalp value is present.
const std::string & placementPath() const
Access to the full path to the placed object.
Definition: Detector.cpp:86