ATLAS Offline Software
ITkPixelClusterOnTrackTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // Implementation file for class ITk::PixelClusterOnTrackTool
8 // (c) ATLAS Detector software
10 // AlgTool used for PixelClusterOnTrack object production
12 // started 1.0 21/04/2004 I.Gavrilenko - see ChangeLog
14 
21 
22 #include <cmath>
24 
25 //clustermap is most likely to be removed at later date
26 #define __clustermap
27 
28 
30 // Constructor
32 
33 namespace
34 {
35  // using x*x might be quicker than pow(x,2), depends on compiler optimisation
36  inline double
37  square(const double x) {
38  return x * x;
39  }
40 
41  double
42  distance(const std::vector<Amg::Vector2D> &vectorOfPositions,
43  const std::vector<Amg::Vector2D> &allLocalPositions,
44  const std::vector<Amg::MatrixX> &allErrorMatrix,
45  const int i, const int j, const int k) {
46  return
47  square(vectorOfPositions[i][0] - allLocalPositions[0][0]) / allErrorMatrix[0](0, 0) +
48  square(vectorOfPositions[j][0] - allLocalPositions[1][0]) / allErrorMatrix[1](0, 0) +
49  square(vectorOfPositions[k][0] - allLocalPositions[2][0]) / allErrorMatrix[2](0, 0) +
50  square(vectorOfPositions[i][1] - allLocalPositions[0][1]) / allErrorMatrix[0](1, 1) +
51  square(vectorOfPositions[j][1] - allLocalPositions[1][1]) / allErrorMatrix[1](1, 1) +
52  square(vectorOfPositions[k][1] - allLocalPositions[2][1]) / allErrorMatrix[2](1, 1);
53  }
54 }
55 
56 namespace ITk
57 {
58 
60  (const std::string &t, const std::string &n, const IInterface *p) :
61  ::AthAlgTool(t, n, p),
62  m_pixelid(nullptr),
63  m_NnClusterizationFactory("InDet::NnClusterizationFactory/NnClusterizationFactory", this),
64  m_doNotRecalibrateNN(false),
65  m_noNNandBroadErrors(false),
66  m_usingTIDE_Ambi(false),
67  m_splitClusterMapKey("")
68  {
69  declareInterface<IRIO_OnTrackCreator>(this);
70 
71  declareProperty("PositionStrategy", m_positionStrategy = 1, "Which calibration of cluster positions");
72  declareProperty("NnClusterizationFactory", m_NnClusterizationFactory);
73  declareProperty("SplitClusterAmbiguityMap", m_splitClusterMapKey);//Remove Later
74  declareProperty("doNotRecalibrateNN", m_doNotRecalibrateNN);
75  declareProperty("m_noNNandBroadErrors", m_noNNandBroadErrors);
76  declareProperty("RunningTIDE_Ambi", m_usingTIDE_Ambi);
77 }
78 
79 
81 // Initialisation
83 
86 
87  ATH_MSG_DEBUG(name() << " initialize()");
88 
90  ATH_MSG_DEBUG("Error strategy is" << m_errorStrategy);
91 
93 
95 
97 
98  // get the error scaling tool
100  if (!m_pixelErrorScalingKey.key().empty()) ATH_MSG_DEBUG("Detected need for scaling Pixel errors.");
101 
102  ATH_CHECK (detStore()->retrieve(m_pixelid, "PixelID"));
103 
106  ATH_CHECK(m_NnClusterizationFactory.retrieve( DisableTool{!m_applyNNcorrection} ));
107 
108  ATH_CHECK(m_lorentzAngleTool.retrieve());
109  return StatusCode::SUCCESS;
110 }
111 
112 
114 // Trk::SiClusterOnTrack production
116 
117 
120  (const Trk::PrepRawData &rio, const Trk::TrackParameters &trackPar) const {
121 
122  if (not m_applyNNcorrection){
123  return correctDefault(rio, trackPar);
124  }else {
125  if (m_errorStrategy == 0 || m_errorStrategy == 1) {
126  // version from Giacinto
127  if (m_noNNandBroadErrors) {
128  return nullptr;
129  }
130  // if we try broad errors, get Pixel Cluster to test if it is split
131  const InDet::PixelCluster *pix = nullptr;
133  pix = static_cast<const InDet::PixelCluster *>(&rio);
134  }
135  if (!pix) {
136  return nullptr;
137  }
139  if (splitProb.isSplit()) {
140  return correctNN(rio, trackPar);
141  } else {
142  return correctDefault(rio, trackPar);
143  }
144  } else {
145  return correctNN(rio, trackPar);
146  }
147  }
148 }
149 
150 
151 
157  (const Trk::PrepRawData &rio, const Trk::TrackParameters &trackPar) const {
158  using CLHEP::micrometer;
159 
160 
161  const double TOPHAT_SIGMA = 1. / std::sqrt(12.);
162  const InDet::PixelCluster *pix = nullptr;
164  pix = static_cast<const InDet::PixelCluster *>(&rio);
165  }
166  else{
167  return nullptr;
168  }
169 
170  ATH_MSG_VERBOSE("Correct called with Error strategy " << m_errorStrategy);
171 
172  // PixelClusterOnTrack production
173  //
174  Trk::LocalParameters locpar;
175  Amg::Vector3D glob(pix->globalPosition());
176 
177 
178  // Get pointer to detector element
179  const InDetDD::SiDetectorElement *element = pix->detectorElement();
180  if (!element) {
181  return nullptr;
182  }
183  IdentifierHash iH = element->identifyHash();
184 
185  double errphi = -1;
186  double erreta = -1;
187 
188  if (pix->rdoList().empty()) {
189  ATH_MSG_WARNING("Pixel RDO-list size is 0, check integrity of pixel clusters! stop ROT creation.");
190  return nullptr;
191  } else {
192  const InDetDD::PixelModuleDesign *design =
193  dynamic_cast<const InDetDD::PixelModuleDesign *>(&element->design());
194 
195  // get candidate track angle in module local frame
196  const Amg::Vector3D& my_track = trackPar.momentum();
197  const Amg::Vector3D& my_normal = element->normal();
198  const Amg::Vector3D& my_phiax = element->phiAxis();
199  const Amg::Vector3D& my_etaax = element->etaAxis();
200  float trkphicomp = my_track.dot(my_phiax);
201  float trketacomp = my_track.dot(my_etaax);
202  float trknormcomp = my_track.dot(my_normal);
203  double bowphi = std::atan2(trkphicomp, trknormcomp);
204  double boweta = std::atan2(trketacomp, trknormcomp);
205 
206  float tanl = m_lorentzAngleTool->getTanLorentzAngle(iH);
207  int readoutside = element->design().readoutSide();
208 
209  // map the angles of inward-going tracks onto [-PI/2, PI/2]
210  if (bowphi > M_PI *0.5) {
211  bowphi -= M_PI;
212  }
213  if (bowphi < -M_PI *0.5) {
214  bowphi += M_PI;
215  }
216  // finally, subtract the Lorentz angle effect
217  // the readoutside term is needed because of a bug in old
218  // geometry versions (CSC-01-* and CSC-02-*)
219  double angle = std::atan(std::tan(bowphi) - readoutside * tanl);
220 
221  // settle the sign/pi periodicity issues
222  double thetaloc = -999.;
223  if (boweta > -0.5 * M_PI && boweta < M_PI / 2.) { //M_PI_2 in cmath
224  thetaloc = M_PI_2 - boweta;
225  }else if (boweta > M_PI_2 && boweta < M_PI) {
226  thetaloc = 1.5 * M_PI - boweta;
227  } else { // 3rd quadrant
228  thetaloc = -M_PI_2 - boweta;
229  }
230  double etaloc = -1 * log(tan(thetaloc * 0.5));
231 
232  // try to understand...
233  const Identifier element_id = element->identify();
234  int PixEtaModule = m_pixelid->eta_module(element_id);
235  int PixPhiModule = m_pixelid->phi_module(element_id);
236  double PixTrkPt = trackPar.pT();
237  double PixTrkEta = trackPar.eta();
238  ATH_MSG_VERBOSE("tanl = " << tanl << " readout side is " << readoutside <<
239  " module " << PixEtaModule << " " << PixPhiModule <<
240  " track pt, eta = " << PixTrkPt << " " << PixTrkEta <<
241  " track momentum phi, norm = " << trkphicomp << " " <<
242  trknormcomp << " bowphi = " << bowphi << " angle = " << angle);
243 
244  float omegaphi = pix->omegax();
245  float omegaeta = pix->omegay();
246  double localphi = -9999.;
247  double localeta = -9999.;
248 
249  const std::vector<Identifier> & rdos = pix->rdoList();
250  InDetDD::SiLocalPosition meanpos(0, 0, 0);
251  int rowmin = 9999;
252  int rowmax = -9999;
253  int colmin = 9999;
254  int colmax = -9999;
255  for (const auto & rId:rdos) {
256  const int row = m_pixelid->phi_index(rId);
257  const int col = m_pixelid->eta_index(rId);
258  rowmin = std::min(rowmin, row);
259  rowmax = std::max(rowmax,row);
260  colmin = std::min(colmin, col);
261  colmax = std::max(colmax, col);
262  meanpos += design->positionFromColumnRow(col, row);
263  }
264  meanpos = meanpos / rdos.size();
266  design->positionFromColumnRow(colmin, rowmin);
268  design->positionFromColumnRow(colmax, rowmin);
270  design->positionFromColumnRow(colmin, rowmax);
272  design->positionFromColumnRow(colmax, rowmax);
273 
274  InDetDD::SiLocalPosition centroid = 0.25 * (pos1 + pos2 + pos3 + pos4);
275  double shift = m_lorentzAngleTool->getLorentzShift(iH);
276  int nrows = rowmax - rowmin + 1;
277  int ncol = colmax - colmin + 1;
278 
279  // TOT interpolation for collision data
281 
282  if (m_positionStrategy > 0 && omegaphi > -0.5 && omegaeta > -0.5) {
283  localphi = centroid.xPhi() + shift;
284  localeta = centroid.xEta();
285 
286  std::pair<double,double> delta = offlineITkCalibDataHandle->getClusterErrorData()->getDelta(&element_id,nrows,angle,ncol,etaloc);
287  double delta_phi = nrows != 1 ? delta.first : 0.;
288  double delta_eta = ncol != 1 ? delta.second : 0.;
289  localphi += delta_phi*(omegaphi-0.5);
290  localeta += delta_eta*(omegaeta-0.5);
291  }
292  // digital
293  else {
294  localphi = meanpos.xPhi() + shift;
295  localeta = meanpos.xEta();
296  }
297 
298  const InDet::SiWidth& width = pix->width();
299 
300  // Error strategies
301 
302  // For very shallow tracks the cluster can easily break as
303  // the average charge per pixel is of the order of the threshold
304  // In this case, an error equal to the geometrical projection
305  // of the track path in silicon onto the module surface seems
306  // appropriate
307  if (std::abs(angle) > 1) {
308  errphi = 250 * micrometer * std::tan(std::abs(angle)) * TOPHAT_SIGMA;
309  erreta = width.z() > 250 * micrometer * std::tan(std::abs(boweta)) ?
310  width.z() * TOPHAT_SIGMA : 250 * micrometer * std::tan(std::abs(boweta)) * TOPHAT_SIGMA;
311  ATH_MSG_VERBOSE("Shallow track with tanl = " << tanl << " bowphi = " <<
312  bowphi << " angle = " << angle << " width.z = " << width.z() <<
313  " errphi = " << errphi << " erreta = " << erreta);
314  }else if (m_errorStrategy == 0) {
315  errphi = width.phiR() * TOPHAT_SIGMA;
316  erreta = width.z() * TOPHAT_SIGMA;
317  }else if (m_errorStrategy == 1) {
318  errphi = (width.phiR() / nrows) * TOPHAT_SIGMA;
319  erreta = (width.z() / ncol) * TOPHAT_SIGMA;
320  }else if (m_errorStrategy == 2) {
321  std::pair<double,double> delta_err = offlineITkCalibDataHandle->getClusterErrorData()->getDeltaError(&element_id);
322  errphi = nrows != 1 ? delta_err.first : (width.phiR()/nrows)*TOPHAT_SIGMA;
323  erreta = ncol != 1 ? delta_err.second : (width.z()/ncol)*TOPHAT_SIGMA;
324  }
325 
326  Amg::Vector2D locpos = Amg::Vector2D(localphi, localeta);
327  locpar = Trk::LocalParameters(locpos);
328  centroid = InDetDD::SiLocalPosition(localeta, localphi, 0.);
329  glob = element->globalPosition(centroid);
330  }
331 
332  // Error matrix production
333 
334  Amg::MatrixX cov = pix->localCovariance();
335 
336  // corrected phi error
337  if (errphi > 0) {
338  cov(0, 0) = errphi * errphi;
339  }
340  if (erreta > 0) {
341  cov(1, 1) = erreta * erreta;
342  }
343 
344  ATH_MSG_VERBOSE(" errphi = " << errphi << " erreta = " << erreta);
345 
346  // create new copy of error matrix
347  if (!m_pixelErrorScalingKey.key().empty()) {
349  cov = Trk::ErrorScalingCast<PixelRIO_OnTrackErrorScaling>(*error_scaling)
350  ->getScaledCovariance(std::move(cov), *m_pixelid,
351  element->identify());
352  }
353  bool isbroad = m_errorStrategy == 0;
354  return new InDet::PixelClusterOnTrack(pix, std::move(locpar),
355  std::move(cov),
356  iH, glob, pix->gangedPixel(), isbroad);
357 }
358 
359 
362  (const Trk::PrepRawData &rio, const Trk::TrackParameters &trackPar,
363  const ITk::PixelClusterStrategy strategy) const {
364  int initial_errorStrategy;
366 
367  switch (strategy) {
368  case PixelClusterStrategy::OUTLIER: // if cluster is outlier, increase errors
370  initial_errorStrategy = m_errorStrategy;
371  m_errorStrategy = 0; // error as size of cluster /sqrt(12)
372  newROT = correct(rio, trackPar);
373  m_errorStrategy = initial_errorStrategy;
374  return newROT;
375 
376  default:
377  return correct(rio, trackPar);
378  }
379 }
380 
381 // GP: NEW correct() method in case of NN based calibration */
384  (const Trk::PrepRawData &rio,
385  const Trk::TrackParameters &trackPar) const {
386 
387  const InDet::PixelCluster *pixelPrepCluster = nullptr;
389  pixelPrepCluster = static_cast<const InDet::PixelCluster *>(&rio);
390  }
391 
392  if (pixelPrepCluster == nullptr) {
393  ATH_MSG_WARNING("This is not a pixel cluster, return 0.");
394  return nullptr;
395  }
396 
397  const InDetDD::SiDetectorElement *element = pixelPrepCluster->detectorElement();
398  if (!element) {
399  ATH_MSG_WARNING("Cannot access detector element. Aborting cluster correction...");
400  return nullptr;
401  }
402 
403  IdentifierHash iH = element->identifyHash();
404 
405  if (m_doNotRecalibrateNN) {
406  Amg::Vector3D glob(pixelPrepCluster->globalPosition());
407 
408  Amg::Vector2D locpos = pixelPrepCluster->localPosition();
410  Amg::MatrixX cov = pixelPrepCluster->localCovariance();
411 
412  return new InDet::PixelClusterOnTrack(pixelPrepCluster, std::move(locpar),
413  std::move(cov), iH, glob,
414  pixelPrepCluster->gangedPixel(), false);
415  }
416 
417 
418 
419  Amg::Vector2D finalposition;
420  Amg::MatrixX finalerrormatrix;
421 
422  if (m_usingTIDE_Ambi) {
423  if (!getErrorsTIDE_Ambi(pixelPrepCluster, trackPar, finalposition, finalerrormatrix)) {
424  return correctDefault(rio, trackPar);
425  }
426  }else {
427  if (!getErrorsDefaultAmbi(pixelPrepCluster, trackPar, finalposition, finalerrormatrix)) {
428  return correctDefault(rio, trackPar);
429  }
430  }
431 
432  ATH_MSG_DEBUG( " Old position x: " << pixelPrepCluster->localPosition()[0]
433  << " +/- " << std::sqrt(pixelPrepCluster->localCovariance()(0, 0))
434  << " y: " << pixelPrepCluster->localPosition()[1]
435  << " +/- " << std::sqrt(pixelPrepCluster->localCovariance()(1, 1)) <<"\n"
436  << " Final position x: " << finalposition[0]
437  << " +/- " << std::sqrt(finalerrormatrix(0, 0))
438  << " y: " << finalposition[1] << " +/- "
439  <<std::sqrt(finalerrormatrix(1, 1)) );
440 
441  Amg::MatrixX cov = finalerrormatrix;
442  // create new copy of error matrix
443  if (!m_pixelErrorScalingKey.key().empty()) {
445  cov = Trk::ErrorScalingCast<PixelRIO_OnTrackErrorScaling>(*error_scaling)
446  ->getScaledCovariance(std::move(cov), *m_pixelid,
447  element->identify());
448  }
449 
451  finalposition[0],
452  0);
453  Trk::LocalParameters locpar = Trk::LocalParameters(finalposition);
454 
455  const Amg::Vector3D &glob = element->globalPosition(centroid);
456 
457 
458  return new InDet::PixelClusterOnTrack(pixelPrepCluster,
459  std::move(locpar),
460  std::move(cov), iH,
461  glob,
462  pixelPrepCluster->gangedPixel(),
463  false);
464 }
465 
466 bool
468  const Trk::TrackParameters &trackPar,
469  Amg::Vector2D &finalposition,
470  Amg::MatrixX &finalerrormatrix) const {
471  std::vector<Amg::Vector2D> vectorOfPositions;
472  int numberOfSubclusters = 1;
473  vectorOfPositions.push_back(pixelPrepCluster->localPosition());
474 
475  if (m_applyNNcorrection){
477  InDet::PixelGangedClusterAmbiguities::const_iterator mapBegin = splitClusterMap->begin();
478  InDet::PixelGangedClusterAmbiguities::const_iterator mapEnd = splitClusterMap->end();
479  for (InDet::PixelGangedClusterAmbiguities::const_iterator mapIter = mapBegin; mapIter != mapEnd; ++mapIter) {
480  const InDet::SiCluster *first = (*mapIter).first;
481  const InDet::SiCluster *second = (*mapIter).second;
482  if (first == pixelPrepCluster && second != pixelPrepCluster) {
483  ATH_MSG_DEBUG("Found additional split cluster in ambiguity map (+=1).");
484  numberOfSubclusters += 1;
485  const InDet::SiCluster *otherOne = second;
486  const InDet::PixelCluster *pixelAddCluster = nullptr;
487  if (otherOne->type(Trk::PrepRawDataType::PixelCluster)) {
488  pixelAddCluster = static_cast<const InDet::PixelCluster *>(otherOne);
489  }
490  if (pixelAddCluster == nullptr) {
491  ATH_MSG_WARNING("Pixel ambiguity map has empty pixel cluster. Please DEBUG!");
492  continue;
493  }
494  vectorOfPositions.push_back(pixelAddCluster->localPosition());
495 
496  ATH_MSG_DEBUG( "Found one more pixel cluster. Position x: "
497  << pixelAddCluster->localPosition()[0] << "y: " << pixelAddCluster->localPosition()[1]);
498  }// find relevant element of map
499  }// iterate over map
500  }
501 
502  // now you have numberOfSubclusters and the vectorOfPositions (Amg::Vector2D)
503 
504  if (trackPar.surfaceType() != Trk::SurfaceType::Plane ||
505  trackPar.type() != Trk::AtaSurface) {
507  "Parameters are not at a plane ! Aborting cluster correction... ");
508  return false;
509  }
510 
511  std::vector<Amg::Vector2D> allLocalPositions;
512  std::vector<Amg::MatrixX> allErrorMatrix;
513  allLocalPositions =
514  m_NnClusterizationFactory->estimatePositions(*pixelPrepCluster,
515  trackPar.associatedSurface(),
516  trackPar,
517  allErrorMatrix,
518  numberOfSubclusters);
519 
520  if (allLocalPositions.empty()) {
521  ATH_MSG_DEBUG( " Cluster cannot be treated by NN. Giving back to default clusterization " );
522 
523  return false;
524  }
525 
526  if (allLocalPositions.size() != size_t(numberOfSubclusters)) {
527  ATH_MSG_WARNING( "Returned position vector size " << allLocalPositions.size() <<
528  " not according to expected number of subclusters: " << numberOfSubclusters << ". Abort cluster correction..." );
529  return false;
530  }
531 
532 
533  // GP: now the not so nice part of matching the new result with the old one...
534  // Takes the error into account to improve the matching
535 
536  if (numberOfSubclusters == 1) {
537  finalposition = allLocalPositions[0];
538  finalerrormatrix = allErrorMatrix[0];
539  }
540 
541  else if (numberOfSubclusters == 2) {
542  double distancesq1 =
543  square(vectorOfPositions[0][0] - allLocalPositions[0][0]) / allErrorMatrix[0](0, 0) +
544  square(vectorOfPositions[1][0] - allLocalPositions[1][0]) / allErrorMatrix[1](0, 0) +
545  square(vectorOfPositions[0][1] - allLocalPositions[0][1]) / allErrorMatrix[0](1, 1) +
546  square(vectorOfPositions[1][1] - allLocalPositions[1][1]) / allErrorMatrix[1](1, 1);
547 
548  double distancesq2 =
549  square(vectorOfPositions[1][0] - allLocalPositions[0][0]) / allErrorMatrix[0](0, 0) +
550  square(vectorOfPositions[0][0] - allLocalPositions[1][0]) / allErrorMatrix[1](0, 0) +
551  square(vectorOfPositions[1][1] - allLocalPositions[0][1]) / allErrorMatrix[0](1, 1) +
552  square(vectorOfPositions[0][1] - allLocalPositions[1][1]) / allErrorMatrix[1](1, 1);
553 
555  " Old pix (1) x: " << vectorOfPositions[0][0] << " y: " << vectorOfPositions[0][1] << "\n"
556  << " Old pix (2) x: " << vectorOfPositions[1][0] << " y: " << vectorOfPositions[1][1] << "\n"
557  << " Pix (1) x: " << allLocalPositions[0][0] << " +/- " << std::sqrt(allErrorMatrix[0](0, 0))
558  << " y: " << allLocalPositions[0][1] << " +/- " << std::sqrt(allErrorMatrix[0](1, 1)) <<"\n"
559  << " Pix (2) x: " << allLocalPositions[1][0] << " +/- " << std::sqrt(allErrorMatrix[1](0, 0))
560  << " y: " << allLocalPositions[1][1] << " +/- " << std::sqrt(allErrorMatrix[1](1, 1)) << "\n"
561  << " Old (1) new (1) dist: " << std::sqrt(distancesq1) << " Old (1) new (2) " << std::sqrt(distancesq2) );
562 
563 
564  if (distancesq1 < distancesq2) {
565  finalposition = allLocalPositions[0];
566  finalerrormatrix = allErrorMatrix[0];
567  }else {
568  finalposition = allLocalPositions[1];
569  finalerrormatrix = allErrorMatrix[1];
570  }
571  }
572 
573 
574  else if (numberOfSubclusters == 3) {
575  double distances[6];
576 
577  distances[0] = distance(vectorOfPositions, allLocalPositions, allErrorMatrix, 0, 1, 2);
578  distances[1] = distance(vectorOfPositions, allLocalPositions, allErrorMatrix, 0, 2, 1);
579  distances[2] = distance(vectorOfPositions, allLocalPositions, allErrorMatrix, 1, 0, 2);
580  distances[3] = distance(vectorOfPositions, allLocalPositions, allErrorMatrix, 1, 2, 0);
581  distances[4] = distance(vectorOfPositions, allLocalPositions, allErrorMatrix, 2, 0, 1);
582  distances[5] = distance(vectorOfPositions, allLocalPositions, allErrorMatrix, 2, 1, 0);
583 
584  int smallestDistanceIndex = -10;
585  double minDistance = 1e10;
586 
587  for (int i = 0; i < 6; i++) {
588  ATH_MSG_VERBOSE(" distance n.: " << i << " distance is: " << distances[i]);
589 
590  if (distances[i] < minDistance) {
591  minDistance = distances[i];
592  smallestDistanceIndex = i;
593  }
594  }
595 
596  ATH_MSG_DEBUG(" The minimum distance is : " << minDistance << " for index: " << smallestDistanceIndex);
597 
598  if (smallestDistanceIndex == 0 || smallestDistanceIndex == 1) {
599  finalposition = allLocalPositions[0];
600  finalerrormatrix = allErrorMatrix[0];
601  }
602  if (smallestDistanceIndex == 2 || smallestDistanceIndex == 4) {
603  finalposition = allLocalPositions[1];
604  finalerrormatrix = allErrorMatrix[1];
605  }
606  if (smallestDistanceIndex == 3 || smallestDistanceIndex == 5) {
607  finalposition = allLocalPositions[2];
608  finalerrormatrix = allErrorMatrix[2];
609  }
610  }
611  return true;
612 }
613 
614 bool
616  const Trk::TrackParameters &trackPar,
617  Amg::Vector2D &finalposition,
618  Amg::MatrixX &finalerrormatrix) const {
620  std::vector<Amg::Vector2D> vectorOfPositions;
621  int numberOfSubclusters = 1;
624  numberOfSubclusters = 1 + splitClusterMap->count(pixelPrepCluster);
625 
626  if (splitClusterMap->count(pixelPrepCluster) == 0 && splitProb.isSplit()) {
627  numberOfSubclusters = 2;
628  }
629  if (splitClusterMap->count(pixelPrepCluster) != 0 && !splitProb.isSplit()) {
630  numberOfSubclusters = 1;
631  }
632  }
633 
634  // now you have numberOfSubclusters and the vectorOfPositions (Amg::Vector2D)
635  if (trackPar.surfaceType() != Trk::SurfaceType::Plane ||
636  trackPar.type() != Trk::AtaSurface) {
637  ATH_MSG_WARNING("Parameters are not at a plane surface ! Aborting cluster "
638  "correction... ");
639  return false;
640  }
641 
642  std::vector<Amg::Vector2D> allLocalPositions;
643  std::vector<Amg::MatrixX> allErrorMatrix;
644  allLocalPositions = m_NnClusterizationFactory->estimatePositions(
645  *pixelPrepCluster,
646  trackPar.associatedSurface(),
647  trackPar,
648  allErrorMatrix,
649  numberOfSubclusters);
650 
651  if (allLocalPositions.empty()) {
653  " Cluster cannot be treated by NN. Giving back to default clusterization, too big: " <<
654  splitProb.isTooBigToBeSplit());
655  return false;
656  }
657 
658  if (allLocalPositions.size() != size_t(numberOfSubclusters)) {
660  "Returned position vector size " << allLocalPositions.size() << " not according to expected number of subclusters: " << numberOfSubclusters <<
661  ". Abort cluster correction...");
662  return false;
663  }
664 
665  // AKM: now the not so nice part find the best match position option
666  // Takes the error into account to scale the importance of the measurement
667 
668  if (numberOfSubclusters == 1) {
669  finalposition = allLocalPositions[0];
670  finalerrormatrix = allErrorMatrix[0];
671  return true;
672  }
673 
674  // Get the track parameters local position
675  const Amg::Vector2D localpos = trackPar.localPosition();
676  // Use the track parameters cov to weight distcances
677  Amg::Vector2D localerr(0.01, 0.05);
678  if (trackPar.covariance()) {
679  localerr = Amg::Vector2D(std::sqrt((*trackPar.covariance())(0, 0)), std::sqrt((*trackPar.covariance())(1, 1)));
680  }
681 
682  double minDistance(1e300);
683  int index(0);
684 
685  for (unsigned int i(0); i < allLocalPositions.size(); ++i) {
686  double distance =
687  square(localpos[0] - allLocalPositions[i][0]) / localerr[0]
688  + square(localpos[1] - allLocalPositions[i][1]) / localerr[1];
689 
690  if (distance < minDistance) {
691  index = i;
692  minDistance = distance;
693  }
694  }
695 
696  finalposition = allLocalPositions[index];
697  finalerrormatrix = allErrorMatrix[index];
698  return true;
699 }
700 
701 } // namespace ITk
ITk::PixelClusterOnTrackTool::m_NnClusterizationFactory
ToolHandle< InDet::NnClusterizationFactory > m_NnClusterizationFactory
NN clusterizationi factory for NN based positions and errors.
Definition: ITkPixelClusterOnTrackTool.h:161
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::strategy
strategy
Definition: L2CombinedMuon_v1.cxx:107
PixelID.h
This is an Identifier helper class for the Pixel subdetector. This class is a factory for creating co...
query_example.row
row
Definition: query_example.py:24
Trk::LocalParameters
Definition: LocalParameters.h:98
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
PixelID::phi_index
int phi_index(const Identifier &id) const
Definition: PixelID.h:658
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:29
ITk::PixelClusterOnTrackTool::m_usingTIDE_Ambi
bool m_usingTIDE_Ambi
Enable different treatment of cluster errors based on NN information (do only if TIDE ambi is run)
Definition: ITkPixelClusterOnTrackTool.h:166
ITk::PixelClusterOnTrackTool::m_splitClusterMapKey
SG::ReadHandleKey< InDet::PixelGangedClusterAmbiguities > m_splitClusterMapKey
Definition: ITkPixelClusterOnTrackTool.h:167
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
max
#define max(a, b)
Definition: cfImp.cxx:41
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
InDetDD::PixelModuleDesign
Definition: PixelModuleDesign.h:48
Trk::ClusterSplitProbabilityContainer::ProbabilityInfo::isSplit
bool isSplit() const
Definition: ClusterSplitProbabilityContainer.h:27
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
index
Definition: index.py:1
Trk::ParametersBase::associatedSurface
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
InDet::SiCluster::type
virtual bool type(Trk::PrepRawDataType type) const override
Interface method checking the type.
Trk::ClusterSplitProbabilityContainer::ProbabilityInfo
Definition: ClusterSplitProbabilityContainer.h:22
InDetDD::SolidStateDetectorElementBase::etaAxis
const Amg::Vector3D & etaAxis() const
Definition: SolidStateDetectorElementBase.cxx:88
Trk::PrepRawData::localCovariance
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
Trk::ParametersBase::surfaceType
constexpr virtual SurfaceType surfaceType() const override=0
Returns the Surface Type enum for the surface used to define the derived class.
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
ITk::PixelClusterOnTrackTool::getClusterSplittingProbability
const Trk::ClusterSplitProbabilityContainer::ProbabilityInfo & getClusterSplittingProbability(const InDet::PixelCluster *pix) const
Definition: ITkPixelClusterOnTrackTool.h:108
M_PI
#define M_PI
Definition: ActiveFraction.h:11
InDetDD::DetectorDesign::readoutSide
int readoutSide() const
ReadoutSide.
Definition: DetectorDesign.h:291
Trk::PrepRawData::type
virtual bool type(PrepRawDataType type) const =0
Interface method checking the type.
ITk::PixelClusterOnTrackTool::correct
virtual InDet::PixelClusterOnTrack * correct(const Trk::PrepRawData &, const Trk::TrackParameters &) const override
produces a PixelClusterOnTrack (object factory!).
Definition: ITkPixelClusterOnTrackTool.cxx:120
ITk::PixelClusterOnTrackTool::m_lorentzAngleTool
ToolHandle< ISiLorentzAngleTool > m_lorentzAngleTool
Definition: ITkPixelClusterOnTrackTool.h:127
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ITk::PixelClusterOnTrackTool::m_noNNandBroadErrors
bool m_noNNandBroadErrors
Definition: ITkPixelClusterOnTrackTool.h:164
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
ITk::PixelClusterOnTrackTool::getErrorsTIDE_Ambi
bool getErrorsTIDE_Ambi(const InDet::PixelCluster *, const Trk::TrackParameters &, Amg::Vector2D &, Amg::MatrixX &) const
Definition: ITkPixelClusterOnTrackTool.cxx:615
x
#define x
InDetDD::SolidStateDetectorElementBase::identifyHash
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
InDetDD::SiLocalPosition
Definition: SiLocalPosition.h:31
ITk::PixelOfflineCalibData::getClusterErrorData
PixelClusterErrorData * getClusterErrorData()
Definition: ITkPixelOfflineCalibData.h:71
InDetDD::PixelModuleDesign::positionFromColumnRow
SiLocalPosition positionFromColumnRow(const int column, const int row) const
Given row and column index of a diode, return position of diode center ALTERNATIVE/PREFERED way is to...
Definition: PixelModuleDesign.cxx:219
InDetDD::SiLocalPosition::xPhi
double xPhi() const
position along phi direction:
Definition: SiLocalPosition.h:123
ITk::PixelClusterOnTrackTool::m_clusterITkErrorKey
SG::ReadCondHandleKey< ITk::PixelOfflineCalibData > m_clusterITkErrorKey
Definition: ITkPixelClusterOnTrackTool.h:129
ITk::PixelClusterOnTrackTool::correctNN
InDet::PixelClusterOnTrack * correctNN(const Trk::PrepRawData &, const Trk::TrackParameters &) const
Definition: ITkPixelClusterOnTrackTool.cxx:384
ITk::PixelClusterOnTrackTool::m_pixelid
const PixelID * m_pixelid
Flag controlling how module distortions are taken into account:
Definition: ITkPixelClusterOnTrackTool.h:154
ITk::PixelClusterOnTrackTool::m_positionStrategy
int m_positionStrategy
toolhandle for central error scaling flag storing if errors need scaling or should be kept nominal
Definition: ITkPixelClusterOnTrackTool.h:136
lumiFormat.i
int i
Definition: lumiFormat.py:92
ITk::PixelClusterOnTrackTool::getErrorsDefaultAmbi
bool getErrorsDefaultAmbi(const InDet::PixelCluster *, const Trk::TrackParameters &, Amg::Vector2D &, Amg::MatrixX &) const
Definition: ITkPixelClusterOnTrackTool.cxx:467
ITk::PixelClusterStrategy::SHARED
@ SHARED
InDetDD::SiLocalPosition::xEta
double xEta() const
position along eta direction:
Definition: SiLocalPosition.h:118
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
angle
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Definition: TRTDetectorFactory_Full.cxx:73
ITk::PixelClusterOnTrackTool::correctDefault
InDet::PixelClusterOnTrack * correctDefault(const Trk::PrepRawData &, const Trk::TrackParameters &) const
The correct method produces a PixelClusterOnTrack using the measured PixelCluster and the track predi...
Definition: ITkPixelClusterOnTrackTool.cxx:157
ITk::PixelClusterStrategy
PixelClusterStrategy
creates PixelClusterOnTrack objects allowing to calibrate cluster position and error using a given tr...
Definition: ITkPixelClusterOnTrackTool.h:52
ITk::PixelClusterOnTrackTool::m_errorStrategy
std::atomic_int m_errorStrategy
Definition: ITkPixelClusterOnTrackTool.h:137
ITk::PixelClusterOnTrackTool::m_pixelErrorScalingKey
SG::ReadCondHandleKey< RIO_OnTrackErrorScaling > m_pixelErrorScalingKey
Definition: ITkPixelClusterOnTrackTool.h:132
PixelID::eta_index
int eta_index(const Identifier &id) const
Definition: PixelID.h:664
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ITk::PixelClusterOnTrackTool::initialize
virtual StatusCode initialize() override
AlgTool initialisation.
Definition: ITkPixelClusterOnTrackTool.cxx:85
ITk::PixelClusterOnTrackTool::m_clusterSplitProbContainer
SG::ReadHandleKey< Trk::ClusterSplitProbabilityContainer > m_clusterSplitProbContainer
Definition: ITkPixelClusterOnTrackTool.h:169
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
Trk::ParametersBase
Definition: ParametersBase.h:55
python.SystemOfUnits.micrometer
int micrometer
Definition: SystemOfUnits.py:71
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
Trk::ParametersBase::type
constexpr virtual ParametersType type() const override=0
Return the ParametersType enum.
InDetDD::SolidStateDetectorElementBase::normal
virtual const Amg::Vector3D & normal() const override final
Get reconstruction local normal axes in global frame.
InDet::SiCluster::detectorElement
virtual const InDetDD::SiDetectorElement * detectorElement() const override final
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
min
#define min(a, b)
Definition: cfImp.cxx:40
Trk::PrepRawData
Definition: PrepRawData.h:62
Trk::ParametersCommon::localPosition
Amg::Vector2D localPosition() const
Access method for the local coordinates, local parameter definitions differ for each surface type.
EventPrimitives.h
PixelID::eta_module
int eta_module(const Identifier &id) const
Definition: PixelID.h:651
Trk::ParametersBase::pT
double pT() const
Access method for transverse momentum.
ITk::PixelClusterErrorData::getDeltaError
std::pair< double, double > getDeltaError(const Identifier *pixelId) const
Definition: ITkPixelClusterErrorData.cxx:56
InDet::SiCluster::gangedPixel
bool gangedPixel() const
return the flag of this cluster containing a gangedPixel
ITk
Definition: ITkPixelOfflineCalibCondAlg.cxx:14
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
Trk::PrepRawDataType::PixelCluster
@ PixelCluster
Trk::PrepRawData::localPosition
const Amg::Vector2D & localPosition() const
return the local position reference
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
ITk::PixelClusterOnTrackTool::m_applyNNcorrection
bool m_applyNNcorrection
Enable NN based calibration (do only if NN calibration is applied)
Definition: ITkPixelClusterOnTrackTool.h:157
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
ITk::PixelClusterOnTrackTool::m_doNotRecalibrateNN
bool m_doNotRecalibrateNN
Definition: ITkPixelClusterOnTrackTool.h:163
query_example.col
col
Definition: query_example.py:7
SiDetectorElement.h
ErrorScalingCast.h
Trk::ClusterSplitProbabilityContainer::ProbabilityInfo::isTooBigToBeSplit
bool isTooBigToBeSplit() const
Definition: ClusterSplitProbabilityContainer.h:26
ITk::PixelClusterErrorData::getDelta
std::pair< double, double > getDelta(const Identifier *pixelId, int sizePhi, double angle, int sizeZ, double eta) const
Methods to access the calibration data.
Definition: ITkPixelClusterErrorData.cxx:35
InDet::PixelCluster
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/PixelCluster.h:49
ITk::PixelClusterOnTrackTool::m_applyNNcorrectionProperty
BooleanProperty m_applyNNcorrectionProperty
Definition: ITkPixelClusterOnTrackTool.h:158
Trk::AtaSurface
@ AtaSurface
Definition: ParametersCommon.h:29
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
InDet::SiCluster::globalPosition
const Amg::Vector3D & globalPosition() const
return global position reference
DeMoScan.index
string index
Definition: DeMoScan.py:362
ITk::PixelClusterOnTrackTool::PixelClusterOnTrackTool
PixelClusterOnTrackTool(const std::string &, const std::string &, const IInterface *)
AlgTool constructor.
Definition: ITkPixelClusterOnTrackTool.cxx:60
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
InDet::PixelClusterOnTrack
Definition: PixelClusterOnTrack.h:51
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
PixelModuleDesign.h
ITk::PixelClusterOnTrackTool::m_errorStrategyProperty
IntegerProperty m_errorStrategyProperty
Definition: ITkPixelClusterOnTrackTool.h:138
InDetDD::SolidStateDetectorElementBase::globalPosition
HepGeom::Point3D< double > globalPosition(const HepGeom::Point3D< double > &localPos) const
transform a reconstruction local position into a global position (inline):
PlaneSurface.h
eFEXNTuple.delta_phi
def delta_phi(phi1, phi2)
Definition: eFEXNTuple.py:15
InDetDD::SolidStateDetectorElementBase::phiAxis
const Amg::Vector3D & phiAxis() const
Definition: SolidStateDetectorElementBase.cxx:74
DeMoScan.first
bool first
Definition: DeMoScan.py:534
ITk::PixelClusterStrategy::OUTLIER
@ OUTLIER
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
InDet::SiWidth
Definition: SiWidth.h:25
Trk::ParametersBase::eta
double eta() const
Access method for pseudorapidity - from momentum.
Trk::SurfaceType::Plane
@ Plane
AthAlgTool
Definition: AthAlgTool.h:26
IdentifierHash
Definition: IdentifierHash.h:38
pix
Definition: PixelMapping.cxx:16
InDetDD::SiDetectorElement::design
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
PixelID::phi_module
int phi_module(const Identifier &id) const
Definition: PixelID.h:644
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
ITkPixelClusterOnTrackTool.h
InDet::SiCluster
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/SiCluster.h:40
InDetDD::SolidStateDetectorElementBase::identify
virtual Identifier identify() const override final
identifier of this detector element (inline)
NSWL1::centroid
Vertex centroid(const Polygon &p)
Definition: GeoUtils.cxx:59
fitman.k
k
Definition: fitman.py:528