CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoPixelVertexing/PixelTriplets/src/QuadrupletSeedMerger.cc

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