CMS 3D CMS Logo

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