CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
18  : RPixDetTrackFinder(parameterSet) {
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  while (hitMap_->size() >= trackMinNumberOfPoints_) {
167  if (verbosity_ >= 1)
168  edm::LogInfo("RPixPlaneCombinatoryTracking") << "Number of plane with hits " << hitMap_->size();
169  if (verbosity_ >= 2)
170  for (const auto &plane : *hitMap_)
171  edm::LogInfo("RPixPlaneCombinatoryTracking")
172  << "\tarm " << plane.first.arm() << " station " << plane.first.station() << " rp " << plane.first.rp()
173  << " plane " << plane.first.plane() << " : " << plane.second.size();
174 
175  //I create the map of all the possible combinations of a group of trackMinNumberOfPoints_ points
176  //and the key keeps the reference of which planes and which hit numbers form the combination
177  PointAndReferenceMap mapOfAllMinRequiredPoint;
178  //I produce the map for all cominations of all hits with all trackMinNumberOfPoints_ plane combinations
179  mapOfAllMinRequiredPoint = produceAllHitCombination(possiblePlaneCombinations_);
180 
181  //Fit all the possible combinations with minimum number of planes required and find the track with minimum chi2
182  double theMinChiSquaredOverNDF = maximumChi2OverNDF_ + 1.; //in order to break the loop in case no track is found;
183  HitReferences pointMapWithMinChiSquared;
184  PointInPlaneList pointsWithMinChiSquared;
185  CTPPSPixelLocalTrack bestTrack;
186 
187  if (verbosity_ >= 2)
188  edm::LogInfo("RPixPlaneCombinatoryTracking")
189  << "Number of combinations of trackMinNumberOfPoints_ planes " << mapOfAllMinRequiredPoint.size();
190  for (const auto &pointsAndRef : mapOfAllMinRequiredPoint) {
191  CTPPSPixelLocalTrack tmpTrack = fitTrack(pointsAndRef.second);
192  double tmpChiSquaredOverNDF = tmpTrack.chiSquaredOverNDF();
193  if (verbosity_ >= 2)
194  edm::LogInfo("RPixPlaneCombinatoryTracking") << "ChiSquare of the present track " << tmpChiSquaredOverNDF;
195  if (!tmpTrack.isValid() || tmpChiSquaredOverNDF > maximumChi2OverNDF_ || tmpChiSquaredOverNDF == 0.)
196  continue; //validity check
197  if (tmpChiSquaredOverNDF < theMinChiSquaredOverNDF) {
198  theMinChiSquaredOverNDF = tmpChiSquaredOverNDF;
199  pointMapWithMinChiSquared = pointsAndRef.first;
200  pointsWithMinChiSquared = pointsAndRef.second;
201  bestTrack = tmpTrack;
202  }
203  }
204 
205  //The loop on the fit of all tracks is done, the track with minimum chiSquared is found
206  // and it is verified that it complies with the maximumChi2OverNDF_ requirement
207  if (theMinChiSquaredOverNDF > maximumChi2OverNDF_)
208  break;
209 
210  //The list of planes not included in the minimum chiSquare track is produced.
211  std::vector<uint32_t> listOfExcludedPlanes;
212  for (const auto &plane : listOfAllPlanes_) {
213  CTPPSPixelDetId tmpRpId = romanPotId_; //in order to avoid to modify the data member
214  tmpRpId.setPlane(plane);
215  CTPPSPixelDetId planeDetId = tmpRpId;
216  if (pointMapWithMinChiSquared.find(planeDetId) == pointMapWithMinChiSquared.end())
217  listOfExcludedPlanes.push_back(plane);
218  }
219 
220  //I produce all the possible combinations of planes to be added to the track,
221  //excluding the case of no other plane added since it has been already fitted.
222  PlaneCombinations planePointedHitListCombination;
223  for (uint32_t i = 1; i <= listOfExcludedPlanes.size(); ++i) {
224  PlaneCombinations tmpPlaneCombination;
225  getPlaneCombinations(listOfExcludedPlanes, i, tmpPlaneCombination);
226  for (const auto &combination : tmpPlaneCombination)
227  planePointedHitListCombination.push_back(combination);
228  }
229 
230  //I produce all the possible combinations of points to be added to the track
231  PointAndReferenceMap mapOfAllPointWithAtLeastBestFitSelected;
232  PointAndReferenceMap mapOfPointCombinationToBeAdded;
233  mapOfPointCombinationToBeAdded = produceAllHitCombination(planePointedHitListCombination);
234  //The found hit combination is added to the hits selected by the best fit;
235  for (const auto &element : mapOfPointCombinationToBeAdded) {
236  HitReferences newPointMap = pointMapWithMinChiSquared;
237  PointInPlaneList newPoints = pointsWithMinChiSquared;
238  for (const auto &pointRef : element.first)
239  newPointMap[pointRef.first] = pointRef.second; //add the new point reference
240  for (const auto &point : element.second)
241  newPoints.push_back(point);
242  mapOfAllPointWithAtLeastBestFitSelected[newPointMap] = newPoints;
243  }
244 
245  //I fit all the possible combination of the minimum plane best fit hits plus hits from the other planes
246  if (verbosity_ >= 1)
247  edm::LogInfo("RPixPlaneCombinatoryTracking")
248  << "Minimum chiSquare over NDF for all the tracks " << theMinChiSquaredOverNDF;
249 
250  // I look for the tracks with maximum number of points with a chiSquare over NDF smaller than maximumChi2OverNDF_
251  // If more than one track fulfill the chiSquare requirement with the same number of points I choose the one with smaller chiSquare
252  std::vector<PointAndReferencePair> orderedVectorOfAllPointWithAtLeastBestFitSelected =
253  orderCombinationsPerNumberOrPoints(mapOfAllPointWithAtLeastBestFitSelected);
254  int currentNumberOfPlanes = 0;
255  theMinChiSquaredOverNDF = maximumChi2OverNDF_ + 1.; //in order to break the loop in case no track is found;
256  bool foundTrackWithCurrentNumberOfPlanes = false;
257  for (const auto &pointsAndRef : orderedVectorOfAllPointWithAtLeastBestFitSelected) {
258  int tmpNumberOfPlanes = pointsAndRef.second.size();
259  // If a valid track has been already found with an higher number of planes the loop stops.
260  if (foundTrackWithCurrentNumberOfPlanes && tmpNumberOfPlanes < currentNumberOfPlanes)
261  break;
262  CTPPSPixelLocalTrack tmpTrack = fitTrack(pointsAndRef.second);
263  double tmpChiSquaredOverNDF = tmpTrack.chiSquaredOverNDF();
264  if (!tmpTrack.isValid() || tmpChiSquaredOverNDF > maximumChi2OverNDF_ || tmpChiSquaredOverNDF == 0.)
265  continue; //validity check
266  if (tmpChiSquaredOverNDF < theMinChiSquaredOverNDF) {
267  theMinChiSquaredOverNDF = tmpChiSquaredOverNDF;
268  pointMapWithMinChiSquared = pointsAndRef.first;
269  bestTrack = tmpTrack;
270  currentNumberOfPlanes = tmpNumberOfPlanes;
271  foundTrackWithCurrentNumberOfPlanes = true;
272  }
273  }
274 
275  if (verbosity_ >= 1)
276  edm::LogInfo("RPixPlaneCombinatoryTracking") << "The best track has " << bestTrack.ndf() / 2 + 2;
277 
278  std::vector<uint32_t> listOfPlaneNotUsedForFit = listOfAllPlanes_;
279  //remove the hits belonging to the tracks from the full list of hits
280  for (const auto &hitToErase : pointMapWithMinChiSquared) {
281  std::map<CTPPSPixelDetId, PointInPlaneList>::iterator hitMapElement = hitMap_->find(hitToErase.first);
282  if (hitMapElement == hitMap_->end()) {
283  throw cms::Exception("RPixPlaneCombinatoryTracking")
284  << "The found tracks has hit belonging to a plane which does not have hits";
285  }
286  std::vector<uint32_t>::iterator planeIt;
287  planeIt = std::find(listOfPlaneNotUsedForFit.begin(), listOfPlaneNotUsedForFit.end(), hitToErase.first.plane());
288  listOfPlaneNotUsedForFit.erase(planeIt);
289  hitMapElement->second.erase(hitMapElement->second.begin() + hitToErase.second);
290  //if the plane at which the hit was erased is empty it is removed from the hit map
291  if (hitMapElement->second.empty())
292  hitMap_->erase(hitMapElement);
293  }
294 
295  //search for hit on the other planes which may belong to the same track
296  //even if they did not contributed to the track
297  //in case of multiple hit, the closest one to the track will be considered
298  //If a hit is found these will not be erased from the list of all hits
299  //If no hit is found, the point on the plane intersecting the track will be saved by a CTPPSPixelFittedRecHit
300  //with the isRealHit_ flag set to false
301  for (const auto &plane : listOfPlaneNotUsedForFit) {
302  CTPPSPixelDetId tmpPlaneId = romanPotId_; //in order to avoid to modify the data member
303  tmpPlaneId.setPlane(plane);
304  std::unique_ptr<CTPPSPixelFittedRecHit> fittedRecHit(new CTPPSPixelFittedRecHit());
305  GlobalPoint pointOnDet;
306  calculatePointOnDetector(&bestTrack, tmpPlaneId, pointOnDet);
307 
308  if (hitMap_->find(tmpPlaneId) != hitMap_->end()) {
309  //I convert the hit search window defined in local coordinated into global
310  //This avoids to convert the global plane-line intersection in order not to call the the geometry
311  math::Vector<3>::type maxGlobalPointDistance(
313 
314  DetGeomDesc::RotationMatrix theRotationMatrix = geometry_->sensor(tmpPlaneId)->rotation();
315  AlgebraicMatrix33 tmpPlaneRotationMatrixMap;
316  theRotationMatrix.GetComponents(tmpPlaneRotationMatrixMap(0, 0),
317  tmpPlaneRotationMatrixMap(0, 1),
318  tmpPlaneRotationMatrixMap(0, 2),
319  tmpPlaneRotationMatrixMap(1, 0),
320  tmpPlaneRotationMatrixMap(1, 1),
321  tmpPlaneRotationMatrixMap(1, 2),
322  tmpPlaneRotationMatrixMap(2, 0),
323  tmpPlaneRotationMatrixMap(2, 1),
324  tmpPlaneRotationMatrixMap(2, 2));
325 
326  maxGlobalPointDistance = tmpPlaneRotationMatrixMap * maxGlobalPointDistance;
327  //I avoid the Sqrt since it will not be saved
328  double maximumXdistance = maxGlobalPointDistance[0] * maxGlobalPointDistance[0];
329  double maximumYdistance = maxGlobalPointDistance[1] * maxGlobalPointDistance[1];
330  // to be sure that the first min distance is from a real point
331  double minimumDistance = 1. + maximumXdistance + maximumYdistance;
332  for (const auto &hit : (*hitMap_)[tmpPlaneId]) {
333  double xResidual = hit.globalPoint.x() - pointOnDet.x();
334  double yResidual = hit.globalPoint.y() - pointOnDet.y();
335  double xDistance = xResidual * xResidual;
336  double yDistance = yResidual * yResidual;
337  double distance = xDistance + yDistance;
338  if (xDistance < maximumXdistance && yDistance < maximumYdistance && distance < minimumDistance) {
339  LocalPoint residuals(xResidual, yResidual, 0.);
340  math::Error<3>::type globalError = hit.globalError;
341  LocalPoint pulls(xResidual / std::sqrt(globalError[0][0]), yResidual / std::sqrt(globalError[1][1]), 0.);
342  fittedRecHit = std::make_unique<CTPPSPixelFittedRecHit>(hit.recHit, pointOnDet, residuals, pulls);
343  fittedRecHit->setIsRealHit(true);
344  }
345  }
346  } else {
347  LocalPoint fakePoint;
348  LocalError fakeError;
349  CTPPSPixelRecHit fakeRecHit(fakePoint, fakeError);
350  fittedRecHit = std::make_unique<CTPPSPixelFittedRecHit>(fakeRecHit, pointOnDet, fakePoint, fakePoint);
351  }
352 
353  bestTrack.addHit(tmpPlaneId, *fittedRecHit);
354  }
355 
356  localTrackVector_.push_back(bestTrack);
357 
358  int pointForTracking = 0;
359  int pointOnTrack = 0;
360 
361  if (verbosity_ >= 1) {
362  for (const auto &planeHits : bestTrack.hits()) {
363  for (const auto &fittedhit : planeHits) {
364  if (fittedhit.isUsedForFit())
365  ++pointForTracking;
366  if (fittedhit.isRealHit())
367  ++pointOnTrack;
368  }
369  }
370  edm::LogInfo("RPixPlaneCombinatoryTracking")
371  << "Best track has " << pointForTracking << " points used for the fit and " << pointOnTrack
372  << " points belonging to the track\n";
373  }
374 
375  } //close of the while loop on all the hits
376 
377  // recoInfo_ calculation
378  // Hardcoded shift periods:
379  // Before run 300802: No shift
380  // Starting from run 300802: Sec45 St2 Rp3 Pl 0,2,3 ROC 0 shifted.
381  // Starting from run 303338: No shift.
382  // Starting from run 305169: Sec45 St2 Rp3 Pl 1,3,5 ROC 0 shifted.
383  // Starting from run 305965: Sec45 St2 Rp3 Pl 1,3,5 ROC 0 shifted & Sec56 St2 Rp3 Pl 2,4,5 ROC 5 shifted.
384  // Starting from run 307083: No shift
385 
386  // These variables hold the information of the runs when the detector was taking data in 3+3 Mode and which planes were bx-shifted
387  // These values will never be changed and the 3+3 Mode will never be used again in the future
388  const CTPPSPixelDetId rpId_arm0_st2 = CTPPSPixelDetId(0, 2, 3);
389  const CTPPSPixelDetId rpId_arm1_st2 = CTPPSPixelDetId(1, 2, 3);
390  static const std::map<unsigned int, std::map<CTPPSPixelDetId, std::vector<bool> > > isPlaneShifted = {
391  {0,
392  {
393  {rpId_arm0_st2, {false, false, false, false, false, false}}, // Shift Period 0 Sec45
394  {rpId_arm1_st2, {false, false, false, false, false, false}} // Shift Period 1 Sec56
395  }},
396  {300802,
397  {
398  {rpId_arm0_st2, {true, false, true, true, false, false}}, // Shift Period 1 Sec45
399  {rpId_arm1_st2, {false, false, false, false, false, false}} // Shift Period 1 Sec56
400  }},
401  {303338,
402  {
403  {rpId_arm0_st2, {false, false, false, false, false, false}}, // Shift Period 2 Sec45
404  {rpId_arm1_st2, {false, false, false, false, false, false}} // Shift Period 2 Sec56
405  }},
406  {305169,
407  {
408  {rpId_arm0_st2, {false, true, false, true, false, true}}, // Shift Period 3 Sec45
409  {rpId_arm1_st2, {false, false, false, false, false, false}} // Shift Period 3 Sec56
410  }},
411  {305965,
412  {
413  {rpId_arm0_st2, {false, true, false, true, false, true}}, // Shift Period 4 Sec45
414  {rpId_arm1_st2, {false, false, true, false, true, true}} // Shift Period 4 Sec56
415  }},
416  {307083,
417  {
418  {rpId_arm0_st2, {false, false, false, false, false, false}}, // Shift Period 0 Sec45
419  {rpId_arm1_st2, {false, false, false, false, false, false}} // Shift Period 1 Sec56
420  }}}; // map< shiftedPeriod, map<DetID,shiftScheme> >
421  const auto &shiftStatusInitialRun = std::prev(isPlaneShifted.upper_bound(run));
422  unsigned short shiftedROC = 10;
423  CTPPSPixelIndices pixelIndices;
424 
425  // Selecting the shifted ROC
426  if (romanPotId_.arm() == 0)
427  shiftedROC = 0;
428  if (romanPotId_.arm() == 1)
429  shiftedROC = 5;
430 
431  // Loop over found tracks to set recoInfo_
432  for (auto &track : localTrackVector_) {
433  if (romanPotId_ != rpId_arm0_st2 && romanPotId_ != rpId_arm1_st2) {
435  if (verbosity_ >= 2)
436  edm::LogInfo("RPixPlaneCombinatoryTracking") << "Analyzing run: " << run << "\nTrack belongs to Arm "
437  << romanPotId_.arm() << " Station " << romanPotId_.station();
438 
439  continue;
440  }
441  unsigned short bxShiftedPlanesUsed = 0;
442  unsigned short bxNonShiftedPlanesUsed = 0;
443  unsigned short hitInShiftedROC = 0;
444 
445  auto const &fittedHits = track.hits();
446  auto const &planeFlags = (shiftStatusInitialRun->second).at(romanPotId_);
447 
448  for (const auto &planeHits : fittedHits) {
449  unsigned short plane = CTPPSPixelDetId(planeHits.detId()).plane();
450  for (const auto &hit : planeHits) {
451  if (hit.isUsedForFit()) {
452  if (pixelIndices.getROCId(hit.minPixelCol(), hit.minPixelRow()) == shiftedROC)
453  hitInShiftedROC++; // Count how many hits are in the shifted ROC
454  if (planeFlags.at(plane))
455  bxShiftedPlanesUsed++; // Count how many bx-shifted planes are used
456  else if (planeFlags != std::vector<bool>(6, false))
457  bxNonShiftedPlanesUsed++; // Count how many non-bx-shifted planes are used, only if there are shifted planes
458  }
459  }
460  }
461 
462  // Set recoInfo_ value
464  invalid); // Initially setting it as invalid. It has to match one of the following options.
465  if (hitInShiftedROC < 3)
467  else {
468  if (bxShiftedPlanesUsed == 0 && bxNonShiftedPlanesUsed == 0)
469  track.setRecoInfo(
470  CTPPSpixelLocalTrackReconstructionInfo::notShiftedRun); // Default value for runs without bx-shift
471  if (bxShiftedPlanesUsed == 3 && bxNonShiftedPlanesUsed == 0)
473  allShiftedPlanes); // Track reconstructed in a shifted ROC, only with bx-shifted planes
474  if (bxShiftedPlanesUsed == 0 && bxNonShiftedPlanesUsed == 3)
475  // Track reconstructed in a shifted ROC, only with non-bx-shifted planes
477  if (bxShiftedPlanesUsed > 0 && bxNonShiftedPlanesUsed > 0)
479  mixedPlanes); // Track reconstructed in a shifted ROC, with mixed planes
480  }
481  if (bxShiftedPlanesUsed + bxNonShiftedPlanesUsed > 6) {
482  throw cms::Exception("RPixPlaneCombinatoryTracking") << "Error in RPixPlaneCombinatoryTracking::findTracks -> "
483  << "More than six points found for a track, skipping.";
484  continue;
485  }
487  throw cms::Exception("RPixPlaneCombinatoryTracking") << "Error in RPixPlaneCombinatoryTracking::findTracks -> "
488  << "recoInfo has not been set properly.";
489  }
490 
491  if (verbosity_ >= 2) {
492  edm::LogInfo("RPixPlaneCombinatoryTracking")
493  << " Track belongs to Arm " << romanPotId_.arm() << " Station " << romanPotId_.station()
494  << "\nFirst run with this bx-shift configuration: " << shiftStatusInitialRun->first
495  << "\nTrack reconstructed with: " << bxShiftedPlanesUsed << " bx-shifted planes, " << bxNonShiftedPlanesUsed
496  << " non-bx-shifted planes, " << hitInShiftedROC << " hits in the bx-shifted ROC"
497  << "\nrecoInfo = " << (unsigned short)track.recoInfo();
498  if (planeFlags != std::vector<bool>(6, false))
499  edm::LogInfo("RPixPlaneCombinatoryTracking") << "The shifted ROC is ROC" << shiftedROC;
500  }
501  }
502  return;
503 }
504 
505 //------------------------------------------------------------------------------------------------//
506 
508  uint32_t const numberOfPlanes = 6;
512 
513  //The matrices and vector xyCoordinates, varianceMatrix and varianceMatrix are built from the points
514  for (uint32_t iHit = 0; iHit < numberOfPlanes; iHit++) {
515  if (iHit < pointList.size()) {
516  const auto &globalPoint = pointList[iHit].globalPoint;
517  xyCoordinates[2 * iHit] = globalPoint.x();
518  xyCoordinates[2 * iHit + 1] = globalPoint.y();
519  zMatrix(2 * iHit, 0) = 1.;
520  zMatrix(2 * iHit, 2) = globalPoint.z() - z0_;
521  zMatrix(2 * iHit + 1, 1) = 1.;
522  zMatrix(2 * iHit + 1, 3) = globalPoint.z() - z0_;
523 
524  AlgebraicMatrix33 globalError = pointList[iHit].globalError;
525  varianceMatrix(2 * iHit, 2 * iHit) = globalError(0, 0);
526  varianceMatrix(2 * iHit, 2 * iHit + 1) = globalError(0, 1);
527  varianceMatrix(2 * iHit + 1, 2 * iHit) = globalError(1, 0);
528  varianceMatrix(2 * iHit + 1, 2 * iHit + 1) = globalError(1, 1);
529  } else {
530  varianceMatrix(2 * iHit, 2 * iHit) = 1.;
531  varianceMatrix(2 * iHit + 1, 2 * iHit + 1) = 1.;
532  }
533  }
534 
535  //Get real point variance matrix
536  if (!varianceMatrix.Invert()) {
537  edm::LogError("RPixPlaneCombinatoryTracking") << "Error in RPixPlaneCombinatoryTracking::fitTrack -> "
538  << "Point variance matrix is singular, skipping.";
539  CTPPSPixelLocalTrack badTrack;
540  badTrack.setValid(false);
541  return badTrack;
542  }
543 
544  math::Error<4>::type covarianceMatrix = ROOT::Math::SimilarityT(zMatrix, varianceMatrix);
545 
546  //To have the real parameter covariance matrix, covarianceMatrix needs to be inverted
547  if (!covarianceMatrix.Invert()) {
548  edm::LogError("RPixPlaneCombinatoryTracking") << "Error in RPixPlaneCombinatoryTracking::fitTrack -> "
549  << "Parameter covariance matrix is singular, skipping.";
550  CTPPSPixelLocalTrack badTrack;
551  badTrack.setValid(false);
552  return badTrack;
553  }
554 
555  // track parameters: (x0, y0, tx, ty); x = x0 + tx*(z-z0)
556  math::Vector<4>::type zMatrixTransposeTimesVarianceMatrixTimesXyCoordinates =
557  ROOT::Math::Transpose(zMatrix) * varianceMatrix * xyCoordinates;
558  math::Vector<4>::type parameterVector = covarianceMatrix * zMatrixTransposeTimesVarianceMatrixTimesXyCoordinates;
559  math::Vector<2 *numberOfPlanes>::type xyCoordinatesMinusZmatrixTimesParameters =
560  xyCoordinates - (zMatrix * parameterVector);
561 
562  double chiSquare = ROOT::Math::Dot(xyCoordinatesMinusZmatrixTimesParameters,
563  (varianceMatrix * xyCoordinatesMinusZmatrixTimesParameters));
564 
565  CTPPSPixelLocalTrack goodTrack(z0_, parameterVector, covarianceMatrix, chiSquare);
566  goodTrack.setValid(true);
567 
568  for (const auto &hit : pointList) {
569  const auto &globalPoint = hit.globalPoint;
570  GlobalPoint pointOnDet;
571  bool foundPoint = calculatePointOnDetector(&goodTrack, hit.detId, pointOnDet);
572  if (!foundPoint) {
573  CTPPSPixelLocalTrack badTrack;
574  badTrack.setValid(false);
575  return badTrack;
576  }
577  double xResidual = globalPoint.x() - pointOnDet.x();
578  double yResidual = globalPoint.y() - pointOnDet.y();
579  LocalPoint residuals(xResidual, yResidual);
580 
581  math::Error<3>::type globalError(hit.globalError);
582  LocalPoint pulls(xResidual / std::sqrt(globalError(0, 0)), yResidual / std::sqrt(globalError(0, 0)));
583 
584  CTPPSPixelFittedRecHit fittedRecHit(hit.recHit, pointOnDet, residuals, pulls);
585  fittedRecHit.setIsUsedForFit(true);
586  goodTrack.addHit(hit.detId, fittedRecHit);
587  }
588 
589  return goodTrack;
590 }
591 
592 //------------------------------------------------------------------------------------------------//
593 
594 //The method calculates the hit pointed by the track on the detector plane
596  CTPPSPixelDetId planeId,
597  GlobalPoint &planeLineIntercept) {
598  double z0 = track->z0();
600 
601  math::Vector<3>::type pointOnLine(parameters[0], parameters[1], z0);
602  GlobalVector tmpLineUnitVector = track->directionVector();
603  math::Vector<3>::type lineUnitVector(tmpLineUnitVector.x(), tmpLineUnitVector.y(), tmpLineUnitVector.z());
604 
605  const CTPPSGeometry::Vector tmpPointLocal(0., 0., 0.);
606  const auto &tmpPointOnPlane = geometry_->localToGlobal(planeId, tmpPointLocal);
607 
608  math::Vector<3>::type pointOnPlane(tmpPointOnPlane.x(), tmpPointOnPlane.y(), tmpPointOnPlane.z());
609  math::Vector<3>::type planeUnitVector(0., 0., 1.);
610 
611  DetGeomDesc::RotationMatrix theRotationMatrix = geometry_->sensor(planeId)->rotation();
612  AlgebraicMatrix33 tmpPlaneRotationMatrixMap;
613  theRotationMatrix.GetComponents(tmpPlaneRotationMatrixMap(0, 0),
614  tmpPlaneRotationMatrixMap(0, 1),
615  tmpPlaneRotationMatrixMap(0, 2),
616  tmpPlaneRotationMatrixMap(1, 0),
617  tmpPlaneRotationMatrixMap(1, 1),
618  tmpPlaneRotationMatrixMap(1, 2),
619  tmpPlaneRotationMatrixMap(2, 0),
620  tmpPlaneRotationMatrixMap(2, 1),
621  tmpPlaneRotationMatrixMap(2, 2));
622 
623  planeUnitVector = tmpPlaneRotationMatrixMap * planeUnitVector;
624 
625  double denominator = ROOT::Math::Dot(lineUnitVector, planeUnitVector);
626  if (denominator == 0) {
627  edm::LogError("RPixPlaneCombinatoryTracking")
628  << "Error in RPixPlaneCombinatoryTracking::calculatePointOnDetector -> "
629  << "Fitted line and plane are parallel. Removing this track";
630  return false;
631  }
632 
633  double distanceFromLinePoint = ROOT::Math::Dot((pointOnPlane - pointOnLine), planeUnitVector) / denominator;
634 
635  math::Vector<3>::type tmpPlaneLineIntercept = distanceFromLinePoint * lineUnitVector + pointOnLine;
636  planeLineIntercept = GlobalPoint(tmpPlaneLineIntercept[0], tmpPlaneLineIntercept[1], tmpPlaneLineIntercept[2]);
637 
638  return true;
639 }
640 //------------------------------------------------------------------------------------------------//
641 
642 // The method sorts the possible point combinations in order to process before fits on the highest possible number of points
643 std::vector<RPixPlaneCombinatoryTracking::PointAndReferencePair>
645  std::vector<PointAndReferencePair> sortedVector(inputMap.begin(), inputMap.end());
646  std::sort(sortedVector.begin(), sortedVector.end(), functionForPlaneOrdering);
647 
648  return sortedVector;
649 }
650 //------------------------------------------------------------------------------------------------//
uint32_t station() const
Definition: CTPPSDetId.h:58
T getUntrackedParameter(std::string const &, T const &) const
uint32_t plane() const
ROOT::Math::SMatrix< double, 3, 3, ROOT::Math::MatRepStd< double, 3, 3 > > AlgebraicMatrix33
const ParameterVector & parameterVector() const
RPixPlaneCombinatoryTracking(edm::ParameterSet const &parameterSet)
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
T y() const
Definition: PV3DBase.h:60
uint32_t factorial(uint32_t x) const
ErrorD< N >::type type
Definition: Error.h:32
CTPPSpixelLocalTrackReconstructionInfo
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
DetGeomDesc::Translation Vector
Definition: CTPPSGeometry.h:36
Vector localToGlobal(const DetGeomDesc *, const Vector &) const
std::vector< CTPPSPixelLocalTrack > localTrackVector_
std::map< HitReferences, PointInPlaneList > PointAndReferenceMap
void getHitCombinations(const std::map< CTPPSPixelDetId, PointInPlaneList > &mapOfAllHits, std::map< CTPPSPixelDetId, PointInPlaneList >::iterator mapIterator, HitReferences tmpHitPlaneMap, const PointInPlaneList &tmpHitVector, PointAndReferenceMap &outputMap)
const edm::DetSetVector< CTPPSPixelFittedRecHit > & hits() const
list denominator
Definition: cuy.py:485
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:19
ParameterSet const & parameterSet(StableProvenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:11
std::vector< RPixDetPatternFinder::PointInPlane > PointInPlaneList
T z() const
Definition: PV3DBase.h:61
int getROCId(const int col, const int row) const
std::map< CTPPSPixelDetId, std::vector< RPixDetPatternFinder::PointInPlane > > * hitMap_
float chiSquaredOverNDF() const
void setIsUsedForFit(bool usedForFit)
uint32_t arm() const
Definition: CTPPSDetId.h:51
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
const DetGeomDesc * sensor(unsigned int id) const
returns geometry of a detector performs necessary checks, returns NULL if fails
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
const CTPPSGeometry * geometry_
math::Vector< dimension >::type ParameterVector
covariance matrix size
PointAndReferenceMap produceAllHitCombination(PlaneCombinations inputPlaneCombination)
CTPPSPixelDetId romanPotId_
static bool functionForPlaneOrdering(PointAndReferencePair a, PointAndReferencePair b)
const RotationMatrix & rotation() const
Definition: DetGeomDesc.h:81
GlobalVector directionVector() const
T x() const
Definition: PV3DBase.h:59
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
void getPlaneCombinations(const std::vector< uint32_t > &inputPlaneList, uint32_t numberToExtract, PlaneCombinations &planeCombinations) const
uint32_t rp() const
Definition: CTPPSDetId.h:65