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