CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoTracker/RoadSearchSeedFinder/src/RoadSearchSeedFinderAlgorithm.cc

Go to the documentation of this file.
00001 //
00002 // Package:         RecoTracker/RoadSearchSeedFinder
00003 // Class:           RoadSearchSeedFinderAlgorithm
00004 // 
00005 // Description:     Loops over Roads, checks for every
00006 //                  RoadSeed if hits are in the inner and
00007 //                  outer SeedRing, applies cuts for all 
00008 //                  combinations of inner and outer SeedHits,
00009 //                  stores valid combination in TrajectorySeed
00010 //
00011 // Original Author: Oliver Gutsche, gutsche@fnal.gov
00012 // Created:         Sat Jan 14 22:00:00 UTC 2006
00013 //
00014 // $Author: gpetrucc $
00015 // $Date: 2009/10/16 08:44:37 $
00016 // $Revision: 1.36 $
00017 //
00018 
00019 #include <vector>
00020 #include <iostream>
00021 #include <cmath>
00022 #include <algorithm>
00023 
00024 #include "RecoTracker/RoadSearchSeedFinder/interface/RoadSearchSeedFinderAlgorithm.h"
00025 
00026 #include "RecoTracker/RoadMapRecord/interface/RoadMapRecord.h"
00027 
00028 #include "FWCore/Framework/interface/ESHandle.h"
00029 #include "FWCore/Framework/interface/EventSetup.h"
00030 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00031 
00032 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h"
00033 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2D.h"
00034 
00035 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00036 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00037 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00038 
00039 #include "RecoTracker/TkSeedGenerator/interface/FastHelix.h"
00040 
00041 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00042 
00043 #include "DataFormats/DetId/interface/DetId.h"
00044 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00045 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00046 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00047 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00048 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00049 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00050 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00051 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00052 
00053 #include "DataFormats/SiStripCluster/interface/SiStripCluster.h"
00054 #include "DataFormats/Common/interface/DetSetVectorNew.h"
00055 #include "DataFormats/Common/interface/DetSetNew.h"
00056 //***top-bottom
00057 #include "RecoTracker/TransientTrackingRecHit/interface/TkTransientTrackingRecHitBuilder.h"
00058 //***
00059 const double speedOfLight = 2.99792458e8;
00060 const double unitCorrection = speedOfLight * 1e-2 * 1e-9;
00061 
00062 RoadSearchSeedFinderAlgorithm::RoadSearchSeedFinderAlgorithm(const edm::ParameterSet& conf) { 
00063 
00064 
00065   minPt_                      = conf.getParameter<double>("MinimalReconstructedTransverseMomentum");
00066   maxBarrelImpactParameter_   = conf.getParameter<double>("MaximalBarrelImpactParameter");
00067   maxEndcapImpactParameter_   = conf.getParameter<double>("MaximalEndcapImpactParameter");
00068   phiRangeDetIdLookup_        = conf.getParameter<double>("PhiRangeForDetIdLookupInRings");
00069   mergeSeedsCenterCut_A_      = conf.getParameter<double>("MergeSeedsCenterCut_A");
00070   mergeSeedsRadiusCut_A_      = conf.getParameter<double>("MergeSeedsRadiusCut_A");
00071   mergeSeedsCenterCut_B_      = conf.getParameter<double>("MergeSeedsCenterCut_B");
00072   mergeSeedsRadiusCut_B_      = conf.getParameter<double>("MergeSeedsRadiusCut_B");
00073   mergeSeedsCenterCut_C_      = conf.getParameter<double>("MergeSeedsCenterCut_C");
00074   mergeSeedsRadiusCut_C_      = conf.getParameter<double>("MergeSeedsRadiusCut_C");
00075   mergeSeedsCenterCut_        = mergeSeedsCenterCut_A_;
00076   mergeSeedsRadiusCut_        = mergeSeedsRadiusCut_A_;
00077   mergeSeedsDifferentHitsCut_ = conf.getParameter<unsigned int>("MergeSeedsDifferentHitsCut");
00078   mode_                       = conf.getParameter<std::string>("Mode");
00079   
00080   //special parameters for cosmic track reconstruction
00081   //cosmicTracking_             = conf.getParameter<bool>("CosmicTracking");
00082   //maxNumberOfClusters_        = conf.getParameter<unsigned int>("MaxNumberOfClusters");
00083 
00084 
00085   // safety check for mode
00086   if ( mode_ != "STANDARD" && mode_ != "STRAIGHT-LINE" ) {
00087     mode_ = "STANDARD";
00088   }
00089 
00090   std::string tmp             = conf.getParameter<std::string>("InnerSeedRecHitAccessMode");
00091   if ( tmp == "STANDARD" ) {
00092     innerSeedHitAccessMode_ = DetHitAccess::standard;
00093   } else if ( tmp == "RPHI" ) {
00094     innerSeedHitAccessMode_ = DetHitAccess::rphi;
00095   } else {
00096     innerSeedHitAccessMode_ = DetHitAccess::standard;
00097   }
00098   innerSeedHitAccessUseRPhi_  = conf.getParameter<bool>("InnerSeedRecHitAccessUseRPhi");
00099   innerSeedHitAccessUseStereo_  = conf.getParameter<bool>("InnerSeedRecHitAccessUseStereo");
00100 
00101   tmp                         = conf.getParameter<std::string>("OuterSeedRecHitAccessMode");
00102   if ( tmp == "STANDARD" ) {
00103     outerSeedHitAccessMode_ = DetHitAccess::standard;
00104   } else if ( tmp == "RPHI" ) {
00105     outerSeedHitAccessMode_ = DetHitAccess::rphi;
00106   } else {
00107     outerSeedHitAccessMode_ = DetHitAccess::standard;
00108   }
00109   outerSeedHitAccessUseRPhi_  = conf.getParameter<bool>("OuterSeedRecHitAccessUseRPhi");
00110   outerSeedHitAccessUseStereo_  = conf.getParameter<bool>("OuterSeedRecHitAccessUseStereo");
00111 
00112   // configure DetHitAccess
00113   innerSeedHitVector_.setMode(innerSeedHitAccessMode_);
00114   innerSeedHitVector_.use_rphiRecHits(innerSeedHitAccessUseRPhi_);
00115   innerSeedHitVector_.use_stereoRecHits(innerSeedHitAccessUseStereo_);
00116   outerSeedHitVector_.setMode(outerSeedHitAccessMode_);
00117   outerSeedHitVector_.use_rphiRecHits(outerSeedHitAccessUseRPhi_);
00118   outerSeedHitVector_.use_stereoRecHits(outerSeedHitAccessUseStereo_);
00119 
00120   roadsLabel_ = conf.getParameter<std::string>("RoadsLabel");
00121 
00122   maxNumberOfSeeds_ = conf.getParameter<int32_t>("MaxNumberOfSeeds");
00123   //***top-bottom
00124   allPositiveOnly = conf.getParameter<bool>("AllPositiveOnly");
00125   allNegativeOnly = conf.getParameter<bool>("AllNegativeOnly");
00126   //***
00127 }
00128 
00129 RoadSearchSeedFinderAlgorithm::~RoadSearchSeedFinderAlgorithm() {
00130 }
00131 
00132 
00133 void RoadSearchSeedFinderAlgorithm::run(const SiStripRecHit2DCollection* rphiRecHits,
00134                                         const SiStripRecHit2DCollection* stereoRecHits,
00135                                         const SiStripMatchedRecHit2DCollection* matchedRecHits,
00136                                         const SiPixelRecHitCollection* pixelRecHits,
00137                                         const edm::EventSetup& es,
00138                                         RoadSearchSeedCollection &output)
00139 {
00140 
00141   // initialize general hit access for road search
00142   innerSeedHitVector_.setCollections(rphiRecHits,stereoRecHits,matchedRecHits,pixelRecHits);
00143   outerSeedHitVector_.setCollections(rphiRecHits,stereoRecHits,matchedRecHits,pixelRecHits);
00144 
00145   // get roads
00146   edm::ESHandle<Roads> roads;
00147   es.get<RoadMapRecord>().get(roadsLabel_,roads);
00148   roads_ = roads.product();
00149 
00150   // get tracker geometry
00151   edm::ESHandle<TrackerGeometry> tracker;
00152   es.get<TrackerDigiGeometryRecord>().get(tracker);
00153   tracker_ = tracker.product();
00154 
00155   // get magnetic field
00156   edm::ESHandle<MagneticField> magnetHandle;
00157   es.get<IdealMagneticFieldRecord>().get(magnetHandle);
00158   magnet_ = magnetHandle.product();
00159 
00160   //***top-bottom
00161   //TTRHBuilder
00162   TkTransientTrackingRecHitBuilder builder(tracker_,0,0,0,false);
00163   //***
00164 
00165   // get magnetic field for 0,0,0 , approximation for minRadius calculation
00166   beamSpotZMagneticField_ = magnet_->inTesla(GlobalPoint(0,0,0)).z();
00167   // calculate minimal radius at globalPoint in cm, take the z component of the magnetic field at GlobalPoint 2
00168   if ( beamSpotZMagneticField_ == 0 ) {
00169     minRadius_ = 999999999999.;
00170   } else {
00171     minRadius_ = minPt_ / 0.3 / beamSpotZMagneticField_ * 100;
00172   }
00173 
00174   // temporary storing collection of circle seeds
00175   std::vector<RoadSearchCircleSeed> localCircleSeeds;
00176 
00177   // loop over seed Ring pairs
00178   for ( Roads::const_iterator road = roads_->begin(); road != roads_->end(); ++road ) {
00179 
00180     localCircleSeeds.clear();
00181 
00182     const Roads::RoadSeed  *seed  = &((*road).first);
00183     const Roads::RoadSet   *set  =  &((*road).second);
00184 
00185     // determine seeding cuts from inner seed ring |eta|
00186     double r = std::abs((*seed->first.begin())->getrmax() + (*seed->first.begin())->getrmin())/2.;
00187     double z = std::abs((*seed->first.begin())->getzmax() + (*seed->first.begin())->getzmin())/2.;
00188     double eta = std::abs(std::log(std::tan(std::atan2(r,z)/2.)));
00189 
00190     if ( eta < 1.1 ) {
00191       mergeSeedsCenterCut_ = mergeSeedsCenterCut_A_;
00192       mergeSeedsRadiusCut_ = mergeSeedsRadiusCut_A_;
00193     } else if ( (eta >= 1.1) && (eta < 1.6) ) {
00194       mergeSeedsCenterCut_ = mergeSeedsCenterCut_B_;
00195       mergeSeedsRadiusCut_ = mergeSeedsRadiusCut_B_;
00196     } else if ( eta >= 1.6 ) {
00197       mergeSeedsCenterCut_ = mergeSeedsCenterCut_C_;
00198       mergeSeedsRadiusCut_ = mergeSeedsRadiusCut_C_;
00199     }
00200 
00201     if ( mode_ == "STRAIGHT-LINE" ) {
00202 
00203       // loop over seed ring pairs
00204       // draw straight line
00205       for ( std::vector<const Ring*>::const_iterator innerSeedRing = seed->first.begin();
00206             innerSeedRing != seed->first.end();
00207             ++innerSeedRing) {
00208         for ( std::vector<const Ring*>::const_iterator outerSeedRing = seed->second.begin();
00209               outerSeedRing != seed->second.end();
00210               ++outerSeedRing) {
00211           calculateCircleSeedsFromRingsOneInnerOneOuter(localCircleSeeds,
00212                                                         seed,
00213                                                         set,
00214                                                         *innerSeedRing,
00215                                                         *outerSeedRing);
00216           
00217         }
00218       }
00219     } else if ( mode_ == "STANDARD" ) {
00220 
00221       // take combinations of one inner and two outer or two inner and one outer seed ring
00222       for ( std::vector<const Ring*>::const_iterator innerSeedRing1 = seed->first.begin();
00223             innerSeedRing1 != seed->first.end();
00224             ++innerSeedRing1) {
00225         // two inner, one outer
00226         for ( std::vector<const Ring*>::const_iterator innerSeedRing2 = innerSeedRing1+1;
00227               innerSeedRing2 != seed->first.end();
00228               ++innerSeedRing2) {
00229           if ( !ringsOnSameLayer(*innerSeedRing1,*innerSeedRing2) ) {
00230             for ( std::vector<const Ring*>::const_iterator outerSeedRing = seed->second.begin();
00231                   outerSeedRing != seed->second.end();
00232                   ++outerSeedRing) {
00233               // calculate seed ring combination identifier
00234               unsigned int identifier = (*innerSeedRing1)->getindex() * 1000000 +
00235                 (*innerSeedRing2)->getindex() * 1000 +
00236                 (*outerSeedRing)->getindex();
00237               bool check = true;
00238               for ( std::vector<unsigned int>::iterator alreadyChecked = usedSeedRingCombinations_.begin();
00239                     alreadyChecked != usedSeedRingCombinations_.end();
00240                     ++alreadyChecked ) {
00241                 if ( identifier == *alreadyChecked ) {
00242                   check = false;
00243                   break;
00244                 }
00245               }
00246 
00247               if ( check ) {
00248                 usedSeedRingCombinations_.push_back(identifier);
00249                 calculateCircleSeedsFromRingsTwoInnerOneOuter(localCircleSeeds,
00250                                                               seed,
00251                                                               set,
00252                                                               *innerSeedRing1,
00253                                                               *innerSeedRing2,
00254                                                               *outerSeedRing);
00255               }
00256             }     
00257           }
00258         }
00259         // one inner, two outer
00260         for ( std::vector<const Ring*>::const_iterator outerSeedRing1 = seed->second.begin();
00261               outerSeedRing1 != seed->second.end();
00262               ++outerSeedRing1) {
00263           for ( std::vector<const Ring*>::const_iterator outerSeedRing2 = outerSeedRing1+1;
00264                 outerSeedRing2 != seed->second.end();
00265                 ++outerSeedRing2) {
00266             if ( !ringsOnSameLayer(*outerSeedRing1,*outerSeedRing2) ) {
00267               // calculate seed ring combination identifier
00268               unsigned int identifier = (*innerSeedRing1)->getindex() * 1000000 +
00269                 (*outerSeedRing1)->getindex() * 1000 +
00270                 (*outerSeedRing2)->getindex();
00271               bool check = true;
00272               for ( std::vector<unsigned int>::iterator alreadyChecked = usedSeedRingCombinations_.begin();
00273                     alreadyChecked != usedSeedRingCombinations_.end();
00274                     ++alreadyChecked ) {
00275                 if ( identifier == *alreadyChecked ) {
00276                   check = false;
00277                   break;
00278                 }
00279               }
00280 
00281               if ( check ) {
00282                 usedSeedRingCombinations_.push_back(identifier);
00283                 calculateCircleSeedsFromRingsOneInnerTwoOuter(localCircleSeeds,
00284                                                               seed,
00285                                                               set,
00286                                                               *innerSeedRing1,
00287                                                               *outerSeedRing1,
00288                                                               *outerSeedRing2);
00289               }
00290             }
00291           }
00292         }
00293       }
00294     }
00295 
00296     // fill in eta mapped multi-map
00297     for ( std::vector<RoadSearchCircleSeed>::iterator localCircle = localCircleSeeds.begin(),
00298             localCircleEnd = localCircleSeeds.end();
00299           localCircle != localCircleEnd;
00300           ++localCircle ) {
00301       RoadSearchSeed seed;
00302       seed.setSet(localCircle->getSet());
00303       seed.setSeed(localCircle->getSeed());
00304       //***top-bottom
00305       bool allPositive = true;
00306       bool allNegative = true;
00307       //***
00308       for (std::vector<const TrackingRecHit*>::const_iterator hit = localCircle->begin_hits();
00309            hit != localCircle->end_hits();
00310            ++hit ) {
00311         seed.addHit(*hit);
00312         //***top-bottom
00313         double seedY = builder.build(*hit)->globalPosition().y();
00314         if (seedY>0) allNegative = false;
00315         if (seedY<0) allPositive = false;
00316         //***
00317       }
00318       //***top-bottom
00319       //output.push_back(seed);
00320       if (allPositive && allPositiveOnly) output.push_back(seed);
00321       if (allNegative && allNegativeOnly) output.push_back(seed);
00322       if (!allPositiveOnly && !allNegativeOnly) output.push_back(seed);
00323       //***
00324     }
00325 
00326     if ((maxNumberOfSeeds_ > 0) && (output.size() > size_t(maxNumberOfSeeds_))) {
00327       edm::LogError("TooManySeeds") << "Found too many seeds, bailing out.\n";
00328       output.clear(); 
00329       break;
00330     }
00331   }
00332     
00333   usedSeedRingCombinations_.clear();
00334   edm::LogInfo("RoadSearch") << "Found " << output.size() << " seeds."; 
00335 
00336 }
00337 
00338 bool RoadSearchSeedFinderAlgorithm::calculateCircleSeedsFromRingsTwoInnerOneOuter(std::vector<RoadSearchCircleSeed> &circleSeeds,
00339                                                                                   const Roads::RoadSeed *seed,
00340                                                                                   const Roads::RoadSet *set,
00341                                                                                   const Ring* ring1,
00342                                                                                   const Ring* ring2,
00343                                                                                   const Ring* ring3) {
00344   //
00345   // calculate RoadSearchCircleSeed
00346   //
00347   // apply circle seed cuts
00348   //
00349 
00350   // return value
00351   bool result = true;
00352 
00353   // loop over detid's in first rings
00354   for ( Ring::const_iterator ring1DetIdIterator = ring1->begin(); 
00355         ring1DetIdIterator != ring1->end(); 
00356         ++ring1DetIdIterator ) {
00357 
00358     DetId ring1DetId = ring1DetIdIterator->second;
00359     std::vector<TrackingRecHit*> ring1RecHits = innerSeedHitVector_.getHitVector(&ring1DetId);
00360 
00361     // loop over inner rechits
00362     for (std::vector<TrackingRecHit*>::const_iterator ring1RecHit = ring1RecHits.begin();
00363          ring1RecHit != ring1RecHits.end(); 
00364          ++ring1RecHit) {
00365             
00366       GlobalPoint ring1GlobalPoint = tracker_->idToDet((*ring1RecHit)->geographicalId())->surface().toGlobal((*ring1RecHit)->localPosition());
00367 
00368       // calculate phi range around inner hit
00369       double innerphi = ring1GlobalPoint.phi();
00370       double upperPhiRangeBorder = innerphi + phiRangeDetIdLookup_;
00371       double lowerPhiRangeBorder = innerphi - phiRangeDetIdLookup_;
00372       if (upperPhiRangeBorder>Geom::pi()) upperPhiRangeBorder -= Geom::twoPi();
00373       if (lowerPhiRangeBorder<(-Geom::pi())) lowerPhiRangeBorder += Geom::twoPi();
00374 
00375       // retrieve vectors of TrackingRecHits in ring2 and ring3 in phi range
00376       std::vector<TrackingRecHit*> ring2RecHits;
00377       std::vector<TrackingRecHit*> ring3RecHits;
00378 
00379       if (lowerPhiRangeBorder <= upperPhiRangeBorder ) {
00380         for ( Ring::const_iterator outerRingDetId = ring2->lower_bound(lowerPhiRangeBorder); 
00381               outerRingDetId != ring2->upper_bound(upperPhiRangeBorder);
00382               ++outerRingDetId) {
00383           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00384           ring2RecHits.insert(ring2RecHits.end(),
00385                               rings.begin(),
00386                               rings.end());
00387         }
00388         for ( Ring::const_iterator outerRingDetId = ring3->lower_bound(lowerPhiRangeBorder); 
00389               outerRingDetId != ring3->upper_bound(upperPhiRangeBorder);
00390               ++outerRingDetId) {
00391           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00392           ring3RecHits.insert(ring3RecHits.end(),
00393                               rings.begin(),
00394                               rings.end());
00395         }
00396       } else {
00397         for ( Ring::const_iterator outerRingDetId = ring2->begin(); 
00398               outerRingDetId != ring2->upper_bound(upperPhiRangeBorder);
00399               ++outerRingDetId) {
00400           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00401           ring2RecHits.insert(ring2RecHits.end(),
00402                               rings.begin(),
00403                               rings.end());
00404         }
00405         for ( Ring::const_iterator outerRingDetId = ring3->begin(); 
00406               outerRingDetId != ring3->upper_bound(upperPhiRangeBorder);
00407               ++outerRingDetId) {
00408           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00409           ring3RecHits.insert(ring3RecHits.end(),
00410                               rings.begin(),
00411                               rings.end());
00412         }
00413         for ( Ring::const_iterator outerRingDetId = ring2->lower_bound(lowerPhiRangeBorder); 
00414               outerRingDetId != ring2->end();
00415               ++outerRingDetId) {
00416           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00417           ring2RecHits.insert(ring2RecHits.end(),
00418                               rings.begin(),
00419                               rings.end());
00420         }
00421         for ( Ring::const_iterator outerRingDetId = ring3->lower_bound(lowerPhiRangeBorder); 
00422               outerRingDetId != ring3->end();
00423               ++outerRingDetId) {
00424           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00425           ring3RecHits.insert(ring3RecHits.end(),
00426                               rings.begin(),
00427                               rings.end());
00428         }
00429       }
00430 
00431       if ( ring2RecHits.size() > 0 &&
00432            ring3RecHits.size() > 0 ) {
00433         calculateCircleSeedsFromHits(circleSeeds, seed, set, ring1GlobalPoint, *ring1RecHit, ring2RecHits, ring3RecHits);
00434       }
00435 
00436     }
00437   }
00438 
00439   return result;
00440 
00441 }
00442 
00443 bool RoadSearchSeedFinderAlgorithm::calculateCircleSeedsFromRingsOneInnerTwoOuter(std::vector<RoadSearchCircleSeed> &circleSeeds,
00444                                                                                   const Roads::RoadSeed *seed,
00445                                                                                   const Roads::RoadSet *set,
00446                                                                                   const Ring* ring1,
00447                                                                                   const Ring* ring2,
00448                                                                                   const Ring* ring3) {
00449   //
00450   // calculate RoadSearchCircleSeed
00451   //
00452   // apply circle seed cuts
00453   //
00454 
00455   // return value
00456   bool result = true;
00457 
00458   // loop over detid's in first rings
00459   for ( Ring::const_iterator ring1DetIdIterator = ring1->begin(); 
00460         ring1DetIdIterator != ring1->end(); 
00461         ++ring1DetIdIterator ) {
00462 
00463     DetId ring1DetId = ring1DetIdIterator->second;
00464     std::vector<TrackingRecHit*> ring1RecHits = innerSeedHitVector_.getHitVector(&ring1DetId);
00465 
00466     // loop over inner rechits
00467     for (std::vector<TrackingRecHit*>::const_iterator ring1RecHit = ring1RecHits.begin();
00468          ring1RecHit != ring1RecHits.end(); 
00469          ++ring1RecHit) {
00470             
00471       GlobalPoint ring1GlobalPoint = tracker_->idToDet((*ring1RecHit)->geographicalId())->surface().toGlobal((*ring1RecHit)->localPosition());
00472 
00473       // calculate phi range around inner hit
00474       double innerphi = ring1GlobalPoint.phi();
00475       double upperPhiRangeBorder = innerphi + phiRangeDetIdLookup_;
00476       double lowerPhiRangeBorder = innerphi - phiRangeDetIdLookup_;
00477       if (upperPhiRangeBorder>Geom::pi()) upperPhiRangeBorder -= Geom::twoPi();
00478       if (lowerPhiRangeBorder<(-Geom::pi())) lowerPhiRangeBorder += Geom::twoPi();
00479 
00480       // retrieve vectors of TrackingRecHits in ring2 and ring3 in phi range
00481       std::vector<TrackingRecHit*> ring2RecHits;
00482       std::vector<TrackingRecHit*> ring3RecHits;
00483 
00484       if (lowerPhiRangeBorder <= upperPhiRangeBorder ) {
00485         for ( Ring::const_iterator outerRingDetId = ring2->lower_bound(lowerPhiRangeBorder); 
00486               outerRingDetId != ring2->upper_bound(upperPhiRangeBorder);
00487               ++outerRingDetId) {
00488           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00489           ring2RecHits.insert(ring2RecHits.end(),
00490                               rings.begin(),
00491                               rings.end());
00492         }
00493         for ( Ring::const_iterator outerRingDetId = ring3->lower_bound(lowerPhiRangeBorder); 
00494               outerRingDetId != ring3->upper_bound(upperPhiRangeBorder);
00495               ++outerRingDetId) {
00496           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00497           ring3RecHits.insert(ring3RecHits.end(),
00498                               rings.begin(),
00499                               rings.end());
00500         }
00501       } else {
00502         for ( Ring::const_iterator outerRingDetId = ring2->begin(); 
00503               outerRingDetId != ring2->upper_bound(upperPhiRangeBorder);
00504               ++outerRingDetId) {
00505           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00506           ring2RecHits.insert(ring2RecHits.end(),
00507                               rings.begin(),
00508                               rings.end());
00509         }
00510         for ( Ring::const_iterator outerRingDetId = ring3->begin(); 
00511               outerRingDetId != ring3->upper_bound(upperPhiRangeBorder);
00512               ++outerRingDetId) {
00513           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00514           ring3RecHits.insert(ring3RecHits.end(),
00515                               rings.begin(),
00516                               rings.end());
00517         }
00518         for ( Ring::const_iterator outerRingDetId = ring2->lower_bound(lowerPhiRangeBorder); 
00519               outerRingDetId != ring2->end();
00520               ++outerRingDetId) {
00521           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00522           ring2RecHits.insert(ring2RecHits.end(),
00523                               rings.begin(),
00524                               rings.end());
00525         }
00526         for ( Ring::const_iterator outerRingDetId = ring3->lower_bound(lowerPhiRangeBorder); 
00527               outerRingDetId != ring3->end();
00528               ++outerRingDetId) {
00529           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00530           ring3RecHits.insert(ring3RecHits.end(),
00531                               rings.begin(),
00532                               rings.end());
00533         }
00534       }
00535 
00536       if ( ring2RecHits.size() > 0 &&
00537            ring3RecHits.size() > 0 ) {
00538         calculateCircleSeedsFromHits(circleSeeds, seed, set, ring1GlobalPoint, *ring1RecHit, ring2RecHits, ring3RecHits);
00539       }
00540 
00541     }
00542   }
00543 
00544   return result;
00545 
00546 }
00547                                                                        
00548 bool RoadSearchSeedFinderAlgorithm::calculateCircleSeedsFromRingsOneInnerOneOuter(std::vector<RoadSearchCircleSeed> &circleSeeds,
00549                                                                                   const Roads::RoadSeed *seed,
00550                                                                                   const Roads::RoadSet *set,
00551                                                                                   const Ring* ring1,
00552                                                                                   const Ring* ring2) {
00553   //
00554   // calculate RoadSearchCircleSeed
00555   //
00556   // apply circle seed cuts
00557   //
00558 
00559   // return value
00560   bool result = true;
00561 
00562   // loop over detid's in first rings
00563   for ( Ring::const_iterator ring1DetIdIterator = ring1->begin(); 
00564         ring1DetIdIterator != ring1->end(); 
00565         ++ring1DetIdIterator ) {
00566 
00567     DetId ring1DetId = ring1DetIdIterator->second;
00568     std::vector<TrackingRecHit*> ring1RecHits = innerSeedHitVector_.getHitVector(&ring1DetId);
00569 
00570     // loop over inner rechits
00571     for (std::vector<TrackingRecHit*>::const_iterator ring1RecHit = ring1RecHits.begin();
00572          ring1RecHit != ring1RecHits.end(); 
00573          ++ring1RecHit) {
00574             
00575       GlobalPoint ring1GlobalPoint = tracker_->idToDet((*ring1RecHit)->geographicalId())->surface().toGlobal((*ring1RecHit)->localPosition());
00576 
00577       // calculate phi range around inner hit
00578       double innerphi = ring1GlobalPoint.phi();
00579       double upperPhiRangeBorder = innerphi + phiRangeDetIdLookup_;
00580       double lowerPhiRangeBorder = innerphi - phiRangeDetIdLookup_;
00581       if (upperPhiRangeBorder>Geom::pi()) upperPhiRangeBorder -= Geom::twoPi();
00582       if (lowerPhiRangeBorder<(-Geom::pi())) lowerPhiRangeBorder += Geom::twoPi();
00583 
00584       // retrieve vectors of TrackingRecHits in ring2 in phi range
00585       std::vector<TrackingRecHit*> ring2RecHits;
00586 
00587       if (lowerPhiRangeBorder <= upperPhiRangeBorder ) {
00588         for ( Ring::const_iterator outerRingDetId = ring2->lower_bound(lowerPhiRangeBorder); 
00589               outerRingDetId != ring2->upper_bound(upperPhiRangeBorder);
00590               ++outerRingDetId) {
00591           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00592           ring2RecHits.insert(ring2RecHits.end(),
00593                               rings.begin(),
00594                               rings.end());
00595         }
00596       } else {
00597         for ( Ring::const_iterator outerRingDetId = ring2->begin(); 
00598               outerRingDetId != ring2->upper_bound(upperPhiRangeBorder);
00599               ++outerRingDetId) {
00600           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00601           ring2RecHits.insert(ring2RecHits.end(),
00602                               rings.begin(),
00603                               rings.end());
00604         }
00605         for ( Ring::const_iterator outerRingDetId = ring2->lower_bound(lowerPhiRangeBorder); 
00606               outerRingDetId != ring2->end();
00607               ++outerRingDetId) {
00608           std::vector<TrackingRecHit*> rings = outerSeedHitVector_.getHitVector(&(outerRingDetId->second));
00609           ring2RecHits.insert(ring2RecHits.end(),
00610                               rings.begin(),
00611                               rings.end());
00612         }
00613       }
00614 
00615       if ( ring2RecHits.size() > 0 ) {
00616         calculateCircleSeedsFromHits(circleSeeds, seed, set, ring1GlobalPoint, *ring1RecHit, ring2RecHits);
00617       }
00618 
00619     }
00620   }
00621 
00622   return result;
00623 
00624 }
00625 
00626 bool RoadSearchSeedFinderAlgorithm::calculateCircleSeedsFromHits(std::vector<RoadSearchCircleSeed> &circleSeeds,
00627                                                                  const Roads::RoadSeed *seed,
00628                                                                  const Roads::RoadSet *set,
00629                                                                  GlobalPoint ring1GlobalPoint,
00630                                                                  TrackingRecHit *ring1RecHit,
00631                                                                  std::vector<TrackingRecHit*> ring2RecHits,
00632                                                                  std::vector<TrackingRecHit*> ring3RecHits) {
00633   //
00634   // calculate RoadSearchCircleSeed
00635   //
00636   // apply circle seed cuts
00637   //
00638 
00639   // return value
00640   bool result = true;
00641 
00642   for ( std::vector<TrackingRecHit*>::iterator ring2RecHit = ring2RecHits.begin();
00643         ring2RecHit != ring2RecHits.end();
00644         ++ring2RecHit) {
00645     GlobalPoint ring2GlobalPoint = tracker_->idToDet((*ring2RecHit)->geographicalId())->surface().toGlobal((*ring2RecHit)->localPosition());
00646     for ( std::vector<TrackingRecHit*>::iterator ring3RecHit = ring3RecHits.begin();
00647           ring3RecHit != ring3RecHits.end();
00648           ++ring3RecHit) {
00649       GlobalPoint ring3GlobalPoint = tracker_->idToDet((*ring3RecHit)->geographicalId())->surface().toGlobal((*ring3RecHit)->localPosition());
00650 
00651       RoadSearchCircleSeed circle(ring1RecHit,
00652                                   *ring2RecHit,
00653                                   *ring3RecHit,
00654                                   ring1GlobalPoint,
00655                                   ring2GlobalPoint,
00656                                   ring3GlobalPoint);
00657             
00658       bool addCircle = false;
00659       if ( circle.Type() == RoadSearchCircleSeed::straightLine ) {
00660         addCircle = true;
00661       } else {
00662         if ( (circle.Radius() > minRadius_) &&
00663              ((circle.InBarrel() &&
00664                circle.ImpactParameter() < maxBarrelImpactParameter_) ||
00665               (!circle.InBarrel() &&
00666                circle.ImpactParameter() < maxEndcapImpactParameter_)) ) {
00667           addCircle = true;
00668         
00669           // check if circle compatible with previous circles, if not, add
00670           for (std::vector<RoadSearchCircleSeed>::iterator alreadyContainedCircle = circleSeeds.begin(),
00671                  alreadyContainedCircleEnd = circleSeeds.end();
00672                alreadyContainedCircle != alreadyContainedCircleEnd;
00673                ++alreadyContainedCircle ) {
00674             if ( circle.Compare(&*alreadyContainedCircle,
00675                                 mergeSeedsCenterCut_,
00676                                 mergeSeedsRadiusCut_,
00677                                 mergeSeedsDifferentHitsCut_) ) {
00678               addCircle = false;
00679               break;
00680             }
00681           }
00682         }
00683       }
00684       
00685       if ( addCircle ) {
00686         circle.setSeed(seed);
00687         circle.setSet(set);
00688         circleSeeds.push_back(circle);
00689       }
00690     }
00691   }
00692 
00693   return result;
00694 }
00695 
00696 bool RoadSearchSeedFinderAlgorithm::calculateCircleSeedsFromHits(std::vector<RoadSearchCircleSeed> &circleSeeds,
00697                                                                  const Roads::RoadSeed *seed,
00698                                                                  const Roads::RoadSet *set,
00699                                                                  GlobalPoint ring1GlobalPoint,
00700                                                                  TrackingRecHit *ring1RecHit,
00701                                                                  std::vector<TrackingRecHit*> ring2RecHits) {
00702   //
00703   // calculate RoadSearchCircleSeed from two hits, calculate straight line
00704   //
00705   //
00706 
00707   // return value
00708   bool result = true;
00709 
00710   for ( std::vector<TrackingRecHit*>::iterator ring2RecHit = ring2RecHits.begin();
00711         ring2RecHit != ring2RecHits.end();
00712         ++ring2RecHit) {
00713     GlobalPoint ring2GlobalPoint = tracker_->idToDet((*ring2RecHit)->geographicalId())->surface().toGlobal((*ring2RecHit)->localPosition());
00714 
00715     RoadSearchCircleSeed circle(ring1RecHit,
00716                                 *ring2RecHit,
00717                                 ring1GlobalPoint,
00718                                 ring2GlobalPoint);
00719     circle.setSeed(seed);
00720     circle.setSet(set);
00721     circleSeeds.push_back(circle);
00722   }
00723 
00724   return result;
00725 }
00726 
00727 bool RoadSearchSeedFinderAlgorithm::ringsOnSameLayer(const Ring *ring1, const Ring* ring2) {
00728   //
00729   // check whether two input rings are on the same layer
00730   //
00731 
00732   // return value
00733   bool result = false;
00734 
00735   // get first DetId of ring
00736   const DetId ring1DetId = ring1->getFirst();
00737   const DetId ring2DetId = ring2->getFirst();
00738 
00739   result = detIdsOnSameLayer(ring1DetId,ring2DetId);
00740   
00741   return result;
00742 }
00743 
00744 bool RoadSearchSeedFinderAlgorithm::detIdsOnSameLayer(DetId id1, DetId id2) {
00745   //
00746   // check whether two detids are on the same layer
00747   //
00748 
00749   // return value
00750   bool result = false;
00751 
00752   // check if both rings belong to same subdetector
00753   if ( (unsigned int)id1.subdetId() == StripSubdetector::TIB && 
00754        (unsigned int)id2.subdetId() == StripSubdetector::TIB ) {
00755     // make TIBDetId instance
00756     TIBDetId id1TIB(id1.rawId());
00757     TIBDetId id2TIB(id2.rawId());
00758     // check whether both rings are on the same TIB layer
00759     if ( id1TIB.layer() == id2TIB.layer() ) {
00760       result = true;
00761     }
00762   } else if ( (unsigned int)id1.subdetId() == StripSubdetector::TOB &&
00763               (unsigned int)id2.subdetId() == StripSubdetector::TOB ) {
00764     // make TOBDetId instance
00765     TOBDetId id1TOB(id1.rawId());
00766     TOBDetId id2TOB(id2.rawId());
00767     // check whether both rings are on the same TOB layer
00768     if ( id1TOB.layer() == id2TOB.layer() ) {
00769       result = true;
00770     }
00771   } else if ( (unsigned int)id1.subdetId() == StripSubdetector::TID && 
00772               (unsigned int)id2.subdetId() == StripSubdetector::TID) {
00773     // make TIDDetId instance
00774     TIDDetId id1TID(id1.rawId());
00775     TIDDetId id2TID(id2.rawId());
00776     // check whether both rings are on the same TID wheel
00777     if ( id1TID.wheel() == id2TID.wheel() ) {
00778       result = true;
00779     }
00780   } else if ( (unsigned int)id1.subdetId() == StripSubdetector::TEC &&
00781               (unsigned int)id2.subdetId() == StripSubdetector::TEC ) {
00782     // make TECDetId instance
00783     TECDetId id1TEC(id1.rawId());
00784     TECDetId id2TEC(id2.rawId());
00785     // check whether both rings are on the same TEC wheel
00786     if ( id1TEC.wheel() == id2TEC.wheel() ) {
00787       result = true;
00788     }
00789   } else if ( (unsigned int)id1.subdetId() == PixelSubdetector::PixelBarrel && 
00790               (unsigned int)id2.subdetId() == PixelSubdetector::PixelBarrel) {
00791     // make PXBDetId instance
00792     PXBDetId id1PXB(id1.rawId());
00793     PXBDetId id2PXB(id2.rawId());
00794     // check whether both rings are on the same PXB layer
00795     if ( id1PXB.layer() == id2PXB.layer() ) {
00796       result = true;
00797     }
00798   } else if ( (unsigned int)id1.subdetId() == PixelSubdetector::PixelEndcap &&
00799               (unsigned int)id2.subdetId() == PixelSubdetector::PixelEndcap) {
00800     // make PXFDetId instance
00801     PXFDetId id1PXF(id1.rawId());
00802     PXFDetId id2PXF(id2.rawId());
00803     // check whether both rings are on the same PXF disk
00804     if ( id1PXF.disk() == id2PXF.disk() ) {
00805       result = true;
00806     }
00807   }
00808   
00809   return result;
00810 }
00811 
00812 
00813 unsigned int RoadSearchSeedFinderAlgorithm::ClusterCounter(const edmNew::DetSetVector<SiStripCluster>* clusters) {
00814 
00815   const edmNew::DetSetVector<SiStripCluster>& input = *clusters;
00816 
00817   unsigned int totalClusters = 0;
00818 
00819   //loop over detectors
00820   for (edmNew::DetSetVector<SiStripCluster>::const_iterator DSViter=input.begin(); DSViter!=input.end();DSViter++ ) {
00821     totalClusters+=DSViter->size();
00822   }
00823 
00824   return totalClusters;
00825 }