CMS 3D CMS Logo

RPixPlaneCombinatoryTracking.cc
Go to the documentation of this file.
3 
4 #include <algorithm>
5 #include <cmath>
6 #include <memory>
7 
11 #include "TMath.h"
12 
14 
15 //------------------------------------------------------------------------------------------------//
16 
19  trackMinNumberOfPoints_ = parameterSet.getParameter<uint>("trackMinNumberOfPoints");
20  verbosity_ = parameterSet.getUntrackedParameter<int>("verbosity");
21  maximumChi2OverNDF_ = parameterSet.getParameter<double>("maximumChi2OverNDF");
22  maximumXLocalDistanceFromTrack_ = parameterSet.getParameter<double>("maximumXLocalDistanceFromTrack");
23  maximumYLocalDistanceFromTrack_ = parameterSet.getParameter<double>("maximumYLocalDistanceFromTrack");
24  numberOfPlanesPerPot_ = parameterSet.getParameter<int>("numberOfPlanesPerPot");
25 
26  if (trackMinNumberOfPoints_ < 3) {
27  throw cms::Exception("RPixPlaneCombinatoryTracking")
28  << "Minimum number of planes required for tracking is 3, "
29  << "tracking is not possible with " << trackMinNumberOfPoints_ << " hits";
30  }
31 }
32 
33 //------------------------------------------------------------------------------------------------//
34 
36 
37 //------------------------------------------------------------------------------------------------//
38 
40  uint32_t numberOfCombinations =
43  if (verbosity_ >= 2)
44  edm::LogInfo("RPixPlaneCombinatoryTracking") << "Number of combinations = " << numberOfCombinations;
45  possiblePlaneCombinations_.reserve(numberOfCombinations);
46 
48 
49  if (verbosity_ >= 2) {
50  for (const auto &vec : possiblePlaneCombinations_) {
51  for (const auto &num : vec) {
52  edm::LogInfo("RPixPlaneCombinatoryTracking") << num << " - ";
53  }
54  edm::LogInfo("RPixPlaneCombinatoryTracking");
55  }
56  }
57 }
58 
59 //------------------------------------------------------------------------------------------------//
60 
61 //This function produces all the possible plane combinations extracting numberToExtract planes over numberOfPlanes planes
62 void RPixPlaneCombinatoryTracking::getPlaneCombinations(const std::vector<uint32_t> &inputPlaneList,
63  uint32_t numberToExtract,
64  PlaneCombinations &planeCombinations) const {
65  uint32_t numberOfPlanes = inputPlaneList.size();
66  std::string bitmask(numberToExtract, 1); // numberToExtract leading 1's
67  bitmask.resize(numberOfPlanes, 0); // numberOfPlanes-numberToExtract trailing 0's
68  planeCombinations.clear();
69 
70  // store the combination and permute bitmask
71  do {
72  planeCombinations.emplace_back();
73  for (uint32_t i = 0; i < numberOfPlanes; ++i) { // [0..numberOfPlanes-1] integers
74  if (bitmask[i])
75  planeCombinations.back().push_back(inputPlaneList.at(i));
76  }
77  } while (std::prev_permutation(bitmask.begin(), bitmask.end()));
78 
79  return;
80 }
81 
82 //------------------------------------------------------------------------------------------------//
83 
84 //This function calls it self in order to get all the possible combinations of hits having a certain selected number of planes
85 //This function avoids to write for loops in cascade which will not allow to define arbitrarily the minimum number of planes to use
86 //The output is stored in a map containing the vector of points and as a key the map of the point forming this vector.
87 //This allows to erase the points already used for the track fit
88 void RPixPlaneCombinatoryTracking::getHitCombinations(const std::map<CTPPSPixelDetId, PointInPlaneList> &mapOfAllHits,
89  std::map<CTPPSPixelDetId, PointInPlaneList>::iterator mapIterator,
90  HitReferences tmpHitPlaneMap,
91  const PointInPlaneList &tmpHitVector,
92  PointAndReferenceMap &outputMap) {
93  //At this point I selected one hit per plane
94  if (mapIterator == mapOfAllHits.end()) {
95  outputMap[tmpHitPlaneMap] = tmpHitVector;
96  return;
97  }
98  for (size_t i = 0; i < mapIterator->second.size(); i++) {
99  HitReferences newHitPlaneMap = tmpHitPlaneMap;
100  newHitPlaneMap[mapIterator->first] = i;
101  PointInPlaneList newVector = tmpHitVector;
102  newVector.push_back(mapIterator->second[i]);
103  std::map<CTPPSPixelDetId, PointInPlaneList>::iterator tmpMapIterator = mapIterator;
104  getHitCombinations(mapOfAllHits, ++tmpMapIterator, newHitPlaneMap, newVector, outputMap);
105  }
106 }
107 
108 //------------------------------------------------------------------------------------------------//
109 
111  PlaneCombinations inputPlaneCombination) {
112  PointAndReferenceMap mapOfAllPoints;
113  CTPPSPixelDetId tmpRpId = romanPotId_; //in order to avoid to modify the data member
114 
115  if (verbosity_ >= 2)
116  edm::LogInfo("RPixPlaneCombinatoryTracking") << "Searching for all combinations...";
117  //Loop on all the plane combinations
118  for (const auto &planeCombination : inputPlaneCombination) {
119  std::map<CTPPSPixelDetId, PointInPlaneList> selectedCombinationHitOnPlane;
120  bool allPlaneAsHits = true;
121 
122  //Loop on all the possible combinations
123  //In this loop the selectedCombinationHitOnPlane is filled
124  //and cases in which one of the selected plane is empty are skipped
125  for (const auto &plane : planeCombination) {
126  tmpRpId.setPlane(plane);
127  CTPPSPixelDetId planeDetId = tmpRpId;
128  if (hitMap_->find(planeDetId) == hitMap_->end()) {
129  if (verbosity_ >= 2)
130  edm::LogInfo("RPixPlaneCombinatoryTracking")
131  << "No data on arm " << planeDetId.arm() << " station " << planeDetId.station() << " rp "
132  << planeDetId.rp() << " plane " << planeDetId.plane();
133  allPlaneAsHits = false;
134  break;
135  }
136  if (selectedCombinationHitOnPlane.find(planeDetId) != selectedCombinationHitOnPlane.end()) {
137  throw cms::Exception("RPixPlaneCombinatoryTracking")
138  << "selectedCombinationHitOnPlane contains already detId " << planeDetId
139  << "Error in the algorithm which created all the possible plane combinations";
140  }
141  selectedCombinationHitOnPlane[planeDetId] = (*hitMap_)[planeDetId];
142  }
143  if (!allPlaneAsHits)
144  continue;
145 
146  //I add the all the hit combinations to the full list of plane combinations
147  auto mapIterator = selectedCombinationHitOnPlane.begin();
148  HitReferences tmpHitPlaneMap; //empty map of plane id and hit number needed the getHitCombinations algorithm
149  PointInPlaneList tmpHitVector; //empty vector of hits needed for the getHitCombinations algorithm
150  getHitCombinations(selectedCombinationHitOnPlane, mapIterator, tmpHitPlaneMap, tmpHitVector, mapOfAllPoints);
151  if (verbosity_ >= 2)
152  edm::LogInfo("RPixPlaneCombinatoryTracking") << "Number of possible tracks " << mapOfAllPoints.size();
153 
154  } //end of loops on all the combinations
155 
156  return mapOfAllPoints;
157 }
158 
159 //------------------------------------------------------------------------------------------------//
160 
162  //The loop search for all the possible tracks starting from the one with the smallest chiSquare/NDF
163  //The loop stops when the number of planes with recorded hits is less than the minimum number of planes required
164  //or if the track with minimum chiSquare found has a chiSquare higher than the maximum required
165 
166  // bad Pot patch -- beginning
167  // check number of hits in road
168  unsigned int hitNum = 0;
169  for (const auto &plane : *hitMap_) {
170  hitNum += plane.second.size();
171  }
172 
173  if (hitMap_->size() == 2 && hitNum == 2) { // look for roads with 2 hits in 2 different planes
174 
175  GlobalPoint hit[2];
176  PointInPlaneList pIPL;
177 
178  unsigned int i = 0;
179  for (const auto &plane : *hitMap_) {
180  if (plane.second.size() > 1)
181  break; // only 1 hit per plane per road allowed
182  GlobalPoint gP(plane.second[0].globalPoint.x(), plane.second[0].globalPoint.y(), plane.second[0].globalPoint.z());
183  hit[i] = gP;
184  i++;
185  pIPL.push_back(plane.second[0]);
186  }
187 
188  // calculate 2 point track parameters (no need of fits)
189  double tx = (hit[0].x() - hit[1].x()) / (hit[0].z() - hit[1].z());
190  double ty = (hit[0].y() - hit[1].y()) / (hit[0].z() - hit[1].z());
191  double xat0 = (hit[1].x() * hit[0].z() - hit[0].x() * hit[1].z()) / (hit[0].z() - hit[1].z());
192  double yat0 = (hit[1].y() * hit[0].z() - hit[0].y() * hit[1].z()) / (hit[0].z() - hit[1].z());
193  double z0 = geometry_->rpTranslation(romanPotId_).z();
194  double xatz0 = xat0 + tx * z0;
195  double yatz0 = yat0 + ty * z0;
196 
197  math::Vector<4>::type parameterVector{xatz0, yatz0, tx, ty};
198  ROOT::Math::SVector<double, 10> v(0.01, 0.0, 0.01, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.01);
199  math::Error<4>::type covarianceMatrix(v);
200 
201  CTPPSPixelLocalTrack track(z0, parameterVector, covarianceMatrix, 0);
202 
203  // save used points into track
204  for (const auto &hhit : pIPL) {
205  GlobalPoint pOD(hhit.globalPoint.x(), hhit.globalPoint.y(), hhit.globalPoint.z());
206  LocalPoint res(0, 0);
207  LocalPoint pulls(0, 0);
208  CTPPSPixelFittedRecHit usedRecHit(hhit.recHit, pOD, res, pulls);
209  usedRecHit.setIsRealHit(true);
210  track.addHit(hhit.detId, usedRecHit);
211  }
212 
213  // save track in collection
214  localTrackVector_.push_back(track);
215  }
216  // bad Pot patch -- end
217 
218  while (hitMap_->size() >= trackMinNumberOfPoints_) {
219  if (verbosity_ >= 1)
220  edm::LogInfo("RPixPlaneCombinatoryTracking") << "Number of plane with hits " << hitMap_->size();
221  if (verbosity_ >= 2)
222  for (const auto &plane : *hitMap_)
223  edm::LogInfo("RPixPlaneCombinatoryTracking")
224  << "\tarm " << plane.first.arm() << " station " << plane.first.station() << " rp " << plane.first.rp()
225  << " plane " << plane.first.plane() << " : " << plane.second.size();
226 
227  //I create the map of all the possible combinations of a group of trackMinNumberOfPoints_ points
228  //and the key keeps the reference of which planes and which hit numbers form the combination
229  PointAndReferenceMap mapOfAllMinRequiredPoint;
230  //I produce the map for all cominations of all hits with all trackMinNumberOfPoints_ plane combinations
231  mapOfAllMinRequiredPoint = produceAllHitCombination(possiblePlaneCombinations_);
232 
233  //Fit all the possible combinations with minimum number of planes required and find the track with minimum chi2
234  double theMinChiSquaredOverNDF = maximumChi2OverNDF_ + 1.; //in order to break the loop in case no track is found;
235  HitReferences pointMapWithMinChiSquared;
236  PointInPlaneList pointsWithMinChiSquared;
237  CTPPSPixelLocalTrack bestTrack;
238 
239  if (verbosity_ >= 2)
240  edm::LogInfo("RPixPlaneCombinatoryTracking")
241  << "Number of combinations of trackMinNumberOfPoints_ planes " << mapOfAllMinRequiredPoint.size();
242  for (const auto &pointsAndRef : mapOfAllMinRequiredPoint) {
243  CTPPSPixelLocalTrack tmpTrack = fitTrack(pointsAndRef.second);
244  double tmpChiSquaredOverNDF = tmpTrack.chiSquaredOverNDF();
245  if (verbosity_ >= 2)
246  edm::LogInfo("RPixPlaneCombinatoryTracking") << "ChiSquare of the present track " << tmpChiSquaredOverNDF;
247  if (!tmpTrack.isValid() || tmpChiSquaredOverNDF > maximumChi2OverNDF_ || tmpChiSquaredOverNDF == 0.)
248  continue; //validity check
249  if (tmpChiSquaredOverNDF < theMinChiSquaredOverNDF) {
250  theMinChiSquaredOverNDF = tmpChiSquaredOverNDF;
251  pointMapWithMinChiSquared = pointsAndRef.first;
252  pointsWithMinChiSquared = pointsAndRef.second;
253  bestTrack = tmpTrack;
254  }
255  }
256 
257  //The loop on the fit of all tracks is done, the track with minimum chiSquared is found
258  // and it is verified that it complies with the maximumChi2OverNDF_ requirement
259  if (theMinChiSquaredOverNDF > maximumChi2OverNDF_)
260  break;
261 
262  //The list of planes not included in the minimum chiSquare track is produced.
263  std::vector<uint32_t> listOfExcludedPlanes;
264  for (const auto &plane : listOfAllPlanes_) {
265  CTPPSPixelDetId tmpRpId = romanPotId_; //in order to avoid to modify the data member
266  tmpRpId.setPlane(plane);
267  CTPPSPixelDetId planeDetId = tmpRpId;
268  if (pointMapWithMinChiSquared.find(planeDetId) == pointMapWithMinChiSquared.end())
269  listOfExcludedPlanes.push_back(plane);
270  }
271 
272  //I produce all the possible combinations of planes to be added to the track,
273  //excluding the case of no other plane added since it has been already fitted.
274  PlaneCombinations planePointedHitListCombination;
275  for (uint32_t i = 1; i <= listOfExcludedPlanes.size(); ++i) {
276  PlaneCombinations tmpPlaneCombination;
277  getPlaneCombinations(listOfExcludedPlanes, i, tmpPlaneCombination);
278  for (const auto &combination : tmpPlaneCombination)
279  planePointedHitListCombination.push_back(combination);
280  }
281 
282  //I produce all the possible combinations of points to be added to the track
283  PointAndReferenceMap mapOfAllPointWithAtLeastBestFitSelected;
284  PointAndReferenceMap mapOfPointCombinationToBeAdded;
285  mapOfPointCombinationToBeAdded = produceAllHitCombination(planePointedHitListCombination);
286  //The found hit combination is added to the hits selected by the best fit;
287  for (const auto &element : mapOfPointCombinationToBeAdded) {
288  HitReferences newPointMap = pointMapWithMinChiSquared;
289  PointInPlaneList newPoints = pointsWithMinChiSquared;
290  for (const auto &pointRef : element.first)
291  newPointMap[pointRef.first] = pointRef.second; //add the new point reference
292  for (const auto &point : element.second)
293  newPoints.push_back(point);
294  mapOfAllPointWithAtLeastBestFitSelected[newPointMap] = newPoints;
295  }
296 
297  //I fit all the possible combination of the minimum plane best fit hits plus hits from the other planes
298  if (verbosity_ >= 1)
299  edm::LogInfo("RPixPlaneCombinatoryTracking")
300  << "Minimum chiSquare over NDF for all the tracks " << theMinChiSquaredOverNDF;
301 
302  // I look for the tracks with maximum number of points with a chiSquare over NDF smaller than maximumChi2OverNDF_
303  // If more than one track fulfill the chiSquare requirement with the same number of points I choose the one with smaller chiSquare
304  std::vector<PointAndReferencePair> orderedVectorOfAllPointWithAtLeastBestFitSelected =
305  orderCombinationsPerNumberOrPoints(mapOfAllPointWithAtLeastBestFitSelected);
306  int currentNumberOfPlanes = 0;
307  theMinChiSquaredOverNDF = maximumChi2OverNDF_ + 1.; //in order to break the loop in case no track is found;
308  bool foundTrackWithCurrentNumberOfPlanes = false;
309  for (const auto &pointsAndRef : orderedVectorOfAllPointWithAtLeastBestFitSelected) {
310  int tmpNumberOfPlanes = pointsAndRef.second.size();
311  // If a valid track has been already found with an higher number of planes the loop stops.
312  if (foundTrackWithCurrentNumberOfPlanes && tmpNumberOfPlanes < currentNumberOfPlanes)
313  break;
314  CTPPSPixelLocalTrack tmpTrack = fitTrack(pointsAndRef.second);
315  double tmpChiSquaredOverNDF = tmpTrack.chiSquaredOverNDF();
316  if (!tmpTrack.isValid() || tmpChiSquaredOverNDF > maximumChi2OverNDF_ || tmpChiSquaredOverNDF == 0.)
317  continue; //validity check
318  if (tmpChiSquaredOverNDF < theMinChiSquaredOverNDF) {
319  theMinChiSquaredOverNDF = tmpChiSquaredOverNDF;
320  pointMapWithMinChiSquared = pointsAndRef.first;
321  bestTrack = tmpTrack;
322  currentNumberOfPlanes = tmpNumberOfPlanes;
323  foundTrackWithCurrentNumberOfPlanes = true;
324  }
325  }
326 
327  if (verbosity_ >= 1)
328  edm::LogInfo("RPixPlaneCombinatoryTracking") << "The best track has " << bestTrack.ndf() / 2 + 2;
329 
330  std::vector<uint32_t> listOfPlaneNotUsedForFit = listOfAllPlanes_;
331  //remove the hits belonging to the tracks from the full list of hits
332  for (const auto &hitToErase : pointMapWithMinChiSquared) {
333  std::map<CTPPSPixelDetId, PointInPlaneList>::iterator hitMapElement = hitMap_->find(hitToErase.first);
334  if (hitMapElement == hitMap_->end()) {
335  throw cms::Exception("RPixPlaneCombinatoryTracking")
336  << "The found tracks has hit belonging to a plane which does not have hits";
337  }
338  std::vector<uint32_t>::iterator planeIt;
339  planeIt = std::find(listOfPlaneNotUsedForFit.begin(), listOfPlaneNotUsedForFit.end(), hitToErase.first.plane());
340  listOfPlaneNotUsedForFit.erase(planeIt);
341  hitMapElement->second.erase(hitMapElement->second.begin() + hitToErase.second);
342  //if the plane at which the hit was erased is empty it is removed from the hit map
343  if (hitMapElement->second.empty())
344  hitMap_->erase(hitMapElement);
345  }
346 
347  //search for hit on the other planes which may belong to the same track
348  //even if they did not contributed to the track
349  //in case of multiple hit, the closest one to the track will be considered
350  //If a hit is found these will not be erased from the list of all hits
351  //If no hit is found, the point on the plane intersecting the track will be saved by a CTPPSPixelFittedRecHit
352  //with the isRealHit_ flag set to false
353  for (const auto &plane : listOfPlaneNotUsedForFit) {
354  CTPPSPixelDetId tmpPlaneId = romanPotId_; //in order to avoid to modify the data member
355  tmpPlaneId.setPlane(plane);
356  std::unique_ptr<CTPPSPixelFittedRecHit> fittedRecHit(new CTPPSPixelFittedRecHit());
357  GlobalPoint pointOnDet;
358  calculatePointOnDetector(&bestTrack, tmpPlaneId, pointOnDet);
359 
360  if (hitMap_->find(tmpPlaneId) != hitMap_->end()) {
361  //I convert the hit search window defined in local coordinated into global
362  //This avoids to convert the global plane-line intersection in order not to call the the geometry
363  math::Vector<3>::type maxGlobalPointDistance(
365 
366  DetGeomDesc::RotationMatrix theRotationMatrix = geometry_->sensor(tmpPlaneId)->rotation();
367  AlgebraicMatrix33 tmpPlaneRotationMatrixMap;
368  theRotationMatrix.GetComponents(tmpPlaneRotationMatrixMap(0, 0),
369  tmpPlaneRotationMatrixMap(0, 1),
370  tmpPlaneRotationMatrixMap(0, 2),
371  tmpPlaneRotationMatrixMap(1, 0),
372  tmpPlaneRotationMatrixMap(1, 1),
373  tmpPlaneRotationMatrixMap(1, 2),
374  tmpPlaneRotationMatrixMap(2, 0),
375  tmpPlaneRotationMatrixMap(2, 1),
376  tmpPlaneRotationMatrixMap(2, 2));
377 
378  maxGlobalPointDistance = tmpPlaneRotationMatrixMap * maxGlobalPointDistance;
379  //I avoid the Sqrt since it will not be saved
380  double maximumXdistance = maxGlobalPointDistance[0] * maxGlobalPointDistance[0];
381  double maximumYdistance = maxGlobalPointDistance[1] * maxGlobalPointDistance[1];
382  // to be sure that the first min distance is from a real point
383  double minimumDistance = 1. + maximumXdistance + maximumYdistance;
384  for (const auto &hit : (*hitMap_)[tmpPlaneId]) {
385  double xResidual = hit.globalPoint.x() - pointOnDet.x();
386  double yResidual = hit.globalPoint.y() - pointOnDet.y();
387  double xDistance = xResidual * xResidual;
388  double yDistance = yResidual * yResidual;
389  double distance = xDistance + yDistance;
390  if (xDistance < maximumXdistance && yDistance < maximumYdistance && distance < minimumDistance) {
391  LocalPoint residuals(xResidual, yResidual, 0.);
392  math::Error<3>::type globalError = hit.globalError;
393  LocalPoint pulls(xResidual / std::sqrt(globalError[0][0]), yResidual / std::sqrt(globalError[1][1]), 0.);
394  fittedRecHit = std::make_unique<CTPPSPixelFittedRecHit>(hit.recHit, pointOnDet, residuals, pulls);
395  fittedRecHit->setIsRealHit(true);
396  }
397  }
398  } else {
399  LocalPoint fakePoint;
400  LocalError fakeError;
401  CTPPSPixelRecHit fakeRecHit(fakePoint, fakeError);
402  fittedRecHit = std::make_unique<CTPPSPixelFittedRecHit>(fakeRecHit, pointOnDet, fakePoint, fakePoint);
403  }
404 
405  bestTrack.addHit(tmpPlaneId, *fittedRecHit);
406  }
407 
408  localTrackVector_.push_back(bestTrack);
409 
410  int pointForTracking = 0;
411  int pointOnTrack = 0;
412 
413  if (verbosity_ >= 1) {
414  for (const auto &planeHits : bestTrack.hits()) {
415  for (const auto &fittedhit : planeHits) {
416  if (fittedhit.isUsedForFit())
417  ++pointForTracking;
418  if (fittedhit.isRealHit())
419  ++pointOnTrack;
420  }
421  }
422  edm::LogInfo("RPixPlaneCombinatoryTracking")
423  << "Best track has " << pointForTracking << " points used for the fit and " << pointOnTrack
424  << " points belonging to the track\n";
425  }
426 
427  } //close of the while loop on all the hits
428 
429  // recoInfo_ calculation
430  // Hardcoded shift periods:
431  // Before run 300802: No shift
432  // Starting from run 300802: Sec45 St2 Rp3 Pl 0,2,3 ROC 0 shifted.
433  // Starting from run 303338: No shift.
434  // Starting from run 305169: Sec45 St2 Rp3 Pl 1,3,5 ROC 0 shifted.
435  // Starting from run 305965: Sec45 St2 Rp3 Pl 1,3,5 ROC 0 shifted & Sec56 St2 Rp3 Pl 2,4,5 ROC 5 shifted.
436  // Starting from run 307083: No shift
437 
438  // These variables hold the information of the runs when the detector was taking data in 3+3 Mode and which planes were bx-shifted
439  // These values will never be changed and the 3+3 Mode will never be used again in the future
440  const CTPPSPixelDetId rpId_arm0_st2 = CTPPSPixelDetId(0, 2, 3);
441  const CTPPSPixelDetId rpId_arm1_st2 = CTPPSPixelDetId(1, 2, 3);
442  static const std::map<unsigned int, std::map<CTPPSPixelDetId, std::vector<bool> > > isPlaneShifted = {
443  {0,
444  {
445  {rpId_arm0_st2, {false, false, false, false, false, false}}, // Shift Period 0 Sec45
446  {rpId_arm1_st2, {false, false, false, false, false, false}} // Shift Period 1 Sec56
447  }},
448  {300802,
449  {
450  {rpId_arm0_st2, {true, false, true, true, false, false}}, // Shift Period 1 Sec45
451  {rpId_arm1_st2, {false, false, false, false, false, false}} // Shift Period 1 Sec56
452  }},
453  {303338,
454  {
455  {rpId_arm0_st2, {false, false, false, false, false, false}}, // Shift Period 2 Sec45
456  {rpId_arm1_st2, {false, false, false, false, false, false}} // Shift Period 2 Sec56
457  }},
458  {305169,
459  {
460  {rpId_arm0_st2, {false, true, false, true, false, true}}, // Shift Period 3 Sec45
461  {rpId_arm1_st2, {false, false, false, false, false, false}} // Shift Period 3 Sec56
462  }},
463  {305965,
464  {
465  {rpId_arm0_st2, {false, true, false, true, false, true}}, // Shift Period 4 Sec45
466  {rpId_arm1_st2, {false, false, true, false, true, true}} // Shift Period 4 Sec56
467  }},
468  {307083,
469  {
470  {rpId_arm0_st2, {false, false, false, false, false, false}}, // Shift Period 0 Sec45
471  {rpId_arm1_st2, {false, false, false, false, false, false}} // Shift Period 1 Sec56
472  }}}; // map< shiftedPeriod, map<DetID,shiftScheme> >
473  const auto &shiftStatusInitialRun = std::prev(isPlaneShifted.upper_bound(run));
474  unsigned short shiftedROC = 10;
475  CTPPSPixelIndices pixelIndices;
476 
477  // Selecting the shifted ROC
478  if (romanPotId_.arm() == 0)
479  shiftedROC = 0;
480  if (romanPotId_.arm() == 1)
481  shiftedROC = 5;
482 
483  // Loop over found tracks to set recoInfo_
484  for (auto &track : localTrackVector_) {
485  if (romanPotId_ != rpId_arm0_st2 && romanPotId_ != rpId_arm1_st2) {
487  if (verbosity_ >= 2)
488  edm::LogInfo("RPixPlaneCombinatoryTracking") << "Analyzing run: " << run << "\nTrack belongs to Arm "
489  << romanPotId_.arm() << " Station " << romanPotId_.station();
490 
491  continue;
492  }
493  unsigned short bxShiftedPlanesUsed = 0;
494  unsigned short bxNonShiftedPlanesUsed = 0;
495  unsigned short hitInShiftedROC = 0;
496 
497  auto const &fittedHits = track.hits();
498  auto const &planeFlags = (shiftStatusInitialRun->second).at(romanPotId_);
499 
500  for (const auto &planeHits : fittedHits) {
501  unsigned short plane = CTPPSPixelDetId(planeHits.detId()).plane();
502  for (const auto &hit : planeHits) {
503  if (hit.isUsedForFit()) {
504  if (pixelIndices.getROCId(hit.minPixelCol(), hit.minPixelRow()) == shiftedROC)
505  hitInShiftedROC++; // Count how many hits are in the shifted ROC
506  if (planeFlags.at(plane))
507  bxShiftedPlanesUsed++; // Count how many bx-shifted planes are used
508  else if (planeFlags != std::vector<bool>(6, false))
509  bxNonShiftedPlanesUsed++; // Count how many non-bx-shifted planes are used, only if there are shifted planes
510  }
511  }
512  }
513 
514  // Set recoInfo_ value
516  invalid); // Initially setting it as invalid. It has to match one of the following options.
517  if (hitInShiftedROC < 3)
519  else {
520  if (bxShiftedPlanesUsed == 0 && bxNonShiftedPlanesUsed == 0)
521  track.setRecoInfo(
522  CTPPSpixelLocalTrackReconstructionInfo::notShiftedRun); // Default value for runs without bx-shift
523  if (bxShiftedPlanesUsed == 3 && bxNonShiftedPlanesUsed == 0)
525  allShiftedPlanes); // Track reconstructed in a shifted ROC, only with bx-shifted planes
526  if (bxShiftedPlanesUsed == 0 && bxNonShiftedPlanesUsed == 3)
527  // Track reconstructed in a shifted ROC, only with non-bx-shifted planes
529  if (bxShiftedPlanesUsed > 0 && bxNonShiftedPlanesUsed > 0)
531  mixedPlanes); // Track reconstructed in a shifted ROC, with mixed planes
532  }
533  if (bxShiftedPlanesUsed + bxNonShiftedPlanesUsed > 6) {
534  throw cms::Exception("RPixPlaneCombinatoryTracking") << "Error in RPixPlaneCombinatoryTracking::findTracks -> "
535  << "More than six points found for a track, skipping.";
536  continue;
537  }
539  throw cms::Exception("RPixPlaneCombinatoryTracking") << "Error in RPixPlaneCombinatoryTracking::findTracks -> "
540  << "recoInfo has not been set properly.";
541  }
542 
543  if (verbosity_ >= 2) {
544  edm::LogInfo("RPixPlaneCombinatoryTracking")
545  << " Track belongs to Arm " << romanPotId_.arm() << " Station " << romanPotId_.station()
546  << "\nFirst run with this bx-shift configuration: " << shiftStatusInitialRun->first
547  << "\nTrack reconstructed with: " << bxShiftedPlanesUsed << " bx-shifted planes, " << bxNonShiftedPlanesUsed
548  << " non-bx-shifted planes, " << hitInShiftedROC << " hits in the bx-shifted ROC"
549  << "\nrecoInfo = " << (unsigned short)track.recoInfo();
550  if (planeFlags != std::vector<bool>(6, false))
551  edm::LogInfo("RPixPlaneCombinatoryTracking") << "The shifted ROC is ROC" << shiftedROC;
552  }
553  }
554  return;
555 }
556 
557 //------------------------------------------------------------------------------------------------//
558 
560  uint32_t const numberOfPlanes = 6;
564 
565  //The matrices and vector xyCoordinates, varianceMatrix and varianceMatrix are built from the points
566  for (uint32_t iHit = 0; iHit < numberOfPlanes; iHit++) {
567  if (iHit < pointList.size()) {
568  const auto &globalPoint = pointList[iHit].globalPoint;
569  xyCoordinates[2 * iHit] = globalPoint.x();
570  xyCoordinates[2 * iHit + 1] = globalPoint.y();
571  zMatrix(2 * iHit, 0) = 1.;
572  zMatrix(2 * iHit, 2) = globalPoint.z() - z0_;
573  zMatrix(2 * iHit + 1, 1) = 1.;
574  zMatrix(2 * iHit + 1, 3) = globalPoint.z() - z0_;
575 
576  AlgebraicMatrix33 globalError = pointList[iHit].globalError;
577  varianceMatrix(2 * iHit, 2 * iHit) = globalError(0, 0);
578  varianceMatrix(2 * iHit, 2 * iHit + 1) = globalError(0, 1);
579  varianceMatrix(2 * iHit + 1, 2 * iHit) = globalError(1, 0);
580  varianceMatrix(2 * iHit + 1, 2 * iHit + 1) = globalError(1, 1);
581  } else {
582  varianceMatrix(2 * iHit, 2 * iHit) = 1.;
583  varianceMatrix(2 * iHit + 1, 2 * iHit + 1) = 1.;
584  }
585  }
586 
587  //Get real point variance matrix
588  if (!varianceMatrix.Invert()) {
589  edm::LogError("RPixPlaneCombinatoryTracking") << "Error in RPixPlaneCombinatoryTracking::fitTrack -> "
590  << "Point variance matrix is singular, skipping.";
591  CTPPSPixelLocalTrack badTrack;
592  badTrack.setValid(false);
593  return badTrack;
594  }
595 
596  math::Error<4>::type covarianceMatrix = ROOT::Math::SimilarityT(zMatrix, varianceMatrix);
597 
598  //To have the real parameter covariance matrix, covarianceMatrix needs to be inverted
599  if (!covarianceMatrix.Invert()) {
600  edm::LogError("RPixPlaneCombinatoryTracking") << "Error in RPixPlaneCombinatoryTracking::fitTrack -> "
601  << "Parameter covariance matrix is singular, skipping.";
602  CTPPSPixelLocalTrack badTrack;
603  badTrack.setValid(false);
604  return badTrack;
605  }
606 
607  // track parameters: (x0, y0, tx, ty); x = x0 + tx*(z-z0)
608  math::Vector<4>::type zMatrixTransposeTimesVarianceMatrixTimesXyCoordinates =
609  ROOT::Math::Transpose(zMatrix) * varianceMatrix * xyCoordinates;
610  math::Vector<4>::type parameterVector = covarianceMatrix * zMatrixTransposeTimesVarianceMatrixTimesXyCoordinates;
611  math::Vector<2 *numberOfPlanes>::type xyCoordinatesMinusZmatrixTimesParameters =
612  xyCoordinates - (zMatrix * parameterVector);
613 
614  double chiSquare = ROOT::Math::Dot(xyCoordinatesMinusZmatrixTimesParameters,
615  (varianceMatrix * xyCoordinatesMinusZmatrixTimesParameters));
616 
617  CTPPSPixelLocalTrack goodTrack(z0_, parameterVector, covarianceMatrix, chiSquare);
618  goodTrack.setValid(true);
619 
620  for (const auto &hit : pointList) {
621  const auto &globalPoint = hit.globalPoint;
622  GlobalPoint pointOnDet;
623  bool foundPoint = calculatePointOnDetector(&goodTrack, hit.detId, pointOnDet);
624  if (!foundPoint) {
625  CTPPSPixelLocalTrack badTrack;
626  badTrack.setValid(false);
627  return badTrack;
628  }
629  double xResidual = globalPoint.x() - pointOnDet.x();
630  double yResidual = globalPoint.y() - pointOnDet.y();
631  LocalPoint residuals(xResidual, yResidual);
632 
633  math::Error<3>::type globalError(hit.globalError);
634  LocalPoint pulls(xResidual / std::sqrt(globalError(0, 0)), yResidual / std::sqrt(globalError(0, 0)));
635 
636  CTPPSPixelFittedRecHit fittedRecHit(hit.recHit, pointOnDet, residuals, pulls);
637  fittedRecHit.setIsUsedForFit(true);
638  goodTrack.addHit(hit.detId, fittedRecHit);
639  }
640 
641  return goodTrack;
642 }
643 
644 //------------------------------------------------------------------------------------------------//
645 
646 //The method calculates the hit pointed by the track on the detector plane
648  CTPPSPixelDetId planeId,
649  GlobalPoint &planeLineIntercept) {
650  double z0 = track->z0();
652 
653  math::Vector<3>::type pointOnLine(parameters[0], parameters[1], z0);
654  GlobalVector tmpLineUnitVector = track->directionVector();
655  math::Vector<3>::type lineUnitVector(tmpLineUnitVector.x(), tmpLineUnitVector.y(), tmpLineUnitVector.z());
656 
657  const CTPPSGeometry::Vector tmpPointLocal(0., 0., 0.);
658  const auto &tmpPointOnPlane = geometry_->localToGlobal(planeId, tmpPointLocal);
659 
660  math::Vector<3>::type pointOnPlane(tmpPointOnPlane.x(), tmpPointOnPlane.y(), tmpPointOnPlane.z());
661  math::Vector<3>::type planeUnitVector(0., 0., 1.);
662 
663  DetGeomDesc::RotationMatrix theRotationMatrix = geometry_->sensor(planeId)->rotation();
664  AlgebraicMatrix33 tmpPlaneRotationMatrixMap;
665  theRotationMatrix.GetComponents(tmpPlaneRotationMatrixMap(0, 0),
666  tmpPlaneRotationMatrixMap(0, 1),
667  tmpPlaneRotationMatrixMap(0, 2),
668  tmpPlaneRotationMatrixMap(1, 0),
669  tmpPlaneRotationMatrixMap(1, 1),
670  tmpPlaneRotationMatrixMap(1, 2),
671  tmpPlaneRotationMatrixMap(2, 0),
672  tmpPlaneRotationMatrixMap(2, 1),
673  tmpPlaneRotationMatrixMap(2, 2));
674 
675  planeUnitVector = tmpPlaneRotationMatrixMap * planeUnitVector;
676 
677  double denominator = ROOT::Math::Dot(lineUnitVector, planeUnitVector);
678  if (denominator == 0) {
679  edm::LogError("RPixPlaneCombinatoryTracking")
680  << "Error in RPixPlaneCombinatoryTracking::calculatePointOnDetector -> "
681  << "Fitted line and plane are parallel. Removing this track";
682  return false;
683  }
684 
685  double distanceFromLinePoint = ROOT::Math::Dot((pointOnPlane - pointOnLine), planeUnitVector) / denominator;
686 
687  math::Vector<3>::type tmpPlaneLineIntercept = distanceFromLinePoint * lineUnitVector + pointOnLine;
688  planeLineIntercept = GlobalPoint(tmpPlaneLineIntercept[0], tmpPlaneLineIntercept[1], tmpPlaneLineIntercept[2]);
689 
690  return true;
691 }
692 //------------------------------------------------------------------------------------------------//
693 
694 // The method sorts the possible point combinations in order to process before fits on the highest possible number of points
695 std::vector<RPixPlaneCombinatoryTracking::PointAndReferencePair>
697  std::vector<PointAndReferencePair> sortedVector(inputMap.begin(), inputMap.end());
698  std::sort(sortedVector.begin(), sortedVector.end(), functionForPlaneOrdering);
699 
700  return sortedVector;
701 }
702 //------------------------------------------------------------------------------------------------//
uint32_t factorial(uint32_t x) const
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
ROOT::Math::SMatrix< double, 3, 3, ROOT::Math::MatRepStd< double, 3, 3 > > AlgebraicMatrix33
RPixPlaneCombinatoryTracking(edm::ParameterSet const &parameterSet)
T z() const
Definition: PV3DBase.h:61
uint32_t arm() const
Definition: CTPPSDetId.h:57
std::map< CTPPSPixelDetId, size_t > HitReferences
bool calculatePointOnDetector(CTPPSPixelLocalTrack *track, CTPPSPixelDetId planeId, GlobalPoint &planeLineIntercept)
std::vector< PointAndReferencePair > orderCombinationsPerNumberOrPoints(PointAndReferenceMap inputMap)
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
ErrorD< N >::type type
Definition: Error.h:32
CTPPSpixelLocalTrackReconstructionInfo
Vector localToGlobal(const DetGeomDesc *, const Vector &) const
void getPlaneCombinations(const std::vector< uint32_t > &inputPlaneList, uint32_t numberToExtract, PlaneCombinations &planeCombinations) const
Log< level::Error, false > LogError
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
ParameterSet const & parameterSet(StableProvenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:11
Definition: Electron.h:6
DetGeomDesc::Translation Vector
Definition: CTPPSGeometry.h:36
T getUntrackedParameter(std::string const &, T const &) const
std::vector< CTPPSPixelLocalTrack > localTrackVector_
std::map< HitReferences, PointInPlaneList > PointAndReferenceMap
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
void getHitCombinations(const std::map< CTPPSPixelDetId, PointInPlaneList > &mapOfAllHits, std::map< CTPPSPixelDetId, PointInPlaneList >::iterator mapIterator, HitReferences tmpHitPlaneMap, const PointInPlaneList &tmpHitVector, PointAndReferenceMap &outputMap)
CTPPSPixelLocalTrack fitTrack(PointInPlaneList pointList)
fixed size vector
Definition: Vector.h:24
bool goodTrack(const reco::Track *pTrack, math::XYZPoint leadPV, trackSelectionParameters parameters, bool debug=false)
T sqrt(T t)
Definition: SSEVec.h:23
std::vector< RPixDetPatternFinder::PointInPlane > PointInPlaneList
const DetGeomDesc * sensor(unsigned int id) const
returns geometry of a detector performs necessary checks, returns NULL if fails
std::map< CTPPSPixelDetId, std::vector< RPixDetPatternFinder::PointInPlane > > * hitMap_
uint32_t plane() const
void setIsUsedForFit(bool usedForFit)
void addHit(unsigned int detId, const CTPPSPixelFittedRecHit &hit)
std::vector< uint32_t > listOfAllPlanes_
void setPlane(uint32_t pl)
Log< level::Info, false > LogInfo
ROOT::Math::SMatrix< double, N, M > type
Definition: Matrix.h:9
void setIsRealHit(bool realHit)
uint32_t rp() const
Definition: CTPPSDetId.h:71
Vector rpTranslation(unsigned int id) const
uint32_t station() const
Definition: CTPPSDetId.h:64
const CTPPSGeometry * geometry_
math::Vector< dimension >::type ParameterVector
covariance matrix size
const RotationMatrix & rotation() const
Definition: DetGeomDesc.h:81
int getROCId(const int col, const int row) const
PointAndReferenceMap produceAllHitCombination(PlaneCombinations inputPlaneCombination)
const edm::DetSetVector< CTPPSPixelFittedRecHit > & hits() const
CTPPSPixelDetId romanPotId_
static bool functionForPlaneOrdering(PointAndReferencePair a, PointAndReferencePair b)
std::vector< std::vector< uint32_t > > PlaneCombinations
ROOT::Math::Rotation3D RotationMatrix
Definition: DetGeomDesc.h:54
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5