CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/RecoTracker/RoadSearchCloudMaker/src/RoadSearchCloudMakerAlgorithm.cc

Go to the documentation of this file.
00001 //
00002 // Package:         RecoTracker/RoadSearchCloudMaker
00003 // Class:           RoadSearchCloudMakerAlgorithm
00004 // 
00005 // Description:     
00006 //                  Road categories determined by outer Seed RecHit
00007 //                      RPhi: outer Seed RecHit in the Barrel
00008 //                      ZPhi: outer Seed RecHit in the Disks
00009 //                  use inner and outer Seed RecHit and BeamSpot to calculate extrapolation
00010 //                      RPhi: phi = phi0 + asin(k r)
00011 //                      ZPhi: phi = phi0 + C z
00012 //                  Loop over RoadSet, access Rings of Road
00013 //                      get average radius of Ring
00014 //                      use extrapolation to calculate phi_ref at average Ring radius
00015 //                      determine window in phi for DetId lookup in the Ring
00016 //                              phi_ref ± phi_window
00017 //                                      PARAMETER: phi_window = pi/24
00018 //                      loop over DetId's in phi window in Ring
00019 //                              two cases (problem of phi = 0/2pi):
00020 //                                      lower window border < upper window border
00021 //                                      upper window border < lower window border
00022 //                  Loop over RecHits of DetId
00023 //                      check compatibility of RecHit with extrapolation (delta phi cut)
00024 //                      single layer sensor treatment
00025 //                              RPhi:
00026 //                                      stereo and barrel single layer sensor
00027 //                                              calculate delta-phi
00028 //                                      disk single layer sensor (r coordinate not well defined)
00029 //                                              calculate delta phi between global positions of maximal strip extension and reference
00030 //                              ZPhi:
00031 //                                      stereo sensor
00032 //                                              calculate delta-phi
00033 //                                      barrel single layer sensor (z coordinate not well defined)
00034 //                                              calculate delta phi between global positions of maximal strip extension and reference
00035 //                                      disk single layer sensor (tilted strips relative to local coordinate system of sensor
00036 //                                              calculate delta phi between global positions of maximal strip extension and reference
00037 //                  Check delta phi cut
00038 //                      cut value can be calculated based on extrapolation and Seed (pT dependent delta phi cut)
00039 //                      currently: constant delta phi cut (PARAMETER)
00040 //                              fill RecHit into Cloud
00041 //                                      do not fill more than 32 RecHits per DetID into cloud (PARAMETER)
00042 //                  first stage of Cloud cleaning cuts:
00043 //                      number of layers with hits in cloud (PARAMETER)
00044 //                      number of layers with no hits in cloud (PARAMETER)
00045 //                      number of consecutive layers with no hits in cloud (PARAMETER)
00046 //
00047 // Original Author: Oliver Gutsche, gutsche@fnal.gov
00048 // Created:         Sat Jan 14 22:00:00 UTC 2006
00049 //
00050 // $Author: innocent $
00051 // $Date: 2012/01/17 15:41:12 $
00052 // $Revision: 1.59 $
00053 //
00054 
00055 #include <vector>
00056 #include <iostream>
00057 #include <cmath>
00058 
00059 #include "RecoTracker/RoadSearchCloudMaker/interface/RoadSearchCloudMakerAlgorithm.h"
00060 
00061 #include "FWCore/ServiceRegistry/interface/Service.h"
00062 
00063 #include "DataFormats/Common/interface/Handle.h"
00064 #include "FWCore/Framework/interface/ESHandle.h"
00065 #include "FWCore/Framework/interface/EventSetup.h"
00066 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00067 
00068 #include "DataFormats/Common/interface/Ref.h"
00069 #include "DataFormats/RoadSearchSeed/interface/RoadSearchSeedCollection.h"
00070 #include "DataFormats/RoadSearchCloud/interface/RoadSearchCloud.h"
00071 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2D.h"
00072 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00073 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00074 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00075 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00076 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00077 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00078 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00079 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00080 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00081 
00082 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00083 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00084 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00085 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
00086 #include "Geometry/CommonTopologies/interface/TrapezoidalStripTopology.h"
00087 #include "Geometry/CommonTopologies/interface/RectangularStripTopology.h"
00088 
00089 #include "DataFormats/SiPixelDigi/interface/PixelDigi.h"
00090 #include "Geometry/CommonTopologies/interface/PixelTopology.h"
00091 
00092 #include "TrackingTools/RoadSearchHitAccess/interface/RoadSearchDetIdHelper.h"
00093 
00094 #include "RecoTracker/RoadMapRecord/interface/RoadMapRecord.h"
00095 
00096 #include "RecoLocalTracker/SiStripRecHitConverter/interface/SiStripRecHitMatcher.h"
00097 #include "Geometry/TrackerGeometryBuilder/interface/GluedGeomDet.h"
00098 
00099 using namespace std;
00100 
00101 double RoadSearchCloudMakerAlgorithm::epsilon      =   0.000000001;
00102 
00103 RoadSearchCloudMakerAlgorithm::RoadSearchCloudMakerAlgorithm(const edm::ParameterSet& conf) : conf_(conf) { 
00104   recHitVectorClass.setMode(DetHitAccess::standard);    
00105   recHitVectorClass.use_rphiRecHits(conf_.getParameter<bool>("UseRphiRecHits"));
00106   recHitVectorClass.use_stereoRecHits(conf_.getParameter<bool>("UseStereoRecHits"));
00107   
00108   
00109   theRPhiRoadSize =  conf_.getParameter<double>("RPhiRoadSize");
00110   theZPhiRoadSize =  conf_.getParameter<double>("ZPhiRoadSize");
00111   UsePixels = conf_.getParameter<bool>("UsePixelsinRS");
00112   NoFieldCosmic = conf_.getParameter<bool>("StraightLineNoBeamSpotCloud");
00113   theMinimumHalfRoad = conf_.getParameter<double>("MinimumHalfRoad");
00114   
00115   maxDetHitsInCloudPerDetId = conf_.getParameter<unsigned int>("MaxDetHitsInCloudPerDetId");
00116   minFractionOfUsedLayersPerCloud = conf_.getParameter<double>("MinimalFractionOfUsedLayersPerCloud");
00117   maxFractionOfMissedLayersPerCloud = conf_.getParameter<double>("MaximalFractionOfMissedLayersPerCloud");
00118   maxFractionOfConsecutiveMissedLayersPerCloud = conf_.getParameter<double>("MaximalFractionOfConsecutiveMissedLayersPerCloud");
00119   increaseMaxNumberOfConsecutiveMissedLayersPerCloud = conf_.getParameter<unsigned int>("IncreaseMaxNumberOfConsecutiveMissedLayersPerCloud");
00120   increaseMaxNumberOfMissedLayersPerCloud = conf_.getParameter<unsigned int>("IncreaseMaxNumberOfMissedLayersPerCloud");
00121   
00122   doCleaning_ = conf.getParameter<bool>("DoCloudCleaning");
00123   mergingFraction_ = conf.getParameter<double>("MergingFraction");
00124   maxRecHitsInCloud_ = (unsigned int)conf.getParameter<int>("MaxRecHitsInCloud");
00125   scalefactorRoadSeedWindow_ = conf.getParameter<double>("scalefactorRoadSeedWindow");
00126   
00127   roadsLabel_ = conf.getParameter<std::string>("RoadsLabel");
00128 
00129 }
00130 
00131 RoadSearchCloudMakerAlgorithm::~RoadSearchCloudMakerAlgorithm() {
00132 
00133 }
00134 
00135 double RoadSearchCloudMakerAlgorithm::map_phi(double phi) {
00136   // map phi to [0,2pi]
00137   double result = phi;
00138   if ( result < -1.0*Geom::twoPi()) result = result + Geom::twoPi();
00139   if ( result < 0)                 result = Geom::twoPi() + result;
00140   if ( result > Geom::twoPi())     result = result - Geom::twoPi();
00141   return result;
00142 }
00143 
00144 double RoadSearchCloudMakerAlgorithm::map_phi2(double phi) {
00145   // map phi to [-pi,pi]
00146   double result = phi;
00147   if ( result < 1.0*Geom::pi() ) result = result + Geom::twoPi();
00148   if ( result >= Geom::pi())  result = result - Geom::twoPi();
00149   return result;
00150 }
00151 
00152 void RoadSearchCloudMakerAlgorithm::run(edm::Handle<RoadSearchSeedCollection> input,
00153                                         const SiStripRecHit2DCollection* rphiRecHits,
00154                                         const SiStripRecHit2DCollection* stereoRecHits,
00155                                         const SiStripMatchedRecHit2DCollection* matchedRecHits,
00156                                         const SiPixelRecHitCollection *pixRecHits,
00157                                         const edm::EventSetup& es,
00158                                         RoadSearchCloudCollection &output)
00159 {  
00160   // intermediate arrays for storing clouds for cleaning
00161   const int nphibin = 24;
00162   const int netabin = 24;
00163   RoadSearchCloudCollection CloudArray[nphibin][netabin];
00164   
00165   // get roads
00166   edm::ESHandle<Roads> roads;
00167   es.get<RoadMapRecord>().get(roadsLabel_, roads);
00168   
00169   // get RoadSearchSeed collection
00170   const RoadSearchSeedCollection* inputSeeds = input.product();
00171   
00172   // set collections for general hit access method
00173   recHitVectorClass.setCollections(rphiRecHits,stereoRecHits,matchedRecHits,pixRecHits);
00174   recHitVectorClass.setMode(DetHitAccess::standard);
00175   
00176   // get tracker geometry
00177   edm::ESHandle<TrackerGeometry> tracker;
00178   es.get<TrackerDigiGeometryRecord>().get(tracker);
00179   
00180   // get hit matcher
00181   SiStripRecHitMatcher* theHitMatcher = new SiStripRecHitMatcher(3.0);
00182 
00183   edm::LogInfo("RoadSearch") << "Found " << inputSeeds->size() << " input seeds.";   
00184   // loop over seeds
00185   for ( RoadSearchSeedCollection::const_iterator seed = inputSeeds->begin(); seed != inputSeeds->end(); ++seed) {
00186     
00187     const Roads::RoadSeed *roadSeed = seed->getSeed();
00188       
00189     if ( roadSeed == 0 ) {
00190       edm::LogWarning("RoadSearch") << "RoadSeed could not be resolved from RoadSearchSeed hits, discard seed!";
00191     } else {
00192         
00193       Roads::type roadType = roads->getRoadType(roadSeed);
00194       if (NoFieldCosmic) roadType = Roads::RPhi;
00195         
00196       // fixme: from here on, calculate with 1st and 3rd seed hit (inner and outer of initial circle)
00197       // fixme: adapt to new seed structure
00198         
00199       // get global positions of the hits, calculate before Road lookup to be used
00200       const TrackingRecHit* innerSeedRingHit = (*(seed->begin()));
00201       const TrackingRecHit* outerSeedRingHit = (*(seed->end() - 1));
00202         
00203       GlobalPoint innerSeedHitGlobalPosition = tracker->idToDet(innerSeedRingHit->geographicalId())->surface().toGlobal(innerSeedRingHit->localPosition());
00204       GlobalPoint outerSeedHitGlobalPosition = tracker->idToDet(outerSeedRingHit->geographicalId())->surface().toGlobal(outerSeedRingHit->localPosition());
00205  
00206       LogDebug("RoadSearch") << "Seed # " <<seed-inputSeeds->begin() << " inner hit (x/y/z): "
00207                              << innerSeedHitGlobalPosition.x() << " / "
00208                              << innerSeedHitGlobalPosition.y() << " / "
00209                              << innerSeedHitGlobalPosition.z();
00210       LogDebug("RoadSearch") << "Seed # " <<seed-inputSeeds->begin() << " outer hit (x/y/z): "
00211                              << outerSeedHitGlobalPosition.x() << " / "
00212                              << outerSeedHitGlobalPosition.y() << " / "
00213                              << outerSeedHitGlobalPosition.z();
00214       
00215       LogDebug("RoadSearch") << "Seed # " <<seed-inputSeeds->begin() << " inner hit (r/phi): "
00216                              << innerSeedHitGlobalPosition.perp() << " / "
00217                              << innerSeedHitGlobalPosition.phi();
00218       LogDebug("RoadSearch") << "Seed # " <<seed-inputSeeds->begin() << " outer hit (r/phi): "
00219                              << outerSeedHitGlobalPosition.perp() << " / "
00220                              << outerSeedHitGlobalPosition.phi();
00221 
00222 
00223       // extrapolation parameters, phio: [0,2pi]
00224       double d0 = 0.0;
00225       double phi0 = -99.;
00226       double k0   = -99999999.99;
00227       
00228       double phi1 = -99.;
00229       double k1   = -99999999.99;
00230       // get bins of eta and phi of outer seed hit;
00231       
00232       double outer_phi = map_phi(outerSeedHitGlobalPosition.phi());
00233       double outer_eta = outerSeedHitGlobalPosition.eta();
00234       
00235       int phibin = (int)(nphibin*(outer_phi/(2*Geom::pi())));
00236       int etabin = (int)(netabin*(outer_eta+3.0)/6.0);
00237         
00238       // calculate phi0 and k0 dependent on RoadType
00239       if ( roadType == Roads::RPhi ) {
00240         double dr = outerSeedHitGlobalPosition.perp() - innerSeedHitGlobalPosition.perp();
00241         const double dr_min = 1; // cm
00242         if ( dr < dr_min ) {
00243           edm::LogWarning("RoadSearch") << "RPhi road: seed Hits distance smaller than 1 cm, do not consider this seed.";
00244         } else {
00245           // calculate r-phi extrapolation: phi = phi0 + asin(k0 r)
00246           double det = innerSeedHitGlobalPosition.x() * outerSeedHitGlobalPosition.y() - innerSeedHitGlobalPosition.y() * outerSeedHitGlobalPosition.x();
00247           if ( det == 0 ) {
00248             edm::LogWarning("RoadSearch") << "RPhi road: 'det' == 0, do not consider this seed.";
00249           } else {
00250             double x0=0.0; double y0=0.0;
00251             double innerx=innerSeedHitGlobalPosition.x();
00252             double innery=innerSeedHitGlobalPosition.y();
00253             double outerx=outerSeedHitGlobalPosition.x();
00254             double outery=outerSeedHitGlobalPosition.y();
00255 
00256             if (NoFieldCosmic){
00257               phi0=atan2(outery-innery,outerx-innerx);
00258               double alpha=atan2(innery,innerx);
00259               double d1=sqrt(innerx*innerx+innery*innery);
00260               d0=d1*sin(alpha-phi0); x0=-d0*sin(phi0); y0=d0*cos(phi0); k0=0.0;
00261             }else{
00262               makecircle(innerx,innery,outerx,outery,x0,y0);
00263               phi0 = phi0h;
00264               k0 = omegah;
00265             }              
00266             LogDebug("RoadSearch") << "Seed # " <<seed-inputSeeds->begin() << " trajectory parameters: d0 = "<< d0 << " phi0 = " << phi0;
00267           }
00268         }
00269       } else {
00270         double dz = outerSeedHitGlobalPosition.z() - innerSeedHitGlobalPosition.z();
00271         const double dz_min = 1.e-6; // cm;
00272         if ( std::abs(dz) < dz_min ) {
00273           edm::LogWarning("RoadSearch") << "ZPhi road: seed Hits are less than .01 microns away in z, do not consider this seed.";
00274         } else {
00275           // calculate z-phi extrapolation: phi = phi0 + k0 z
00276           k0 = map_phi2(outerSeedHitGlobalPosition.phi() - innerSeedHitGlobalPosition.phi()) / dz;
00277           phi0 =  map_phi(innerSeedHitGlobalPosition.phi() - k0 * innerSeedHitGlobalPosition.z());
00278           
00279           // get approx pt for use in correcting matched hits
00280           makecircle(innerSeedHitGlobalPosition.x(),innerSeedHitGlobalPosition.y(),
00281                      outerSeedHitGlobalPosition.x(),outerSeedHitGlobalPosition.y(),
00282                      0.0,0.0); // x0,y0 = 0.0 for now
00283           phi1 = phi0h;
00284           k1 = omegah;
00285         }
00286       }
00287         
00288       // continue if valid extrapolation parameters have been found
00289       if ( (phi0 != -99.) && (k0 != -99999999.99) ) {
00290         const Roads::RoadSet *roadSet = seed->getSet();
00291 
00292         // create cloud
00293         RoadSearchCloud cloud;
00294           
00295         bool firstHitFound = false;
00296         unsigned int layerCounter = 0;
00297         unsigned int usedLayers = 0;
00298         unsigned int missedLayers = 0;
00299         unsigned int consecutiveMissedLayers = 0;
00300 
00301         unsigned int totalLayers = roadSet->size();
00302 
00303         // caluclate minNumberOfUsedLayersPerCloud, maxNumberOfMissedLayersPerCloud and maxNumberOfConsecutiveMissedLayersPerCloud 
00304         // by rounding to integer minFractionOfUsedLayersPerCloud. maxFractionOfMissedLayersPerCloud and maxFractionOfConsecutiveMissedLayersPerCloud
00305         unsigned int minNumberOfUsedLayersPerCloud = static_cast<unsigned int>(totalLayers * minFractionOfUsedLayersPerCloud + 0.5);
00306         if (minNumberOfUsedLayersPerCloud < 3) minNumberOfUsedLayersPerCloud = 3;
00307         unsigned int maxNumberOfMissedLayersPerCloud = static_cast<unsigned int>(totalLayers * maxFractionOfMissedLayersPerCloud + 0.5);
00308         unsigned int maxNumberOfConsecutiveMissedLayersPerCloud = static_cast<unsigned int>(totalLayers * maxFractionOfConsecutiveMissedLayersPerCloud + 0.5);
00309 
00310         // increase consecutive layer cuts between 0.9 and 1.5
00311         if (std::abs(outer_eta) > 0.9 && std::abs(outer_eta) < 1.5) {
00312           maxNumberOfConsecutiveMissedLayersPerCloud += increaseMaxNumberOfConsecutiveMissedLayersPerCloud;
00313           maxNumberOfMissedLayersPerCloud += increaseMaxNumberOfMissedLayersPerCloud;
00314         }
00315           
00316         for ( Roads::RoadSet::const_iterator roadSetVector = roadSet->begin();
00317               roadSetVector != roadSet->end();
00318               ++roadSetVector ) {
00319             
00320           ++layerCounter;
00321           unsigned int usedHitsInThisLayer = 0;
00322           bool intersectsLayer = false;
00323             
00324           for ( std::vector<const Ring*>::const_iterator ring = roadSetVector->begin(); ring != roadSetVector->end(); ++ring ) {
00325               
00326             // calculate phi-range for lookup of DetId's in Rings of RoadSet
00327             // calculate phi at radius of Ring using extrapolation, Ring radius average of Ring.rmin() and Ring.rmax()
00328             double ringRadius = (*ring)->getrmin() + ((*ring)->getrmax()-(*ring)->getrmin())/2;
00329             double ringZ      = (*ring)->getzmin() + ((*ring)->getzmax()-(*ring)->getzmin())/2;
00330             double ringPhi = 0.0;
00331             if ( roadType == Roads::RPhi ) {
00332               ringPhi = phiFromExtrapolation(d0,phi0,k0,ringRadius,roadType);
00333             } else {
00334               ringPhi = phiFromExtrapolation(d0,phi0,k0,ringZ,roadType);
00335             }
00336             if (ringPhi == -99) continue;
00337             intersectsLayer = true;
00338 
00339             LogDebug("RoadSearch") << "Seed # " <<seed-inputSeeds->begin() << " testing ring at R = " << ringRadius
00340                                    << " Z = " << ringZ << " ringPhi = " << ringPhi;
00341               
00342             int nDetIds = (*ring)->getNumDetIds();
00343             double theHalfRoad = theMinimumHalfRoad*(2.0*Geom::pi())/((double)nDetIds);
00344             // calculate range in phi around ringPhi
00345             double upperPhiRangeBorder = map_phi2(ringPhi + theHalfRoad);
00346             double lowerPhiRangeBorder = map_phi2(ringPhi - theHalfRoad);
00347 
00348             if ( lowerPhiRangeBorder <= upperPhiRangeBorder ) {
00349                 
00350               for ( Ring::const_iterator detid = (*ring)->lower_bound(lowerPhiRangeBorder); detid != (*ring)->upper_bound(upperPhiRangeBorder); ++detid) {
00351                 usedHitsInThisLayer += FillRecHitsIntoCloudGeneral(detid->second,d0,phi0,k0,phi1,k1,roadType,ringPhi,
00352                                                                    tracker.product(),theHitMatcher,cloud);
00353               }
00354                 
00355             } else {
00356               for ( Ring::const_iterator detid = (*ring)->lower_bound(lowerPhiRangeBorder); detid != (*ring)->end(); ++detid) {
00357                 usedHitsInThisLayer += FillRecHitsIntoCloudGeneral(detid->second,d0,phi0,k0,phi1,k1,roadType,ringPhi,
00358                                                                    tracker.product(),theHitMatcher,cloud);
00359               }
00360                 
00361               for ( Ring::const_iterator detid = (*ring)->begin(); detid != (*ring)->upper_bound(upperPhiRangeBorder); ++detid) {
00362                 usedHitsInThisLayer += FillRecHitsIntoCloudGeneral(detid->second,d0,phi0,k0,phi1,k1,roadType,ringPhi,
00363                                                                    tracker.product(),theHitMatcher,cloud);
00364               }
00365             }
00366           LogDebug("RoadSearch") << "Seed # " <<seed-inputSeeds->begin() << " now has " << usedHitsInThisLayer << "  hits in ring at R = " << ringRadius
00367                                  << " Z = " << ringZ << " ringPhi = " << ringPhi;
00368           }
00369             
00370           if ( !firstHitFound ) {
00371             if ( usedHitsInThisLayer > 0 ) {
00372 
00373               firstHitFound = true;
00374 
00375               // reset totalLayers according to first layer with hit
00376               totalLayers = roadSet->size() - layerCounter + 1;
00377 
00378               // re-caluclate minNumberOfUsedLayersPerCloud, maxNumberOfMissedLayersPerCloud and maxNumberOfConsecutiveMissedLayersPerCloud 
00379               // by rounding to integer minFractionOfUsedLayersPerCloud. maxFractionOfMissedLayersPerCloud and maxFractionOfConsecutiveMissedLayersPerCloud
00380               minNumberOfUsedLayersPerCloud = static_cast<unsigned int>(totalLayers * minFractionOfUsedLayersPerCloud + 0.5);
00381               if (minNumberOfUsedLayersPerCloud < 3) minNumberOfUsedLayersPerCloud = 3;
00382               maxNumberOfMissedLayersPerCloud = static_cast<unsigned int>(totalLayers * maxFractionOfMissedLayersPerCloud + 0.5);
00383               maxNumberOfConsecutiveMissedLayersPerCloud = static_cast<unsigned int>(totalLayers * maxFractionOfConsecutiveMissedLayersPerCloud + 0.5);
00384 
00385               // increase consecutive layer cuts between 0.9 and 1.5
00386               if (std::abs(outer_eta) > 0.9 && std::abs(outer_eta) < 1.5) {
00387                 maxNumberOfConsecutiveMissedLayersPerCloud += increaseMaxNumberOfConsecutiveMissedLayersPerCloud;
00388                 maxNumberOfMissedLayersPerCloud += increaseMaxNumberOfMissedLayersPerCloud;
00389               }
00390 
00391               ++usedLayers;
00392               consecutiveMissedLayers = 0;
00393 
00394             }
00395           } else {
00396             if (intersectsLayer){
00397               if ( usedHitsInThisLayer > 0 ) {
00398                 ++usedLayers;
00399                 consecutiveMissedLayers = 0;
00400               } else {
00401                 ++ missedLayers;
00402                 ++consecutiveMissedLayers;
00403               }
00404             }
00405             LogDebug("RoadSearch") << "Seed # "<<seed-inputSeeds->begin() << " Layer info: " 
00406                                    << " totalLayers: " << totalLayers 
00407                                    << " usedLayers: " << usedLayers 
00408                                    << " missedLayers: " << missedLayers
00409                                    << " consecutiveMissedLayers: " << consecutiveMissedLayers;
00410 
00411             // break condition, hole larger than maxNumberOfConsecutiveMissedLayersPerCloud
00412             if ( consecutiveMissedLayers > maxNumberOfConsecutiveMissedLayersPerCloud ) {
00413               LogDebug("RoadSearch") << "BREAK: seed # "<<seed-inputSeeds->begin() 
00414                                      << " More than " << maxNumberOfConsecutiveMissedLayersPerCloud << " missed consecutive layers!";
00415               break;
00416             }
00417 
00418             // break condition, already  missed too many layers
00419             if ( missedLayers > maxNumberOfMissedLayersPerCloud ) {
00420               LogDebug("RoadSearch") << "BREAK: seed # "<<seed-inputSeeds->begin() 
00421                                      << " More than " << maxNumberOfMissedLayersPerCloud << " missed layers!";
00422               break;
00423             }
00424 
00425             // break condition, cannot satisfy minimal number of used layers
00426             if ( totalLayers-missedLayers < minNumberOfUsedLayersPerCloud ) {
00427               LogDebug("RoadSearch") << "BREAK: seed # "<<seed-inputSeeds->begin() 
00428                                      << " Cannot satisfy at least " << minNumberOfUsedLayersPerCloud << " used layers!";
00429               break;
00430             }
00431           }       
00432             
00433         }
00434 
00435         if ( consecutiveMissedLayers <= maxNumberOfConsecutiveMissedLayersPerCloud ) {
00436           if ( usedLayers >= minNumberOfUsedLayersPerCloud ) {
00437             if ( missedLayers <= maxNumberOfMissedLayersPerCloud ) {
00438 
00439               CloudArray[phibin][etabin].push_back(cloud);
00440 
00441               if ( roadType == Roads::RPhi ){ 
00442                 LogDebug("RoadSearch") << "This r-phi seed # "<<seed-inputSeeds->begin()
00443                                        <<" yields a cloud with " <<cloud.size() <<" hits on " << usedLayers << " layers out of " << totalLayers;
00444               } else {
00445                 LogDebug("RoadSearch") << "This z-phi seed # "<<seed-inputSeeds->begin()
00446                                        <<" yields a cloud with " <<cloud.size() <<" hits on " << usedLayers << " layers out of " << totalLayers;
00447               }
00448             } else {
00449               LogDebug("RoadSearch") << "Missed layers: " << missedLayers << " More than " << maxNumberOfMissedLayersPerCloud << " missed layers!";
00450               if ( roadType == Roads::RPhi ){ 
00451                 LogDebug("RoadSearch") << "This r-phi seed # "<<seed-inputSeeds->begin() <<" yields no clouds";
00452               } else {
00453                 LogDebug("RoadSearch") << "This z-phi seed # "<<seed-inputSeeds->begin() <<" yields no clouds";
00454               }
00455             }
00456           }
00457           else {
00458             LogDebug("RoadSearch") << "Seed # "<<seed-inputSeeds->begin() <<" fails: used layers = " << usedLayers << " < " << minNumberOfUsedLayersPerCloud;
00459           }
00460         }
00461         else {
00462           LogDebug("RoadSearch") << "Seed # "<<seed-inputSeeds->begin() <<" fails: consecutive missed layers = " << consecutiveMissedLayers << " > " << maxNumberOfConsecutiveMissedLayersPerCloud;
00463         }
00464       }
00465     }
00466   }
00467   
00468   // Loop for initial cleaning
00469   for (int iphi=0; iphi<nphibin; ++iphi){
00470     for (int ieta=0; ieta<netabin; ++ieta){
00471       if (!CloudArray[iphi][ieta].empty()) {
00472         if (doCleaning_){
00473           RoadSearchCloudCollection temp = Clean(&CloudArray[iphi][ieta]);
00474           for ( RoadSearchCloudCollection::const_iterator ic = temp.begin(); ic!=temp.end(); ++ic)
00475             output.push_back(*ic);
00476         }
00477         else 
00478           for ( RoadSearchCloudCollection::const_iterator ic = CloudArray[iphi][ieta].begin(); 
00479                 ic!=CloudArray[iphi][ieta].end(); ++ic)
00480             output.push_back(*ic);
00481       }
00482     }
00483   }
00484 
00485   delete theHitMatcher;
00486   edm::LogInfo("RoadSearch") << "Found " << output.size() << " clouds."; 
00487   for ( RoadSearchCloudCollection::const_iterator ic = output.begin(); ic!=output.end(); ++ic)
00488     edm::LogInfo("RoadSearch") << "    Cloud " << ic-output.begin()<< " has " << ic->size() << " hits."; 
00489   
00490 }
00491 
00492 unsigned int RoadSearchCloudMakerAlgorithm::FillRecHitsIntoCloudGeneral(DetId id, double d0, double phi0, double k0, double phi1, double k1, 
00493                                                                         Roads::type roadType, double ringPhi,
00494                                                                         const TrackerGeometry *tracker, const SiStripRecHitMatcher* theHitMatcher,
00495                                                                         RoadSearchCloud &cloud) {
00496   
00497   unsigned int usedRecHits = 0;
00498   
00499   bool double_ring_layer = !isSingleLayer(id);
00500   
00501   std::vector<TrackingRecHit*> recHitVector = recHitVectorClass.getHitVector(&id);
00502   
00503   for ( std::vector<TrackingRecHit*>::const_iterator recHitIterator = recHitVector.begin(); recHitIterator != recHitVector.end(); ++recHitIterator) {
00504     
00505     if (      (unsigned int)id.subdetId() == StripSubdetector::TIB 
00506               || (unsigned int)id.subdetId() == StripSubdetector::TOB 
00507               || (unsigned int)id.subdetId() == StripSubdetector::TID 
00508               || (unsigned int)id.subdetId() == StripSubdetector::TEC ) {
00509       
00510       const SiStripRecHit2D *recHit = (SiStripRecHit2D*)(*recHitIterator);
00511       DetId hitId = recHit->geographicalId();
00512 
00513       LogDebug("RoadSearch") << "    Testing hit at (x/y/z): " 
00514                              << tracker->idToDet(recHit->geographicalId())->surface().toGlobal(recHit->localPosition()).x() << " / " 
00515                              << tracker->idToDet(recHit->geographicalId())->surface().toGlobal(recHit->localPosition()).y() << " / " 
00516                              << tracker->idToDet(recHit->geographicalId())->surface().toGlobal(recHit->localPosition()).z();
00517 
00518       if ( roadType == Roads::RPhi ) {
00519         if (double_ring_layer && isSingleLayer(hitId)) {
00520           //
00521           //  This is where the barrel stereoRecHits end up for Roads::RPhi
00522           //
00523           
00524           // Adjust matched hit for track angle
00525 
00526           const GluedGeomDet *theGluedDet = dynamic_cast<const GluedGeomDet*>(tracker->idToDet(hitId));
00527 
00528           SiStripMatchedRecHit2D* theCorrectedHit = CorrectMatchedHit(*recHitIterator,theGluedDet,
00529                                                                         tracker, theHitMatcher,
00530                                                                         k0, phi0);
00531           if (theCorrectedHit != 0){
00532 
00533             GlobalPoint ghit = tracker->idToDet(theCorrectedHit->geographicalId())->surface().toGlobal(theCorrectedHit->localPosition());
00534             double hitRadius = sqrt(ghit.x()*ghit.x()+ghit.y()*ghit.y());
00535             double hitphi = map_phi(ghit.phi());
00536             double phi = phiFromExtrapolation(d0,phi0,k0,hitRadius,roadType);
00537             
00538             float dp = (hitphi-phi);
00539             float dx = hitRadius*tan(dp);
00540             
00541             LogDebug("RoadSearch") << "   Hit phi = " << hitphi << " expected phi = " << phi
00542                                        <<"  dx = " << dx << " for dxMax = " << phiMax(roadType,phi0,k0);
00543 
00544             // switch cut to dx instead of dphi
00545             if ( std::abs(dx) < phiMax(roadType,phi0,k0) ) {
00546               if ((usedRecHits < maxDetHitsInCloudPerDetId) && (cloud.size() < maxRecHitsInCloud_)) {
00547                 cloud.addHit(recHit);
00548                 ++usedRecHits;
00549               }
00550             }
00551             delete theCorrectedHit;
00552           }
00553         } else { // Single layer hits here
00554           if ( isBarrelSensor(hitId) ) {
00555             //
00556             //  This is where the barrel rphiRecHits end up for Roads::RPhi
00557             //
00558             GlobalPoint ghit = tracker->idToDet(recHit->geographicalId())->surface().toGlobal(recHit->localPosition());
00559             double hitRadius = sqrt(ghit.x()*ghit.x()+ghit.y()*ghit.y());
00560             double hitphi = map_phi(ghit.phi());
00561             double phi = phiFromExtrapolation(d0,phi0,k0,hitRadius,roadType);
00562               
00563             float dp = (hitphi-phi);
00564             float dx = hitRadius*tan(dp);
00565             LogDebug("RoadSearch") << "   Hit phi = " << hitphi << " expected phi = " << phi
00566                                        <<"  dx = " << dx << " for dxMax = " << phiMax(roadType,phi0,k0);
00567             // switch cut to dx instead of dphi
00568             if ( std::abs(dx) < phiMax(roadType,phi0,k0) ) {
00569               if ((usedRecHits < maxDetHitsInCloudPerDetId) && (cloud.size() < maxRecHitsInCloud_)) {
00570                 cloud.addHit(recHit);
00571                 ++usedRecHits;
00572               }
00573             }
00574           } 
00575           else {
00576 
00577             LocalPoint hit = recHit->localPosition();
00578             const StripTopology *topology = dynamic_cast<const StripTopology*>(&(tracker->idToDetUnit(hitId)->topology()));
00579             double stripAngle = topology->stripAngle(topology->strip(hit));
00580             double stripLength = topology->localStripLength(hit);
00581 
00582             LocalPoint innerHitLocal(hit.x()+stripLength/2*std::sin(stripAngle),hit.y()-stripLength/2*std::cos(stripAngle),0);
00583             LocalPoint outerHitLocal(hit.x()-stripLength/2*std::sin(stripAngle),hit.y()+stripLength/2*std::cos(stripAngle),0);
00584 
00585             double innerRadius = tracker->idToDetUnit(hitId)->surface().toGlobal(innerHitLocal).perp(); 
00586             double outerRadius = tracker->idToDetUnit(hitId)->surface().toGlobal(outerHitLocal).perp();
00587             double innerExtrapolatedPhi = phiFromExtrapolation(d0,phi0,k0,innerRadius,roadType);
00588             double outerExtrapolatedPhi = phiFromExtrapolation(d0,phi0,k0,outerRadius,roadType);
00589 
00590             GlobalPoint innerHitGlobal =tracker->idToDetUnit(hitId)->surface().toGlobal(innerHitLocal); 
00591             GlobalPoint outerHitGlobal =tracker->idToDetUnit(hitId)->surface().toGlobal(outerHitLocal); 
00592 
00593             GlobalPoint innerRoadGlobal(GlobalPoint::Cylindrical(innerRadius,innerExtrapolatedPhi,
00594                                                                  tracker->idToDetUnit(hitId)->surface().toGlobal(hit).z()));
00595             GlobalPoint outerRoadGlobal(GlobalPoint::Cylindrical(outerRadius,outerExtrapolatedPhi,
00596                                                                  tracker->idToDetUnit(hitId)->surface().toGlobal(hit).z()));
00597 
00598             LocalPoint innerRoadLocal = tracker->idToDetUnit(hitId)->surface().toLocal(innerRoadGlobal);
00599             LocalPoint outerRoadLocal = tracker->idToDetUnit(hitId)->surface().toLocal(outerRoadGlobal);
00600 
00601             double dxinter = CheckXYIntersection(innerHitLocal, outerHitLocal, 
00602                                                innerRoadLocal, outerRoadLocal);
00603 
00604             LogDebug("RoadSearch") << " Hit phi inner = " << innerHitGlobal.phi() << " and outer = " << outerHitGlobal.phi()
00605                                    << " expected inner phi = " << innerExtrapolatedPhi
00606                                    << " and outer phi = "      << outerExtrapolatedPhi
00607                                    <<"  dx = " << dxinter << " for dxMax = " << phiMax(roadType,phi0,k0);
00608 
00609             if ( fabs(dxinter) < phiMax(roadType,phi0,k0)) {
00610               //
00611               //  This is where the disk rphiRecHits end up for Roads::ZPhi
00612               //
00613               if ((usedRecHits < maxDetHitsInCloudPerDetId) && (cloud.size() < maxRecHitsInCloud_)) {
00614                 cloud.addHit(recHit);
00615                 ++usedRecHits;
00616               }
00617             }
00618             //else
00619               //std::cout<< " ===>>> HIT FAILS !!! " << std::endl;
00620           }
00621         } 
00622       } else {
00623         //
00624         // roadType == Roads::ZPhi
00625         //
00626         if (double_ring_layer && isSingleLayer(hitId)) {
00627 
00628           // Adjust matched hit for track angle
00629 
00630           //const SiStripMatchedRecHit2D *theRH = dynamic_cast<SiStripMatchedRecHit2D*>(*recHitIterator);
00631           const GluedGeomDet *theGluedDet = dynamic_cast<const GluedGeomDet*>(tracker->idToDet(hitId));
00632 
00633           SiStripMatchedRecHit2D* theCorrectedHit = CorrectMatchedHit(*recHitIterator,theGluedDet,
00634                                                                         tracker, theHitMatcher,
00635                                                                         k1, phi1);
00636           if (theCorrectedHit != 0){
00637 
00638             GlobalPoint ghit = tracker->idToDet(theCorrectedHit->geographicalId())->surface().toGlobal(theCorrectedHit->localPosition());
00639             double hitphi = map_phi(ghit.phi());
00640             double hitZ = ghit.z();
00641             double phi = phiFromExtrapolation(d0,phi0,k0,hitZ,roadType);
00642             
00643             float dp = hitphi-phi;
00644             float dx = hitZ*tan(dp);
00645               
00646             //
00647             //  This is where the disk stereoRecHits end up for Roads::ZPhi
00648             //
00649             if ( std::abs(dx) < phiMax(roadType,phi0,k1)) {
00650               if ((usedRecHits < maxDetHitsInCloudPerDetId) && (cloud.size() < maxRecHitsInCloud_)) {
00651                 cloud.addHit(recHit);
00652                 ++usedRecHits;
00653               }
00654             }
00655             delete theCorrectedHit;
00656           }
00657         } else { // Single layer hits here
00658           if ( isBarrelSensor(hitId) ) {
00659             //
00660             //  This is where the barrel (???) rphiRecHits end up for Roads::ZPhi
00661             //
00662             LocalPoint hit = recHit->localPosition();
00663             const StripTopology *topology = dynamic_cast<const StripTopology*>(&(tracker->idToDetUnit(hitId)->topology()));
00664             double stripAngle = topology->stripAngle(topology->strip(hit));
00665             double stripLength = topology->localStripLength(hit);
00666 
00667             //if (stripAngle!=0) std::cout<<"HEY, WE FOUND A HIT ON A STEREO MODULE!!!" << std::endl;
00668             // new method
00669             LocalPoint innerHitLocal(hit.x()+stripLength/2*std::sin(stripAngle),hit.y()-stripLength/2*std::cos(stripAngle),0);
00670             LocalPoint outerHitLocal(hit.x()-stripLength/2*std::sin(stripAngle),hit.y()+stripLength/2*std::cos(stripAngle),0);
00671             double innerHitPhi = map_phi(tracker->idToDetUnit(hitId)->surface().toGlobal(innerHitLocal).phi()); 
00672             double outerHitPhi = map_phi(tracker->idToDetUnit(hitId)->surface().toGlobal(outerHitLocal).phi());
00673             double innerHitZ = tracker->idToDetUnit(hitId)->surface().toGlobal(innerHitLocal).z(); 
00674             double outerHitZ = tracker->idToDetUnit(hitId)->surface().toGlobal(outerHitLocal).z();
00675             double innerExtrapolatedPhi = phiFromExtrapolation(d0,phi0,k0,innerHitZ,roadType);
00676             double outerExtrapolatedPhi = phiFromExtrapolation(d0,phi0,k0,outerHitZ,roadType);
00677 
00678             double midPointZ = 0.5*(innerHitZ+outerHitZ);
00679 
00680             double dPhiInter = CheckZPhiIntersection(innerHitPhi, innerHitZ, outerHitPhi, outerHitZ, 
00681                                                    innerExtrapolatedPhi, innerHitZ,
00682                                                    outerExtrapolatedPhi, outerHitZ);
00683 
00684             double dX = midPointZ*tan(dPhiInter);
00685 
00686             if (std::abs(dX) < 1.5*phiMax(roadType,phi0,k1)) {
00687               if ((usedRecHits < maxDetHitsInCloudPerDetId) && (cloud.size() < maxRecHitsInCloud_)) {
00688                 cloud.addHit(recHit);
00689                 ++usedRecHits;
00690               }
00691             }
00692 
00693           } else {
00694 
00695             //
00696             //  This is where the disk rphiRecHits end up for Roads::ZPhi
00697             //
00698             LocalPoint hit = recHit->localPosition();
00699             const StripTopology *topology = dynamic_cast<const StripTopology*>(&(tracker->idToDetUnit(hitId)->topology()));
00700             double stripAngle = topology->stripAngle(topology->strip(hit));
00701             double stripLength = topology->localStripLength(hit);
00702             // new method
00703             double hitZ = tracker->idToDetUnit(hitId)->surface().toGlobal(hit).z(); 
00704             double extrapolatedPhi = phiFromExtrapolation(d0,phi0,k0,hitZ,roadType);
00705 
00706             LocalPoint innerHitLocal(hit.x()+stripLength/2*std::sin(stripAngle),hit.y()-stripLength/2*std::cos(stripAngle),0);
00707             LocalPoint outerHitLocal(hit.x()-stripLength/2*std::sin(stripAngle),hit.y()+stripLength/2*std::cos(stripAngle),0);
00708 
00709             double innerHitPhi = map_phi(tracker->idToDetUnit(hitId)->surface().toGlobal(innerHitLocal).phi()); 
00710             double outerHitPhi = map_phi(tracker->idToDetUnit(hitId)->surface().toGlobal(outerHitLocal).phi());
00711             //double innerZ = tracker->idToDetUnit(hitId)->surface().toGlobal(innerHitLocal).z(); 
00712             //double outerZ = tracker->idToDetUnit(hitId)->surface().toGlobal(outerHitLocal).z();
00713             //if (innerZ != outerZ)  std::cout<<"HEY!!! innerZ = " << innerZ << " != outerZ = " << outerZ << std::endl;
00714 
00715             double deltaPhi = ZPhiDeltaPhi(innerHitPhi,outerHitPhi,extrapolatedPhi);
00716             double deltaX   =  hitZ*tan(deltaPhi);
00717             if (std::abs(deltaX) < phiMax(roadType,phi0,k1)){
00718               if ((usedRecHits < maxDetHitsInCloudPerDetId) && (cloud.size() < maxRecHitsInCloud_)) {
00719                 cloud.addHit(recHit);
00720                 ++usedRecHits;
00721               }
00722             }
00723           }
00724         } 
00725       }
00726     } else if ( (unsigned int)id.subdetId() == PixelSubdetector::PixelBarrel 
00727                 || (unsigned int)id.subdetId() == PixelSubdetector::PixelEndcap) {
00728       if ( UsePixels ) {
00729         
00730         const SiPixelRecHit *recHit = (SiPixelRecHit*)(*recHitIterator);
00731         
00732         if ( roadType == Roads::RPhi ) {
00733           
00734           if ( isBarrelSensor(id) ) {
00735             // Barrel Pixel, RoadType RPHI
00736             
00737             GlobalPoint ghit = tracker->idToDet(recHit->geographicalId())->surface().toGlobal(recHit->localPosition());
00738             double hitRadius = sqrt(ghit.x()*ghit.x()+ghit.y()*ghit.y());
00739             double hitphi = map_phi(ghit.phi());
00740             double phi = phiFromExtrapolation(d0,phi0,k0,hitRadius,roadType);
00741             
00742             float dp = hitphi-phi;
00743             float dx = hitRadius*tan(dp);
00744             
00745             // switch cut to dx instead of dphi
00746             if ( std::abs(dx) < phiMax(roadType,phi0,k0) ) {
00747               cloud.addHit(recHit);
00748               ++usedRecHits;
00749             }
00750           } else {
00751               
00752             // Forward Pixel,roadtype RPHI
00753               
00754             // Get Local Hit Position of the Pixel Hit
00755             LocalPoint hit = recHit->localPosition();
00756               
00757             // Get Phi of hit position 
00758             double hitphi = map_phi(tracker->idToDetUnit(id)->surface().toGlobal(hit).phi());
00759               
00760             // Get Global Hit position
00761             GlobalPoint ghit = tracker->idToDet(recHit->geographicalId())->surface().toGlobal(recHit->localPosition());
00762               
00763             // Get Hit Radis
00764             double hitRadius = sqrt(ghit.x()*ghit.x()+ghit.y()*ghit.y());
00765               
00766             // Get Phi from extrapolation
00767             double phi = phiFromExtrapolation(d0,phi0,k0,hitRadius,roadType);
00768               
00769             if ( std::abs(hitphi-phi) < phiMax(roadType,phi0,k0) ) {
00770               cloud.addHit(recHit);
00771               ++usedRecHits;
00772             }   
00773           }
00774         } else {
00775             
00776           GlobalPoint ghit = tracker->idToDet(recHit->geographicalId())->surface().toGlobal(recHit->localPosition());            
00777           double  phi = phiFromExtrapolation(d0,phi0,k0,ghit.z(),roadType);            
00778           double hitphi = map_phi(ghit.phi());
00779           double dphi = map_phi2(hitphi-phi);
00780           float dx = ghit.z()*tan(dphi);
00781             
00782           if ( std::abs(dx) < 0.25 ) {
00783             cloud.addHit(recHit);
00784             ++usedRecHits;
00785           }
00786         }
00787       }
00788     } else {
00789       edm::LogError("RoadSearch") << "recHitVector from general hit access function contains unknown detector id: " << (unsigned int)id.subdetId() << " rawId: " << id.rawId();
00790     }
00791     
00792   } //for loop over all recHits
00793   
00794   
00795   return usedRecHits;
00796 }
00797 
00798 unsigned int RoadSearchCloudMakerAlgorithm::FillPixRecHitsIntoCloud(DetId id, const SiPixelRecHitCollection *inputRecHits, 
00799                                                                     double d0, double phi0, double k0, Roads::type roadType, double ringPhi,
00800                                                                     const TrackerGeometry *tracker, RoadSearchCloud &cloud) {
00801   
00802   
00803   unsigned int usedRecHits = 0;
00804   
00805   // Get Geometry
00806   //const PixelTopology *topology = dynamic_cast<const PixelTopology*>(&(tracker->idToDetUnit(id)->topology()));
00807   
00808   
00809   // retrieve vector<SiPixelRecHit> for id
00810   // loop over SiPixelRecHit
00811   // check if compatible with cloud, fill into cloud
00812   
00813   SiPixelRecHitCollection::const_iterator recHitMatch = inputRecHits->find(id);
00814   if (recHitMatch == inputRecHits->end()) return usedRecHits;
00815 
00816   const SiPixelRecHitCollection::DetSet recHitRange = *recHitMatch;
00817   
00818   for ( SiPixelRecHitCollection::DetSet::const_iterator recHitIterator = recHitRange.begin(); 
00819         recHitIterator != recHitRange.end(); ++recHitIterator) {
00820     
00821     const SiPixelRecHit * recHit = &(*recHitIterator);
00822     
00823     if ( roadType == Roads::RPhi ) {
00824       
00825       if ( isBarrelSensor(id) ) {
00826         // Barrel Pixel, RoadType RPHI
00827         
00828         GlobalPoint ghit = tracker->idToDet(recHit->geographicalId())->surface().toGlobal(recHit->localPosition());
00829         double hitRadius = sqrt(ghit.x()*ghit.x()+ghit.y()*ghit.y());
00830         double hitphi = map_phi(ghit.phi());
00831         double phi = phiFromExtrapolation(d0,phi0,k0,hitRadius,roadType);
00832         
00833         if ( std::abs(hitphi-phi) < phiMax(roadType,phi0,k0) ) {
00834           cloud.addHit(recHit);
00835           ++usedRecHits;
00836         }
00837       } 
00838       else {
00839         
00840         // Forward Pixel,roadtype RPHI
00841         
00842         // Get Local Hit Position of the Pixel Hit
00843         LocalPoint hit = recHit->localPosition();
00844         
00845         // Get Phi of hit position 
00846         double hitphi = map_phi(tracker->idToDetUnit(id)->surface().toGlobal(hit).phi());
00847         
00848         // Get Global Hit position
00849         GlobalPoint ghit = tracker->idToDet(recHit->geographicalId())->surface().toGlobal(recHit->localPosition());
00850         
00851         // Get Hit Radis
00852         double hitRadius = sqrt(ghit.x()*ghit.x()+ghit.y()*ghit.y());
00853         
00854         // Get Phi from extrapolation
00855         double phi = phiFromExtrapolation(d0,phi0,k0,hitRadius,roadType);
00856         
00857         if ( std::abs(hitphi-phi) < phiMax(roadType,phi0,k0) ) {
00858           cloud.addHit(recHit);
00859           ++usedRecHits;
00860         }       
00861       }
00862     } 
00863     
00864     else {
00865       
00866       GlobalPoint ghit = tracker->idToDet(recHit->geographicalId())->surface().toGlobal(recHit->localPosition());
00867       
00868       double  phi = phiFromExtrapolation(d0,phi0,k0,ghit.z(),roadType);
00869       if ( (phi - phiMax(roadType,phi0,k0)) < ringPhi && (phi + phiMax(roadType,phi0,k0))>ringPhi ) {
00870         cloud.addHit(recHit);
00871         ++usedRecHits;
00872       }
00873     }
00874     
00875   }
00876   
00877   return usedRecHits;
00878 }
00879 
00880 bool RoadSearchCloudMakerAlgorithm::isSingleLayer(DetId id) {
00881   
00882   if ( (unsigned int)id.subdetId() == StripSubdetector::TIB ) {
00883     TIBDetId tibid(id.rawId()); 
00884     if ( !tibid.glued() ) {
00885       return true;
00886     }
00887   } else if ( (unsigned int)id.subdetId() == StripSubdetector::TOB ) {
00888     TOBDetId tobid(id.rawId()); 
00889     if ( !tobid.glued() ) {
00890       return true;
00891     }
00892   } else if ( (unsigned int)id.subdetId() == StripSubdetector::TID ) {
00893     TIDDetId tidid(id.rawId()); 
00894     if ( !tidid.glued() ) {
00895       return true;
00896     }
00897   } else if ( (unsigned int)id.subdetId() == StripSubdetector::TEC ) {
00898     TECDetId tecid(id.rawId()); 
00899     if ( !tecid.glued() ) {
00900       return true;
00901     }
00902   } else {
00903     return false;
00904   }
00905   
00906   return false;
00907 }
00908 
00909 bool RoadSearchCloudMakerAlgorithm::isBarrelSensor(DetId id) {
00910   
00911   if ( (unsigned int)id.subdetId() == StripSubdetector::TIB ) {
00912     return true;
00913   } else if ( (unsigned int)id.subdetId() == StripSubdetector::TOB ) {
00914     return true;
00915   } else if ( (unsigned int)id.subdetId() == PixelSubdetector::PixelBarrel ) {
00916     return true;
00917   } else {
00918     return false;
00919   }
00920   
00921 }
00922 
00923 double RoadSearchCloudMakerAlgorithm::phiFromExtrapolation(double d0, double phi0, double k0, double ringRadius, Roads::type roadType) {
00924   
00925   double ringPhi = -99.;
00926   if ( roadType == Roads::RPhi ) {
00927     double omega=k0, rl=ringRadius;
00928     double sp0=sin(phi0); double cp0=cos(phi0);  
00929     if (fabs(omega)>0.000005){
00930       double xc=-sp0*(d0+1.0/omega);    
00931       double yc=cp0*(d0+1.0/omega);
00932       double rh=fabs(1.0/omega);
00933       double bbb=fabs(d0+1.0/omega);
00934       double sss=0.5*(rl+rh+bbb);
00935       double ddd=sqrt((sss-bbb)*(sss-rh)/(sss*(sss-rl)));
00936       double phil1=2.0*atan(ddd);
00937       double phit=phi0+phil1; if (omega<0.0)phit=phi0-phil1;
00938       double xh=xc+sin(phit)/omega;
00939       double yh=yc-cos(phit)/omega;
00940       double phih=atan2(yh,xh);
00941       ringPhi = map_phi(phih);
00942     }
00943     else {
00944       double cee = rl*rl - d0*d0 -0.25*omega*omega - omega*d0;
00945       if (cee<0.0){return ringPhi;}
00946       double l = sqrt(cee);
00947       double xh=-sp0*d0+l*cp0-0.5*l*l*omega*sp0;
00948       double yh= cp0*d0+l*sp0+0.5*l*l*omega*cp0;
00949       double phih=atan2(yh,xh);
00950       ringPhi = map_phi(phih);     
00951     }
00952   } 
00953   else {
00954     ringPhi = map_phi(phi0 + k0 * ringRadius);
00955   }
00956   
00957   return ringPhi;
00958 }
00959 
00960 double RoadSearchCloudMakerAlgorithm::phiMax(Roads::type roadType,
00961                                              double phi0, double k0) {
00962   
00963   double dphi;
00964   if ( roadType == Roads::RPhi ) {
00965     // switch cut to dx instead of dphi
00966     // Still call this dphi, but will now be dx
00967     dphi = theRPhiRoadSize + 0.15*82.0*fabs(k0);
00968   }
00969   else if ( roadType == Roads::ZPhi ) {
00970     dphi = theZPhiRoadSize + 0.4*82.0*fabs(k0);
00971   }
00972   else {
00973     edm::LogWarning("RoadSearch") << "Bad roadType: "<< roadType;
00974     dphi = theZPhiRoadSize;
00975   }
00976   return dphi;
00977   
00978 }
00979 
00980 void RoadSearchCloudMakerAlgorithm::makecircle(double x1, double y1, 
00981                                                double x2,double y2, double x3, double y3){
00982   double x1t=x1-x3; double y1t=y1-y3; double r1s=x1t*x1t+y1t*y1t;
00983   double x2t=x2-x3; double y2t=y2-y3; double r2s=x2t*x2t+y2t*y2t;
00984   double rho=x1t*y2t-x2t*y1t;
00985   double xc, yc, rc, fac;
00986   if (fabs(rho)<RoadSearchCloudMakerAlgorithm::epsilon){
00987     rc=1.0/(RoadSearchCloudMakerAlgorithm::epsilon);
00988     fac=sqrt(x1t*x1t+y1t*y1t);
00989     xc=x2+y1t*rc/fac;
00990     yc=y2-x1t*rc/fac;
00991   }else{
00992     fac=0.5/rho;
00993     xc=fac*(r1s*y2t-r2s*y1t);
00994     yc=fac*(r2s*x1t-r1s*x2t); 
00995     rc=sqrt(xc*xc+yc*yc); xc+=x3; yc+=y3;
00996   }
00997   double s3=0.0;
00998   double f1=x1*yc-y1*xc; double f2=x2*yc-y2*xc; 
00999   double f3=x3*yc-y3*xc;
01000   if ((f1<0.0)&&(f2<0.0)&&(f3<=0.0))s3=1.0;
01001   if ((f1>0.0)&&(f2>0.0)&&(f3>=0.0))s3=-1.0;
01002   d0h=-s3*(sqrt(xc*xc+yc*yc)-rc);
01003   phi0h=atan2(yc,xc)+s3*Geom::halfPi();
01004   omegah=-s3/rc;
01005 }
01006 
01007 double RoadSearchCloudMakerAlgorithm::CheckXYIntersection(LocalPoint& inner1, LocalPoint& outer1,
01008                                                         LocalPoint& inner2, LocalPoint& outer2){
01009 
01010   double deltaX = -999.;
01011   // just get the x coord of intersection of two line segments
01012   // check if intersection lies inside segments
01013   double det12 = inner1.x()*outer1.y() - inner1.y()*outer1.x();
01014   double det34 = inner2.x()*outer2.y() - inner2.y()*outer2.x();
01015 
01016   double xinter = (det12*(inner2.x()-outer2.x()) - det34*(inner1.x()-outer1.x()))/
01017     ((inner1.x()-outer1.x())*(inner2.y()-outer2.y()) - 
01018      (inner2.x()-outer2.x())*(inner1.y()-outer1.y()));
01019 
01020   bool inter = true;
01021   if (inner1.x() < outer1.x()){
01022     if ((xinter<inner1.x()) || (xinter>outer1.x())) inter = false;
01023   }
01024   else{
01025     if ((xinter>inner1.x()) || (xinter<outer1.x())) inter = false;
01026   }
01027 
01028   if (inner2.x() < outer2.x()){
01029     if ((xinter<inner2.x()) || (xinter>outer2.x())) inter = false;
01030   }
01031   else{
01032     if ((xinter>inner2.x()) || (xinter<outer2.x())) inter = false;
01033   }
01034 
01035   if (inter){
01036     deltaX = 0;
01037   }
01038   else{
01039     deltaX = min(fabs(inner1.x()-inner2.x()),fabs(outer1.x()-outer2.x()));
01040   }
01041   return deltaX;
01042 
01043 }
01044 
01045 double RoadSearchCloudMakerAlgorithm::CheckZPhiIntersection(double iPhi1, double iZ1, double oPhi1, double oZ1,
01046                                                             double iPhi2, double iZ2, double oPhi2, double oZ2){
01047   
01048   // Have to make sure all are in the same hemisphere
01049   if ((iPhi1 > Geom::pi() || oPhi1 > Geom::pi() || iPhi2 > Geom::pi() || oPhi2 > Geom::pi()) &&
01050       (iPhi1 < Geom::pi() || oPhi1 < Geom::pi() || iPhi2 < Geom::pi() || oPhi2 < Geom::pi())){
01051     iPhi1 = map_phi2(iPhi1);  oPhi1 = map_phi2(oPhi1);
01052     iPhi2 = map_phi2(iPhi2);  oPhi2 = map_phi2(oPhi2);
01053   }
01054 
01055   double deltaPhi = -999.;
01056   // just get the x coord of intersection of two line segments
01057   // check if intersection lies inside segments
01058   double det12 = iZ1*oPhi1 - iPhi1*oZ1;
01059   double det34 = iZ2*oPhi2 - iPhi2*oZ2;
01060 
01061   double xinter = (det12*(iZ2-oZ2) - det34*(iZ1-oZ1))/
01062     ((iZ1-oZ1)*(iPhi2-oPhi2) - 
01063      (iZ2-oZ2)*(iPhi1-oPhi1));
01064 
01065   bool inter = true;
01066   if (iZ1 < oZ1){
01067     if ((xinter<iZ1) || (xinter>oZ1)) inter = false;
01068   }
01069   else{
01070     if ((xinter>iZ1) || (xinter<oZ1)) inter = false;
01071   }
01072 
01073   if (iZ2 < oZ2){
01074     if ((xinter<iZ2) || (xinter>oZ2)) inter = false;
01075   }
01076   else{
01077     if ((xinter>iZ2) || (xinter<oZ2)) inter = false;
01078   }
01079 
01080   if (inter){
01081     deltaPhi = 0;
01082   }
01083   else{
01084     deltaPhi = min(fabs(iPhi2-iPhi1),fabs(oPhi2-oPhi1));
01085   }
01086   return deltaPhi;
01087 
01088 }
01089 
01090 
01091 double RoadSearchCloudMakerAlgorithm::ZPhiDeltaPhi(double hitPhi1, double hitPhi2, double predictedPhi){
01092 
01093   double deltaPhi = -999.;
01094 
01095   double dPhiHits = map_phi2(hitPhi1-hitPhi2);
01096   double dPhi1 = map_phi2(hitPhi1-predictedPhi);
01097   double dPhi2 = map_phi2(hitPhi2-predictedPhi);
01098 
01099   if (dPhiHits >= 0){  // hitPhi1 >= hitPhi2
01100     if ( (dPhi1>=0.0) && (dPhi2 <= 0.0))
01101       deltaPhi = 0.0;
01102     else{
01103       if (std::abs(dPhi1)<std::abs(dPhi2))
01104         deltaPhi = dPhi1;
01105       else
01106         deltaPhi = dPhi2;
01107     }
01108   }
01109   else { // hitPhi1 < hitPhi2
01110     if ( (dPhi1<=0.0) && (dPhi2 >= 0.0))
01111       deltaPhi = 0.0;
01112     else{
01113       if (std::abs(dPhi1)<std::abs(dPhi2))
01114         deltaPhi = dPhi1;
01115       else
01116         deltaPhi = dPhi2;
01117     }
01118   }
01119 
01120   return deltaPhi;
01121 
01122 }
01123 
01124 RoadSearchCloudCollection RoadSearchCloudMakerAlgorithm::Clean(RoadSearchCloudCollection* inputCollection){
01125   
01126   RoadSearchCloudCollection output;
01127   
01128   //
01129   //  no raw clouds - nothing to try merging
01130   //
01131 
01132   if ( inputCollection->empty() ){
01133     LogDebug("RoadSearch") << "Found " << output.size() << " clean clouds.";
01134     return output;  
01135   }
01136   
01137   //
01138   //  1 raw cloud - nothing to try merging, but one cloud to duplicate
01139   //
01140   
01141   if ( 1==inputCollection->size() ){
01142     output = *inputCollection;
01143 //     RoadSearchCloud *temp = inputCollection->begin()->clone();
01144 //     output.push_back(*temp);
01145 //     delete temp;
01146     LogDebug("RoadSearch") << "Found " << output.size() << " clean clouds.";
01147     return output;
01148   }  
01149   
01150   //
01151   //  got > 1 raw cloud - something to try merging
01152   //
01153   std::vector<bool> already_gone(inputCollection->size());
01154   for (unsigned int i=0; i<inputCollection->size(); ++i) {
01155     already_gone[i] = false; 
01156   }
01157   
01158   int raw_cloud_ctr=0;
01159   // loop over clouds
01160   for ( RoadSearchCloudCollection::const_iterator raw_cloud = inputCollection->begin(); raw_cloud != inputCollection->end(); ++raw_cloud) {
01161     ++raw_cloud_ctr;
01162     
01163     if (already_gone[raw_cloud_ctr-1])continue;
01164     
01165     // produce output cloud where other clouds are merged in
01166     // create temp pointer for clone which will be deleted afterwards
01167 //     RoadSearchCloud *temp_lone_cloud = raw_cloud->clone();
01168 //     RoadSearchCloud lone_cloud = *temp_lone_cloud;
01169     RoadSearchCloud lone_cloud = *raw_cloud;
01170 
01171     int second_cloud_ctr=raw_cloud_ctr;
01172     for ( RoadSearchCloudCollection::const_iterator second_cloud = raw_cloud+1; second_cloud != inputCollection->end(); ++second_cloud) {
01173       second_cloud_ctr++;
01174       
01175       std::vector<const TrackingRecHit*> unshared_hits;
01176       
01177       if ( already_gone[second_cloud_ctr-1] )continue;
01178       
01179       for ( RoadSearchCloud::RecHitVector::const_iterator second_cloud_hit = second_cloud->begin_hits();
01180             second_cloud_hit != second_cloud->end_hits();
01181             ++ second_cloud_hit ) {
01182         bool is_shared = false;
01183         for ( RoadSearchCloud::RecHitVector::const_iterator lone_cloud_hit = lone_cloud.begin_hits();
01184               lone_cloud_hit != lone_cloud.end_hits();
01185               ++ lone_cloud_hit ) {
01186           
01187           if ((*lone_cloud_hit)->geographicalId() == (*second_cloud_hit)->geographicalId())
01188             if ((*lone_cloud_hit)->localPosition().x() == (*second_cloud_hit)->localPosition().x())
01189               if ((*lone_cloud_hit)->localPosition().y() == (*second_cloud_hit)->localPosition().y())
01190                 {is_shared=true; break;}
01191         }
01192         if (!is_shared)  unshared_hits.push_back(*second_cloud_hit);
01193           
01194         if ( ((float(unshared_hits.size())/float(lone_cloud.size())) > 
01195               ((float(second_cloud->size())/float(lone_cloud.size()))-mergingFraction_)) &&
01196              ((float(unshared_hits.size())/float(second_cloud->size())) > (1-mergingFraction_))){
01197           // You'll never merge these clouds..... Could quit now!
01198           break;
01199         }
01200           
01201         if (lone_cloud.size()+unshared_hits.size() > maxRecHitsInCloud_) {
01202           break;
01203         }
01204           
01205       }
01206         
01207       double f_lone_shared=double(second_cloud->size()-unshared_hits.size())/double(lone_cloud.size());
01208       double f_second_shared=double(second_cloud->size()-unshared_hits.size())/double(second_cloud->size());
01209       
01210       if ( ( (static_cast<unsigned int>(f_lone_shared*1E9) > static_cast<unsigned int>(mergingFraction_*1E9))||(static_cast<unsigned int>(f_second_shared*1E9) > static_cast<unsigned int>(mergingFraction_*1E9)) ) 
01211            && (lone_cloud.size()+unshared_hits.size() <= maxRecHitsInCloud_) ){
01212         
01213         LogDebug("RoadSearch") << " Merge CloudA: " << raw_cloud_ctr << " with  CloudB: " << second_cloud_ctr 
01214                                << " Shared fractions are " << f_lone_shared << " and " << f_second_shared;
01215           
01216         //
01217         //  got a cloud to merge
01218         //
01219         for (unsigned int k=0; k<unshared_hits.size(); ++k) {
01220           lone_cloud.addHit(unshared_hits[k]);
01221         }
01222           
01223         already_gone[second_cloud_ctr-1]=true;
01224         
01225       }//end got a cloud to merge
01226       
01227     }//interate over all second clouds
01228       
01229     output.push_back(lone_cloud);
01230     
01231   }//iterate over all raw clouds
01232   
01233   LogDebug("RoadSearch") << "Found " << output.size() << " clean clouds.";
01234   
01235   return output;
01236 }
01237 
01238 SiStripMatchedRecHit2D* RoadSearchCloudMakerAlgorithm::CorrectMatchedHit(const TrackingRecHit *originalHit,
01239                                                                          const GluedGeomDet* gluedDet,
01240                                                                          const TrackerGeometry *tracker,
01241                                                                          const SiStripRecHitMatcher* theHitMatcher,
01242                                                                          double k0, double phi0) {
01243           // VI January 2012
01244           // this is not supported anymore w/o cpe
01245     
01246           const SiStripMatchedRecHit2D *theRH = dynamic_cast<const SiStripMatchedRecHit2D*>(originalHit);
01247           if (theRH == 0) {
01248             std::cout<<" Could not cast original hit" << std::endl;
01249           }
01250           if (theRH != 0){
01251             const GeomDet *recHitGeomDet = tracker->idToDet(theRH->geographicalId());
01252             const GluedGeomDet *theGluedDet = dynamic_cast<const GluedGeomDet*>(recHitGeomDet);
01253              
01254             const GeomDetUnit* theMonoDet = theGluedDet->monoDet();
01255             const SiStripRecHit2D theMonoHit   = theRH->monoHit();
01256             //GlobalPoint monoRHpos = (theMonoDet->surface()).toGlobal(theMonoHit.localPosition());
01257              
01258             GlobalPoint gcenterofstrip=(theMonoDet->surface()).toGlobal(theMonoHit.localPosition());
01259              
01260             float gtrackangle_xy = map_phi2(phi0 + 2.0*asin(0.5*gcenterofstrip.perp()*k0));
01261             float rzangle = atan2(gcenterofstrip.perp(),gcenterofstrip.z());
01262  
01263             GlobalVector gtrackangle2(cos(gtrackangle_xy)*sin(rzangle),
01264                                       sin(gtrackangle_xy)*sin(rzangle),
01265                                       cos(rzangle));
01266             LocalVector trackdirection2=((tracker->idToDet(theRH->geographicalId()))->surface()).toLocal(gtrackangle2);
01267             //GlobalVector gdir = theMonoDet->surface().toGlobal(trackdirection2);
01268  
01269             SiStripMatchedRecHit2D* theCorrectedHit = theHitMatcher->match(theRH,theGluedDet,trackdirection2);
01270             if (theCorrectedHit!=0) return theCorrectedHit;
01271           }
01272  
01273           return 0;
01274 }