CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
QuadrupletSeedMerger.cc
Go to the documentation of this file.
6 
8 
10 
11 #include <algorithm>
12 
13 namespace {
14  template <typename T>
15  constexpr T sqr(T x) {
16  return x*x;
17  }
18 }
19 
20 /***
21 
22 QuadrupletSeedMerger
23 
24 * merge triplet into quadruplet seeds
25  for either SeedingHitSets or TrajectorySeeds
26 
27 * method:
28  QuadrupletSeedMerger::mergeTriplets( const OrderedSeedingHits&, const edm::EventSetup& ) const
29  for use in HLT with: RecoPixelVertexing/PixelTrackFitting/src/PixelTrackReconstruction.cc
30  contains the merging functionality
31 
32 * method:
33  QuadrupletSeedMerger::mergeTriplets( const TrajectorySeedCollection&, TrackingRegion&, EventSetup& ) const
34  is a wrapper for the former, running on TrajectorySeeds
35  for use in iterative tracking with: RecoTracker/TkSeedGenerator/plugins/SeedGeneratorFromRegionHitsEDProducer
36 
37 ***/
38 
39 
40 // Helper functions
41 namespace {
42  bool areHitsOnLayers(const SeedMergerPixelLayer& layer1, const SeedMergerPixelLayer& layer2,
43  const std::pair<SeedingHitSet::ConstRecHitPointer,SeedingHitSet::ConstRecHitPointer>& hits,
44  const TrackerTopology *tTopo) {
45  DetId firstHitId = hits.first->geographicalId();
46  DetId secondHitId = hits.second->geographicalId();
47  return ((layer1.isContainsDetector(firstHitId, tTopo) &&
48  layer2.isContainsDetector(secondHitId, tTopo)) ||
49  (layer1.isContainsDetector(secondHitId, tTopo) &&
50  layer2.isContainsDetector(firstHitId, tTopo)));
51  }
52 
53  bool areHitsEqual(const TrackingRecHit & hit1, const TrackingRecHit & hit2) {
54  constexpr double epsilon = 0.00001;
55  if(hit1.geographicalId() != hit2.geographicalId())
56  return false;
57 
58  LocalPoint lp1 = hit1.localPosition(), lp2 = hit2.localPosition();
59  return std::abs(lp1.x() - lp2.x()) < epsilon && std::abs(lp1.y() - lp2.y()) < epsilon;
60  }
61 }
62 
63 
64 
69  QuadrupletSeedMerger(iConfig, nullptr, iC) {}
71  QuadrupletSeedMerger(iConfig,
72  SeedCreatorFactory::get()->create(seedCreatorConfig.getParameter<std::string>("ComponentName") , seedCreatorConfig),
73  iC) {}
75  theLayerBuilder_(iConfig, iC),
76  theSeedCreator_(seedCreator)
77  {
78 
79  // by default, do not..
80  // ..merge triplets
81  isMergeTriplets_ = false;
82  // ..add remaining triplets
84 }
85 
87  // copy geometry
89 }
90 
95 
96 }
97 
98 
99 
108 
109 //const std::vector<SeedingHitSet> QuadrupletSeedMerger::mergeTriplets( const OrderedSeedingHits& inputTriplets, const edm::EventSetup& es ) {
111 
112  //Retrieve tracker topology from geometry
114  es.get<TrackerTopologyRcd>().get(tTopoHand);
115  const TrackerTopology *tTopo=tTopoHand.product();
116 
117  // the list of layers on which quadruplets should be formed
118  if(theLayerBuilder_.check(es)) {
119  theLayerSets_ = theLayerBuilder_.layers( es ); // this is a vector<vector<SeedingLayer> >
120  }
121 
122 
123  // make a working copy of the input triplets
124  // to be able to remove merged triplets
125 
126  std::vector<std::pair<double,double> > phiEtaCache;
127  std::vector<SeedingHitSet> tripletCache; //somethings strange about OrderedSeedingHits?
128 
129  const unsigned int nInputTriplets = inputTriplets.size();
130  phiEtaCache.reserve(nInputTriplets);
131  tripletCache.reserve(nInputTriplets);
132 
133  for( unsigned int it = 0; it < nInputTriplets; ++it ) {
134  tripletCache.push_back((inputTriplets[it]));
135  phiEtaCache.push_back(calculatePhiEta( (tripletCache[it]) ));
136 
137  }
138 
139  // the output
140  quads_.clear();
141 
142  // check if the input is all triplets
143  // (code is also used for pairs..)
144  // if not, copy the input to the output & return
145  bool isAllTriplets = true;
146  for( unsigned int it = 0; it < nInputTriplets; ++it ) {
147  if( tripletCache[it].size() != 3 ) {
148  isAllTriplets = false;
149  break;
150  }
151  }
152 
153  if( !isAllTriplets && isMergeTriplets_ )
154  std::cout << "[QuadrupletSeedMerger::mergeTriplets] (in HLT) ** bailing out since non-triplets in input." << std::endl;
155 
156  if( !isAllTriplets || !isMergeTriplets_ ) {
157  quads_.reserve(nInputTriplets);
158  for( unsigned int it = 0; it < nInputTriplets; ++it ) {
159  quads_.push_back( (tripletCache[it]));
160  }
161 
162  return quads_;
163  }
164 
165 
166  quads_.reserve(0.2*nInputTriplets); //rough guess
167 
168  // loop all possible 4-layer combinations
169  // as specified in python/quadrupletseedmerging_cff.py
170 
171  std::vector<bool> usedTriplets(nInputTriplets,false);
172  std::pair<SeedingHitSet::ConstRecHitPointer,SeedingHitSet::ConstRecHitPointer> sharedHits;
173  std::pair<SeedingHitSet::ConstRecHitPointer,SeedingHitSet::ConstRecHitPointer> nonSharedHits;
174 
175  // k-d tree, indices are (th)eta, phi
176  // build the tree
177  std::vector<KDTreeNodeInfo<unsigned int> > nodes;
178  std::vector<unsigned int> foundNodes;
179  nodes.reserve(2*nInputTriplets);
180  foundNodes.reserve(100);
182  double minEta=1e10, maxEta=-1e10;
183  for(unsigned int it=0; it < nInputTriplets; ++it) {
184  double phi = phiEtaCache[it].first;
185  double eta = phiEtaCache[it].second;
186  nodes.push_back(KDTreeNodeInfo<unsigned int>(it, eta, phi));
187  minEta = std::min(minEta, eta);
188  maxEta = std::max(maxEta, eta);
189 
190  // to wrap all points in phi
191  // if(phi < 0) phi += twoPi(); else phi -= twoPi();
192  double twoPi = std::copysign(Geom::twoPi(), phi);
193  nodes.push_back(KDTreeNodeInfo<unsigned int>(it, eta, phi-twoPi));
194  }
195  KDTreeBox kdEtaPhi(minEta-0.01, maxEta+0.01, -1*Geom::twoPi(), Geom::twoPi());
196  kdtree.build(nodes, kdEtaPhi);
197  nodes.clear();
198 
199  // loop over triplets, search for close-by triplets by using the k-d tree
200  // also identify the hits which are shared by triplet pairs, and
201  // store indices to hits which are not shared
202  std::vector<unsigned int> t1List;
203  std::vector<unsigned int> t2List;
204  std::vector<short> t1NonSharedHitList;
205  std::vector<short> t2NonSharedHitList;
206  constexpr short sharedToNonShared[7] = {-1, -1, -1,
207  2, // 011=3 shared, not shared = 2
208  -1,
209  1, // 101=5 shared, not shared = 1
210  0}; // 110=6 shared, not shared = 0
211  constexpr short nonSharedToShared[3][2] = {
212  {1, 2},
213  {0, 2},
214  {0, 1}
215  };
216 
217  typedef std::tuple<unsigned int, short, short> T2NonSharedTuple;
218  std::vector<T2NonSharedTuple> t2Tmp; // temporary to sort t2's before insertion to t2List
219  for(unsigned int t1=0; t1<nInputTriplets; ++t1) {
220  double phi = phiEtaCache[t1].first;
221  double eta = phiEtaCache[t1].second;
222 
223  KDTreeBox box(eta-0.05, eta+0.05, phi-0.15, phi+0.15);
224  foundNodes.clear();
225  kdtree.search(box, foundNodes);
226  if(foundNodes.empty())
227  continue;
228 
229  const SeedingHitSet& tr1 = tripletCache[t1];
230 
231  for(unsigned int t2: foundNodes) {
232  if(t1 >= t2)
233  continue;
234 
235  // Ensure here that the triplet pairs share two hits.
236  const SeedingHitSet& tr2 = tripletCache[t2];
237 
238  // If neither of first two hits in tr1 are found from tr2, this
239  // pair can be skipped
240  int equalHits=0;
241  // Find the indices of shared hits in both t1 and t2, use them
242  // to obtain the index of non-shared hit for both. The index of
243  // non-shared hit is then stored for later use (the indices of
244  // shared hits can be easily obtained from them).
245  unsigned int t1Shared = 0;
246  unsigned int t2Shared = 0;
247  for(unsigned int i=0; i<2; ++i) {
248  for(unsigned int j=0; j<3; ++j) {
249  if(areHitsEqual(*tr1[i], *tr2[j])) {
250  t1Shared |= (1<<i);
251  t2Shared |= (1<<j);
252  ++equalHits;
253  break;
254  }
255  }
256  }
257  if(equalHits == 0)
258  continue;
259  // If, after including the third hit of tr1, number of equal
260  // hits is not 2, this pair can be skipped
261  if(equalHits != 2) {
262  for(unsigned int j=0; j<3; ++j) {
263  if(areHitsEqual(*tr1[2], *tr2[j])) {
264  t1Shared |= (1<<2);
265  t2Shared |= (1<<j);
266  ++equalHits;
267  break;
268  }
269  }
270  if(equalHits != 2)
271  continue;
272  }
273  // valid values for the bitfields are 011=3, 101=5, 110=6
274  assert(t1Shared <= 6 && t2Shared <= 6); // against out-of-bounds of sharedToNonShared[]
275  short t1NonShared = sharedToNonShared[t1Shared];
276  short t2NonShared = sharedToNonShared[t2Shared];
277  assert(t1NonShared >= 0 && t2NonShared >= 0); // against invalid value from sharedToNonShared[]
278 
279  t2Tmp.emplace_back(t2, t1NonShared, t2NonShared);
280  }
281 
282  // Sort to increasing order in t2 in order to get exactly same result as before
283  std::sort(t2Tmp.begin(), t2Tmp.end(), [](const T2NonSharedTuple& a, const T2NonSharedTuple& b){
284  return std::get<0>(a) < std::get<0>(b);
285  });
286  for(T2NonSharedTuple& t2tpl: t2Tmp) {
287  t1List.push_back(t1);
288  t2List.push_back(std::get<0>(t2tpl));
289  t1NonSharedHitList.push_back(std::get<1>(t2tpl));
290  t2NonSharedHitList.push_back(std::get<2>(t2tpl));
291  }
292  t2Tmp.clear();
293  }
294  nodes.clear();
295 
296  for( ctfseeding::SeedingLayerSets::const_iterator lsIt = theLayerSets_.begin(); lsIt < theLayerSets_.end(); ++lsIt ) {
297 
298  // fill a vector with the layers in this set
299  std::vector<SeedMergerPixelLayer> currentLayers;
300  currentLayers.reserve(lsIt->size());
301  for( ctfseeding::SeedingLayers::const_iterator layIt = lsIt->begin(); layIt < lsIt->end(); ++layIt ) {
302  currentLayers.push_back( SeedMergerPixelLayer( layIt->name() ) );
303  }
304  // loop all pair combinations of these 4 layers;
305  // strategy is to look for shared hits on such a pair and
306  // then merge the remaining hits in both triplets if feasible
307  // (SeedingLayers is a vector<SeedingLayer>)
308 
309  for( unsigned int s1=0; s1<currentLayers.size()-1; s1++) {
310 
311  for( unsigned int s2=s1+1; s2<currentLayers.size(); s2++) {
312 
313  std::vector<unsigned int> nonSharedLayerNums;
314  for ( unsigned int us1=0; us1<currentLayers.size(); us1++) {
315  if ( s1!=us1 && s2!=us1) nonSharedLayerNums.push_back(us1);
316  }
317 
318  // loop all possible triplet pairs (which come as input)
319  for (unsigned int t12=0; t12<t1List.size(); t12++) {
320  unsigned int t1=t1List[t12];
321  unsigned int t2=t2List[t12];
322 
323  if (usedTriplets[t1] || usedTriplets[t2] ) continue;
324 
325  const SeedingHitSet& firstTriplet = tripletCache[t1];
326 
327  short t1NonShared = t1NonSharedHitList[t12];
328  sharedHits.first = firstTriplet[nonSharedToShared[t1NonShared][0]];
329  sharedHits.second = firstTriplet[nonSharedToShared[t1NonShared][1]];
330 
331  // are the shared hits on these two layers?
332  if(areHitsOnLayers(currentLayers[s1], currentLayers[s2], sharedHits, tTopo)) {
333  short t2NonShared = t2NonSharedHitList[t12];
334  const SeedingHitSet& secondTriplet = tripletCache[t2];
335  nonSharedHits.first = firstTriplet[t1NonShared];
336  nonSharedHits.second = secondTriplet[t2NonShared];
337 
338  // are the remaining hits on different layers?
339  if(areHitsOnLayers(currentLayers[nonSharedLayerNums[0]], currentLayers[nonSharedLayerNums[1]], nonSharedHits, tTopo)) {
340  QuadrupletHits unsortedHits{ {sharedHits.first, sharedHits.second,
341  nonSharedHits.first, nonSharedHits.second} };
342 
343  mySort(unsortedHits);
344 
345  //start here with old addtoresult
346  if( isValidQuadruplet( unsortedHits, currentLayers, tTopo ) ) {
347  // and create the quadruplet
348  SeedingHitSet quadruplet(unsortedHits[0],unsortedHits[1],unsortedHits[2],unsortedHits[3]);
349 
350  // insert this quadruplet
351  quads_.push_back( quadruplet );
352  // remove both triplets from the list,
353  // needs this 4-permutation since we're in a double loop
354  usedTriplets[t1]=true;
355  usedTriplets[t2]=true;
356  }
357 
358  } // isMergeableHitsInTriplets
359  } // isTripletsShareHitsOnLayers
360  // } // triplet double loop
361  }
362  } // seeding layers double loop
363  }
364 
365  } // seeding layer sets
366 
367  // add the remaining triplets
369  for( unsigned int it = 0; it < nInputTriplets; ++it ) {
370  if ( !usedTriplets[it] )
371  quads_.push_back( tripletCache[it]);
372  }
373  }
374 
375  //calc for printout...
376 // unsigned int nLeft=0;
377 // for ( unsigned int i=0; i<nInputTriplets; i++)
378 // if ( !usedTriplets[i] ) nLeft++;
379  // some stats
380 // std::cout << " [QuadrupletSeedMerger::mergeTriplets] -- Created: " << theResult.size()
381 // << " quadruplets from: " << nInputTriplets << " input triplets (" << nLeft
382 // << " remaining ";
383 // std::cout << (isAddRemainingTriplets_?"added":"dropped");
384 // std::cout << ")." << std::endl;
385 
386  return quads_;
387 
388 }
389 
390 
391 
403  const TrackingRegion& region,
404  const edm::EventSetup& es) {
405 
406  // ttrh builder for HitSet -> TrajectorySeed conversion;
407  // require this to be correctly configured, otherwise -> exception
409 
410  // output collection
411  TrajectorySeedCollection theResult;
412 
413  // loop to see if we have triplets ONLY
414  // if not, copy input -> output and return
415  bool isAllTriplets = true;
416  for( TrajectorySeedCollection::const_iterator aTrajectorySeed = seedCollection.begin();
417  aTrajectorySeed < seedCollection.end(); ++aTrajectorySeed ) {
418  if( 3 != aTrajectorySeed->nHits() ) isAllTriplets = false;
419  }
420 
421  if( !isAllTriplets && isMergeTriplets_ )
422  std::cout << " [QuadrupletSeedMerger::mergeTriplets] (in RECO) -- bailing out since non-triplets in input." << std::endl;
423 
424  if( !isAllTriplets || !isMergeTriplets_ ) {
425  for( TrajectorySeedCollection::const_iterator aTrajectorySeed = seedCollection.begin();
426  aTrajectorySeed < seedCollection.end(); ++aTrajectorySeed ) {
427  theResult.push_back( *aTrajectorySeed );
428  }
429 
430  return theResult;
431  }
432 
433 
434  // all this fiddling here is now about converting
435  // TrajectorySeedCollection <-> OrderedSeedingHits
436 
437  // create OrderedSeedingHits first;
438  OrderedHitTriplets inputTriplets;
439 
440  // loop seeds
441  for( TrajectorySeedCollection::const_iterator aTrajectorySeed = seedCollection.begin();
442  aTrajectorySeed < seedCollection.end(); ++aTrajectorySeed ) {
443 
444  std::vector<SeedingHitSet::ConstRecHitPointer> recHitPointers;
445 
446  // loop RecHits
447  const TrajectorySeed::range theHitsRange = aTrajectorySeed->recHits();
448  for( edm::OwnVector<TrackingRecHit>::const_iterator aHit = theHitsRange.first;
449  aHit < theHitsRange.second; ++aHit ) {
450 
451  // this is a collection of: ReferenceCountingPointer< SeedingHitSet>
452  recHitPointers.push_back( (SeedingHitSet::ConstRecHitPointer)(&*aHit ) );
453 
454  }
455 
456  // add to input collection
457  inputTriplets.push_back( OrderedHitTriplet( recHitPointers.at( 0 ), recHitPointers.at( 1 ), recHitPointers.at( 2 ) ) );
458 
459  }
460 
461  // do the real merging..
462  const OrderedSeedingHits &quadrupletHitSets = mergeTriplets( inputTriplets, es );
463 
464  // convert back to TrajectorySeedCollection
465 
466  // the idea here is to fetch the same SeedCreator and PSet
467  // as those used by the plugin which is calling the merger
468  // (at the moment that's SeedGeneratorFromRegionHitsEDProducer)
469  theSeedCreator_->init(region, es, 0);
470  for ( unsigned int i=0; i< quadrupletHitSets.size(); i++) {
471  // add trajectory seed to result collection
472  theSeedCreator_->makeSeed( theResult, quadrupletHitSets[i]);
473  }
474 
475  return theResult;
476 
477 }
478 
479 
483 std::pair<double,double> QuadrupletSeedMerger::calculatePhiEta( SeedingHitSet const& nTuplet ) const {
484 
485 // if( nTuplet.size() < 3 ) {
486 // std::cerr << " [QuadrupletSeedMerger::calculatePhiEta] ** ERROR: nTuplet has less than 3 hits" << std::endl;
487 // throw; // tbr.
488 // }
489 
490  GlobalPoint p1 = nTuplet[0]->globalPosition();
491  GlobalPoint p2 = nTuplet[1]->globalPosition();
492 
493  const double x1 = p1.x();
494  const double x2 = p2.x();
495  const double y1 = p1.y();
496  const double y2 = p2.y();
497  const double z1 = p1.z();
498  const double z2 = p2.z();
499 
500  const double phi = atan2( x2 - x1, y2 -y1 );
501  const double eta = acos( (z2 - z1) / sqrt( sqr( x2 - x1 ) + sqr( y2 - y1 ) + sqr( z2 - z1 ) ) ); // this is theta angle in reality
502 
503  std::pair<double,double> retVal;
504  retVal=std::make_pair (phi,eta);
505  return retVal;
506  //return std::make_pair<double,double>( phi, eta );
507 
508 }
509 
510 
511 
512 
517 
518  const GeomDet* geomDet = theTrackerGeometry_->idToDet( aHit->geographicalId() );
519  const double r = geomDet->surface().position().perp();
520  const double x = geomDet->toGlobal( aHit->localPosition() ).x();
521  const double y = geomDet->toGlobal( aHit->localPosition() ).y();
522  const double z = geomDet->toGlobal( aHit->localPosition() ).z();
523  std::cout << "<RecHit> x: " << x << " y: " << y << " z: " << z << " r: " << r << std::endl;
524 
525 }
526 
530 void QuadrupletSeedMerger::printNtuplet( const SeedingHitSet& aNtuplet ) const {
531 
532  std::cout << "DUMPING NTUPLET OF SIZE:";
533  std::cout << aNtuplet.size() << std::endl;
534 
535  for( unsigned int aHit = 0; aHit < aNtuplet.size(); ++aHit ) {
536 
537  const TrackingRecHit* theHit = aNtuplet[aHit]->hit();
538  const GeomDet* geomDet = theTrackerGeometry_->idToDet( theHit->geographicalId() );
539  const double x = geomDet->toGlobal( theHit->localPosition() ).x();
540  const double y = geomDet->toGlobal( theHit->localPosition() ).y();
541  const double z = geomDet->toGlobal( theHit->localPosition() ).z();
542  const double r = sqrt( x*x + y*y );
543 
544  unsigned int layer;
545  std::string detName;
547  detName = "BPIX ";
548  PixelBarrelName pbn( aNtuplet[aHit]->hit()->geographicalId());
549  layer = pbn.layerName();
550  }
551  else {
552  detName = "FPIX";
553  if( z > 0 ) detName += "+";
554  else detName += "-";
555 
556  PixelEndcapName pen( theHit->geographicalId() );
557  layer = pen.diskName();
558  }
559 
560  std::cout << "<NtupletHit> D: " << detName << " L: " << layer << " x: " << x << " y: " << y << " z: " << z << " r: " << r << std::endl;
561 
562 }
563 
564  std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
565 
566 }
567 
568 
569 
574 
576 
577 }
578 
579 
580 
584 void QuadrupletSeedMerger::setMergeTriplets( bool isMergeTriplets ) {
585  isMergeTriplets_ = isMergeTriplets;
586 }
587 
588 
589 
594  isAddRemainingTriplets_ = isAddTriplets;
595 }
596 
597 
598 
604 bool QuadrupletSeedMerger::isValidQuadruplet(const QuadrupletHits &quadruplet, const std::vector<SeedMergerPixelLayer>& layers, const TrackerTopology *tTopo) const {
605 
606  const unsigned int quadrupletSize = quadruplet.size();
607 
608  // basic size test..
609  if( quadrupletSize != layers.size() ) {
610  std::cout << " [QuadrupletSeedMerger::isValidQuadruplet] ** WARNING: size mismatch: "
611  << quadrupletSize << "/" << layers.size() << std::endl;
612  return false;
613  }
614 
615  // go along layers and check if all (parallel) quadruplet hits match
616  for( unsigned int index = 0; index < quadrupletSize; ++index ) {
617  if( ! layers[index].isContainsDetector( quadruplet[index]->geographicalId(), tTopo ) ) {
618  return false;
619  }
620  }
621 
622  return true;
623 
624 }
625 
626 
631 
632  if( ! isValidName( name ) ) {
633  std::cerr << " [SeedMergerPixelLayer::SeedMergerPixelLayer] ** ERROR: illegal name: \"" << name << "\"." << std::endl;
634  isValid_ = false;
635  return;
636  }
637 
638  // bare name, can be done here
639  name_ = name;
640 
641  // (output format -> see DataFormats/SiPixelDetId/interface/PixelSubdetector.h)
642  if( std::string::npos != name_.find( "BPix" ) )
644  else if( std::string::npos != name_.find( "FPix" ) )
646  if( std::string::npos != name_.find( "pos", 6 ) ) side_ = Plus;
647  else if( std::string::npos != name_.find( "neg", 6 ) ) side_ = Minus;
648  else {
649  std::cerr << " [PixelLayerNameParser::side] ** ERROR: something's wrong here.." << std::endl;
650  side_ = SideError;
651  }
652  }
653  else {
654  std::cerr << " [PixelLayerNameParser::subdetector] ** ERROR: something's wrong here.." << std::endl;
655  }
656 
657  // layer
658  layer_ = atoi( name_.substr( 4, 1 ).c_str() );
659 
660 }
661 
662 
663 
668 
669  const int layer = atoi( name.substr( 4, 1 ).c_str() );
670 
671  if( std::string::npos != name.find( "BPix" ) ) {
672  if( layer > 0 && layer < 5 ) return true;
673  }
674 
675  else if( std::string::npos != name.find( "FPix" ) ) {
676  if( layer > 0 && layer < 10 ) {
677  if( std::string::npos != name.find( "pos", 6 ) || std::string::npos != name.find( "neg", 6 ) ) return true;
678  }
679 
680  }
681 
682  std::cerr << " [SeedMergerPixelLayer::isValidName] ** WARNING: invalid name: \"" << name << "\"." << std::endl;
683  return false;
684 
685 }
686 
687 
688 
693 bool SeedMergerPixelLayer::isContainsDetector( const DetId& detId, const TrackerTopology *tTopo ) const {
694 
696 
697  // same subdet?
698  if( detId.subdetId() == subdet ) {
699 
700  // same barrel layer?
701  if( PixelSubdetector::PixelBarrel == subdet ) {
702  if (tTopo->pxbLayer(detId) == getLayerNumber()) {
703  return true;
704  }
705  }
706 
707  // same endcap disk?
708  else if( PixelSubdetector::PixelEndcap == subdet ) {
709 
710  if (tTopo->pxfDisk(detId) == getLayerNumber()) {
711  if (tTopo->pxfSide(detId) == (unsigned)getSide()) {
712  return true;
713  }
714  }
715  }
716 
717  }
718 
719  return false;
720 
721 }
722 
723 
724 void QuadrupletSeedMerger::mySort(std::array<SeedingHitSet::ConstRecHitPointer, 4>& unsortedHits) {
725  float radiiSq[4];
726  for ( unsigned int iR=0; iR<4; iR++){
727  GlobalPoint p1 = unsortedHits[iR]->globalPosition();
728  radiiSq[iR]=( p1.x()*p1.x()+p1.y()*p1.y()); // no need to take the sqrt
729  }
731  float tempFloat=0.;
732  for ( unsigned int iR1=0; iR1<3; iR1++) {
733  for ( unsigned int iR2=iR1+1; iR2<4; iR2++) {
734  if (radiiSq[iR1]>radiiSq[iR2]) {
735  tempRHP=unsortedHits[iR1];
736  unsortedHits[iR1]=unsortedHits[iR2];
737  unsortedHits[iR2]=tempRHP;
738  tempFloat=radiiSq[iR1];
739  radiiSq[iR1]=radiiSq[iR2];
740  radiiSq[iR2]=tempFloat;
741  }
742  }
743  }
744 }
745 
746 
747 
edm::ESHandle< TrackerGeometry > theTrackerGeometry_
int i
Definition: DBlmapReader.cc:9
ctfseeding::SeedingLayerSets layers(const edm::EventSetup &es)
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Definition: LayerTriplets.cc:4
T perp() const
Definition: PV3DBase.h:72
void setTTRHBuilderLabel(std::string)
void printNtuplet(const SeedingHitSet &) const
SeedMergerPixelLayer(const std::string &)
void build(std::vector< KDTreeNodeInfoT< DATA, DIM > > &eltList, const KDTreeBoxT< DIM > &region)
unsigned int pxfDisk(const DetId &id) const
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
QuadrupletSeedMerger(const edm::ParameterSet &iConfig, edm::ConsumesCollector &&iC)
unsigned getLayerNumber(void) const
assert(m_qm.get())
T y() const
Definition: PV3DBase.h:63
double maxEta
virtual unsigned int size() const =0
bool check(const edm::EventSetup &es)
void search(const KDTreeBoxT< DIM > &searchBox, std::vector< KDTreeNodeInfoT< DATA, DIM > > &resRecHitList)
#define nullptr
ctfseeding::SeedingLayerSets theLayerSets_
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:42
std::pair< double, double > calculatePhiEta(SeedingHitSet const &) const
#define constexpr
PixelSubdetector::SubDetector subdet_
void mySort(QuadrupletHits &unsortedHits)
int sharedHits(const reco::GsfTrackRef &, const reco::GsfTrackRef &)
tuple s2
Definition: indexGen.py:106
T x() const
Cartesian x coordinate.
BaseTrackerRecHit const * ConstRecHitPointer
Definition: SeedingHitSet.h:11
std::vector< TrajectorySeed > TrajectorySeedCollection
auto const T2 &decltype(t1.eta()) t2
Definition: deltaR.h:16
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
PixelSubdetector::SubDetector getSubdet(void) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int j
Definition: DBlmapReader.cc:9
std::pair< const_iterator, const_iterator > range
std::array< SeedingHitSet::ConstRecHitPointer, 4 > QuadrupletHits
T min(T a, T b)
Definition: MathUtil.h:58
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
double p2[4]
Definition: TauolaWrapper.h:90
unsigned int pxbLayer(const DetId &id) const
Definition: DetId.h:18
void update(const edm::EventSetup &)
const T & get() const
Definition: EventSetup.h:56
const OrderedSeedingHits & mergeTriplets(const OrderedSeedingHits &, const edm::EventSetup &)
int layerName() const
layer id
T const * product() const
Definition: ESHandle.h:86
bool isContainsDetector(const DetId &, const TrackerTopology *tTopo) const
double b
Definition: hdecay.h:120
edm::ESHandle< TransientTrackingRecHitBuilder > theTTRHBuilder_
Side getSide(void) const
double p1[4]
Definition: TauolaWrapper.h:89
double a
Definition: hdecay.h:121
Square< F >::type sqr(const F &f)
Definition: Square.h:13
unsigned int size() const
Definition: SeedingHitSet.h:46
void printHit(const TrackingRecHit *) const
bool isValidQuadruplet(const QuadrupletHits &quadruplet, const std::vector< SeedMergerPixelLayer > &layers, const TrackerTopology *tTopo) const
unsigned int pxfSide(const DetId &id) const
std::unique_ptr< SeedCreator > theSeedCreator_
tuple cout
Definition: gather_cfg.py:145
SeedingLayerSetsBuilder theLayerBuilder_
int diskName() const
disk id
SeedMergerPixelLayer::Side side_
DetId geographicalId() const
long double T
constexpr double twoPi()
Definition: Pi.h:32
T x() const
Definition: PV3DBase.h:62
virtual LocalPoint localPosition() const =0
const PositionType & position() const
tuple size
Write out results.
T get(const Candidate &c)
Definition: component.h:55
bool isValidName(const std::string &)