Belle II Software  release-05-01-25
Hierarchy.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2015 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Tadeas Bilka *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <alignment/Hierarchy.h>
12 
13 #include <alignment/GlobalLabel.h>
14 
15 #include <boost/crc.hpp>
16 
17 namespace Belle2 {
22  namespace alignment {
23 
24  // ------------------ GlobalDerivativesHierarchy ----------------------------
25 
26  void GlobalDerivativesHierarchy::buildConstraints(Constraints& constraints)
27  {
28  for (auto& parent_childs : m_hierarchy) {
29  auto parent = parent_childs.first;
30  auto childs = parent_childs.second;
31 
32  // We need to check if such constraint entry already exists.
33  // For timedep parameters, some to all labels (and coefficients optionally, too) can change and
34  // in such case, we need a new constraint entry.
35  // Note the checksum for a constraint does not depend on the parent element. If parent object changes,
36  // the relative transofrmation to its children are unchanged. While if (some of) the childs change,
37  // for each time interval they are constant, there must a new constraint entry as this is an independent
38  // linear combination of parameters (because there are other parameters).
39  // Continued bellow...
40  boost::crc_32_type crc32;
41 
42  auto parentLabels = getElementLabels(parent);
43  for (unsigned int iCon = 0; iCon < parentLabels.size(); iCon++) {
44  auto constraint = Constraint();
45  //auto & constraint = constraints[parentLabels[iCon]];
46 
47  // No constraints if parent is global reference frame
48  // All subdetectors are actually nominally placed at constant position and rotation
49  // and rotating the detectors could only happen due cohherent movements of sub-structures (CDC layers, VXD half-shells)
50  if (parentLabels[iCon] == 0) continue;
51 
52  for (unsigned int j = 0; j < childs.size(); j++) {
53  auto child = childs[j];
54  auto childLabels = getElementLabels(child);
55 
56  for (unsigned int iPar = 0; iPar < childLabels.size(); iPar++) {
57  double coefficient = getChildToMotherTransform(child).second(iCon, iPar);
58  if (fabs(coefficient) > 1.0e-14) {
59  auto childLabel = childLabels[iPar];
60  constraint.push_back(std::make_pair(childLabel, coefficient));
61  // On the other hand, if the labels do not change, the checksum should not change.
62  // In future I should add second checksum and warn user if this happens. It means user has ignored the fact,
63  // that the objects already change in the input global tag. The point here is, it still might be reasonable
64  // to use the constraint coefficients we already have, as the alignment changes are usually small and do not change
65  // the constraint coefficients in first order for most use-cases. The warning should be enough -> TODO
66  crc32.process_bytes(&childLabel, sizeof(childLabel));
67  }
68  }
69  }
70 
71  //constraints.insert(std::make_pair(parentLabels[iCon], constraint));
72  constraints.insert(std::make_pair(crc32.checksum(), constraint));
73 
74  }
75  }
76  }
77 
78  Belle2::alignment::GlobalDerivativeSet GlobalDerivativesHierarchy::buildGlobalDerivativesHierarchy(TMatrixD matrixChain,
79  Belle2::alignment::DetectorLevelElement child)
80  {
81  auto loc2glo = getChildToMotherTransform(child);
82 
83  if (loc2glo.first == std::make_pair((unsigned short)0, (unsigned short)0))
84  return std::make_pair(std::vector<int>(), TMatrixD());
85 
86 
87  TMatrixD glo2loc(loc2glo.second.Invert());
88  TMatrixD drdparent = matrixChain * glo2loc;
89 
90 
91  GlobalDerivativeSet retVal = std::make_pair(getElementLabels(loc2glo.first), drdparent);
92  mergeGlobals(retVal, buildGlobalDerivativesHierarchy(drdparent, loc2glo.first));
93 
94  return retVal;
95  }
96 
97  void GlobalDerivativesHierarchy::mergeGlobals(Belle2::alignment::GlobalDerivativeSet& main,
98  Belle2::alignment::GlobalDerivativeSet additional)
99  {
100  if (additional.first.empty())
101  return;
102 
103  // Create composed matrix of derivatives
104  //TODO: check main and additional matrix has the same number of rows
105  TMatrixD allDerivatives(main.second.GetNrows(), main.second.GetNcols() + additional.second.GetNcols());
106  allDerivatives.Zero();
107  allDerivatives.SetSub(0, 0, main.second);
108  allDerivatives.SetSub(0, main.second.GetNcols(), additional.second);
109 
110  // Merge labels
111  main.first.insert(main.first.end(), additional.first.begin(), additional.first.end());
112  // Update matrix
113  main.second.ResizeTo(allDerivatives);
114  main.second = allDerivatives;
115 
116  }
117 
119  {
120  for (auto& entry : m_lookup) {
121  std::cout << "Child : " << entry.first.second << std::endl;
122  std::cout << "Mother :" << entry.second.first.second << std::endl;
123  entry.second.second.Print();
124  }
125  }
126 
127  std::pair< Belle2::alignment::DetectorLevelElement, TMatrixD > GlobalDerivativesHierarchy::getChildToMotherTransform(
128  Belle2::alignment::DetectorLevelElement child)
129  {
130  auto entry = m_lookup.find(child);
131  if (entry == m_lookup.end())
132  return std::make_pair(std::make_pair(0, 0), TMatrixD());
133 
134  return entry->second;
135  }
136 
137  // ------------------ LorentShiftHierarchy ----------------------------
138 
139  std::vector< int > LorentShiftHierarchy::getElementLabels(Belle2::alignment::DetectorLevelElement element)
140  {
141  std::vector<int> labels;
142  GlobalLabel label;
143  label.construct(element.first, element.second, 0);
144  // TODO: constants instead of numbers
145  labels.push_back(label.setParameterId(20));
146 
147  return labels;
148  }
149 
151  {
152  // values for global derivatives
153  //TMatrixD derGlobal(2, 6);
154  TMatrixD derGlobal(2, 1);
155  derGlobal.Zero();
156 
157  // electrons in device go in local w-direction to P-side
158  B2Vector3D v = sop->getPlane()->getNormal();
159  // Lorentz force (without E-field) direction
160  B2Vector3D F_dir = v.Cross(bField);
161  // ... projected to sensor coordinates:
162  genfit::StateOnPlane localForce = *sop;
163  localForce.setPosMom(sop->getPos(), F_dir);
164  B2Vector3D lorentzLocal(localForce.getState()[3], localForce.getState()[4], 0); // or 0,1?
165  // Lorentz shift = parameter(layer) * B_local
166  derGlobal(0, 0) = lorentzLocal(0);
167  derGlobal(1, 0) = lorentzLocal(1);
168 
169  return derGlobal;
170  }
171 
172  // ------------------ RigidBodyHierarchy ----------------------------
173 
174  std::vector< int > RigidBodyHierarchy::getElementLabels(Belle2::alignment::DetectorLevelElement element)
175  {
176  std::vector<int> labels;
177  GlobalLabel label;
178  label.construct(element.first, element.second, 0);
179  // TODO: constants instead of numbers
180  labels.push_back(label.setParameterId(1));
181  labels.push_back(label.setParameterId(2));
182  labels.push_back(label.setParameterId(3));
183  labels.push_back(label.setParameterId(4));
184  labels.push_back(label.setParameterId(5));
185  labels.push_back(label.setParameterId(6));
186 
187 
188 // // TODO: constants instead of numbers
189 // label.construct(element.first, element.second, 1);
190 // labels.push_back(label.label());
191 // label.construct(element.first, element.second, 2);
192 // labels.push_back(label.label());
193 // label.construct(element.first, element.second, 3);
194 // labels.push_back(label.label());
195 // label.construct(element.first, element.second, 4);
196 // labels.push_back(label.label());
197 // label.construct(element.first, element.second, 5);
198 // labels.push_back(label.label());
199 // label.construct(element.first, element.second, 6);
200 // labels.push_back(label.label());
201 //
202  return labels;
203  }
204 
206  {
207  TMatrixD derGlobal(2, 6);
208 
209  // track u-slope in local sensor system
210  double uSlope = sop->getState()[1];
211  // track v-slope in local sensor system
212  double vSlope = sop->getState()[2];
213  // Predicted track u-position in local sensor system
214  double uPos = sop->getState()[3];
215  // Predicted track v-position in local sensor system
216  double vPos = sop->getState()[4];
217 
218  //Global derivatives for alignment in sensor local coordinates
219 
220  derGlobal(0, 0) = 1.0;
221  derGlobal(0, 1) = 0.0;
222  derGlobal(0, 2) = - uSlope;
223  derGlobal(0, 3) = vPos * uSlope;
224  derGlobal(0, 4) = -uPos * uSlope;
225  derGlobal(0, 5) = vPos;
226 
227  derGlobal(1, 0) = 0.0;
228  derGlobal(1, 1) = 1.0;
229  derGlobal(1, 2) = - vSlope;
230  derGlobal(1, 3) = vPos * vSlope;
231  derGlobal(1, 4) = -uPos * vSlope;
232  derGlobal(1, 5) = -uPos;
233 
234  return derGlobal;
235  }
236 
237  TMatrixD RigidBodyHierarchy::convertG4ToRigidBodyTransformation(G4Transform3D g4transform)
238  {
239  TMatrixD rotationT(3, 3);
240  TMatrixD offset(3, 3);
241  for (int i = 0; i < 3; i++) {
242  for (int j = 0; j < 3; j++) {
243  rotationT(i, j) = g4transform.getRotation()(i, j);//trafo(j, i);
244  // or transposed???? have to check
245  }
246  }
247  double xDet = g4transform.getTranslation()(0);
248  double yDet = g4transform.getTranslation()(1);
249  double zDet = g4transform.getTranslation()(2);
250  offset.Zero();
251  offset(0, 1) = - zDet;
252  offset(0, 2) = yDet;
253  offset(1, 0) = zDet;
254  offset(1, 2) = - xDet;
255  offset(2, 0) = - yDet;
256  offset(2, 1) = xDet;
257 
258  TMatrixD loc2glo(6, 6);
259  loc2glo.Zero();
260  loc2glo.SetSub(0, 0, rotationT);
261  loc2glo.SetSub(0, 3, -1. * offset * rotationT);
262  loc2glo.SetSub(3, 3, rotationT);
263 
264  return loc2glo;
265  }
266 
268  {
269  TMatrixD rotationT(3, 3);
270  TMatrixD offset(3, 3);
271  for (int i = 0; i < 3; i++) {
272  for (int j = 0; j < 3; j++) {
273  rotationT(i, j) = tgeo.GetRotationMatrix()[i * 3 + j];
274  // or transposed???? have to check
275  }
276  }
277  double xDet = tgeo.GetTranslation()[0];
278  double yDet = tgeo.GetTranslation()[1];
279  double zDet = tgeo.GetTranslation()[2];
280  offset.Zero();
281  offset(0, 1) = - zDet;
282  offset(0, 2) = yDet;
283  offset(1, 0) = zDet;
284  offset(1, 2) = - xDet;
285  offset(2, 0) = - yDet;
286  offset(2, 1) = xDet;
287 
288  TMatrixD loc2glo(6, 6);
289  loc2glo.Zero();
290  loc2glo.SetSub(0, 0, rotationT);
291  loc2glo.SetSub(0, 3, -1. * offset * rotationT);
292  loc2glo.SetSub(3, 3, rotationT);
293 
294  return loc2glo;
295  }
296  }
298 }
Belle2::alignment::LorentShiftHierarchy::getLorentzShiftDerivatives
TMatrixD getLorentzShiftDerivatives(const genfit::StateOnPlane *sop, B2Vector3D bField)
Derivatives for Lorentz shift in sensor plane.
Definition: Hierarchy.cc:158
Belle2::alignment::GlobalDerivativesHierarchy::getChildToMotherTransform
std::pair< DetectorLevelElement, TMatrixD > getChildToMotherTransform(DetectorLevelElement child)
Find the transformation in the lookup.
Definition: Hierarchy.cc:135
Belle2::alignment::GlobalDerivativesHierarchy::m_lookup
std::map< DetectorLevelElement, std::pair< DetectorLevelElement, TMatrixD > > m_lookup
Map with all the parameter data (child -> (mother, transform_child2mother))
Definition: Hierarchy.h:108
Belle2::alignment::RigidBodyHierarchy::convertG4ToRigidBodyTransformation
TMatrixD convertG4ToRigidBodyTransformation(G4Transform3D g4transform)
Conversion from G4Transform3D to 6D rigid body transformation parametrization.
Definition: Hierarchy.cc:245
Belle2::alignment::GlobalDerivativesHierarchy::m_hierarchy
std::map< DetectorLevelElement, std::vector< DetectorLevelElement > > m_hierarchy
Map of hierarchy relations mother-> child.
Definition: Hierarchy.h:110
Belle2::alignment::GlobalDerivativesHierarchy::getElementLabels
virtual std::vector< int > getElementLabels(DetectorLevelElement element)=0
The only function to implement: what are the global labels for the element?
genfit::StateOnPlane
A state with arbitrary dimension defined in a DetPlane.
Definition: StateOnPlane.h:47
Belle2::alignment::RigidBodyHierarchy::getElementLabels
std::vector< int > getElementLabels(DetectorLevelElement element) override
Rigid body labels.
Definition: Hierarchy.cc:182
Belle2::GlobalLabel
Class to convert to/from global labels for Millepede II to/from detector & parameter identificators.
Definition: GlobalLabel.h:51
Belle2::B2Vector3< double >
Belle2::alignment::RigidBodyHierarchy::convertTGeoToRigidBodyTransformation
TMatrixD convertTGeoToRigidBodyTransformation(TGeoHMatrix tgeo)
Conversion from G4Transform3D to 6D rigid body transformation parametrization.
Definition: Hierarchy.cc:275
main
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:77
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::alignment::GlobalDerivativesHierarchy::mergeGlobals
static void mergeGlobals(GlobalDerivativeSet &main, GlobalDerivativeSet additional)
Merge additional set into main set of global labels and derivatives TODO: move to some utilities.
Definition: Hierarchy.cc:105
Belle2::alignment::GlobalDerivativesHierarchy::buildConstraints
void buildConstraints(Constraints &constraints)
Adds constraints from current hierarchy to a constraints vector.
Definition: Hierarchy.cc:34
Belle2::alignment::GlobalDerivativesHierarchy::buildGlobalDerivativesHierarchy
GlobalDerivativeSet buildGlobalDerivativesHierarchy(TMatrixD matrixChain, DetectorLevelElement child)
Recursive function which adds labels and derivatives until top element in hierarchy is found.
Definition: Hierarchy.cc:86
Belle2::alignment::LorentShiftHierarchy::getElementLabels
std::vector< int > getElementLabels(DetectorLevelElement element) final
Label for lorentz shift parameter.
Definition: Hierarchy.cc:147
Belle2::alignment::RigidBodyHierarchy::getRigidBodyDerivatives
TMatrixD getRigidBodyDerivatives(const genfit::StateOnPlane *sop)
2x6 matrix of rigid body derivatives
Definition: Hierarchy.cc:213
Belle2::alignment::GlobalDerivativesHierarchy::printHierarchy
void printHierarchy()
print the lookup map
Definition: Hierarchy.cc:126