FairRoot/PandaRoot
PndLmdSensorAligner.cxx
Go to the documentation of this file.
1 /*
2  * PndLmdSensorAligner.cxx
3  *
4  * Created on: May 6, 2015
5  * Author: Roman Klasen, roklasen@uni-mainz.de or klasen@kph.uni-mainz.de
6  */
7 
8 #include "PndLmdSensorAligner.h"
9 #include "PndLmdGeometryHelper.h"
10 
11 #include <cmath> // for std::abs() that handles doubles
12 #include <fstream>
13 #include <iomanip>
14 #include <iostream>
15 #include <string>
16 #include <sstream>
17 
18 #include <icpPointToPoint.h>
19 #include <matrix.h>
20 #include <PndLmdAlignManager.h>
21 
22 //do NOT delete this, or else abs() comes from cstdlib and casts everything to ints
23 using std::abs;
24 
25 using std::cerr;
26 using std::cout;
27 using std::make_pair;
28 using std::string;
29 
31  maxNoOfPairs = 0;
32  numberOfPairs = 0;
33  forceInstant = true;
34  _moduleID = -1;
35  nonSanePairs = 0;
36  skippedPairs = 0;
37  swappedPairs = 0;
38  verbose = 0;
39  overlapID = -1;
40  inCentimeters = true;
41  success = false;
42  zIsTimestamp = true;
43  debug = false;
44  dim = 2;
45 }
46 
48  init();
49 }
50 
52  //destroy everything. leave nothing standing.
53 }
54 
56  std::cerr
57  << "PndLmdSensorAligner::Warning! Unnecessary copy-construction. These aligners should never be copied.\n";
58  init();
59 }
60 
62 
63  int zeroVals = 0;
64  int modxinv = 0, modyinv = 0, modzinv = 0;
65  int temxinv = 0, temyinv = 0, temzinv = 0;
66 
67  unsigned int nPairs = simplePairs.size();
68 
69  if (verbose == 3) cout << "checking for zero values...\n";
70 
71  for (auto &pair : simplePairs) {
72  std::abs(pair[0]) < 1e-15 ? modxinv++ : modxinv;
73  std::abs(pair[1]) < 1e-15 ? modyinv++ : modxinv;
74  std::abs(pair[2]) < 1e-15 ? modzinv++ : modxinv;
75  std::abs(pair[3]) < 1e-15 ? temxinv++ : modxinv;
76  std::abs(pair[4]) < 1e-15 ? temyinv++ : modxinv;
77  std::abs(pair[5]) < 1e-15 ? temzinv++ : modxinv;
78  }
79 
80  zeroVals = modxinv + modyinv + modzinv + temxinv + temyinv + temzinv;
81 
82  // 3 dimension and 2 arrays = 6
83  double zeroFactor = zeroVals / ((double) nPairs * 6.0);
84  if (zeroFactor > 0.15 && zeroFactor <= 0.3) {
85  cout << "WARNING. More than 15 % of your entries is zero. That must be a mistake. \n";
86  cout << "Also, the kdtree creation could crash. Keep an eye out for that...\n";
87  cout << "Zero factor: " << zeroFactor << "\n";
88  cout << "model x vals invalid: " << modxinv / (double) nPairs << "\n";
89  cout << "model y vals invalid: " << modyinv / (double) nPairs << "\n";
90  cout << "model z vals invalid: " << modzinv / (double) nPairs << "\n";
91  cout << "templ x vals invalid: " << temxinv / (double) nPairs << "\n";
92  cout << "templ y vals invalid: " << temyinv / (double) nPairs << "\n";
93  cout << "templ z vals invalid: " << temzinv / (double) nPairs << "\n";
94 
95  }
96  if (zeroFactor > 0.3) {
97  cout << "ERROR. More than 30 % of your entries is zero. That must be a mistake. \n";
98  cout << "Also, the kdtree creation will probably crash. Exiting.\n";
99  cout << "Zero factor: " << zeroFactor << "\n";
100  cout << "model x vals invalid: " << modxinv / (double) nPairs << "\n";
101  cout << "model y vals invalid: " << modyinv / (double) nPairs << "\n";
102  cout << "model z vals invalid: " << modzinv / (double) nPairs << "\n";
103  cout << "templ x vals invalid: " << temxinv / (double) nPairs << "\n";
104  cout << "templ y vals invalid: " << temyinv / (double) nPairs << "\n";
105  cout << "templ z vals invalid: " << temzinv / (double) nPairs << "\n";
106  cout << "=== additional data ===\n";
107  cout << "overlap id: " << overlapID << "\n";
108  cout << "no of Pairs: " << nPairs << "\n";
109  return false;
110  }
111  return true;
112 }
113 
115 
116  if (simplePairs[0].size() < 7) {
117  cerr << "WARNING. Can't apply dynamic cut because distance information is not stored.\n";
118  cerr << "Did you read an old version of the binary pair files?\n";
119  return;
120  }
121 
122  //sort pairs by distance, which is the 7th entry of the inner vector
123  //std::sort(simplePairs.begin(), simplePairs.end(),
124  // [](const std::vector< double >& a, const std::vector< double >& b) {return a[6] < b[6];});
125 
126  // sort by xy-distance, ignore z distance
127  std::sort(simplePairs.begin(), simplePairs.end(),
128  [](const std::vector< double >& a, const std::vector< double >& b) {return
129  (a[0]*a[0] + a[1]*a[1]) < (b[0]*b[0] + b[1]*b[1]) ;});
130 
131  int quantileMargin = simplePairs.size() * (percent/100); // cut from back
132 
133  vector<vector<double> >::const_iterator first = simplePairs.begin();// + quantileMargin; // KEEP smallest distances
134  vector<vector<double> >::const_iterator last = simplePairs.end() - quantileMargin;
135  vector<vector<double> > newSimplePairs(first, last); // this creates a copy
136 
137  //overwrite simple pairs vector with new, reduced vector
138  simplePairs = newSimplePairs;
139 
140  //remove possible bias from sorting
141  std::random_shuffle(simplePairs.begin(), simplePairs.end());
142 }
143 
145 
146  unsigned int nPairs;
147 
148  nPairs = simplePairs.size();
149 
150  if (skippedPairs > 0) {
151  cout << "=====================================================\n";
152  cout << "WARNING! Invalid pairs in pair file, check your data!\n";
153  cout << "=====================================================\n";
154  }
155 
156  //TODO: set from Manager or parameter file!
157  bool eventTimeCheck = true;
158  double minDelta = 1e-6;
159  zIsTimestamp = true;
160 
161  // only allow max Pairs!
162  if (nPairs > maxNoOfPairs && maxNoOfPairs > 0) {
163  nPairs = maxNoOfPairs;
164  }
165 
166  //number of pairs used in this run can not change anymore
167  lastNoOfPairs = nPairs;
168 
169  //check if nPairs > 0
170  if (nPairs < 50) {
171  cerr << "PndLmdSensrAligner::Error: Trying to use less than 50 pairs!\n";
172  cerr << "(And that's not going to work.) Aborting.\n";
173  success = false;
174  return;
175  }
176 
177  //check for zero values, largely not needed anymore, but keep it for now
178  zeroValCheck();
179 
180  double* Model = new double[dim * nPairs];
181  double* Template = new double[dim * nPairs];
182 
183  if (verbose == 3) {
184  cout << "arranging pairs...\n";
185  cout << "num pairs from bin: " << numberOfPairs << "\n";
186  cout << "num pairs from vec: " << simplePairs.size() << "\n";
187  cout << "num pairs from dec: " << nPairs << "\n";
188  }
189 
190  if (dim == 2) {
191  for (unsigned int ipair = 0; ipair < nPairs; ipair++) {
192  Model[ipair * dim + 0] = simplePairs[ipair][0];
193  Model[ipair * dim + 1] = simplePairs[ipair][1];
194  Template[ipair * dim + 0] = simplePairs[ipair][3];
195  Template[ipair * dim + 1] = simplePairs[ipair][4];
196  }
197  }
198 
199  else if (dim == 3) {
200  for (unsigned int ipair = 0; ipair < nPairs; ipair++) {
201  Model[ipair * dim + 0] = simplePairs[ipair][0];
202  Model[ipair * dim + 1] = simplePairs[ipair][1];
203  Model[ipair * dim + 2] = simplePairs[ipair][2];
204  Template[ipair * dim + 0] = simplePairs[ipair][3];
205  Template[ipair * dim + 1] = simplePairs[ipair][4];
206  Template[ipair * dim + 2] = simplePairs[ipair][5];
207  }
208  }
209 
210  if (verbose == 3) {
211  cout << "creating ICP...\n";
212  }
213 
214  // start with identity as initial transformation
215  Matrix Rotation;
216  Matrix translation;
217 
218  //perform ICP and store quality parameters
219  //attention! dim * nPairs must equal size of model!
220  IcpPointToPoint icp(Model, nPairs, dim);
221 
222  if (verbose == 3) cout << "ICP and model created...\n";
223 
224  //prepare Matrices
225  if (dim == 2) {
226  Rotation = Matrix::eye(2);
227  translation = Matrix(2, 1);
228  }
229  else if (dim == 3) {
230  Rotation = Matrix::eye(3);
231  translation = Matrix(3, 1);
232  }
233 
235  icp.fit(Template, nPairs, Rotation, translation, -1);
236 
237  if (verbose == 3) cout << "ICP fit step done.\n";
238 
239  if (dim == 2) {
240 
241  //make 4x4 matrix
242  double* tempR = new double[4];
243  double* tempT = new double[2];
244 
245  Rotation.getData(tempR);
246  translation.getData(tempT);
247 
248  double* finalMatrix = new double[16];
249 
250  //okay, this is the version that FIRST rotates, THEN translates.
251  finalMatrix[0] = tempR[0];
252  finalMatrix[1] = tempR[1];
253  finalMatrix[2] = 0;
254  finalMatrix[3] = tempT[0];
255  finalMatrix[4] = tempR[2];
256  finalMatrix[5] = tempR[3];
257  finalMatrix[6] = 0;
258  finalMatrix[7] = tempT[1];
259  finalMatrix[8] = 0;
260  finalMatrix[9] = 0;
261  finalMatrix[10] = 1.0;
262  finalMatrix[11] = 0;
263  finalMatrix[12] = 0;
264  finalMatrix[13] = 0;
265  finalMatrix[14] = 0;
266  finalMatrix[15] = 1.0;
267  resultMatrix = Matrix(4, 4);
268 
269  //save matrix!
270  resultMatrix.setVal(4, 4, finalMatrix);
271 
272  delete tempR;
273  delete tempT;
274  delete finalMatrix;
275 
276  }
277  else if (dim == 3) {
278 
279  //make 4x4 matrix
280  double* tempR = new double[9];
281  double* tempT = new double[3];
282 
283  Rotation.getData(tempR);
284  translation.getData(tempT);
285 
286  double* finalMatrix = new double[16];
287 
288  //TODO: check if this still works when we return TGeoHMatrix objects
289  //okay, this is the version that FIRST rotates, THEN translates.
290  finalMatrix[0] = tempR[0];
291  finalMatrix[1] = tempR[1];
292  finalMatrix[2] = tempR[2];
293  finalMatrix[3] = tempT[0];
294  finalMatrix[4] = tempR[3];
295  finalMatrix[5] = tempR[4];
296  finalMatrix[6] = tempR[5];
297  finalMatrix[7] = tempT[1];
298  finalMatrix[8] = tempR[6];
299  finalMatrix[9] = tempR[7];
300  finalMatrix[10] = tempR[8];
301  finalMatrix[11] = tempT[2];
302  finalMatrix[12] = 0;
303  finalMatrix[13] = 0;
304  finalMatrix[14] = 0;
305  finalMatrix[15] = 1;
306 
307  resultMatrix = Matrix(4, 4);
308 
309  //save matrix!
310  resultMatrix.setVal(4, 4, finalMatrix);
311 
312  delete tempR;
313  delete tempT;
314  delete finalMatrix;
315  }
316 
317  std::stringstream alignlog;
318 
319  if (icp.hasConverged()) {
320  if (verbose == 3) cout << "ICP convergence ok.\n";
321  success = true;
322 
323  //and say a few words for the log
324  alignlog << "\n";
325  alignlog << "====================================================\n";
326  alignlog << "icp converged for overlapID " << overlapID << " in " << icp.getInterations()
327  << " iterations.\n";
328 
329  alignlog << "pairs available: " << nPairs;
330  if (nPairs < 100000) {
331  alignlog << " (WARNING! This is not enough for accurate alignment!)\n";
332  }
333  else {
334  alignlog << "\n";
335  }
336  alignlog << "minDelta: " << minDelta << "\n";
337 
338  alignlog << "EventTimeCheck: ";
339  eventTimeCheck ? alignlog << "on (and passed)\n" : alignlog << "off\n";
340 
341  alignlog << "Force Instant: ";
342  forceInstant ? alignlog << "on\n" : alignlog << "off\n";
343 
344  alignlog << "====================================================\n";
345  }
346  else {
347  alignlog << "\n";
348  alignlog << "====================================================\n";
349  alignlog << "CRITICAL ERROR:\n";
350  alignlog << "no convergence for overlapID " << overlapID << "." << "\n";
351  alignlog << "====================================================\n";
352  alignlog << "\n";
353  if (verbose == 3) cout << "ICP did not converge!\n";
354  success = false;
355  }
356  if (verbose == 3) cout << alignlog.str();
357 
358  delete[] Model;
359  delete[] Template;
360 
361  return;
362 }
363 
365 
366  if (simplePairs.size() >= maxNoOfPairs && maxNoOfPairs > 0) {
367  return false;
368  }
369 
370  /*
371  * add pair as follows:
372  * vector<double> pair;
373  *
374  * [0]: oneX
375  * [1]: oneY
376  * [2]: oneZ
377  * [3]: twoX
378  * [4]: twoY
379  * [5]: twoZ
380  * [6]: distance
381  */
382 
383  if (inCentimeters) {
384  vector<double> tempPair;
385 
386  tempPair.push_back(pair.getHit1().x());
387  tempPair.push_back(pair.getHit1().y());
388  tempPair.push_back(pair.getHit1().z());
389 
390  tempPair.push_back(pair.getHit2().x());
391  tempPair.push_back(pair.getHit2().y());
392  tempPair.push_back(pair.getHit2().z());
393 
394  tempPair.push_back(pair.getDistance());
395 
396  simplePairs.push_back(tempPair);
397  }
398  else {
399  vector<double> tempPair;
400 
401  tempPair.push_back(pair.getCol1());
402  tempPair.push_back(pair.getRow1());
403  tempPair.push_back(simplePairs.size());
404 
405  tempPair.push_back(pair.getCol2());
406  tempPair.push_back(pair.getRow2());
407  tempPair.push_back(simplePairs.size());
408 
409  tempPair.push_back(pair.getDistance());
410 
411  simplePairs.push_back(tempPair);
412  }
413  return true;
414 }
415 
417 
418  string filename; //target directory
419  double* pdata; //array with pairs
420 
421  unsigned int nPairs = simplePairs.size();
422  if (nPairs == 0) {
423  cout << "warning: attempting to write empty binary pair file! (no pairs in buffer for overlapID "
424  << overlapID << ")\n";
425  return false;
426  }
427 
428  int doublesPerPair = simplePairs[0].size(); //well, doubles per Pair, this is determined by addPair()
429 
430  size_t length = nPairs * doublesPerPair + 6; //number of raw doubles (including header), remember pairs have 6 doubles
431 
432  filename = directory;
434 
435  //construct header
436  unsigned int headersize = 6; //header size in number of doubles
437 
438  double* header = new double[headersize];
439  header[0] = headersize; //header size in double fields
440  header[1] = doublesPerPair; //doubles per pair
441  header[2] = nPairs; //nPairs, read the correct vector!
442  header[3] = sizeof(double); //sizeof(double), check when reading files! might be different on other OSes.
443  header[4] = overlapID; //overlapID
444  header[5] = 2.1; //version, cant read older versions
445 
446  pdata = new double[length];
447 
448  //save header
449  for (unsigned int i = 0; i < headersize; i++) {
450  pdata[i] = header[i];
451  }
452  //save data
453  unsigned int currentIndex = headersize; //data starts here
454 
455  //iterate over all pairs
456  for (unsigned int iPair = 0; iPair < nPairs; iPair++) {
457 
458  //iterate over all entries of the pair
459  for (unsigned int jPairIndex = 0; jPairIndex < simplePairs[0].size(); jPairIndex++) {
460  pdata[currentIndex + jPairIndex] = simplePairs[iPair][jPairIndex];
461  }
462  currentIndex += doublesPerPair;
463  }
464 
465  /*
466  * the write part is easy, just dump everything. read part is more difficult,
467  * need to check file first
468  */
469 
470  //TODO: abstract this to Manager!
471  //create directory if not already present
472  PndLmdAlignManager::mkdir(directory);
473  std::ofstream os(filename.c_str(), std::ios::binary | std::ios::out);
474  if (!os.is_open()) {
475  cout << "ERROR! Could not write to " << filename << "!\n";
476  return false;
477  }
478 
479  os.write(reinterpret_cast<const char*>(pdata), std::streamsize(length * sizeof(double)));
480  os.close();
481  delete[] pdata;
482  delete[] header;
483  return true;
484 }
485 
487 
488  string filename; //binary pair file
489  //size_t length; //number of raw doubles, remember pairs have 6 doubles
490  double* pdata; //array with pairs
491  size_t filesize;
492  size_t doublesize = sizeof(double);
493  unsigned int nPairs;
494  unsigned int doublesPerPair;
495  unsigned int noOfDoubles = 0;
496 
497  /*
498  * read goes as follows:
499  *
500  * first, check file size.
501  * file size is larger than one double (headersize is stored there)? -> read header only! else return false;
502  * read header and interpret data from header.
503  * is nPairs*doublesPerPair*sizeof(double) + headersize*sizeof(double) (header) == filezise?
504  * is nPairs in header == headersize * sizeof(double) (filesize - header)
505  * if so, file seems okay, read header + file. else return false;
506  * when entire file is read, copy data without header to arrays for ICP *
507  */
508 
509  filename = directory;
511 
512  //check if file exists and file size
513  std::fstream inStream(filename.c_str(), std::ios::binary | std::ios::in | std::ios::ate);
514  if (inStream) {
515  std::fstream::pos_type size = inStream.tellg();
516  filesize = size;
517  }
518  else {
519  cout << filename.c_str() << " could not be read!\n";
520  return false;
521  }
522 
523  double* headersizeD = new double[1];
524  //read header size
525  if (filesize >= sizeof(double)) {
526  //read header
527  std::ifstream is(filename.c_str(), std::ios::binary | std::ios::in);
528  if (!is.is_open()) return false;
529  is.read(reinterpret_cast<char*>(headersizeD), std::streamsize(sizeof(double)));
530  is.close();
531  }
532 
533  int headersize;
534  if (headersizeD[0] < 6) {
535  //cout << "headersize is " << headersizeD[0] << ", seems to be old format. using 6 for now.";
536  headersize = 6;
537  }
538  else {
539  headersize = headersizeD[0];
540  }
541 
542  //read header
543  if (filesize >= headersize * sizeof(double)) {
544  double* header = new double[headersize];
545 
546  //read header
547  std::ifstream is(filename.c_str(), std::ios::binary | std::ios::in);
548  if (!is.is_open()) return false;
549  is.read(reinterpret_cast<char*>(header), std::streamsize(headersize * sizeof(double)));
550  is.close();
551 
552  //check header
553  if (verbose == 3) {
554  cout << "header size: " << header[0] << "\n";
555  cout << "doubles / pair: " << header[1] << "\n";
556  cout << "no of pairs: " << header[2] << "\n";
557  }
558 
559  //check header
560  doublesPerPair = header[1];
561  nPairs = std::round(header[2]);
562  numberOfPairs = nPairs;
563  noOfDoubles = nPairs * doublesPerPair + headersize;
564  size_t filesizeMust = sizeof(double) * (noOfDoubles);
565 
566  if (doublesize != header[3]) {
567  cout
568  << "warning! sizeof(double) on this system is different than on the system that made this binary!\n";
569  //TODO: decide what to do in this case
570  exit(1);
571  doublesize = header[3];
572  return false;
573  }
574 
575  if (overlapID != header[4]) {
576  cout << "error! file name and overlapID do not match! did you rename the file?\n";
577  }
578 
579  if (filesizeMust != filesize) {
580  cout << "file is corrupt!\n";
581  return false;
582  }
583 
584  //free allocated space!
585  delete[] header;
586 
587  }
588  else {
589  cout << filename.c_str() << " is too small, file corrupt!\n";
590  return false;
591  }
592 
593  //allocate double array for entire file
594  pdata = new double[noOfDoubles];
595 
596  //actually read file
597  std::ifstream is(filename.c_str(), std::ios::binary | std::ios::in);
598  if (!is.is_open()) return false;
599  is.read(reinterpret_cast<char*>(pdata), std::streamsize(noOfDoubles * sizeof(double)));
600  is.close();
601  // the entire file is now in memory. it's only about 30 MB, so this is okay
602 
603  //save data
604  unsigned int currentIndex = headersize; //data starts here
605  //bool error = false;
606 
607  for (unsigned int iPair = 0; iPair < nPairs; iPair++) {
608 
609  vector<double> tempPair;
610  //assign pair data
611  for (unsigned int jPairIndex = 0; jPairIndex < doublesPerPair; jPairIndex++) {
612  double currentVal = pdata[currentIndex + jPairIndex];
613  //cout << "current val is: " << currentVal << "\n";
614  tempPair.push_back(currentVal);
615  }
616  simplePairs.push_back(tempPair);
617 
618  //get next index, every pair has doublesPerPair doubles
619  currentIndex += doublesPerPair;
620  }
621 
622  //check size one last time
623  if (nPairs != simplePairs.size()) {
624  cerr << "Warning! Error while reading binary pair file!\n";
625  return false;
626  }
627 
628  //delete array!
629  delete[] pdata;
630 
631  return true;
632 }
633 
635  lastNoOfPairs = simplePairs.size();
636  //call destructors of the member objects (well, they're doubles, so... yeah.)
637  simplePairs.clear();
638  //force release of allocated memory by vectors
639  vector<vector<double> >().swap(simplePairs);
640 }
641 
643 
644  //check for number of pairs
645  if (simplePairs.size() < 50) {
646  cerr << "PndLmdSensorAligner::check: ERROR! Aligner " << overlapID
647  << "doesn't have enough pairs! Aborting.\n";
648  return false;
649  }
650 
651  //check if pair array is strictly rectangular
652  unsigned int dimy = simplePairs[0].size();
653  for (auto &pair : simplePairs) {
654  if (pair.size() != dimy) {
655  return false;
656  }
657  }
658 
659  //check... I don't know, something.
660  return true;
661 
662 }
663 
664 std::vector<double> PndLmdSensorAligner::getPairSpread(int what) {
665 
666  double xcom, ycom, zcom, xspread, yspread, zspread, xmin, xmax, ymin, ymax, zmin, zmax, avgDist;
667  unsigned int nPairs = 0;
668  nPairs = simplePairs.size();
669 
670  xcom = ycom = zcom = xspread = yspread = zspread = xmin = xmax = ymin = ymax = zmin = zmax = avgDist =
671  0.0;
672 
673  // set all values to first entry
674  if (what == 0 || what == 1) {
675  xcom += simplePairs[0][0];
676  ycom += simplePairs[0][1];
677  zcom += simplePairs[0][2];
678 
679  xmin = simplePairs[0][0];
680  xmax = simplePairs[0][0];
681  ymin = simplePairs[0][1];
682  ymax = simplePairs[0][1];
683  zmin = simplePairs[0][2];
684  zmax = simplePairs[0][2];
685  }
686 
687  if (what == 0 || what == 2) {
688  xcom += simplePairs[0][3];
689  ycom += simplePairs[0][4];
690  zcom += simplePairs[0][5];
691 
692  xmin = simplePairs[0][3];
693  xmax = simplePairs[0][3];
694  ymin = simplePairs[0][4];
695  ymax = simplePairs[0][4];
696  zmin = simplePairs[0][5];
697  zmax = simplePairs[0][5];
698  }
699 
700  avgDist = simplePairs[0][6];
701 
702  // collect center of mass and spread in all coordinates
703  for (unsigned int i = 1; i < simplePairs.size(); i++) {
704  auto &pair = simplePairs[i];
705 
706  if (what == 0 || what == 1) {
707  xcom += pair[0];
708  ycom += pair[1];
709  zcom += pair[2];
710 
711  xmin = std::min(xmin, pair[0]);
712  xmax = std::max(xmax, pair[0]);
713  ymin = std::min(ymin, pair[1]);
714  ymax = std::max(ymax, pair[1]);
715  zmin = std::min(zmin, pair[2]);
716  zmax = std::max(zmax, pair[2]);
717  }
718 
719  if (what == 0 || what == 2) {
720  xcom += pair[3];
721  ycom += pair[4];
722  zcom += pair[5];
723 
724  xmin = std::min(xmin, pair[3]);
725  xmax = std::max(xmax, pair[3]);
726  ymin = std::min(ymin, pair[4]);
727  ymax = std::max(ymax, pair[4]);
728  zmin = std::min(zmin, pair[5]);
729  zmax = std::max(zmax, pair[5]);
730  }
731 
732  avgDist += pair[6];
733  }
734 
735  // calculate center of mass and spread
736  if (what == 1 || what == 2) {
737  xcom /= nPairs;
738  ycom /= nPairs;
739  zcom /= nPairs;
740 
741  avgDist /= nPairs;
742  }
743  else if (what == 0) {
744  xcom /= 2.0 * nPairs;
745  ycom /= 2.0 * nPairs;
746  zcom /= 2.0 * nPairs;
747 
748  avgDist /= 2.0 * nPairs;
749  }
750 
751  xspread = std::abs(xmax - xmin);
752  yspread = std::abs(ymax - ymin);
753  zspread = std::abs(zmax - zmin);
754 
755  std::vector<double> spread;
756 
757  spread.push_back(xcom);
758  spread.push_back(ycom);
759  spread.push_back(zcom);
760 
761  spread.push_back(xspread);
762  spread.push_back(yspread);
763  spread.push_back(zspread);
764 
765  spread.push_back(avgDist);
766 
767  return spread;
768 
769 }
770 
772 
773  auto spread = getPairSpread(what);
774 
775  cout << "x com: " << spread[0] << "\n";
776  cout << "y com: " << spread[1] << "\n";
777  cout << "z com: " << spread[2] << "\n";
778 
779  cout << "x spread: " << spread[3] << "\n";
780  cout << "y spread: " << spread[4] << "\n";
781  cout << "z spread: " << spread[5] << "\n";
782 
783  cout << "avg Dist: " << spread[6] << "\n";
784 }
785 
787 
788  Matrix toLMD = Matrix::eye(4);
789 
790  // maybe this helps with thread safety | should be in geometryHelper now!
792 
794  int id1 = helper->getSensorOneFromOverlapID(overlapID);
795  TGeoHMatrix matrix = helper->getMatrixPndGlobalToSensor(id1);
796 
797  // maybe this helps with thread safety | should be in geometryHelper now!
799 
800  toLMD = superManager->castTGeoHMatrixToMatrix(matrix);
801 
802  // it appears we have to make an actrive trafo from a passive one
803  toLMD.inv();
804 
805  for (auto &pair : simplePairs) {
806  transformPair(toLMD, pair);
807  }
808 
809  return toLMD;
810 }
811 
813 
814  Matrix toLMD = Matrix::eye(4);
815 
816  // maybe this helps with thread safety
818 
820  TGeoHMatrix matrix = helper->getMatrixPndGlobalToLmdLocal();
821  toLMD = superManager->castTGeoHMatrixToMatrix(matrix);
822 
823  // maybe this helps with thread safety
825 
826  // it appears we have to make an actrive trafo from a passive one
827  toLMD.inv();
828  for (auto &pair : simplePairs) {
829  transformPair(toLMD, pair);
830  }
831  return toLMD;
832 }
833 
834 void PndLmdSensorAligner::transformPair(Matrix& trafoMatrix, std::vector<double>& pair) {
835 
836  if (trafoMatrix.m != 4 || trafoMatrix.n != 4 || pair.size() < 6) {
837  std::cerr << "ERROR. Matrix is not 4x4 or pair has less than 6 entries\n";
838  return;
839  }
840 
841  Matrix pairVal1(4, 1);
842  Matrix pairVal2(4, 1);
843 
844  pairVal1.val[0][0] = pair[0];
845  pairVal1.val[1][0] = pair[1];
846  pairVal1.val[2][0] = pair[2];
847  pairVal1.val[3][0] = 1.0;
848 
849  pairVal2.val[0][0] = pair[3];
850  pairVal2.val[1][0] = pair[4];
851  pairVal2.val[2][0] = pair[5];
852  pairVal2.val[3][0] = 1.0;
853 
854  pairVal1 = trafoMatrix * pairVal1;
855  pairVal2 = trafoMatrix * pairVal2;
856 
857  // don't forget to de-homogenize
858  pair[0] = pairVal1.val[0][0] / pairVal1.val[3][0];
859  pair[1] = pairVal1.val[1][0] / pairVal1.val[3][0];
860  pair[2] = pairVal1.val[2][0] / pairVal1.val[3][0];
861 
862  pair[3] = pairVal2.val[0][0] / pairVal2.val[3][0];
863  pair[4] = pairVal2.val[1][0] / pairVal2.val[3][0];
864  pair[5] = pairVal2.val[2][0] / pairVal2.val[3][0];
865 
866 }
std::mutex geometryHelperMutex
Double_t getCol2() const
bool writePairsToBinary(const std::string directory)
Int_t i
Definition: run_full.C:25
TTree * b
exit(0)
Double_t getRow2() const
std::vector< std::vector< double > > simplePairs
Double_t xmax
static PndLmdGeometryHelper & getInstance()
void transformPair(Matrix &trafoMatrix, std::vector< double > &pair)
friend F32vec4 max(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:26
static bool mkdir(std::string path)
bool addSimplePair(const PndLmdHitPair &pair)
bool hasConverged()
Definition: icp.h:77
void applyDynamicCut(double percent=5.0)
const TVector3 & getHit1() const
Definition: PndLmdHitPair.h:79
void setVal(const int32_t m, const int32_t n, const FLOAT *val_)
static Matrix castTGeoHMatrixToMatrix(const TGeoHMatrix &matrix)
static std::string makeBinaryPairFileName(int overlapId=0, bool incentimeters=true)
Int_t a
Definition: anaLmdDigi.C:126
PndLmdGeometryHelper * helper
std::vector< double > getPairSpread(int what=0)
Double_t getDistance() const
const TGeoHMatrix getMatrixPndGlobalToLmdLocal()
double fit(double *T, const int32_t T_num, Matrix &R, Matrix &t, const double indist)
const TGeoHMatrix getMatrixPndGlobalToSensor(const int sensorId)
const TVector3 & getHit2() const
Definition: PndLmdHitPair.h:89
int getSensorOneFromOverlapID(int overlapID)
friend F32vec4 min(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:25
int32_t m
Definition: matrix.h:139
TFile * out
Definition: reco_muo.C:20
Definition: matrix.h:50
PndLmdAlignManager * superManager
static int is
Definition: ranlxd.cxx:374
static Matrix inv(const Matrix &M)
int32_t n
Definition: matrix.h:139
void getData(FLOAT *val_, int32_t i1=0, int32_t j1=0, int32_t i2=-1, int32_t j2=-1)
Double_t xmin
int32_t getInterations()
Definition: icp.h:80
void forceInstantResult(bool val)
Definition: icp.h:47
TString directory
void printPairSpread(int what=0)
void eye()
FLOAT ** val
Definition: matrix.h:138
Double_t getRow1() const
bool readPairsFromBinary(const std::string directory)
Double_t getCol1() const
const string filename