CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SETSeedFinder.cc
Go to the documentation of this file.
1 
15 
16 #include "TMath.h"
17 
18 using namespace edm;
19 using namespace std;
20 
21 const string metname = "Muon|RecoMuon|SETMuonSeedFinder";
22 
24  // Parameter set for the Builder
25  ParameterSet trajectoryBuilderParameters = parameterSet.getParameter<ParameterSet>("SETTrajBuilderParameters");
26  apply_prePruning = trajectoryBuilderParameters.getParameter<bool>("Apply_prePruning");
27  // load pT seed parameters
28  thePtExtractor = new MuonSeedPtExtractor(trajectoryBuilderParameters);
29 }
30 
31 void SETSeedFinder::seeds(const MuonRecHitContainer& cluster, std::vector<TrajectorySeed>& result) {}
32 
33 // there is an existing sorter somewhere in the CMSSW code (I think) - delete that
34 namespace {
35  struct sorter {
36  sorter() {}
39  return (hit_1->globalPosition().mag2() < hit_2->globalPosition().mag2());
40  }
41  }; // smaller first
42  const sorter sortSegRadius;
43 } // namespace
44 
45 std::vector<SETSeedFinder::MuonRecHitContainer> SETSeedFinder::sortByLayer(MuonRecHitContainer& cluster) const {
46  stable_sort(cluster.begin(), cluster.end(), sortSegRadius);
47  //---- group hits in detector layers (if in same layer); the idea is that
48  //---- some hits could not belong to a track simultaneously - these will be in a
49  //---- group; two hits from one and the same group will not go to the same track
50  std::vector<MuonRecHitContainer> MuonRecHitContainer_perLayer;
51  if (!cluster.empty()) {
52  int iHit = 0;
53  MuonRecHitContainer hitsInThisLayer;
54  hitsInThisLayer.push_back(cluster[iHit]);
55  DetId detId = cluster[iHit]->hit()->geographicalId();
56  const GeomDet* geomDet = theService->trackingGeometry()->idToDet(detId);
57  while (iHit < int(cluster.size()) - 1) {
58  DetId detId_2 = cluster[iHit + 1]->hit()->geographicalId();
59  const GlobalPoint gp_nextHit = cluster[iHit + 1]->globalPosition();
60 
61  // this is the distance of the "second" hit to the "first" detector (containing the "first hit")
62  float distanceToDetector = fabs(geomDet->surface().localZ(gp_nextHit));
63 
64  //---- hits from DT and CSC could be very close in angle but incosistent with
65  //---- belonging to a common track (and these are different surfaces);
66  //---- also DT (and CSC now - 090822) hits from a station (in a pre-cluster) should be always in a group together;
67  //---- take this into account and put such hits in a group together
68 
69  bool specialCase = false;
70  if (detId.subdetId() == MuonSubdetId::DT && detId_2.subdetId() == MuonSubdetId::DT) {
71  DTChamberId dtCh(detId);
72  DTChamberId dtCh_2(detId_2);
73  specialCase = (dtCh.station() == dtCh_2.station());
74  } else if (detId.subdetId() == MuonSubdetId::CSC && detId_2.subdetId() == MuonSubdetId::CSC) {
75  CSCDetId cscCh(detId);
76  CSCDetId cscCh_2(detId_2);
77  specialCase = (cscCh.station() == cscCh_2.station() && cscCh.ring() == cscCh_2.ring());
78  }
79 
80  if (distanceToDetector < 0.001 || true == specialCase) { // hardcoded value - remove!
81  hitsInThisLayer.push_back(cluster[iHit + 1]);
82  } else {
83  specialCase = false;
84  if (((cluster[iHit]->isDT() && cluster[iHit + 1]->isCSC()) ||
85  (cluster[iHit]->isCSC() && cluster[iHit + 1]->isDT())) &&
86  //---- what is the minimal distance between a DT and a CSC hit belonging
87  //---- to a common track? (well, with "reasonable" errors; put 10 cm for now)
88  fabs(cluster[iHit + 1]->globalPosition().mag() - cluster[iHit]->globalPosition().mag()) < 10.) {
89  hitsInThisLayer.push_back(cluster[iHit + 1]);
90  // change to Stoyan - now we also update the detID here... give it a try. IBL 080905
91  detId = cluster[iHit + 1]->hit()->geographicalId();
92  geomDet = theService->trackingGeometry()->idToDet(detId);
93  } else if (!specialCase) {
94  //---- put the group of hits in the vector (containing the groups of hits)
95  //---- and continue with next layer (group)
96  MuonRecHitContainer_perLayer.push_back(hitsInThisLayer);
97  hitsInThisLayer.clear();
98  hitsInThisLayer.push_back(cluster[iHit + 1]);
99  detId = cluster[iHit + 1]->hit()->geographicalId();
100  geomDet = theService->trackingGeometry()->idToDet(detId);
101  }
102  }
103  ++iHit;
104  }
105  MuonRecHitContainer_perLayer.push_back(hitsInThisLayer);
106  }
107  return MuonRecHitContainer_perLayer;
108 }
109 //
110 void SETSeedFinder::limitCombinatorics(std::vector<MuonRecHitContainer>& MuonRecHitContainer_perLayer) {
111  const int maximumNumberOfCombinations = 1000000;
112  unsigned nLayers = MuonRecHitContainer_perLayer.size();
113  if (1 == nLayers) {
114  return;
115  }
116  // maximal number of (segment) layers would be upto ~12; see next function
117  // below is just a quick fix for a rare "overflow"
118  if (MuonRecHitContainer_perLayer.size() > 15) {
119  MuonRecHitContainer_perLayer.resize(1);
120  return;
121  }
122 
123  std::vector<double> sizeOfLayer(nLayers);
124  //std::cout<<" nLayers = "<<nLayers<<std::endl;
125  double nAllCombinations = 1.;
126  for (unsigned int i = 0; i < nLayers; ++i) {
127  //std::cout<<" i = "<<i<<" size = "<<MuonRecHitContainer_perLayer.at(i).size()<<std::endl;
128  sizeOfLayer.at(i) = MuonRecHitContainer_perLayer.at(i).size();
129  nAllCombinations *= MuonRecHitContainer_perLayer.at(i).size();
130  }
131  //std::cout<<"nAllCombinations = "<<nAllCombinations<<std::endl;
132  //---- Erase most busy detector layers until we get less than maximumNumberOfCombinations combinations
133  int iCycle = 0;
134  while (nAllCombinations > float(maximumNumberOfCombinations)) {
135  ++iCycle;
136  std::vector<double>::iterator maxEl_it = max_element(sizeOfLayer.begin(), sizeOfLayer.end());
137  int maxEl = maxEl_it - sizeOfLayer.begin();
138  nAllCombinations /= MuonRecHitContainer_perLayer.at(maxEl).size();
139  //std::cout<<" iCycle = "<<iCycle<<" nAllCombinations = "<<nAllCombinations<<std::endl;
140  MuonRecHitContainer_perLayer.erase(MuonRecHitContainer_perLayer.begin() + maxEl);
141  sizeOfLayer.erase(sizeOfLayer.begin() + maxEl);
142  }
143  return;
144 }
145 //
146 std::vector<SETSeedFinder::MuonRecHitContainer> SETSeedFinder::findAllValidSets(
147  const std::vector<SETSeedFinder::MuonRecHitContainer>& MuonRecHitContainer_perLayer) {
148  std::vector<MuonRecHitContainer> allValidSets;
149  // build all possible combinations (i.e valid sets; the algorithm name is after this feature -
150  // SET algorithm)
151  //
152  // ugly... use recursive function?!
153  // or implement Ingo's suggestion (a la ST)
154  unsigned nLayers = MuonRecHitContainer_perLayer.size();
155  if (1 == nLayers) {
156  return allValidSets;
157  }
158  MuonRecHitContainer validSet;
159  unsigned int iPos0 = 0;
160  std::vector<unsigned int> iLayer(12); // could there be more than 11 layers?
161  std::vector<unsigned int> size(12);
162  if (iPos0 < nLayers) {
163  size.at(iPos0) = MuonRecHitContainer_perLayer.at(iPos0).size();
164  for (iLayer[iPos0] = 0; iLayer[iPos0] < size[iPos0]; ++iLayer[iPos0]) {
165  validSet.clear();
166  validSet.push_back(MuonRecHitContainer_perLayer[iPos0][iLayer[iPos0]]);
167  unsigned int iPos1 = 1;
168  if (iPos1 < nLayers) {
169  size.at(iPos1) = MuonRecHitContainer_perLayer.at(iPos1).size();
170  for (iLayer[iPos1] = 0; iLayer[iPos1] < size[iPos1]; ++iLayer[iPos1]) {
171  validSet.resize(iPos1);
172  validSet.push_back(MuonRecHitContainer_perLayer[iPos1][iLayer[iPos1]]);
173  unsigned int iPos2 = 2;
174  if (iPos2 < nLayers) {
175  size.at(iPos2) = MuonRecHitContainer_perLayer.at(iPos2).size();
176  for (iLayer[iPos2] = 0; iLayer[iPos2] < size[iPos2]; ++iLayer[iPos2]) {
177  validSet.resize(iPos2);
178  validSet.push_back(MuonRecHitContainer_perLayer[iPos2][iLayer[iPos2]]);
179  unsigned int iPos3 = 3;
180  if (iPos3 < nLayers) {
181  size.at(iPos3) = MuonRecHitContainer_perLayer.at(iPos3).size();
182  for (iLayer[iPos3] = 0; iLayer[iPos3] < size[iPos3]; ++iLayer[iPos3]) {
183  validSet.resize(iPos3);
184  validSet.push_back(MuonRecHitContainer_perLayer[iPos3][iLayer[iPos3]]);
185  unsigned int iPos4 = 4;
186  if (iPos4 < nLayers) {
187  size.at(iPos4) = MuonRecHitContainer_perLayer.at(iPos4).size();
188  for (iLayer[iPos4] = 0; iLayer[iPos4] < size[iPos4]; ++iLayer[iPos4]) {
189  validSet.resize(iPos4);
190  validSet.push_back(MuonRecHitContainer_perLayer[iPos4][iLayer[iPos4]]);
191  unsigned int iPos5 = 5;
192  if (iPos5 < nLayers) {
193  size.at(iPos5) = MuonRecHitContainer_perLayer.at(iPos5).size();
194  for (iLayer[iPos5] = 0; iLayer[iPos5] < size[iPos5]; ++iLayer[iPos5]) {
195  validSet.resize(iPos5);
196  validSet.push_back(MuonRecHitContainer_perLayer[iPos5][iLayer[iPos5]]);
197  unsigned int iPos6 = 6;
198  if (iPos6 < nLayers) {
199  size.at(iPos6) = MuonRecHitContainer_perLayer.at(iPos6).size();
200  for (iLayer[iPos6] = 0; iLayer[iPos6] < size[iPos6]; ++iLayer[iPos6]) {
201  validSet.resize(iPos6);
202  validSet.push_back(MuonRecHitContainer_perLayer[iPos6][iLayer[iPos6]]);
203  unsigned int iPos7 = 7;
204  if (iPos7 < nLayers) {
205  size.at(iPos7) = MuonRecHitContainer_perLayer.at(iPos7).size();
206  for (iLayer[iPos7] = 0; iLayer[iPos7] < size[iPos7]; ++iLayer[iPos7]) {
207  validSet.resize(iPos7);
208  validSet.push_back(MuonRecHitContainer_perLayer[iPos7][iLayer[iPos7]]);
209  unsigned int iPos8 = 8;
210  if (iPos8 < nLayers) {
211  size.at(iPos8) = MuonRecHitContainer_perLayer.at(iPos8).size();
212  for (iLayer[iPos8] = 0; iLayer[iPos8] < size[iPos8]; ++iLayer[iPos8]) {
213  validSet.resize(iPos8);
214  validSet.push_back(MuonRecHitContainer_perLayer[iPos8][iLayer[iPos8]]);
215  unsigned int iPos9 = 9;
216  if (iPos9 < nLayers) {
217  size.at(iPos9) = MuonRecHitContainer_perLayer.at(iPos9).size();
218  for (iLayer[iPos9] = 0; iLayer[iPos9] < size[iPos9]; ++iLayer[iPos9]) {
219  validSet.resize(iPos9);
220  validSet.push_back(MuonRecHitContainer_perLayer[iPos9][iLayer[iPos9]]);
221  unsigned int iPos10 = 10;
222  if (iPos10 < nLayers) {
223  size.at(iPos10) = MuonRecHitContainer_perLayer.at(iPos10).size();
224  for (iLayer[iPos10] = 0; iLayer[iPos10] < size[iPos10]; ++iLayer[iPos10]) {
225  validSet.resize(iPos10);
226  validSet.push_back(MuonRecHitContainer_perLayer[iPos10][iLayer[iPos10]]);
227  unsigned int iPos11 = 11; // more?
228  if (iPos11 < nLayers) {
229  size.at(iPos11) = MuonRecHitContainer_perLayer.at(iPos11).size();
230  for (iLayer[iPos11] = 0; iLayer[iPos11] < size[iPos11];
231  ++iLayer[iPos11]) {
232  }
233  } else {
234  allValidSets.push_back(validSet);
235  }
236  }
237  } else {
238  allValidSets.push_back(validSet);
239  }
240  }
241  } else {
242  allValidSets.push_back(validSet);
243  }
244  }
245  } else {
246  allValidSets.push_back(validSet);
247  }
248  }
249  } else {
250  allValidSets.push_back(validSet);
251  }
252  }
253  } else {
254  allValidSets.push_back(validSet);
255  }
256  }
257  } else {
258  allValidSets.push_back(validSet);
259  }
260  }
261  } else {
262  allValidSets.push_back(validSet);
263  }
264  }
265  } else {
266  allValidSets.push_back(validSet);
267  }
268  }
269  } else {
270  allValidSets.push_back(validSet);
271  }
272  }
273  } else {
274  allValidSets.push_back(validSet);
275  }
276  }
277  } else {
278  allValidSets.push_back(validSet);
279  }
280  return allValidSets;
281 }
282 
283 std::pair<int, int> // or <bool, bool>
284 SETSeedFinder::checkAngleDeviation(double dPhi_1, double dPhi_2) const {
285  // Two conditions:
286  // a) deviations should be only to one side (above some absolute value cut to avoid
287  // material effects; this should be refined)
288  // b) deviatiation in preceding steps should be bigger due to higher magnetic field
289  // (again - a minimal value cut should be in place; this also should account for
290  // the small (Z) distances in overlaping CSC chambers)
291 
292  double mult = dPhi_1 * dPhi_2;
293  int signVal = 1;
294  if (fabs(dPhi_1) < fabs(dPhi_2)) {
295  signVal = -1;
296  }
297  int signMult = -1;
298  if (mult > 0)
299  signMult = 1;
300  std::pair<int, int> sign;
301  sign = make_pair(signVal, signMult);
302 
303  return sign;
304 }
305 
306 void SETSeedFinder::validSetsPrePruning(std::vector<SETSeedFinder::MuonRecHitContainer>& allValidSets) {
307  //---- this actually is a pre-pruning; it does not include any fit information;
308  //---- it is intended to remove only very "wild" segments from a set;
309  //---- no "good" segment is to be lost (otherwise - widen the parameters)
310 
311  for (unsigned int iSet = 0; iSet < allValidSets.size(); ++iSet) {
312  pre_prune(allValidSets[iSet]);
313  }
314 }
315 
317  unsigned nHits = validSet.size();
318  if (nHits > 3) { // to decide we need at least 4 measurements
319  // any information could be used to make a decision for pruning
320  // maybe dPhi (delta Phi) is enough
321  std::vector<double> dPhi;
322  double dPhi_tmp;
323  bool wildCandidate;
324  int pruneHit_tmp;
325 
326  for (unsigned int iHit = 1; iHit < nHits; ++iHit) {
327  dPhi_tmp = validSet[iHit]->globalPosition().phi() - validSet[iHit - 1]->globalPosition().phi();
328  dPhi.push_back(dPhi_tmp);
329  }
330  std::vector<int> pruneHit;
331  //---- loop over all the hits in a set
332 
333  for (unsigned int iHit = 0; iHit < nHits; ++iHit) {
334  double dPHI_MIN = 0.02; //?? hardcoded - remove it
335  if (iHit) {
336  // if we have to remove the very first hit (iHit == 0) then
337  // we'll probably be in trouble already
338  wildCandidate = false;
339  // actually 2D is bad only if not r-phi... Should I refine it?
340  // a hit is a candidate for pruning only if dPhi > dPHI_MIN;
341  // pruning decision is based on combination of hits characteristics
342  if (4 == validSet[iHit - 1]->dimension() && 4 == validSet[iHit]->dimension() &&
343  fabs(validSet[iHit]->globalPosition().phi() - validSet[iHit - 1]->globalPosition().phi()) > dPHI_MIN) {
344  wildCandidate = true;
345  }
346  pruneHit_tmp = -1;
347  if (wildCandidate) {
348  // OK - this couple doesn't look good (and is from 4D segments); proceed...
349  if (1 == iHit) { // the first and the last hits are special case
350  if (4 == validSet[iHit + 1]->dimension() && 4 == validSet[iHit + 2]->dimension()) { //4D?
351  // is the picture better if we remove the second hit?
352  dPhi_tmp = validSet[iHit + 1]->globalPosition().phi() - validSet[iHit - 1]->globalPosition().phi();
353  // is the deviation what we expect (sign, not magnitude)?
354  std::pair<int, int> sign = checkAngleDeviation(dPhi_tmp, dPhi[2]);
355  if (1 == sign.first && 1 == sign.second) {
356  pruneHit_tmp = iHit; // mark the hit 1 for removing
357  }
358  }
359  } else if (iHit > 1 && iHit < validSet.size() - 1) {
360  if (4 == validSet[0]->dimension() && // we rely on the first (most important) couple
361  4 == validSet[1]->dimension() && pruneHit.back() != int(iHit - 1) &&
362  pruneHit.back() != 1) { // check if hits are already marked
363  // decide which of the two hits should be removed (if any; preferably the outer one i.e.
364  // iHit rather than iHit-1); here - check what we get by removing iHit
365  dPhi_tmp = validSet[iHit + 1]->globalPosition().phi() - validSet[iHit - 1]->globalPosition().phi();
366  // first couple is most important anyway so again compare to it
367  std::pair<int, int> sign = checkAngleDeviation(dPhi[0], dPhi_tmp);
368  if (1 == sign.first && 1 == sign.second) {
369  pruneHit_tmp = iHit; // mark the hit iHit for removing
370  } else { // iHit is not to be removed; proceed...
371  // what if we remove (iHit - 1) instead of iHit?
372  dPhi_tmp = validSet[iHit + 1]->globalPosition().phi() - validSet[iHit]->globalPosition().phi();
373  std::pair<int, int> sign = checkAngleDeviation(dPhi[0], dPhi_tmp);
374  if (1 == sign.first && 1 == sign.second) {
375  pruneHit_tmp = iHit - 1; // mark the hit (iHit -1) for removing
376  }
377  }
378  }
379  } else {
380  // the last hit: if picture is not good - remove it
381  if (pruneHit.size() > 1 && pruneHit[pruneHit.size() - 1] < 0 && pruneHit[pruneHit.size() - 2] < 0) {
382  std::pair<int, int> sign = checkAngleDeviation(dPhi[dPhi.size() - 2], dPhi[dPhi.size() - 1]);
383  if (-1 == sign.first && -1 == sign.second) { // here logic is a bit twisted
384  pruneHit_tmp = iHit; // mark the last hit for removing
385  }
386  }
387  }
388  }
389  pruneHit.push_back(pruneHit_tmp);
390  }
391  }
392  // }
393  // actual pruning
394  for (unsigned int iHit = 1; iHit < nHits; ++iHit) {
395  int count = 0;
396  if (pruneHit[iHit - 1] > 0) {
397  validSet.erase(validSet.begin() + pruneHit[iHit - 1] - count);
398  ++count;
399  }
400  }
401  }
402 }
403 
404 std::vector<SeedCandidate> SETSeedFinder::fillSeedCandidates(std::vector<MuonRecHitContainer>& allValidSets) {
405  //---- we have the valid sets constructed; transform the information in an
406  //---- apropriate form; meanwhile - estimate the momentum for a given set
407 
408  // RPCs should not be used (no parametrization)
409  std::vector<SeedCandidate> seedCandidates_inCluster;
410  // calculate and fill the inputs needed
411  // loop over all valid sets
412  for (unsigned int iSet = 0; iSet < allValidSets.size(); ++iSet) {
413  //
414  //std::cout<<" This is SET number : "<<iSet<<std::endl;
415  //for(unsigned int iHit = 0;iHit<allValidSets[iSet].size();++iHit){
416  //std::cout<<" measurements in the SET: iHit = "<<iHit<<" pos = "<<allValidSets[iSet][iHit]->globalPosition()<<
417  //" dim = "<<allValidSets[iSet][iHit]->dimension()<<std::endl;
418  //}
419 
420  CLHEP::Hep3Vector momEstimate;
421  int chargeEstimate;
422  estimateMomentum(allValidSets[iSet], momEstimate, chargeEstimate);
423  MuonRecHitContainer MuonRecHitContainer_theSet_prep;
424  // currently hardcoded - will be in proper loop of course:
425 
426  SeedCandidate seedCandidates_inCluster_prep;
427  seedCandidates_inCluster_prep.theSet = allValidSets[iSet];
428  seedCandidates_inCluster_prep.momentum = momEstimate;
429  seedCandidates_inCluster_prep.charge = chargeEstimate;
430  seedCandidates_inCluster.push_back(seedCandidates_inCluster_prep);
431  // END estimateMomentum
432  }
433  return seedCandidates_inCluster;
434 }
435 
437  CLHEP::Hep3Vector& momEstimate,
438  int& charge) const {
439  int firstMeasurement = -1;
440  int lastMeasurement = -1;
441 
442  // don't use 2D measurements for momentum estimation
443 
444  //if( 4==allValidSets[iSet].front()->dimension() &&
445  //(allValidSets[iSet].front()->isCSC() || allValidSets[iSet].front()->isDT())){
446  //firstMeasurement = 0;
447  //}
448  //else{
449  // which is the "first" hit (4D)?
450  for (unsigned int iMeas = 0; iMeas < validSet.size(); ++iMeas) {
451  if (4 == validSet[iMeas]->dimension() && (validSet[iMeas]->isCSC() || validSet[iMeas]->isDT())) {
452  firstMeasurement = iMeas;
453  break;
454  }
455  }
456  //}
457 
458  std::vector<double> momentum_estimate;
459  double pT = 0.;
462  // which is the second hit?
463  for (int loop = 0; loop < 2; ++loop) { // it is actually not used; to be removed
464  // this is the last measurement
465  if (!loop) { // this is what is used currently
466  // 23.04.09 : it becomes a problem with introduction of ME42 chambers -
467  // the initial pT parametrization is incorrect for them
468  for (int iMeas = validSet.size() - 1; iMeas > -1; --iMeas) {
469  if (4 == validSet[iMeas]->dimension() && (validSet[iMeas]->isCSC() || validSet[iMeas]->isDT()) &&
470  // below is a fix saying "don't use ME4 chambers for initial pT estimation";
471  // not using ME41 should not be a big loss too (and is more "symmetric" solution)
472  fabs(validSet[iMeas]->globalPosition().z()) < 1000.) {
473  lastMeasurement = iMeas;
474  break;
475  }
476  }
477  } else {
478  // this is the second measurement
479  for (unsigned int iMeas = 1; iMeas < validSet.size(); ++iMeas) {
480  if (4 == validSet[iMeas]->dimension() && (validSet[iMeas]->isCSC() || validSet[iMeas]->isDT())) {
481  lastMeasurement = iMeas;
482  break;
483  }
484  }
485  }
486  // only 2D measurements (it should have been already abandoned)
487  if (-1 == lastMeasurement && -1 == firstMeasurement) {
488  firstMeasurement = 0;
489  lastMeasurement = validSet.size() - 1;
490  }
491  // because of the ME42 above lastMeasurement could be -1
492  else if (-1 == lastMeasurement) {
493  lastMeasurement = firstMeasurement;
494  } else if (-1 == firstMeasurement) {
495  firstMeasurement = lastMeasurement;
496  }
497 
498  firstHit = validSet[firstMeasurement];
499  secondHit = validSet[lastMeasurement];
500  if (firstHit->isRPC() && secondHit->isRPC()) { // remove all RPCs from here?
501  momentum_estimate.push_back(300.);
502  momentum_estimate.push_back(300.);
503  } else {
504  if (firstHit->isRPC()) {
505  firstHit = secondHit;
506  } else if (secondHit->isRPC()) {
507  secondHit = firstHit;
508  }
509  //---- estimate pT given two hits
510  //std::cout<<" hits for initial pT estimate: first -> dim = "<<firstHit->dimension()<<" pos = "<<firstHit->globalPosition()<<
511  //" , second -> "<<" dim = "<<secondHit->dimension()<<" pos = "<<secondHit->globalPosition()<<std::endl;
512  //---- pT throws exception if hits are MB4
513  // (no coding for them - 2D hits in the outer station)
514  if (2 == firstHit->dimension() && 2 == secondHit->dimension()) {
515  momentum_estimate.push_back(999999999.);
516  momentum_estimate.push_back(999999999.);
517  } else {
518  momentum_estimate = thePtExtractor->pT_extract(firstHit, secondHit);
519  }
520  }
521  pT = fabs(momentum_estimate[0]);
522  if (true || pT > 40.) { //it is skipped; we have to look at least into number of hits in the chamber actually...
523  // and then decide which segment to use
524  // use the last measurement, otherwise use the second; this is to be investigated
525  break;
526  }
527  }
528 
529  const float pT_min = 1.99; // many hardcoded - remove them!
530  if (pT > 3000.) {
531  pT = 3000.;
532  } else if (pT < pT_min) {
533  if (pT > 0) {
534  pT = pT_min;
535  } else if (pT > (-1) * pT_min) {
536  pT = (-1) * pT_min;
537  } else if (pT < -3000.) {
538  pT = -3000;
539  }
540  }
541  //std::cout<<" THE pT from the parametrization: "<<momentum_estimate[0]<<std::endl;
542  // estimate the charge of the track candidate from the delta phi of two segments:
543  //int charge = dPhi > 0 ? 1 : -1; // what we want is: dphi < 0 => charge = -1
544  charge = momentum_estimate[0] > 0 ? 1 : -1;
545 
546  // we have the pT - get the 3D momentum estimate as well
547 
548  // this is already final info:
549  double xHit = validSet[firstMeasurement]->globalPosition().x();
550  double yHit = validSet[firstMeasurement]->globalPosition().y();
551  double rHit = TMath::Sqrt(pow(xHit, 2) + pow(yHit, 2));
552 
553  double thetaInner = validSet[firstMeasurement]->globalPosition().theta();
554  // if some of the segments is missing r-phi measurement then we should
555  // use only the 4D phi estimate (also use 4D eta estimate only)
556  // the direction is not so important (it will be corrected)
557 
558  double rTrack = (pT / (0.3 * 3.8)) * 100.; //times 100 for conversion to cm!
559 
560  double par = -1. * (2. / charge) * (TMath::ASin(rHit / (2 * rTrack)));
561  double sinPar = TMath::Sin(par);
562  double cosPar = TMath::Cos(par);
563 
564  // calculate phi at coordinate origin (0,0,0).
565  double sinPhiH = 1. / (2. * charge * rTrack) * (xHit + ((sinPar) / (cosPar - 1.)) * yHit);
566  double cosPhiH = -1. / (2. * charge * rTrack) * (((sinPar) / (1. - cosPar)) * xHit + yHit);
567 
568  // finally set the return vector
569 
570  // try out the reco info:
571  // should used into to theta directly here (rather than tan(atan2(...)))
572  momEstimate = CLHEP::Hep3Vector(pT * cosPhiH, pT * sinPhiH, pT / TMath::Tan(thetaInner));
573  //Hep3Vector momEstimate(6.97961, 5.89732, -50.0855);
574  const float minMomenum = 5.; //hardcoded - remove it! same in SETFilter
575  if (momEstimate.mag() < minMomenum) {
576  int sign = (pT < 0.) ? -1 : 1;
577  pT = sign * (fabs(pT) + 1);
578  CLHEP::Hep3Vector momEstimate2(pT * cosPhiH, pT * sinPhiH, pT / TMath::Tan(thetaInner));
579  momEstimate = momEstimate2;
580  if (momEstimate.mag() < minMomenum) {
581  pT = sign * (fabs(pT) + 1);
582  CLHEP::Hep3Vector momEstimate3(pT * cosPhiH, pT * sinPhiH, pT / TMath::Tan(thetaInner));
583  momEstimate = momEstimate3;
584  if (momEstimate.mag() < minMomenum) {
585  pT = sign * (fabs(pT) + 1);
586  CLHEP::Hep3Vector momEstimate4(pT * cosPhiH, pT * sinPhiH, pT / TMath::Tan(thetaInner));
587  momEstimate = momEstimate4;
588  }
589  }
590  }
591 }
592 
595  edm::OwnVector<TrackingRecHit> recHitsContainer;
596  for (unsigned int iHit = 0; iHit < hits.size(); ++iHit) {
597  recHitsContainer.push_back(hits.at(iHit)->hit()->clone());
598  }
601  dir = alongMomentum; // why forward (for rechits) later?
602  }
603 
604  PTrajectoryStateOnDet const& seedTSOS =
605  trajectoryStateTransform::persistentState(firstTSOS, hits.at(0)->geographicalId().rawId());
606  TrajectorySeed seed(seedTSOS, recHitsContainer, dir);
607 
608  //MuonPatternRecoDumper debug;
609  //std::cout<<" firstTSOS = "<<debug.dumpTSOS(firstTSOS)<<std::endl;
610  //std::cout<<" iTraj = ???"<<" hits = "<<range.second-range.first<<std::endl;
611  //std::cout<<" nhits = "<<hits.size()<<std::endl;
612  //for(unsigned int iRH=0;iRH<hits.size();++iRH){
613  //std::cout<<" RH = "<<iRH+1<<" globPos = "<<hits.at(iRH)->globalPosition()<<std::endl;
614  //}
615  return seed;
616 }
bool apply_prePruning
Definition: SETSeedFinder.h:55
const std::string metname
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
CLHEP::Hep3Vector momentum
Definition: SETFilter.h:35
double sign(double x)
PTrajectoryStateOnDet persistentState(const TrajectoryStateOnSurface &ts, unsigned int detid)
std::pair< int, int > checkAngleDeviation(double dPhi_1, double dPhi_2) const
float localZ(const GlobalPoint &gp) const
Definition: Plane.h:45
void pre_prune(MuonRecHitContainer &validSet) const
bool useSegmentsInTrajectory
Definition: SETSeedFinder.h:56
PropagationDirection
TrajectorySeed makeSeed(const TrajectoryStateOnSurface &tsos, const TransientTrackingRecHit::ConstRecHitContainer &hits) const
bool isDT(GeomDetEnumerators::SubDetector m)
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
std::vector< MuonRecHitContainer > sortByLayer(MuonRecHitContainer &cluster) const
void estimateMomentum(const MuonRecHitContainer &validSet, CLHEP::Hep3Vector &momentum, int &charge) const
sorter()
Definition: SETFilter.cc:33
tuple result
Definition: mps_fire.py:311
void push_back(D *&d)
Definition: OwnVector.h:326
std::shared_ptr< MuonTransientTrackingRecHit > MuonRecHitPointer
ParameterSet const & parameterSet(StableProvenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:11
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
bool operator()(TransientTrackingRecHit::ConstRecHitPointer hit_1, TransientTrackingRecHit::ConstRecHitPointer hit_2) const
Definition: SETFilter.cc:34
MuonTransientTrackingRecHit::MuonRecHitContainer MuonRecHitContainer
Definition: SETSeedFinder.h:13
std::vector< ConstRecHitPointer > ConstRecHitContainer
MuonSeedPtExtractor * thePtExtractor
void limitCombinatorics(std::vector< MuonRecHitContainer > &MuonRecHitContainer_perLayer)
int ring() const
Definition: CSCDetId.h:68
Definition: DetId.h:17
void seeds(const MuonRecHitContainer &cluster, std::vector< TrajectorySeed > &result) override
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
std::vector< MuonRecHitContainer > findAllValidSets(const std::vector< MuonRecHitContainer > &MuonRecHitContainer_perLayer)
caConstants::TupleMultiplicity const CAHitNtupletGeneratorKernelsGPU::HitToTuple const cms::cuda::AtomicPairCounter GPUCACell const *__restrict__ uint32_t const *__restrict__ gpuPixelDoublets::CellNeighborsVector const gpuPixelDoublets::CellTracksVector const GPUCACell::OuterHitOfCell const int32_t nHits
MuonServiceProxy * theService
Definition: SETSeedFinder.h:53
void validSetsPrePruning(std::vector< MuonRecHitContainer > &allValidSets)
bool isCSC(GeomDetEnumerators::SubDetector m)
MuonTransientTrackingRecHit::MuonRecHitContainer theSet
Definition: SETFilter.h:34
int station() const
Definition: CSCDetId.h:79
std::shared_ptr< MuonTransientTrackingRecHit const > ConstMuonRecHitPointer
static constexpr int DT
Definition: MuonSubdetId.h:11
std::vector< SeedCandidate > fillSeedCandidates(std::vector< MuonRecHitContainer > &allValidSets)
virtual std::vector< double > pT_extract(MuonTransientTrackingRecHit::ConstMuonRecHitPointer firstHit, MuonTransientTrackingRecHit::ConstMuonRecHitPointer secondHit) const
int station() const
Return the station number.
Definition: DTChamberId.h:42
uint32_t dimension(pat::CandKinResolution::Parametrization parametrization)
Returns the number of free parameters in a parametrization (3 or 4)
static constexpr int CSC
Definition: MuonSubdetId.h:12
SETSeedFinder(const edm::ParameterSet &pset)
tuple size
Write out results.
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29