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