CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/RecoPixelVertexing/PixelTriplets/src/QuadrupletSeedMerger.cc

Go to the documentation of this file.
00001 
00002 #include "RecoPixelVertexing/PixelTriplets/interface/QuadrupletSeedMerger.h"
00003 #include <time.h>
00004 
00005 /***
00006 
00007 QuadrupletSeedMerger
00008 
00009 * merge triplet into quadruplet seeds
00010   for either SeedingHitSets or TrajectorySeeds
00011 
00012 * method: 
00013     QuadrupletSeedMerger::mergeTriplets( const OrderedSeedingHits&, const edm::EventSetup& ) const
00014   for use in HLT with: RecoPixelVertexing/PixelTrackFitting/src/PixelTrackReconstruction.cc
00015   contains the merging functionality
00016 
00017 * method:
00018     QuadrupletSeedMerger::mergeTriplets( const TrajectorySeedCollection&, TrackingRegion&, EventSetup& ) const
00019   is a wrapper for the former, running on TrajectorySeeds
00020   for use in iterative tracking with: RecoTracker/TkSeedGenerator/plugins/SeedGeneratorFromRegionHitsEDProducer
00021 
00022 ***/
00023 
00024 
00025 
00026 
00030 QuadrupletSeedMerger::QuadrupletSeedMerger( ) {
00031 
00032   // by default, do not..
00033   // ..merge triplets
00034   isMergeTriplets_ = false;
00035   // ..add remaining triplets
00036   isAddRemainingTriplets_ = false;
00037 
00038   // default is the layer list from plain quadrupletseedmerging_cff
00039   // unless configured contrarily via setLayerListName()
00040   layerListName_ = std::string( "PixelSeedMergerQuadruplets" );
00041 }
00042 
00043 void QuadrupletSeedMerger::update(const edm::EventSetup& es) {
00044   // copy geometry
00045   es.get<TrackerDigiGeometryRecord>().get( theTrackerGeometry_ );
00046 }
00047 
00051 QuadrupletSeedMerger::~QuadrupletSeedMerger() {
00052 
00053 }
00054 
00055 
00056 
00065 
00066 //const std::vector<SeedingHitSet> QuadrupletSeedMerger::mergeTriplets( const OrderedSeedingHits& inputTriplets, const edm::EventSetup& es ) {
00067 const OrderedSeedingHits& QuadrupletSeedMerger::mergeTriplets( const OrderedSeedingHits& inputTriplets, const edm::EventSetup& es ) {
00068   
00069   // the list of layers on which quadruplets should be formed
00070   edm::ESHandle<SeedingLayerSetsBuilder> layerBuilder;
00071   es.get<TrackerDigiGeometryRecord>().get( layerListName_.c_str(), layerBuilder );
00072   theLayerSets_ = layerBuilder->layers( es ); // this is a vector<vector<SeedingLayer> >
00073 
00074   
00075   // make a working copy of the input triplets
00076   // to be able to remove merged triplets
00077 
00078   std::vector<std::pair<double,double> > phiEtaCache;
00079   std::vector<SeedingHitSet> tripletCache; //somethings strange about OrderedSeedingHits?
00080 
00081   const unsigned int nInputTriplets = inputTriplets.size();
00082   phiEtaCache.reserve(nInputTriplets);
00083   tripletCache.reserve(nInputTriplets);
00084 
00085   for( unsigned int it = 0; it < nInputTriplets; ++it ) {
00086     tripletCache.push_back((inputTriplets[it]));
00087     phiEtaCache.push_back(calculatePhiEta( (tripletCache[it]) ));
00088 
00089   }
00090 
00091   // the output
00092   quads_.clear();
00093 
00094   // check if the input is all triplets
00095   // (code is also used for pairs..)
00096   // if not, copy the input to the output & return
00097   bool isAllTriplets = true;
00098   for( unsigned int it = 0; it < nInputTriplets; ++it ) {
00099     if( tripletCache[it].size() != 3 ) {
00100       isAllTriplets = false;
00101       break;
00102     }
00103   }
00104 
00105   if( !isAllTriplets && isMergeTriplets_ )
00106     std::cout << "[QuadrupletSeedMerger::mergeTriplets] (in HLT) ** bailing out since non-triplets in input." << std::endl;
00107 
00108   if( !isAllTriplets || !isMergeTriplets_ ) {
00109     quads_.reserve(nInputTriplets);
00110     for( unsigned int it = 0; it < nInputTriplets; ++it ) {
00111       quads_.push_back( (tripletCache[it]));
00112     }
00113 
00114     return quads_;
00115   }
00116 
00117 
00118   quads_.reserve(0.2*nInputTriplets); //rough guess
00119 
00120   // loop all possible 4-layer combinations
00121   // as specified in python/quadrupletseedmerging_cff.py
00122 
00123   std::vector<bool> usedTriplets(nInputTriplets,false);
00124   std::pair<TransientTrackingRecHit::ConstRecHitPointer,TransientTrackingRecHit::ConstRecHitPointer> sharedHits;
00125   std::pair<TransientTrackingRecHit::ConstRecHitPointer,TransientTrackingRecHit::ConstRecHitPointer> nonSharedHits;
00126 
00127   //std::vector<bool> phiEtaClose(nInputTriplets*nInputTriplets,true);
00128 
00129   //  for (unsigned int t1=0; t1<nInputTriplets-1; t1++) {
00130   //  for (unsigned int t2=t1+1; t2<nInputTriplets; t2++) {
00131   //    if( fabs( phiEtaCache[t1].second - phiEtaCache[t2].second ) > 0.05 ) {
00132   //    phiEtaClose[t1*nInputTriplets+t2]=false;
00133   //    phiEtaClose[t2*nInputTriplets+t1]=false;
00134   //    continue;
00135   //   }
00136   //   double temp = fabs( phiEtaCache[t1].first - phiEtaCache[t2].first );
00137   //   if( (temp > 0.15) && (temp <6.133185) ) {
00138   //phiEtaClose[t1*nInputTriplets+t2]=false;
00139   //phiEtaClose[t2*nInputTriplets+t1]=false;
00140   //  }
00141   //}
00142   //}
00143  
00144   std::vector<unsigned int> t1List;
00145   std::vector<unsigned int> t2List;
00146   for (unsigned int t1=0; t1<nInputTriplets-1; t1++) {
00147     for (unsigned int t2=t1+1; t2<nInputTriplets; t2++) {
00148       if( fabs( phiEtaCache[t1].second - phiEtaCache[t2].second ) > 0.05 ) 
00149         continue;
00150       double temp = fabs( phiEtaCache[t1].first - phiEtaCache[t2].first );
00151       if( (temp > 0.15) && (temp <6.133185) ) {
00152         continue;
00153       }
00154       t1List.push_back(t1);
00155       t2List.push_back(t2);
00156     }
00157   }
00158 
00159   for( ctfseeding::SeedingLayerSets::const_iterator lsIt = theLayerSets_.begin(); lsIt < theLayerSets_.end(); ++lsIt ) {
00160 
00161     // fill a vector with the layers in this set
00162     std::vector<SeedMergerPixelLayer> currentLayers;
00163     currentLayers.reserve(lsIt->size());
00164     for( ctfseeding::SeedingLayers::const_iterator layIt = lsIt->begin(); layIt < lsIt->end(); ++layIt ) {
00165       currentLayers.push_back( SeedMergerPixelLayer( layIt->name() ) );
00166     }
00167     // loop all pair combinations of these 4 layers;
00168     // strategy is to look for shared hits on such a pair and
00169     // then merge the remaining hits in both triplets if feasible
00170     // (SeedingLayers is a vector<SeedingLayer>)
00171 
00172     for( unsigned int s1=0; s1<currentLayers.size()-1; s1++) {
00173 
00174       for( unsigned int s2=s1+1; s2<currentLayers.size(); s2++) {
00175 
00176         std::vector<unsigned int> nonSharedLayerNums;
00177         for ( unsigned int us1=0; us1<currentLayers.size(); us1++) {
00178           if ( s1!=us1 && s2!=us1) nonSharedLayerNums.push_back(us1);
00179         }
00180 
00181         // loop all possible triplet pairs (which come as input)
00182         for (unsigned int t12=0; t12<t1List.size(); t12++) {
00183           unsigned int t1=t1List[t12];
00184           unsigned int t2=t2List[t12];
00185 
00186             if (usedTriplets[t1] || usedTriplets[t2] ) continue; 
00187 
00188             //    if ( !phiEtaClose[t1*nInputTriplets+t2] ) continue;
00189 
00190             // do both triplets have shared hits on these two layers?
00191             if( isTripletsShareHitsOnLayers( (tripletCache[t1]), (tripletCache[t2]), 
00192                                              currentLayers[s1],
00193                                              currentLayers[s2], sharedHits ) ) {
00194 
00195               // are the remaining hits on different layers?
00196               if( isMergeableHitsInTriplets( (tripletCache[t1]), (tripletCache[t2]), 
00197                                              currentLayers[nonSharedLayerNums[0]],
00198                                              currentLayers[nonSharedLayerNums[1]], nonSharedHits ) ) {
00199 
00200 
00201                 std::vector<TransientTrackingRecHit::ConstRecHitPointer> unsortedHits=mySort(sharedHits.first,
00202                                                                                              sharedHits.second,
00203                                                                                              nonSharedHits.first,
00204                                                                                              nonSharedHits.second);
00205 
00206                 //start here with old addtoresult
00207                 if( isValidQuadruplet( unsortedHits, currentLayers ) ) {
00208                   // and create the quadruplet
00209                   SeedingHitSet quadruplet(unsortedHits[0],unsortedHits[1],unsortedHits[2],unsortedHits[3]);
00210                   
00211                   // insert this quadruplet
00212                   quads_.push_back( quadruplet );
00213                   // remove both triplets from the list,
00214                   // needs this 4-permutation since we're in a double loop
00215                   usedTriplets[t1]=true;
00216                   usedTriplets[t2]=true;
00217                 }
00218                 
00219               } // isMergeableHitsInTriplets
00220             } // isTripletsShareHitsOnLayers
00221             // } // triplet double loop
00222         }
00223       } // seeding layers double loop
00224     }
00225   
00226   } // seeding layer sets
00227   
00228   // add the remaining triplets
00229   if( isAddRemainingTriplets_ ) {
00230     for( unsigned int it = 0; it < nInputTriplets; ++it ) {
00231       if ( !usedTriplets[it] ) 
00232         quads_.push_back( tripletCache[it]);
00233     }
00234   }
00235 
00236   //calc for printout...
00237 //  unsigned int nLeft=0;
00238 //  for ( unsigned int i=0; i<nInputTriplets; i++)
00239 //    if ( !usedTriplets[i] ) nLeft++;
00240   // some stats
00241 //  std::cout << " [QuadrupletSeedMerger::mergeTriplets] -- Created: " << theResult.size()
00242 //          << " quadruplets from: " << nInputTriplets << " input triplets (" << nLeft
00243 //          << " remaining ";
00244 //  std::cout << (isAddRemainingTriplets_?"added":"dropped");
00245 //  std::cout << ")." << std::endl;
00246 
00247   return quads_;
00248 
00249 }
00250 
00251 
00252 
00263 const TrajectorySeedCollection QuadrupletSeedMerger::mergeTriplets( const TrajectorySeedCollection& seedCollection,
00264                                                                     const TrackingRegion& region,
00265                                                                     const edm::EventSetup& es,
00266                                                                     const edm::ParameterSet& cfg ) {
00267 
00268   // ttrh builder for HitSet -> TrajectorySeed conversion;
00269   // require this to be correctly configured, otherwise -> exception
00270   es.get<TransientRecHitRecord>().get( theTTRHBuilderLabel_, theTTRHBuilder_ );
00271 
00272   // output collection
00273   TrajectorySeedCollection theResult;
00274 
00275   // loop to see if we have triplets ONLY
00276   // if not, copy input -> output and return
00277   bool isAllTriplets = true;
00278   for( TrajectorySeedCollection::const_iterator aTrajectorySeed = seedCollection.begin();
00279        aTrajectorySeed < seedCollection.end(); ++aTrajectorySeed ) {
00280     if( 3 != aTrajectorySeed->nHits() ) isAllTriplets = false;
00281   }
00282 
00283   if( !isAllTriplets && isMergeTriplets_ )
00284     std::cout << " [QuadrupletSeedMerger::mergeTriplets] (in RECO) -- bailing out since non-triplets in input." << std::endl;
00285 
00286   if( !isAllTriplets || !isMergeTriplets_ ) {
00287     for( TrajectorySeedCollection::const_iterator aTrajectorySeed = seedCollection.begin();
00288        aTrajectorySeed < seedCollection.end(); ++aTrajectorySeed ) {
00289       theResult.push_back( *aTrajectorySeed );
00290     }
00291 
00292     return theResult;
00293   }
00294 
00295 
00296   // all this fiddling here is now about converting
00297   // TrajectorySeedCollection <-> OrderedSeedingHits
00298 
00299   // create OrderedSeedingHits first;
00300   OrderedHitTriplets inputTriplets;
00301 
00302   // loop seeds
00303   for( TrajectorySeedCollection::const_iterator aTrajectorySeed = seedCollection.begin();
00304        aTrajectorySeed < seedCollection.end(); ++aTrajectorySeed ) {
00305 
00306     std::vector<TransientTrackingRecHit::RecHitPointer> recHitPointers;
00307 
00308     // loop RecHits
00309     const TrajectorySeed::range theHitsRange = aTrajectorySeed->recHits();
00310     for( edm::OwnVector<TrackingRecHit>::const_iterator aHit = theHitsRange.first;
00311          aHit < theHitsRange.second; ++aHit ) {
00312       
00313       // this is a collection of: ReferenceCountingPointer< TransientTrackingRecHit> 
00314       recHitPointers.push_back( theTTRHBuilder_->build( &(*aHit) ) );
00315 
00316     }
00317     
00318     // add to input collection
00319     inputTriplets.push_back( OrderedHitTriplet( recHitPointers.at( 0 ), recHitPointers.at( 1 ), recHitPointers.at( 2 ) ) );
00320 
00321   }
00322 
00323   // do the real merging..
00324   const OrderedSeedingHits &quadrupletHitSets = mergeTriplets( inputTriplets, es );
00325   
00326   // convert back to TrajectorySeedCollection
00327 
00328   // the idea here is to fetch the same SeedCreator and PSet
00329   // as those used by the plugin which is calling the merger
00330   // (at the moment that's SeedGeneratorFromRegionHitsEDProducer)
00331   edm::ParameterSet creatorPSet = cfg.getParameter<edm::ParameterSet>("SeedCreatorPSet");
00332   std::string const& creatorName = creatorPSet.getParameter<std::string>( "ComponentName" );
00333   SeedCreator* seedCreator = SeedCreatorFactory::get()->create( creatorName, creatorPSet );
00334 
00335   for ( unsigned int i=0; i< quadrupletHitSets.size(); i++) {
00336     // add trajectory seed to result collection
00337     seedCreator->trajectorySeed( theResult, quadrupletHitSets[i], region, es, 0 );
00338   }
00339 
00340   return theResult;
00341   
00342 }
00343 
00344 
00345 
00349 bool QuadrupletSeedMerger::isEqual( const TrackingRecHit* hit1, const TrackingRecHit* hit2 ) const {
00350 
00351   const double epsilon = 0.00001;
00352   
00353   DetId det1 =  hit1->geographicalId(), det2 =  hit2->geographicalId();
00354   if (det1 == det2) { 
00355     LocalPoint lp1 = hit1->localPosition(), lp2 = hit2->localPosition();
00356     if( ( fabs( lp1.x() - lp2.x() ) < epsilon ) &&
00357         ( fabs( lp1.y() - lp2.y() ) < epsilon ) ) {
00358       return true;
00359     }
00360     
00361   }
00362   return false;
00363   
00364 }
00365 
00366 
00367 
00371 std::pair<double,double> QuadrupletSeedMerger::calculatePhiEta( SeedingHitSet const& nTuplet ) const {
00372 
00373 //   if( nTuplet.size() < 3 ) {
00374 //     std::cerr << " [QuadrupletSeedMerger::calculatePhiEta] ** ERROR: nTuplet has less than 3 hits" << std::endl;
00375 //     throw; // tbr.
00376 //   }
00377 
00378   const TrackingRecHit* hit1 = nTuplet[0]->hit();
00379   const GeomDet* geomDet1 = theTrackerGeometry_->idToDet( hit1->geographicalId() );
00380 
00381   const TrackingRecHit* hit2 = nTuplet[1]->hit();
00382   const GeomDet* geomDet2 = theTrackerGeometry_->idToDet( hit2->geographicalId() );
00383 
00384   GlobalPoint p1=geomDet1->toGlobal( hit1->localPosition() );
00385   GlobalPoint p2=geomDet2->toGlobal( hit2->localPosition() );
00386 
00387   const double x1 = p1.x();
00388   const double x2 = p2.x();
00389   const double y1 = p1.y();
00390   const double y2 = p2.y();
00391   const double z1 = p1.z();
00392   const double z2 = p2.z();
00393 
00394   const double phi = atan2( x2 - x1, y2 -y1 );
00395   const double eta = acos( (z2 - z1) / sqrt( pow( x2 - x1, 2. ) + pow( y2 - y1, 2. ) + pow( z2 - z1, 2. ) ) );
00396 
00397   std::pair<double,double> retVal;
00398   retVal=std::make_pair (phi,eta);
00399   return retVal;
00400   //return std::make_pair<double,double>( phi, eta );
00401   
00402 }
00403 
00404 
00405 
00409 void QuadrupletSeedMerger::printHit( const TransientTrackingRecHit::ConstRecHitPointer& aRecHitPointer ) const {
00410 
00411   printHit( aRecHitPointer->hit() );
00412 
00413 }
00414 
00415 
00416 
00420 void QuadrupletSeedMerger::printHit( const TrackingRecHit* aHit ) const {
00421 
00422   const GeomDet* geomDet = theTrackerGeometry_->idToDet( aHit->geographicalId() );
00423   const double r = geomDet->surface().position().perp();
00424   const double x = geomDet->toGlobal( aHit->localPosition() ).x();
00425   const double y = geomDet->toGlobal( aHit->localPosition() ).y();
00426   const double z = geomDet->toGlobal( aHit->localPosition() ).z();
00427   std::cout << "<RecHit> x: " << x << " y: " << y << " z: " << z << " r: " << r << std::endl;
00428 
00429 }
00430 
00434 void QuadrupletSeedMerger::printNtuplet( const SeedingHitSet& aNtuplet ) const {
00435 
00436   std::cout << "DUMPING NTUPLET OF SIZE:";
00437   std::cout << aNtuplet.size() << std::endl;
00438 
00439   for( unsigned int aHit = 0; aHit < aNtuplet.size(); ++aHit ) {
00440 
00441     const TrackingRecHit* theHit = aNtuplet[aHit]->hit();
00442     const GeomDet* geomDet = theTrackerGeometry_->idToDet( theHit->geographicalId() );
00443     const double x = geomDet->toGlobal( theHit->localPosition() ).x();
00444     const double y = geomDet->toGlobal( theHit->localPosition() ).y();
00445     const double z = geomDet->toGlobal( theHit->localPosition() ).z();
00446     const double r = sqrt( x*x + y*y );
00447 
00448     unsigned int layer;
00449     std::string detName;
00450     if( PixelSubdetector::PixelBarrel == theHit->geographicalId().subdetId() ) {
00451       detName = "BPIX ";
00452       PixelBarrelName pbn( aNtuplet[aHit]->hit()->geographicalId());
00453       layer = pbn.layerName();
00454     }
00455     else {
00456       detName = "FPIX";
00457       if( z > 0 ) detName += "+";
00458       else detName += "-";
00459 
00460       PixelEndcapName pen( theHit->geographicalId() );
00461       layer = pen.diskName();
00462     }
00463 
00464     std::cout << "<NtupletHit> D: " << detName << " L: " << layer << " x: " << x << " y: " << y << " z: " << z << " r: " << r << std::endl;
00465     
00466 }
00467 
00468   std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
00469 
00470 }
00471 
00472 
00473 
00477 void QuadrupletSeedMerger::setTTRHBuilderLabel( std::string label ) {
00478 
00479   theTTRHBuilderLabel_ = label;
00480   
00481 }
00482 
00483 
00484 
00488 void QuadrupletSeedMerger::setLayerListName( std::string layerListName ) {
00489   layerListName_ = layerListName;
00490 }
00491 
00492 
00493 
00497 void QuadrupletSeedMerger::setMergeTriplets( bool isMergeTriplets ) {
00498   isMergeTriplets_ = isMergeTriplets;
00499 }
00500 
00501 
00502 
00506 void QuadrupletSeedMerger::setAddRemainingTriplets( bool isAddTriplets ) {
00507   isAddRemainingTriplets_ = isAddTriplets;
00508 }
00509 
00510 
00511 
00517 bool QuadrupletSeedMerger::isValidQuadruplet( std::vector<TransientTrackingRecHit::ConstRecHitPointer> &quadruplet, const std::vector<SeedMergerPixelLayer>& layers ) const {
00518 
00519   const unsigned int quadrupletSize = quadruplet.size();
00520 
00521   // basic size test..
00522   if( quadrupletSize != layers.size() ) {
00523     std::cout << " [QuadrupletSeedMerger::isValidQuadruplet] ** WARNING: size mismatch: "
00524               << quadrupletSize << "/" << layers.size() << std::endl;
00525     return false;
00526   }
00527 
00528   // go along layers and check if all (parallel) quadruplet hits match
00529   for( unsigned int index = 0; index < quadrupletSize; ++index ) {
00530     if( ! layers[index].isContainsDetector( quadruplet[index]->geographicalId() ) ) {
00531       return false;
00532     }
00533   }
00534 
00535   return true;
00536 
00537 }
00538 
00539 
00540 
00546 bool QuadrupletSeedMerger::isTripletsShareHitsOnLayers( const SeedingHitSet& firstTriplet, const SeedingHitSet& secondTriplet, 
00547                                                         const SeedMergerPixelLayer &shared1, const SeedMergerPixelLayer &shared2,
00548   std::pair<TransientTrackingRecHit::ConstRecHitPointer,TransientTrackingRecHit::ConstRecHitPointer>& hits ) const {
00549 
00550   bool isSuccess1[2],isSuccess2[2];
00551   isSuccess1[0]=false;
00552   isSuccess1[1]=false;
00553   isSuccess2[0]=false;
00554   isSuccess2[1]=false;
00555 
00556   std::pair<TransientTrackingRecHit::ConstRecHitPointer,TransientTrackingRecHit::ConstRecHitPointer> hitsTriplet1, hitsTriplet2;
00557 
00558   // check if firstTriplet and secondTriplet have hits on sharedLayers
00559   for( unsigned int index = 0; index < 3; ++index )
00560     { // first triplet
00561       if( ! firstTriplet[index]->isValid() ) return false; // catch invalid TTRH pointers (tbd: erase triplet)
00562       bool firsthit(false); // Don't look in second layer if found in first
00563       DetId const& thisDetId = firstTriplet[index]->hit()->geographicalId();
00564       
00565       if( ! isSuccess1[0] ) { // first triplet on shared layer 1
00566         if( shared1.isContainsDetector( thisDetId ) ) {
00567           isSuccess1[0] = true;
00568           firsthit = true;
00569           hitsTriplet1.first = firstTriplet[index];
00570         }
00571       }
00572       
00573       if ( (! firsthit) && (! isSuccess1[1] ) && ((index !=3) || isSuccess1[0]) ) { // first triplet on shared layer 2
00574         if( shared2.isContainsDetector( thisDetId ) ) {
00575           isSuccess1[1] = true;
00576           hitsTriplet1.second = firstTriplet[index];
00577         }
00578       } 
00579     }
00580   
00581   if ( isSuccess1[0] && isSuccess1[1]) { // Don't do second triplet if first unsuccessful
00582     for( unsigned int index = 0; index < 3; ++index )
00583       { // second triplet
00584         if( ! secondTriplet[index]->isValid() ) { return false; } // catch invalid TTRH pointers (tbd: erase triplet)
00585         bool firsthit(false); // Don't look in second layer if found in first
00586         DetId const& thisDetId = secondTriplet[index]->hit()->geographicalId();
00587         
00588         if( ! isSuccess2[0] ) { // second triplet on shared layer 1
00589           if( shared1.isContainsDetector( thisDetId ) ) {
00590             isSuccess2[0] = true;
00591             firsthit = true;
00592             hitsTriplet2.first = secondTriplet[index];
00593           }
00594         }
00595         
00596         if( (! firsthit) && (! isSuccess2[1]) && ((index !=3) || isSuccess2[0]) ) { // second triplet on shared layer 2
00597           if( shared2.isContainsDetector( thisDetId ) ) {
00598             isSuccess2[1] = true;
00599             hitsTriplet2.second = secondTriplet[index];
00600           }
00601         }
00602       }
00603     
00604     // check if these hits are pairwise equal
00605     if( isSuccess2[0] && isSuccess2[1] ) {
00606       if( isEqual( hitsTriplet1.first->hit(),  hitsTriplet2.first->hit()  ) &&
00607           isEqual( hitsTriplet1.second->hit(), hitsTriplet2.second->hit() )    ) {
00608         
00609         // copy to output, take triplet1 since they're equal anyway
00610         hits.first  = hitsTriplet1.first;
00611         hits.second = hitsTriplet1.second;
00612         return true;
00613       }
00614     }
00615   }
00616   
00617   // empty output, careful
00618   return false;
00619   
00620 }
00621 
00622 
00623 
00628 bool QuadrupletSeedMerger::isMergeableHitsInTriplets( const SeedingHitSet& firstTriplet, const SeedingHitSet& secondTriplet, 
00629                                                       const SeedMergerPixelLayer &nonShared1, const SeedMergerPixelLayer &nonShared2,
00630    std::pair<TransientTrackingRecHit::ConstRecHitPointer,TransientTrackingRecHit::ConstRecHitPointer>& hits ) const {
00631 
00632   // check if firstTriplet and secondTriplet have hits on sharedLayers
00633   for( unsigned int index1 = 0; index1 < 3; ++index1 ) {
00634     
00635     { // first triplet on non-shared layer 1
00636       DetId const& aDetId = firstTriplet[index1]->hit()->geographicalId();
00637       if( nonShared1.isContainsDetector( aDetId ) ) {
00638         
00639         // look for hit in other (second) triplet on other layer
00640         for( unsigned int index2 = 0; index2 < 3; ++index2 ) {
00641           
00642           DetId const& anotherDetId = secondTriplet[index2]->hit()->geographicalId();
00643           if( nonShared2.isContainsDetector( anotherDetId ) ) {
00644             
00645             // ok!
00646             hits.first  = firstTriplet[index1];
00647             hits.second = secondTriplet[index2];
00648             return true;
00649             
00650           }
00651         }
00652       }
00653     }
00654 
00655     // and vice versa..
00656 
00657     { // second triplet on non-shared layer 1
00658       DetId const& aDetId = secondTriplet[index1]->hit()->geographicalId();
00659       if( nonShared1.isContainsDetector( aDetId ) ) {
00660         
00661         // look for hit in other (second) triplet on other layer
00662         for( unsigned int index2 = 0; index2 < 3; ++index2 ) {
00663           
00664           DetId const& anotherDetId = firstTriplet[index2]->hit()->geographicalId();
00665           if( nonShared2.isContainsDetector( anotherDetId ) ) {
00666             
00667             // ok!
00668             hits.first  = firstTriplet[index1];
00669             hits.second = secondTriplet[index2];
00670             return true;
00671             
00672           }
00673         }
00674       }
00675     }
00676 
00677   } // for( index1
00678 
00679   return false;
00680     
00681 }
00682 
00683 
00684 
00688 SeedMergerPixelLayer::SeedMergerPixelLayer( const std::string& name ) {
00689   
00690   if( ! isValidName( name ) ) { 
00691     std::cerr << " [SeedMergerPixelLayer::SeedMergerPixelLayer] ** ERROR: illegal name: \"" << name << "\"." << std::endl;
00692     isValid_ = false;
00693     return;
00694   }
00695 
00696   // bare name, can be done here
00697   name_ = name;
00698 
00699   // (output format -> see DataFormats/SiPixelDetId/interface/PixelSubdetector.h)
00700   if( std::string::npos != name_.find( "BPix" ) ) 
00701     { subdet_ = PixelSubdetector::PixelBarrel; side_ = Undefined;}
00702   else if( std::string::npos != name_.find( "FPix" ) ) 
00703     { subdet_ = PixelSubdetector::PixelEndcap;
00704       if( std::string::npos != name_.find( "pos", 6 ) ) side_ = Plus;
00705       else if( std::string::npos != name_.find( "neg", 6 ) ) side_ = Minus;
00706       else {
00707         std::cerr << " [PixelLayerNameParser::side] ** ERROR: something's wrong here.." << std::endl;
00708         side_ = SideError;
00709       }
00710     }
00711   else {
00712     std::cerr << " [PixelLayerNameParser::subdetector] ** ERROR: something's wrong here.." << std::endl;
00713   }
00714 
00715   // layer
00716   layer_ = atoi( name_.substr( 4, 1 ).c_str() );
00717 
00718 }
00719 
00720 
00721 
00725 bool SeedMergerPixelLayer::isValidName( const std::string& name ) {
00726 
00727   const int layer = atoi( name.substr( 4, 1 ).c_str() );
00728 
00729   if( std::string::npos != name.find( "BPix" ) ) {
00730     if( layer > 0 && layer < 5 ) return true;
00731   }
00732 
00733   else if( std::string::npos != name.find( "FPix" ) ) {
00734     if( layer > 0 && layer < 4 ) {
00735       if( std::string::npos != name.find( "pos", 6 ) || std::string::npos != name.find( "neg", 6 ) ) return true;
00736     }
00737 
00738   }
00739 
00740   std::cerr << " [SeedMergerPixelLayer::isValidName] ** WARNING: invalid name: \"" << name << "\"." << std::endl;
00741   return false;
00742 
00743 }
00744 
00745 
00746 
00751 bool SeedMergerPixelLayer::isContainsDetector( const DetId& detId ) const {
00752 
00753   PixelSubdetector::SubDetector subdet = getSubdet();
00754 
00755   // same subdet?
00756   if( detId.subdetId() == subdet ) {
00757     
00758     // same barrel layer?
00759     if( PixelSubdetector::PixelBarrel == subdet ) {
00760       const PXBDetId cmssw_numbering(detId);
00761       if (cmssw_numbering.layer() == getLayerNumber()) {
00762         return true;
00763       }
00764     }
00765     
00766     // same endcap disk?
00767     else if( PixelSubdetector::PixelEndcap == subdet ) {
00768       PXFDetId px_numbering(detId);
00769       if (px_numbering.disk() == getLayerNumber()) {
00770         if (px_numbering.side() == (unsigned)getSide()) {
00771           return true;
00772         }
00773       }
00774     }
00775     
00776   }
00777   
00778   return false;
00779   
00780 }
00781 
00782 
00783 std::vector<TransientTrackingRecHit::ConstRecHitPointer> QuadrupletSeedMerger::mySort(TransientTrackingRecHit::ConstRecHitPointer &h1,
00784                                                                                       TransientTrackingRecHit::ConstRecHitPointer &h2,
00785                                                                                       TransientTrackingRecHit::ConstRecHitPointer &h3,
00786                                                                                       TransientTrackingRecHit::ConstRecHitPointer &h4) {
00787   // create an intermediate vector with all hits
00788   std::vector<TransientTrackingRecHit::ConstRecHitPointer> unsortedHits;
00789   unsortedHits.reserve(4);
00790   unsortedHits.push_back( h1);
00791   unsortedHits.push_back( h2);
00792   unsortedHits.push_back( h3);
00793   unsortedHits.push_back( h4);
00794   
00795   float radiiSq[4];
00796   for ( unsigned int iR=0; iR<4; iR++){
00797     const GeomDet* geom1=theTrackerGeometry_->idToDet( unsortedHits[iR]->hit()->geographicalId() );
00798     GlobalPoint p1=geom1->toGlobal(  unsortedHits[iR]->hit()->localPosition() );
00799     radiiSq[iR]=( p1.x()*p1.x()+p1.y()*p1.y()); // no need to take the sqrt
00800   }
00801   TransientTrackingRecHit::ConstRecHitPointer tempRHP;
00802   float tempFloat=0.;
00803   for ( unsigned int iR1=0; iR1<3; iR1++) {
00804     for ( unsigned int iR2=iR1+1; iR2<4; iR2++) {
00805       if (radiiSq[iR1]>radiiSq[iR2]) {
00806         tempRHP=unsortedHits[iR1];
00807         unsortedHits[iR1]=unsortedHits[iR2];
00808         unsortedHits[iR2]=tempRHP;
00809         tempFloat=radiiSq[iR1];
00810         radiiSq[iR1]=radiiSq[iR2];
00811         radiiSq[iR2]=tempFloat;
00812       }
00813     }
00814   }
00815   return unsortedHits;
00816 }
00817 
00818 
00819