CMS 3D CMS Logo

MuonSeedCleaner.cc
Go to the documentation of this file.
1 
8 
9 // Data Formats
18 
19 // Geometry
25 
26 // muon service
29 
30 // Framework
36 
37 // C++
38 #include <vector>
39 #include <deque>
40 #include <utility>
41 
42 //typedef std::pair<double, TrajectorySeed> seedpr ;
43 //static bool ptDecreasing(const seedpr s1, const seedpr s2) { return ( s1.first > s2.first ); }
44 static bool lengthSorting(const TrajectorySeed& s1, const TrajectorySeed& s2) { return (s1.nHits() > s2.nHits()); }
45 
46 /*
47  * Constructor
48  */
50  // Local Debug flag
51  debug = pset.getParameter<bool>("DebugMuonSeed");
52 
53  // muon service
54  edm::ParameterSet serviceParameters = pset.getParameter<edm::ParameterSet>("ServiceParameters");
55  theService = new MuonServiceProxy(serviceParameters);
56 }
57 
58 /*
59  * Destructor
60  */
62  if (theService)
63  delete theService;
64 }
65 
66 /***********************************
67  *
68  * Seed Cleaner
69  *
70  ***********************************/
71 
72 std::vector<TrajectorySeed> MuonSeedCleaner::seedCleaner(const edm::EventSetup& eventSetup,
73  std::vector<TrajectorySeed>& seeds) {
74  theService->update(eventSetup);
75 
76  std::vector<TrajectorySeed> FinalSeeds;
77 
78  // group the seeds
79  std::vector<SeedContainer> theCollection = GroupSeeds(seeds);
80 
81  // ckeck each group and pick the good one
82  for (size_t i = 0; i < theCollection.size(); i++) {
83  // separate seeds w/ more than 1 segments and w/ 1st layer segment information
84  SeedContainer goodSeeds = SeedCandidates(theCollection[i], true);
85  SeedContainer otherSeeds = SeedCandidates(theCollection[i], false);
86  if (MomentumFilter(goodSeeds)) {
87  //std::cout<<" == type1 "<<std::endl;
88  TrajectorySeed bestSeed = Chi2LengthSelection(goodSeeds);
89  FinalSeeds.push_back(bestSeed);
90 
91  GlobalPoint seedgp = SeedPosition(bestSeed);
92  double eta = fabs(seedgp.eta());
93  if (goodSeeds.size() > 2 && eta > 1.5) {
94  TrajectorySeed anotherSeed = MoreRecHits(goodSeeds);
95  FinalSeeds.push_back(anotherSeed);
96  }
97  } else if (MomentumFilter(otherSeeds)) {
98  //std::cout<<" == type2 "<<std::endl;
99  TrajectorySeed bestSeed = MoreRecHits(otherSeeds);
100  FinalSeeds.push_back(bestSeed);
101 
102  GlobalPoint seedgp = SeedPosition(bestSeed);
103  double eta = fabs(seedgp.eta());
104  if (otherSeeds.size() > 2 && eta > 1.5) {
105  TrajectorySeed anotherSeed = LeanHighMomentum(otherSeeds);
106  FinalSeeds.push_back(anotherSeed);
107  }
108  } else {
109  //std::cout<<" == type3 "<<std::endl;
110  TrajectorySeed bestSeed = LeanHighMomentum(theCollection[i]);
111  FinalSeeds.push_back(bestSeed);
112 
113  GlobalPoint seedgp = SeedPosition(bestSeed);
114  double eta = fabs(seedgp.eta());
115  if (theCollection.size() > 2 && eta > 1.5) {
116  TrajectorySeed anotherSeed = BiggerCone(theCollection[i]);
117  FinalSeeds.push_back(anotherSeed);
118  }
119  }
120  }
121  return FinalSeeds;
122 }
123 
124 TrajectorySeed MuonSeedCleaner::Chi2LengthSelection(std::vector<TrajectorySeed>& seeds) {
125  if (seeds.size() == 1)
126  return seeds[0];
127 
128  int winner = 0;
129  int moreHits = 0;
130  double bestChi2 = 99999.;
131  for (size_t i = 0; i < seeds.size(); i++) {
132  // 1. fill out the Nchi2 of segments of the seed
133  //GlobalVector mom = SeedMomentum( seeds[i] ); // temporary use for debugging
134  //double pt = sqrt( (mom.x()*mom.x()) + (mom.y()*mom.y()) );
135  //std::cout<<" > SEED"<<i<<" pt:"<<pt<< std::endl;
136 
137  double theChi2 = SeedChi2(seeds[i]);
138  double dChi2 = fabs(1. - (theChi2 / bestChi2));
139  int theHits = seeds[i].nHits();
140  int dHits = theHits - moreHits;
141  //std::cout<<" ----- "<<std::endl;
142 
143  // 2. better chi2
144  if (theChi2 < bestChi2 && dChi2 > 0.05) {
145  winner = static_cast<int>(i);
146  bestChi2 = theChi2;
147  moreHits = theHits;
148  }
149  // 3. if chi2 is not much better, pick more rechits one
150  if (theChi2 >= bestChi2 && dChi2 < 0.05 && dHits > 0) {
151  winner = static_cast<int>(i);
152  bestChi2 = theChi2;
153  moreHits = theHits;
154  }
155  }
156  //std::cout<<" Winner is "<< winner <<std::endl;
157  TrajectorySeed theSeed = seeds[winner];
158  seeds.erase(seeds.begin() + winner);
159  return theSeed;
160 }
161 
162 TrajectorySeed MuonSeedCleaner::BiggerCone(std::vector<TrajectorySeed>& seeds) {
163  if (seeds.size() == 1)
164  return seeds[0];
165 
166  float biggerProjErr = 9999.;
167  int winner = 0;
168  AlgebraicSymMatrix mat(5, 0);
169  for (size_t i = 0; i < seeds.size(); i++) {
170  edm::OwnVector<TrackingRecHit>::const_iterator r1 = seeds[i].recHits().first;
171  mat = r1->parametersError().similarityT(r1->projectionMatrix());
172 
173  int NRecHits = NRecHitsFromSegment(*r1);
174 
175  float ddx = mat[1][1];
176  float ddy = mat[2][2];
177  float dxx = mat[3][3];
178  float dyy = mat[4][4];
179  float projectErr = sqrt((ddx * 10000.) + (ddy * 10000.) + dxx + dyy);
180 
181  if (NRecHits < 5)
182  continue;
183  if (projectErr < biggerProjErr)
184  continue;
185 
186  winner = static_cast<int>(i);
187  biggerProjErr = projectErr;
188  }
189  TrajectorySeed theSeed = seeds[winner];
190  seeds.erase(seeds.begin() + winner);
191  return theSeed;
192 }
193 
194 TrajectorySeed MuonSeedCleaner::LeanHighMomentum(std::vector<TrajectorySeed>& seeds) {
195  if (seeds.size() == 1)
196  return seeds[0];
197 
198  double highestPt = 0.;
199  int winner = 0;
200  for (size_t i = 0; i < seeds.size(); i++) {
201  GlobalVector mom = SeedMomentum(seeds[i]);
202  double pt = sqrt((mom.x() * mom.x()) + (mom.y() * mom.y()));
203  if (pt > highestPt) {
204  winner = static_cast<int>(i);
205  highestPt = pt;
206  }
207  }
208  TrajectorySeed theSeed = seeds[winner];
209  seeds.erase(seeds.begin() + winner);
210  return theSeed;
211 }
212 
213 TrajectorySeed MuonSeedCleaner::MoreRecHits(std::vector<TrajectorySeed>& seeds) {
214  if (seeds.size() == 1)
215  return seeds[0];
216 
217  int winner = 0;
218  int moreHits = 0;
219  double betterChi2 = 99999.;
220  for (size_t i = 0; i < seeds.size(); i++) {
221  int theHits = 0;
222  for (edm::OwnVector<TrackingRecHit>::const_iterator r1 = seeds[i].recHits().first; r1 != seeds[i].recHits().second;
223  r1++) {
224  theHits += NRecHitsFromSegment(*r1);
225  }
226 
227  double theChi2 = SeedChi2(seeds[i]);
228 
229  if (theHits == moreHits && theChi2 < betterChi2) {
230  betterChi2 = theChi2;
231  winner = static_cast<int>(i);
232  }
233  if (theHits > moreHits) {
234  moreHits = theHits;
235  betterChi2 = theChi2;
236  winner = static_cast<int>(i);
237  }
238  }
239  TrajectorySeed theSeed = seeds[winner];
240  seeds.erase(seeds.begin() + winner);
241  return theSeed;
242 }
243 
244 SeedContainer MuonSeedCleaner::LengthFilter(std::vector<TrajectorySeed>& seeds) {
245  SeedContainer longSeeds;
246  int NSegs = 0;
247  for (size_t i = 0; i < seeds.size(); i++) {
248  int theLength = static_cast<int>(seeds[i].nHits());
249  if (theLength > NSegs) {
250  NSegs = theLength;
251  longSeeds.clear();
252  longSeeds.push_back(seeds[i]);
253  } else if (theLength == NSegs) {
254  longSeeds.push_back(seeds[i]);
255  } else {
256  continue;
257  }
258  }
259  //std::cout<<" final Length :"<<NSegs<<std::endl;
260 
261  return longSeeds;
262 }
263 
264 bool MuonSeedCleaner::MomentumFilter(std::vector<TrajectorySeed>& seeds) {
265  bool findgoodMomentum = false;
266  SeedContainer goodMomentumSeeds = seeds;
267  seeds.clear();
268  for (size_t i = 0; i < goodMomentumSeeds.size(); i++) {
269  GlobalVector mom = SeedMomentum(goodMomentumSeeds[i]);
270  double pt = sqrt((mom.x() * mom.x()) + (mom.y() * mom.y()));
271  if (pt < 6. || pt > 2000.)
272  continue;
273  //if ( pt < 6. ) continue;
274  //std::cout<<" passed momentum :"<< pt <<std::endl;
275  seeds.push_back(goodMomentumSeeds[i]);
276  findgoodMomentum = true;
277  }
278  if (seeds.empty())
279  seeds = goodMomentumSeeds;
280 
281  return findgoodMomentum;
282 }
283 
284 SeedContainer MuonSeedCleaner::SeedCandidates(std::vector<TrajectorySeed>& seeds, bool good) {
285  SeedContainer theCandidate;
286  theCandidate.clear();
287 
288  bool longSeed = false;
289  bool withFirstLayer = false;
290 
291  //std::cout<<"***** Seed Classification *****"<< seeds.size() <<std::endl;
292  for (size_t i = 0; i < seeds.size(); i++) {
293  if (seeds[i].nHits() > 1)
294  longSeed = true;
295  //std::cout<<" Seed: "<<i<<" w/"<<seeds[i].nHits()<<" segs "<<std::endl;
296  // looking for 1st layer segment
297  int idx = 0;
298  for (edm::OwnVector<TrackingRecHit>::const_iterator r1 = seeds[i].recHits().first; r1 != seeds[i].recHits().second;
299  r1++) {
300  idx++;
301  const GeomDet* gdet = theService->trackingGeometry()->idToDet((*r1).geographicalId());
302  DetId geoId = gdet->geographicalId();
303 
304  if (geoId.subdetId() == MuonSubdetId::DT) {
305  DTChamberId DT_Id((*r1).geographicalId());
306  //std::cout<<" ID:"<<DT_Id <<" pos:"<< r1->localPosition() <<std::endl;
307  if (DT_Id.station() != 1)
308  continue;
309  withFirstLayer = true;
310  }
311  if (geoId.subdetId() == MuonSubdetId::CSC) {
312  idx++;
313  CSCDetId CSC_Id = CSCDetId((*r1).geographicalId());
314  //std::cout<<" ID:"<<CSC_Id <<" pos:"<< r1->localPosition() <<std::endl;
315  if (CSC_Id.station() != 1)
316  continue;
317  withFirstLayer = true;
318  }
319  }
320  bool goodseed = (longSeed && withFirstLayer) ? true : false;
321 
322  if (goodseed == good)
323  theCandidate.push_back(seeds[i]);
324  }
325  return theCandidate;
326 }
327 
328 std::vector<SeedContainer> MuonSeedCleaner::GroupSeeds(std::vector<TrajectorySeed>& seeds) {
329  std::vector<SeedContainer> seedCollection;
330  seedCollection.clear();
331  std::vector<TrajectorySeed> theGroup;
332  std::vector<bool> usedSeed(seeds.size(), false);
333 
334  // categorize seeds by comparing overlapping segments or a certian eta-phi cone
335  for (size_t i = 0; i < seeds.size(); i++) {
336  if (usedSeed[i])
337  continue;
338  theGroup.push_back(seeds[i]);
339  usedSeed[i] = true;
340 
341  GlobalPoint pos1 = SeedPosition(seeds[i]);
342 
343  for (size_t j = i + 1; j < seeds.size(); j++) {
344  // 1.1 seeds with overlaaping segments will be grouped together
345  unsigned int overlapping = OverlapSegments(seeds[i], seeds[j]);
346  if (!usedSeed[j] && overlapping > 0) {
347  // reject the identical seeds
348  if (seeds[i].nHits() == overlapping && seeds[j].nHits() == overlapping) {
349  usedSeed[j] = true;
350  continue;
351  }
352  theGroup.push_back(seeds[j]);
353  usedSeed[j] = true;
354  }
355  if (usedSeed[j])
356  continue;
357 
358  // 1.2 seeds in a certain cone are grouped together
359  GlobalPoint pos2 = SeedPosition(seeds[j]);
360  double dh = pos1.eta() - pos2.eta();
361  double df = pos1.phi() - pos2.phi();
362  double dR = sqrt((dh * dh) + (df * df));
363 
364  if (dR > 0.3 && seeds[j].nHits() == 1)
365  continue;
366  if (dR > 0.2 && seeds[j].nHits() > 1)
367  continue;
368  theGroup.push_back(seeds[j]);
369  usedSeed[j] = true;
370  }
371  sort(theGroup.begin(), theGroup.end(), lengthSorting);
372  seedCollection.push_back(theGroup);
373  //std::cout<<" group "<<seedCollection.size() <<" w/"<< theGroup.size() <<" seeds"<<std::endl;
374  theGroup.clear();
375  }
376  return seedCollection;
377 }
378 
379 unsigned int MuonSeedCleaner::OverlapSegments(const TrajectorySeed& seed1, const TrajectorySeed& seed2) {
380  unsigned int overlapping = 0;
381  for (edm::OwnVector<TrackingRecHit>::const_iterator r1 = seed1.recHits().first; r1 != seed1.recHits().second; r1++) {
382  DetId id1 = (*r1).geographicalId();
383  const GeomDet* gdet1 = theService->trackingGeometry()->idToDet(id1);
384  GlobalPoint gp1 = gdet1->toGlobal((*r1).localPosition());
385 
386  for (edm::OwnVector<TrackingRecHit>::const_iterator r2 = seed2.recHits().first; r2 != seed2.recHits().second;
387  r2++) {
388  DetId id2 = (*r2).geographicalId();
389  if (id1 != id2)
390  continue;
391 
392  const GeomDet* gdet2 = theService->trackingGeometry()->idToDet(id2);
393  GlobalPoint gp2 = gdet2->toGlobal((*r2).localPosition());
394 
395  double dx = gp1.x() - gp2.x();
396  double dy = gp1.y() - gp2.y();
397  double dz = gp1.z() - gp2.z();
398  double dL = sqrt(dx * dx + dy * dy + dz * dz);
399 
400  if (dL < 1.)
401  overlapping++;
402  }
403  }
404  return overlapping;
405 }
406 
408  double theChi2 = 0.;
409  for (edm::OwnVector<TrackingRecHit>::const_iterator r1 = seed.recHits().first; r1 != seed.recHits().second; r1++) {
410  //std::cout<<" segmet : "<<it <<std::endl;
411  theChi2 += NChi2OfSegment(*r1);
412  }
413  theChi2 = theChi2 / seed.nHits();
414 
415  //std::cout<<" final Length :"<<NSegs<<std::endl;
416  return theChi2;
417 }
418 
420  int theHits = 0;
421  for (edm::OwnVector<TrackingRecHit>::const_iterator r1 = seed.recHits().first; r1 != seed.recHits().second; r1++) {
422  //std::cout<<" segmet : "<<it <<std::endl;
423  theHits += NRecHitsFromSegment(*r1);
424  }
425 
426  //std::cout<<" final Length :"<<NSegs<<std::endl;
427  return theHits;
428 }
429 
431  PTrajectoryStateOnDet pTSOD = seed.startingState();
432  DetId SeedDetId(pTSOD.detId());
433  const GeomDet* geoDet = theService->trackingGeometry()->idToDet(SeedDetId);
434  TrajectoryStateOnSurface SeedTSOS =
435  trajectoryStateTransform::transientState(pTSOD, &(geoDet->surface()), &*theService->magneticField());
436  GlobalPoint pos = SeedTSOS.globalPosition();
437 
438  return pos;
439 }
440 
442  PTrajectoryStateOnDet pTSOD = seed.startingState();
443  DetId SeedDetId(pTSOD.detId());
444  const GeomDet* geoDet = theService->trackingGeometry()->idToDet(SeedDetId);
445  TrajectoryStateOnSurface SeedTSOS =
446  trajectoryStateTransform::transientState(pTSOD, &(geoDet->surface()), &*theService->magneticField());
447  GlobalVector mom = SeedTSOS.globalMomentum();
448 
449  return mom;
450 }
451 
453  int NRechits = 0;
454  const GeomDet* gdet = theService->trackingGeometry()->idToDet(rhit.geographicalId());
457 
458  DetId geoId = gdet->geographicalId();
459  if (geoId.subdetId() == MuonSubdetId::DT) {
460  DTChamberId DT_Id(rhit.geographicalId());
461  std::vector<TrackingRecHit*> DThits = theSeg->recHits();
462  int dt1DHits = 0;
463  for (size_t j = 0; j < DThits.size(); j++) {
464  dt1DHits += (DThits[j]->recHits()).size();
465  }
466  NRechits = dt1DHits;
467  }
468 
469  if (geoId.subdetId() == MuonSubdetId::CSC) {
470  NRechits = (theSeg->recHits()).size();
471  }
472  return NRechits;
473 }
474 
476  int NRechits = 0;
477  DetId geoId = rhit->geographicalId();
478  if (geoId.subdetId() == MuonSubdetId::DT) {
479  DTChamberId DT_Id(geoId);
480  std::vector<TrackingRecHit*> DThits = rhit->recHits();
481  int dt1DHits = 0;
482  for (size_t j = 0; j < DThits.size(); j++) {
483  dt1DHits += (DThits[j]->recHits()).size();
484  }
485  NRechits = dt1DHits;
486  //std::cout<<" D_rh("<< dt1DHits <<") " ;
487  }
488  if (geoId.subdetId() == MuonSubdetId::CSC) {
489  NRechits = (rhit->recHits()).size();
490  //std::cout<<" C_rh("<<(rhit->recHits()).size() <<") " ;
491  }
492  return NRechits;
493 }
494 
496  double NChi2 = 999999.;
497  const GeomDet* gdet = theService->trackingGeometry()->idToDet(rhit.geographicalId());
500 
501  double dof = static_cast<double>(theSeg->degreesOfFreedom());
502  NChi2 = theSeg->chi2() / dof;
503  //std::cout<<" Chi2 = "<< NChi2 <<" |" ;
504 
505  return NChi2;
506 }
void update(const edm::EventSetup &setup)
update the services each event
size
Write out results.
T getParameter(std::string const &) const
TrajectorySeed BiggerCone(std::vector< TrajectorySeed > &seeds)
select the seed with bigger projection cone to next layer
static bool lengthSorting(const TrajectorySeed &s1, const TrajectorySeed &s2)
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
T y() const
Definition: PV3DBase.h:60
MuonServiceProxy * theService
GlobalPoint globalPosition() const
GlobalPoint SeedPosition(const TrajectorySeed &seed)
retrieve seed global position
~MuonSeedCleaner()
Destructor.
double SeedChi2(const TrajectorySeed &seed)
MuonSeedCleaner(const edm::ParameterSet &)
Constructor.
edm::ESHandle< MagneticField > magneticField() const
get the magnetic field
unsigned int OverlapSegments(const TrajectorySeed &seed1, const TrajectorySeed &seed2)
check overlapping segment for seeds
bool MomentumFilter(std::vector< TrajectorySeed > &seeds)
filter out the bad pt seeds, if all are bad pt seeds then keep all
double NChi2OfSegment(const TrackingRecHit &rhit)
retrieve number of rechits& normalized chi2 of associated segments of a seed
std::shared_ptr< MuonTransientTrackingRecHit > MuonRecHitPointer
T sqrt(T t)
Definition: SSEVec.h:19
T z() const
Definition: PV3DBase.h:61
virtual TrackingRecHit * clone() const =0
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:64
unsigned int detId() const
std::vector< const TrackingRecHit * > recHits() const override
Access to component RecHits (if any)
TrajectorySeed LeanHighMomentum(std::vector< TrajectorySeed > &seeds)
select the highest momentum pt seed
Definition: DetId.h:17
int NRecHitsFromSegment(const TrackingRecHit &rhit)
PTrajectoryStateOnDet const & startingState() const
TrajectoryStateOnSurface transientState(const PTrajectoryStateOnDet &ts, const Surface *surface, const MagneticField *field)
std::vector< SeedContainer > GroupSeeds(std::vector< TrajectorySeed > &seeds)
group the seeds
SeedContainer SeedCandidates(std::vector< TrajectorySeed > &seeds, bool good)
pick the seeds w/ 1st layer information and w/ more than 1 segments
range recHits() const
SeedContainer LengthFilter(std::vector< TrajectorySeed > &seeds)
edm::ESHandle< GlobalTrackingGeometry > trackingGeometry() const
get the tracking geometry
T eta() const
Definition: PV3DBase.h:73
unsigned int nHits() const
GlobalVector globalMomentum() const
const GeomDet * idToDet(DetId) const override
CLHEP::HepSymMatrix AlgebraicSymMatrix
GlobalVector SeedMomentum(const TrajectorySeed &seed)
retrieve seed global momentum
int station() const
Definition: CSCDetId.h:79
std::vector< TrajectorySeed > seedCleaner(const edm::EventSetup &eventSetup, std::vector< TrajectorySeed > &seeds)
Cache pointer to geometry.
TrajectorySeed MoreRecHits(std::vector< TrajectorySeed > &seeds)
select the seed with more rechits
DetId geographicalId() const
static constexpr int DT
Definition: MuonSubdetId.h:11
dh
Definition: cuy.py:355
std::vector< TrajectorySeed > SeedContainer
static constexpr int CSC
Definition: MuonSubdetId.h:12
T x() const
Definition: PV3DBase.h:59
static MuonRecHitPointer specificBuild(const GeomDet *geom, const TrackingRecHit *rh)
int SeedLength(const TrajectorySeed &seed)
TrajectorySeed Chi2LengthSelection(std::vector< TrajectorySeed > &seeds)
select seed by balance length and chi2