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