Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AlignmentTransformation.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file AlignmentTransformation.cc
2 
3 #include "ActsGeometry.h"
4 #include "TpcDefs.h"
5 #include "TrkrDefs.h"
6 
8 
10 
11 #include <phool/PHCompositeNode.h>
12 #include <phool/getClass.h>
13 #include <phool/phool.h>
14 #include <phool/PHDataNode.h>
15 #include <phool/PHNode.h>
16 #include <phool/PHNodeIterator.h>
17 #include <phool/PHObject.h>
18 #include <phool/PHTimer.h>
19 
23 
24 #include <Eigen/Dense>
25 #include <Eigen/Geometry>
26 #include <Eigen/LU>
27 
28 #include <cmath>
29 #include <fstream>
30 
31 
32 
34 {
35  // The default is to use translation parameters that are in global coordinates
37  std::cout << "AlignmentTransformation: use global translation perturbations = " << use_global_millepede_translations << std::endl;
38 
39  getNodes(topNode);
40 
41  // Use construction transforms as a reference for making the map
43 
44  // Define Parsing Variables
46  float alpha = 0.0, beta = 0.0, gamma = 0.0, dx = 0.0, dy = 0.0, dz = 0.0;
47 
48  // load alignment constants file
49  std::ifstream datafile;
50  datafile.open(alignmentParamsFile); // looks for default file name on disk
51  if(datafile.is_open())
52  {
53  std::cout << "AlignmentTransformation: Reading alignment parameters from disk file: "
54  << alignmentParamsFile << " localVerbosity = " << localVerbosity << std::endl;
55  }
56  else
57  {
58  datafile.clear();
59  // load alignment constants file from database
60  alignmentParamsFile = CDBInterface::instance()->getUrl("TRACKINGALIGNMENT");
61  std::cout << "AlignmentTransformation: Reading alignment parameters from database file: " << alignmentParamsFile << std::endl;
62  datafile.open(alignmentParamsFile);
63  }
64 
65  ActsSurfaceMaps surfMaps = m_tGeometry->maps();
66  Surface surf;
67 
68  int fileLines = 1824;
69  for (int i=0; i<fileLines; i++)
70  {
71  datafile >> hitsetkey >> alpha >> beta >> gamma >> dx >> dy >> dz;
72 
73  // Perturbation translations and angles for stave and sensor
74  Eigen::Vector3d sensorAngles(alpha,beta,gamma);
75  Eigen::Vector3d millepedeTranslation(dx,dy,dz);
76 
77  unsigned int trkrId = TrkrDefs::getTrkrId(hitsetkey); // specify between detectors
78 
79  perturbationAngles = Eigen::Vector3d(0.0,0.0,0.0);
80  perturbationTranslation = Eigen::Vector3d(0.0,0.0,0.0);
81 
82  if(trkrId == TrkrDefs::mvtxId)
83  {
84  if(perturbMVTX)
85  {
87  sensorAngles = sensorAngles + perturbationAngles;
88  millepedeTranslation = millepedeTranslation + perturbationTranslation;
89  }
90 
91  surf = surfMaps.getSiliconSurface(hitsetkey);
92 
94  transform = newMakeTransform(surf, millepedeTranslation, sensorAngles, false);
95 
96  Acts::GeometryIdentifier id = surf->geometryId();
97 
98  if(localVerbosity)
99  {
100 
101  std::cout << " Add transform for MVTX with surface GeometryIdentifier " << id << " trkrid " << trkrId << std::endl;
102  std::cout << " final mvtx transform:" << std::endl << transform.matrix() << std::endl;
103  }
104  transformMap->addTransform(id,transform);
105  transformMapTransient->addTransform(id,transform);
106  }
107 
108  else if(trkrId == TrkrDefs::inttId)
109  {
110 
111  if(perturbINTT)
112  {
114  sensorAngles = sensorAngles + perturbationAngles;
115  millepedeTranslation = millepedeTranslation + perturbationTranslation;
116  }
117 
118  surf = surfMaps.getSiliconSurface(hitsetkey);
119 
121  transform = newMakeTransform(surf, millepedeTranslation, sensorAngles, use_intt_survey_geometry);
122  Acts::GeometryIdentifier id = surf->geometryId();
123 
124  if(localVerbosity)
125  {
126  std::cout << " Add transform for INTT with surface GeometryIdentifier " << id << " trkrid " << trkrId << std::endl;
127  }
128 
129  transformMap->addTransform(id,transform);
130  transformMapTransient->addTransform(id,transform);
131  }
132 
133 
134  else if(trkrId == TrkrDefs::tpcId)
135  {
136  if(perturbTPC)
137  {
139  sensorAngles = sensorAngles + perturbationAngles;
140  millepedeTranslation = millepedeTranslation + perturbationTranslation;
141  }
142  unsigned int sector = TpcDefs::getSectorId(hitsetkey);
143  unsigned int side = TpcDefs::getSide(hitsetkey);
144  int subsurfkey_min = (1-side)*144 + (144-sector*12) - 12 - 6;
145  int subsurfkey_max = subsurfkey_min + 12;
146  //std::cout << " sector " << sector << " side " << side << " subsurfkey_min " << subsurfkey_min << " subsurfkey_max " << subsurfkey_max << std::endl;
147 
148  for(int subsurfkey = subsurfkey_min; subsurfkey<subsurfkey_max; subsurfkey++)
149  {
150  int sskey = subsurfkey;
151  if(sskey < 0) { sskey += 288; }
152 
153  surf = surfMaps.getTpcSurface(hitsetkey,(unsigned int) sskey);
154 
156  transform = newMakeTransform(surf, millepedeTranslation, sensorAngles, false);
157  Acts::GeometryIdentifier id = surf->geometryId();
158 
159  if(localVerbosity)
160  {
161  unsigned int layer = TrkrDefs::getLayer(hitsetkey);
162  std::cout << " Add transform for TPC with surface GeometryIdentifier " << id << std::endl
163  << " trkrid " << trkrId << " hitsetkey " << hitsetkey << " layer " << layer << " sector " << sector << " side " << side
164  << " subsurfkey " << subsurfkey << std::endl;
165  Acts::Vector3 center = surf->center(m_tGeometry->geometry().getGeoContext()) * 0.1; // convert to cm
166  std::cout << "Ideal surface center: " << std::endl <<center << std::endl;
167  std::cout << "transform matrix: " << std::endl << transform.matrix() << std::endl;
168  }
169  transformMap->addTransform(id,transform);
170  transformMapTransient->addTransform(id,transform);
171  }
172  }
173  else if(trkrId == TrkrDefs::micromegasId)
174  {
175  if(perturbMM)
176  {
178 
179  sensorAngles = sensorAngles + perturbationAngles;
180  millepedeTranslation = millepedeTranslation + perturbationTranslation;
181  }
182  surf = surfMaps.getMMSurface(hitsetkey);
183 
185  transform = newMakeTransform(surf, millepedeTranslation, sensorAngles, false);
186  Acts::GeometryIdentifier id = surf->geometryId();
187 
188  if(localVerbosity)
189  {
190  std::cout << " Add transform for Micromegas with surface GeometryIdentifier " << id << " trkrid " << trkrId << std::endl;
191  }
192 
193  transformMap->addTransform(id,transform);
194  transformMapTransient->addTransform(id,transform);
195  }
196 
197  else
198  {
199  std::cout<< "Error: Invalid Hitsetkey" << std::endl;
200  }
201  }
202 
203  // copy map into geoContext
205 
206  // map is created, now we can use the transforms
208 
209 
210 }
211 
212 // currently used as the transform maker
213 Acts::Transform3 AlignmentTransformation::newMakeTransform(Surface surf, Eigen::Vector3d& millepedeTranslation, Eigen::Vector3d& sensorAngles, bool survey)
214 {
215  //define null matrices
216  Eigen::Vector3d nullTranslation(0,0,0);
217  Eigen::AngleAxisd a(0, Eigen::Vector3d::UnitX());
218  Eigen::AngleAxisd b(0, Eigen::Vector3d::UnitY());
219  Eigen::AngleAxisd g(0, Eigen::Vector3d::UnitZ());
220  Eigen::Quaternion<double> qnull = g*b*a;
221  Eigen::Matrix3d nullRotation = qnull.matrix();
222 
223  // Create alignment rotation matrix
224 
225  // Note that Acts transforms local coordinates of (x,z,y) to global (x,y,z)
226  //=====================================================
227  // If we use a local alignment translation vector (dx,dy,dz) it
228  // should be converted to (dx,dz,dy) before applying the Acts transform to global
229  // It seems we can just interchange the x and y coordinates for this
230  //=====================================================
231 
232  Eigen::AngleAxisd alpha(sensorAngles(0), Eigen::Vector3d::UnitX());
233  Eigen::AngleAxisd beta(sensorAngles(1), Eigen::Vector3d::UnitY());
234  Eigen::AngleAxisd gamma(sensorAngles(2), Eigen::Vector3d::UnitZ());
235 
236  Eigen::Quaternion<double> q = gamma*beta*alpha;
237 
238  Eigen::Matrix3d millepedeRotation = q.matrix();
239 
240  Acts::Transform3 mpRotationAffine;
241  mpRotationAffine.linear() = millepedeRotation;
242  mpRotationAffine.translation() = nullTranslation;
243 
244  // create alignment translation matrix
245  Acts::Transform3 mpTranslationAffine;
246  mpTranslationAffine.linear() = nullRotation;
248  {
249  mpTranslationAffine.translation() = millepedeTranslation;
250  }
251  else
252  {
253  // offsets should now be in local frame, so (dx,dz,dy)
254  Eigen::Vector3d millepedeTranslationxzy(millepedeTranslation(0), millepedeTranslation(2), millepedeTranslation(1));
255  mpTranslationAffine.translation() = millepedeTranslationxzy;
256  }
257 
258  // get the acts transform components
259  Acts::Transform3 actsTransform = surf->transform(m_tGeometry->geometry().getGeoContext());
260  Eigen::Matrix3d actsRotationPart = actsTransform.rotation();
261  Eigen::Vector3d actsTranslationPart = actsTransform.translation();
262 
263  // and make affine matrices from each
264  Acts::Transform3 actsRotationAffine;
265  actsRotationAffine.linear() = actsRotationPart;
266  actsRotationAffine.translation() = nullTranslation;
267  Acts::Transform3 actsTranslationAffine;
268  actsTranslationAffine.linear() = nullRotation;
269  actsTranslationAffine.translation() = actsTranslationPart;
270 
271  //Put them together into a combined transform
274  if(survey)
275  {
279  transform = mpTranslationAffine * mpRotationAffine;
280  }
282  else
283  {
285  {
286  // put the mp translations in the global frame
287  transform = mpTranslationAffine * actsTranslationAffine * mpRotationAffine * actsRotationAffine;
288  }
289  else
290  {
291  // put the mp translations in the local coordinate frame
292  transform = actsTranslationAffine * actsRotationAffine * mpTranslationAffine * mpRotationAffine;
293  }
294  }
295 
296  if(localVerbosity)
297  {
298  Acts::Transform3 actstransform = actsTranslationAffine * actsRotationAffine;
299  Acts::Transform3 mptransform = mpTranslationAffine * mpRotationAffine;
300 
301  std::cout << "newMakeTransform" << std::endl;
302  std::cout << " use_global_translations = " << use_global_millepede_translations << std::endl;
303  std::cout << "mpRotationAffine: "<< std::endl<< mpRotationAffine.matrix() <<std::endl;
305  {
306  std::cout << "mpTranslationAffine: " << std::endl << mpTranslationAffine.matrix() <<std::endl;
307  std::cout << " mptranslationAffine * mpRotationAffine " << std::endl
308  << (mpTranslationAffine * mpRotationAffine).matrix() << std::endl;
309  }
310  std::cout << "millepederotation * acts " << std::endl << millepedeRotation * actsRotationPart << std::endl;
311  std::cout << "actsRotationAffine: "<< std::endl<< actsRotationAffine.matrix() <<std::endl;
312  std::cout << "actsTranslationAffine: "<< std::endl<< actsTranslationAffine.matrix() <<std::endl;
313  std::cout << "full acts transform " << std::endl << actstransform.matrix() << std::endl << "full mp transform " << std::endl << mptransform.matrix() << std::endl;
315  {
316  std::cout << "mpTranslationAffine: " << std::endl << mpTranslationAffine.matrix() <<std::endl;
317  }
318  std::cout << "Overall transform: " << std::endl << transform.matrix() <<std::endl;
319  std::cout << "overall * idealinv " << std::endl << (transform * actstransform.inverse()).matrix() << std::endl;
320  std::cout << "overall - ideal " << std::endl;
321  for(int test = 0; test < transform.matrix().rows(); test++)
322  {
323  for(int test2 = 0; test2 < transform.matrix().cols(); test2++)
324  {
325  std::cout << transform(test,test2) - actstransform(test,test2) << ", ";
326  }
327  std::cout << std::endl;
328  }
329 
330  }
331 
332  return transform;
333 }
334 
336 {
337  m_tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
338  if(!m_tGeometry)
339  {
340  std::cout << "ActsGeometry not on node tree. Exiting."
341  << std::endl;
342 
344  }
345 
346  return 0;
347 }
348 
349 void AlignmentTransformation::misalignmentFactor(uint8_t layer, const double factor)
350 {
351  transformMap->setMisalignmentFactor(layer, factor);
352 }
354 {
355  //​ Get a pointer to the top of the node tree
356  PHNodeIterator iter(topNode);
357 
358  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
359  if (!dstNode)
360  {
361  std::cerr << "DST node is missing, quitting" << std::endl;
362  throw std::runtime_error("Failed to find DST node in AlignmentTransformation::createNodes");
363  }
364 
365  transformMap = findNode::getClass<alignmentTransformationContainer>(topNode, "alignmentTransformationContainer");
366  if(!transformMap)
367  {
369  auto node = new PHDataNode<alignmentTransformationContainer>(transformMap, "alignmentTransformationContainer");
370  dstNode->addNode(node);
371  }
372 
373  transformMapTransient = findNode::getClass<alignmentTransformationContainer>(topNode, "alignmentTransformationContainerTransient");
375  {
377  auto node = new PHDataNode<alignmentTransformationContainer>(transformMapTransient, "alignmentTransformationContainerTransient");
378  dstNode->addNode(node);
379  }
380 }
381 
382 
383 void AlignmentTransformation::generateRandomPerturbations(Eigen::Vector3d angleDev, Eigen::Vector3d transformDev)
384 {
385  /*Creates random perturbations for the correctional parameters with a given standard deviation and mean of zero*/
386 
387  std::cout << "Generating Random Perturbations..."<<std::endl;
388 
389  if(angleDev(0)!=0)
390  {
391  std::normal_distribution<double> distribution(0,angleDev(0));
392  perturbationAngles(0) = distribution(generator);
393  }
394  if(angleDev(1)!=0)
395  {
396  std::normal_distribution<double> distribution(0,angleDev(1));
397  perturbationAngles(1) = distribution(generator);
398  }
399  if(angleDev(2)!=0)
400  {
401  std::normal_distribution<double> distribution(0,angleDev(2));
402  perturbationAngles(2) = distribution(generator);
403  }
404  if(transformDev(0)!=0)
405  {
406  std::normal_distribution<double> distribution(0,transformDev(0));
407  perturbationTranslation(0) = distribution(generator);
408  }
409  if(transformDev(1)!=0)
410  {
411  std::normal_distribution<double> distribution(0,transformDev(1));
412  perturbationTranslation(1) = distribution(generator);
413  }
414  if(transformDev(2)!=0)
415  {
416  std::normal_distribution<double> distribution(0,transformDev(2));
417  perturbationTranslation(2) = distribution(generator);
418  }
419  if(localVerbosity)
420  {
421  std::cout << "randomperturbationAngles" << perturbationAngles << " randomperturbationTrans:" << perturbationTranslation << std::endl;
422  }
423 }
424