CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoEgamma/EgammaElectronAlgos/src/SiStripElectronSeedGenerator.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    EgammaElectronAlgos
00004 // Class:      SiStripElectronSeedGenerator.
00005 //
00011 //
00012 //
00013 
00014 #include <vector>
00015 #include <utility>
00016 
00017 #include "DataFormats/Math/interface/Point3D.h"
00018 #include "DataFormats/Common/interface/Handle.h"
00019 
00020 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
00021 
00022 
00023 
00024 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00025 
00026 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00028 
00029 #include "RecoTracker/TransientTrackingRecHit/interface/TSiStripMatchedRecHit.h"
00030 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
00031 #include "RecoTracker/TkSeedGenerator/interface/FastHelix.h"
00032 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
00033 
00034 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00035 #include "TrackingTools/MaterialEffects/interface/PropagatorWithMaterial.h"
00036 
00037 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00038 
00039 // files for retrieving hits using measurement tracker
00040 
00041 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00042 #include "TrackingTools/PatternTools/interface/TransverseImpactPointExtrapolator.h"
00043 #include "TrackingTools/MeasurementDet/interface/LayerMeasurements.h"
00044 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00045 
00046 
00047 #include "RecoEgamma/EgammaElectronAlgos/interface/SiStripElectronSeedGenerator.h"
00048 
00049 SiStripElectronSeedGenerator::SiStripElectronSeedGenerator(const edm::ParameterSet &pset)
00050  : beamSpotTag_("offlineBeamSpot"),
00051    theUpdator(0),thePropagator(0),theMeasurementTracker(0),
00052    theSetup(0), theMatcher_(0),
00053    cacheIDMagField_(0),cacheIDCkfComp_(0),cacheIDTrkGeom_(0),
00054    tibOriginZCut_(pset.getParameter<double>("tibOriginZCut")),
00055    tidOriginZCut_(pset.getParameter<double>("tidOriginZCut")),
00056    tecOriginZCut_(pset.getParameter<double>("tecOriginZCut")),
00057    monoOriginZCut_(pset.getParameter<double>("monoOriginZCut")),
00058    tibDeltaPsiCut_(pset.getParameter<double>("tibDeltaPsiCut")),
00059    tidDeltaPsiCut_(pset.getParameter<double>("tidDeltaPsiCut")),
00060    tecDeltaPsiCut_(pset.getParameter<double>("tecDeltaPsiCut")),
00061    monoDeltaPsiCut_(pset.getParameter<double>("monoDeltaPsiCut")),
00062    tibPhiMissHit2Cut_(pset.getParameter<double>("tibPhiMissHit2Cut")),
00063    tidPhiMissHit2Cut_(pset.getParameter<double>("tidPhiMissHit2Cut")),
00064    tecPhiMissHit2Cut_(pset.getParameter<double>("tecPhiMissHit2Cut")),
00065    monoPhiMissHit2Cut_(pset.getParameter<double>("monoPhiMissHit2Cut")),
00066    tibZMissHit2Cut_(pset.getParameter<double>("tibZMissHit2Cut")),
00067    tidRMissHit2Cut_(pset.getParameter<double>("tidRMissHit2Cut")),
00068    tecRMissHit2Cut_(pset.getParameter<double>("tecRMissHit2Cut")),
00069    tidEtaUsage_(pset.getParameter<double>("tidEtaUsage")),
00070    tidMaxHits_(pset.getParameter<int>("tidMaxHits")),
00071    tecMaxHits_(pset.getParameter<int>("tecMaxHits")),
00072    monoMaxHits_(pset.getParameter<int>("monoMaxHits")),
00073    maxSeeds_(pset.getParameter<int>("maxSeeds"))
00074 {
00075   // use of a theMeasurementTrackerName
00076   if (pset.exists("measurementTrackerName"))
00077    { theMeasurementTrackerName = pset.getParameter<std::string>("measurementTrackerName") ; }
00078 
00079   // new beamSpot tag
00080   if (pset.exists("beamSpot"))
00081    { beamSpotTag_ = pset.getParameter<edm::InputTag>("beamSpot") ; }
00082 
00083   theUpdator = new KFUpdator();
00084   theEstimator = new Chi2MeasurementEstimator(30,3);
00085 }
00086 
00087 
00088 SiStripElectronSeedGenerator::~SiStripElectronSeedGenerator() {
00089   delete thePropagator;
00090   delete theUpdator;
00091 }
00092 
00093 
00094 void SiStripElectronSeedGenerator::setupES(const edm::EventSetup& setup) {
00095 
00096   if (cacheIDMagField_!=setup.get<IdealMagneticFieldRecord>().cacheIdentifier()) {
00097     setup.get<IdealMagneticFieldRecord>().get(theMagField);
00098     cacheIDMagField_=setup.get<IdealMagneticFieldRecord>().cacheIdentifier();
00099     if (thePropagator) delete thePropagator;
00100     thePropagator = new PropagatorWithMaterial(alongMomentum,.000511,&(*theMagField));
00101   }
00102 
00103   if (cacheIDCkfComp_!=setup.get<CkfComponentsRecord>().cacheIdentifier()) {
00104     setup.get<CkfComponentsRecord>().get(theMeasurementTrackerName,measurementTrackerHandle);
00105     cacheIDCkfComp_=setup.get<CkfComponentsRecord>().cacheIdentifier();
00106     theMeasurementTracker = measurementTrackerHandle.product();
00107   }
00108 
00109   if (cacheIDTrkGeom_!=setup.get<TrackerDigiGeometryRecord>().cacheIdentifier()) {
00110     setup.get<TrackerDigiGeometryRecord>().get(trackerGeometryHandle);
00111     cacheIDTrkGeom_=setup.get<TrackerDigiGeometryRecord>().cacheIdentifier();
00112   }
00113 
00114 }
00115 
00116 void  SiStripElectronSeedGenerator::run(edm::Event& e, const edm::EventSetup& setup,
00117                                         const edm::Handle<reco::SuperClusterCollection> &clusters,
00118                                         reco::ElectronSeedCollection & out) {
00119   theSetup= &setup;
00120   e.getByLabel(beamSpotTag_,theBeamSpot);
00121   theMeasurementTracker->update(e);
00122 
00123   for  (unsigned int i=0;i<clusters->size();++i) {
00124     edm::Ref<reco::SuperClusterCollection> theClusB(clusters,i);
00125     // Find the seeds
00126     LogDebug ("run") << "new cluster, calling findSeedsFromCluster";
00127     findSeedsFromCluster(theClusB,theBeamSpot,out);
00128   }
00129 
00130   LogDebug ("run") << ": For event "<<e.id();
00131   LogDebug ("run") <<"Nr of superclusters: "<<clusters->size()
00132                    <<", no. of ElectronSeeds found  = " << out.size();
00133 }
00134 
00135 
00136 // Find seeds using a supercluster
00137 void SiStripElectronSeedGenerator::findSeedsFromCluster
00138  ( edm::Ref<reco::SuperClusterCollection> seedCluster,
00139    edm::Handle<reco::BeamSpot> bs,
00140          reco::ElectronSeedCollection & result )
00141  {
00142   // clear the member vectors of good hits
00143   layer1Hits_.clear() ;
00144   layer2Hits_.clear() ;
00145   backupLayer2Hits_.clear() ;
00146 
00147   using namespace std;
00148 
00149   double sCenergy = seedCluster->energy();
00150   math::XYZPoint sCposition = seedCluster->position();
00151   double scEta = seedCluster->eta();
00152 
00153   double scz = sCposition.z();
00154   double scr = sqrt(pow(sCposition.x(),2)+pow(sCposition.y(),2));
00155 
00156   double pT = sCenergy * seedCluster->position().rho()/sqrt(seedCluster->x()*seedCluster->x()+seedCluster->y()*seedCluster->y()+seedCluster->z()*seedCluster->z());
00157 
00158   // FIXME use nominal field (see below)
00159   double magneticField = 3.8;
00160 
00161   // cf Jackson p. 581-2, a little geometry
00162   double phiVsRSlope = -3.00e-3 * magneticField / pT / 2.;
00163 
00164 
00165   //Need to create TSOS to feed MeasurementTracker
00166   GlobalPoint beamSpot(bs->x0(),bs->y0(),bs->z0());
00167   GlobalPoint superCluster(sCposition.x(),sCposition.y(),sCposition.z());
00168   double r0 = beamSpot.perp();
00169   double z0 = beamSpot.z();
00170 
00171   //We need to pick a charge for the particle we want to reconstruct before hits can be retrieved
00172   //Choosing both charges improves seeding efficiency by less than 0.5% for signal events
00173   //If we pick a single charge, this reduces fake rate and CPU time
00174   //So we pick a charge that is equally likely to be positive or negative
00175 
00176   int chargeHypothesis;
00177   double chargeSelector = sCenergy - (int)sCenergy;
00178   if(chargeSelector >= 0.5) chargeHypothesis = -1;
00179   if(chargeSelector < 0.5) chargeHypothesis = 1;
00180 
00181   //Use BeamSpot and SC position to estimate 3rd point
00182   double rFake = 25.;
00183   double phiFake = phiDiff(superCluster.phi(),chargeHypothesis * phiVsRSlope * (scr - rFake));
00184   double zFake = (rFake*(scz-z0)-r0*scz+scr*z0)/(scr-r0);
00185   double xFake = rFake * cos(phiFake);
00186   double yFake = rFake * sin(phiFake);
00187   GlobalPoint fakePoint(xFake,yFake,zFake);
00188 
00189   // FIXME optmize, move outside loop
00190   edm::ESHandle<MagneticField> bfield;
00191   theSetup->get<IdealMagneticFieldRecord>().get(bfield);
00192   float nomField = bfield->nominalValue();
00193 
00194   //Use 3 points to make helix
00195   FastHelix initialHelix(superCluster,fakePoint,beamSpot,nomField,&*bfield);
00196 
00197   //Use helix to get FTS
00198   FreeTrajectoryState initialFTS(initialHelix.stateAtVertex());
00199 
00200   //Use FTS and BeamSpot to create TSOS
00201   TransverseImpactPointExtrapolator* tipe = new TransverseImpactPointExtrapolator(*thePropagator);
00202   TrajectoryStateOnSurface initialTSOS = tipe->extrapolate(initialFTS,beamSpot);
00203 
00204   //Use GST to retrieve hits from various DetLayers using layerMeasurements class
00205   const GeometricSearchTracker* gst = theMeasurementTracker->geometricSearchTracker();
00206 
00207   std::vector<BarrelDetLayer*> tibLayers = gst->tibLayers();
00208   DetLayer* tib1 = tibLayers.at(0);
00209   DetLayer* tib2 = tibLayers.at(1);
00210 
00211   std::vector<ForwardDetLayer*> tecLayers;
00212   std::vector<ForwardDetLayer*> tidLayers;
00213   if(scEta < 0){
00214     tecLayers = gst->negTecLayers();
00215     tidLayers = gst->negTidLayers();
00216   }
00217   if(scEta > 0){
00218     tecLayers = gst->posTecLayers();
00219     tidLayers = gst->posTidLayers();
00220   }
00221 
00222   DetLayer* tid1 = tidLayers.at(0);
00223   DetLayer* tid2 = tidLayers.at(1);
00224   DetLayer* tid3 = tidLayers.at(2);
00225   DetLayer* tec1 = tecLayers.at(0);
00226   DetLayer* tec2 = tecLayers.at(1);
00227   DetLayer* tec3 = tecLayers.at(2);
00228 
00229   //Figure out which DetLayers to use based on SC Eta
00230   std::vector<bool> useDL = useDetLayer(scEta);
00231   bool useTID = false;
00232 
00233   //Use counters to restrict the number of hits in TID and TEC layers
00234   //This reduces seed multiplicity
00235   int tid1MHC = 0;
00236   int tid2MHC = 0;
00237   int tid3MHC = 0;
00238   int tid1BHC = 0;
00239   int tid2BHC = 0;
00240   int tid3BHC = 0;
00241   int tec1MHC = 0;
00242   int tec2MHC = 0;
00243   int tec3MHC = 0;
00244 
00245   //Use counter to limit the allowed number of seeds
00246   int seedCounter = 0;
00247 
00248   bool hasLay1Hit = false;
00249   bool hasLay2Hit = false;
00250   bool hasBackupHit = false;
00251 
00252   LayerMeasurements layerMeasurements(theMeasurementTracker);
00253 
00254   std::vector<TrajectoryMeasurement> tib1measurements;
00255   if(useDL.at(0)) tib1measurements = layerMeasurements.measurements(*tib1,initialTSOS,*thePropagator,*theEstimator);
00256   std::vector<TrajectoryMeasurement> tib2measurements;
00257   if(useDL.at(1)) tib2measurements = layerMeasurements.measurements(*tib2,initialTSOS,*thePropagator,*theEstimator);
00258 
00259   //Basic idea: Retrieve hits from a given DetLayer
00260   //Check if it is a Matched Hit and satisfies some cuts
00261   //If yes, accept hit for seed making
00262 
00263   for(std::vector<TrajectoryMeasurement>::const_iterator tmIter = tib1measurements.begin(); tmIter != tib1measurements.end(); ++ tmIter){
00264     ConstRecHitPointer hit = tmIter->recHit();
00265     const SiStripMatchedRecHit2D* matchedHit = matchedHitConverter(hit);
00266     if(matchedHit){
00267       GlobalPoint position = trackerGeometryHandle->idToDet(matchedHit->geographicalId())->surface().toGlobal(matchedHit->localPosition());
00268       if(preselection(position, superCluster, phiVsRSlope, 1)){
00269         hasLay1Hit = true;
00270         layer1Hits_.push_back(matchedHit);
00271       }
00272     }
00273   }
00274 
00275   for(std::vector<TrajectoryMeasurement>::const_iterator tmIter = tib2measurements.begin(); tmIter != tib2measurements.end(); ++ tmIter){
00276     ConstRecHitPointer hit = tmIter->recHit();
00277     const SiStripMatchedRecHit2D* matchedHit = matchedHitConverter(hit);
00278     if(matchedHit){
00279       GlobalPoint position = trackerGeometryHandle->idToDet(matchedHit->geographicalId())->surface().toGlobal(matchedHit->localPosition());
00280       if(preselection(position, superCluster, phiVsRSlope, 1)){
00281         hasLay2Hit = true;
00282         layer2Hits_.push_back(matchedHit);
00283       }
00284     }
00285   }
00286 
00287   if(!(hasLay1Hit && hasLay2Hit)) useTID = true;
00288   if(std::abs(scEta) > tidEtaUsage_) useTID = true;
00289   std::vector<TrajectoryMeasurement> tid1measurements;
00290   if(useDL.at(2) && useTID) tid1measurements = layerMeasurements.measurements(*tid1,initialTSOS,*thePropagator,*theEstimator);
00291   std::vector<TrajectoryMeasurement> tid2measurements;
00292   if(useDL.at(3) && useTID) tid2measurements = layerMeasurements.measurements(*tid2,initialTSOS,*thePropagator,*theEstimator);
00293   std::vector<TrajectoryMeasurement> tid3measurements;
00294   if(useDL.at(4) && useTID) tid3measurements = layerMeasurements.measurements(*tid3,initialTSOS,*thePropagator,*theEstimator);
00295 
00296   for(std::vector<TrajectoryMeasurement>::const_iterator tmIter = tid1measurements.begin(); tmIter != tid1measurements.end(); ++ tmIter){
00297     if(tid1MHC < tidMaxHits_){
00298     ConstRecHitPointer hit = tmIter->recHit();
00299     const SiStripMatchedRecHit2D* matchedHit = matchedHitConverter(hit);
00300     if(matchedHit){
00301       GlobalPoint position = trackerGeometryHandle->idToDet(matchedHit->geographicalId())->surface().toGlobal(matchedHit->localPosition());
00302       if(preselection(position, superCluster, phiVsRSlope, 2)){
00303         tid1MHC++;
00304         hasLay1Hit = true;
00305         layer1Hits_.push_back(matchedHit);
00306         hasLay2Hit = true;
00307         layer2Hits_.push_back(matchedHit);
00308       }
00309     }else if(useDL.at(8) && tid1BHC < monoMaxHits_){
00310       const SiStripRecHit2D* backupHit = backupHitConverter(hit);
00311       if(backupHit){
00312         GlobalPoint position = trackerGeometryHandle->idToDet(backupHit->geographicalId())->surface().toGlobal(backupHit->localPosition());
00313         if(preselection(position, superCluster, phiVsRSlope, 4) && position.perp() > 37.){
00314           tid1BHC++;
00315           hasBackupHit = true;
00316           backupLayer2Hits_.push_back(backupHit);
00317         }
00318       }
00319     }
00320     }
00321   }
00322 
00323   for(std::vector<TrajectoryMeasurement>::const_iterator tmIter = tid2measurements.begin(); tmIter != tid2measurements.end(); ++ tmIter){
00324     if(tid2MHC < tidMaxHits_){
00325     ConstRecHitPointer hit = tmIter->recHit();
00326     const SiStripMatchedRecHit2D* matchedHit = matchedHitConverter(hit);
00327     if(matchedHit){
00328       GlobalPoint position = trackerGeometryHandle->idToDet(matchedHit->geographicalId())->surface().toGlobal(matchedHit->localPosition());
00329       if(preselection(position, superCluster, phiVsRSlope, 2)){
00330         tid2MHC++;
00331         hasLay1Hit = true;
00332         layer1Hits_.push_back(matchedHit);
00333         hasLay2Hit = true;
00334         layer2Hits_.push_back(matchedHit);
00335       }
00336     }else if(useDL.at(8) && tid2BHC < monoMaxHits_){
00337       const SiStripRecHit2D* backupHit = backupHitConverter(hit);
00338       if(backupHit){
00339         GlobalPoint position = trackerGeometryHandle->idToDet(backupHit->geographicalId())->surface().toGlobal(backupHit->localPosition());
00340         if(preselection(position, superCluster, phiVsRSlope, 4) && position.perp() > 37.){
00341           tid2BHC++;
00342           hasBackupHit = true;
00343           backupLayer2Hits_.push_back(backupHit);
00344         }
00345       }
00346     }
00347     }
00348   }
00349 
00350   for(std::vector<TrajectoryMeasurement>::const_iterator tmIter = tid3measurements.begin(); tmIter != tid3measurements.end(); ++ tmIter){
00351     if(tid3MHC < tidMaxHits_){
00352     ConstRecHitPointer hit = tmIter->recHit();
00353     const SiStripMatchedRecHit2D* matchedHit = matchedHitConverter(hit);
00354     if(matchedHit){
00355       GlobalPoint position = trackerGeometryHandle->idToDet(matchedHit->geographicalId())->surface().toGlobal(matchedHit->localPosition());
00356       if(preselection(position, superCluster, phiVsRSlope, 2)){
00357         tid3MHC++;
00358         hasLay1Hit = true;
00359         layer1Hits_.push_back(matchedHit);
00360         hasLay2Hit = true;
00361         layer2Hits_.push_back(matchedHit);
00362       }
00363     }else if(useDL.at(8) && tid3BHC < monoMaxHits_){
00364       const SiStripRecHit2D* backupHit = backupHitConverter(hit);
00365       if(backupHit){
00366         GlobalPoint position = trackerGeometryHandle->idToDet(backupHit->geographicalId())->surface().toGlobal(backupHit->localPosition());
00367         if(preselection(position, superCluster, phiVsRSlope, 4) && position.perp() > 37.){
00368           tid3BHC++;
00369           hasBackupHit = true;
00370           backupLayer2Hits_.push_back(backupHit);
00371         }
00372       }
00373     }
00374     }
00375   }
00376 
00377   std::vector<TrajectoryMeasurement> tec1measurements;
00378   if(useDL.at(5)) tec1measurements = layerMeasurements.measurements(*tec1,initialTSOS,*thePropagator,*theEstimator);
00379   std::vector<TrajectoryMeasurement> tec2measurements;
00380   if(useDL.at(6)) tec2measurements = layerMeasurements.measurements(*tec2,initialTSOS,*thePropagator,*theEstimator);
00381   std::vector<TrajectoryMeasurement> tec3measurements;
00382   if(useDL.at(7)) tec3measurements = layerMeasurements.measurements(*tec3,initialTSOS,*thePropagator,*theEstimator);
00383 
00384   for(std::vector<TrajectoryMeasurement>::const_iterator tmIter = tec1measurements.begin(); tmIter != tec1measurements.end(); ++ tmIter){
00385     if(tec1MHC < tecMaxHits_){
00386     ConstRecHitPointer hit = tmIter->recHit();
00387     const SiStripMatchedRecHit2D* matchedHit = matchedHitConverter(hit);
00388     if(matchedHit){
00389       GlobalPoint position = trackerGeometryHandle->idToDet(matchedHit->geographicalId())->surface().toGlobal(matchedHit->localPosition());
00390       if(preselection(position, superCluster, phiVsRSlope, 3)){
00391         tec1MHC++;
00392         hasLay1Hit = true;
00393         layer1Hits_.push_back(matchedHit);
00394         hasLay2Hit = true;
00395         layer2Hits_.push_back(matchedHit);
00396       }
00397     }
00398     }
00399   }
00400 
00401   for(std::vector<TrajectoryMeasurement>::const_iterator tmIter = tec2measurements.begin(); tmIter != tec2measurements.end(); ++ tmIter){
00402     if(tec2MHC < tecMaxHits_){
00403     ConstRecHitPointer hit = tmIter->recHit();
00404     const SiStripMatchedRecHit2D* matchedHit = matchedHitConverter(hit);
00405     if(matchedHit){
00406       GlobalPoint position = trackerGeometryHandle->idToDet(matchedHit->geographicalId())->surface().toGlobal(matchedHit->localPosition());
00407       if(preselection(position, superCluster, phiVsRSlope, 3)){
00408         tec2MHC++;
00409         hasLay1Hit = true;
00410         layer1Hits_.push_back(matchedHit);
00411         hasLay2Hit = true;
00412         layer2Hits_.push_back(matchedHit);
00413       }
00414     }
00415     }
00416   }
00417 
00418   for(std::vector<TrajectoryMeasurement>::const_iterator tmIter = tec3measurements.begin(); tmIter != tec3measurements.end(); ++ tmIter){
00419     if(tec3MHC < tecMaxHits_){
00420     ConstRecHitPointer hit = tmIter->recHit();
00421     const SiStripMatchedRecHit2D* matchedHit = matchedHitConverter(hit);
00422     if(matchedHit){
00423       GlobalPoint position = trackerGeometryHandle->idToDet(matchedHit->geographicalId())->surface().toGlobal(matchedHit->localPosition());
00424       if(preselection(position, superCluster, phiVsRSlope, 3)){
00425         tec3MHC++;
00426         hasLay2Hit = true;
00427         layer2Hits_.push_back(matchedHit);
00428       }
00429     }
00430     }
00431   }
00432 
00433   // We have 2 arrays of hits, combine them to form seeds
00434   if( hasLay1Hit && hasLay2Hit ){
00435 
00436     for (std::vector<const SiStripMatchedRecHit2D*>::const_iterator hit1 = layer1Hits_.begin() ; hit1!= layer1Hits_.end(); ++hit1) {
00437       for (std::vector<const SiStripMatchedRecHit2D*>::const_iterator hit2 = layer2Hits_.begin() ; hit2!= layer2Hits_.end(); ++hit2) {
00438 
00439         if(seedCounter < maxSeeds_){
00440 
00441           if(checkHitsAndTSOS(hit1,hit2,scr,scz,pT,scEta)) {
00442 
00443             seedCounter++;
00444 
00445             recHits_.clear();
00446 
00447             SiStripMatchedRecHit2D *hit;
00448             hit=new SiStripMatchedRecHit2D(*(dynamic_cast <const SiStripMatchedRecHit2D *> (*hit1) ) );
00449             recHits_.push_back(hit);
00450             hit=new SiStripMatchedRecHit2D(*(dynamic_cast <const SiStripMatchedRecHit2D *> (*hit2) ) );
00451             recHits_.push_back(hit);
00452 
00453             PropagationDirection dir = alongMomentum;
00454             reco::ElectronSeed seed(pts_,recHits_,dir) ;
00455             reco::ElectronSeed::CaloClusterRef caloCluster(seedCluster) ;
00456             seed.setCaloCluster(caloCluster) ;
00457             result.push_back(seed);
00458 
00459           }
00460 
00461         }
00462 
00463       }// end of hit 2 loop
00464 
00465     }// end of hit 1 loop
00466 
00467   }//end of seed making
00468 
00469   //Make seeds using TID Ring 3 if necessary
00470 
00471   if(hasLay1Hit && hasBackupHit && seedCounter == 0){
00472 
00473     for (std::vector<const SiStripMatchedRecHit2D*>::const_iterator hit1 = layer1Hits_.begin() ; hit1!= layer1Hits_.end(); ++hit1) {
00474       for (std::vector<const SiStripRecHit2D*>::const_iterator hit2 = backupLayer2Hits_.begin() ; hit2!= backupLayer2Hits_.end(); ++hit2) {
00475 
00476         if(seedCounter < maxSeeds_){
00477 
00478           if(altCheckHitsAndTSOS(hit1,hit2,scr,scz,pT,scEta)) {
00479 
00480             seedCounter++;
00481 
00482             recHits_.clear();
00483 
00484             SiStripMatchedRecHit2D *innerHit;
00485             innerHit=new SiStripMatchedRecHit2D(*(dynamic_cast <const SiStripMatchedRecHit2D *> (*hit1) ) );
00486             recHits_.push_back(innerHit);
00487             SiStripRecHit2D *outerHit;
00488             outerHit=new SiStripRecHit2D(*(dynamic_cast <const SiStripRecHit2D *> (*hit2) ) );
00489             recHits_.push_back(outerHit);
00490 
00491             PropagationDirection dir = alongMomentum;
00492             reco::ElectronSeed seed(pts_,recHits_,dir) ;
00493             reco::ElectronSeed::CaloClusterRef caloCluster(seedCluster) ;
00494             seed.setCaloCluster(caloCluster) ;
00495             result.push_back(seed);
00496 
00497           }
00498 
00499         }
00500 
00501       }// end of hit 2 loop
00502 
00503     }// end of hit 1 loop
00504 
00505   }// end of backup seed making
00506 
00507 } // end of findSeedsFromCluster
00508 
00509 
00510 
00511 bool SiStripElectronSeedGenerator::checkHitsAndTSOS(std::vector<const SiStripMatchedRecHit2D*>::const_iterator hit1,
00512                                                     std::vector<const SiStripMatchedRecHit2D*>::const_iterator hit2,
00513                                                     double rc,double zc,double pT,double scEta) {
00514 
00515   bool seedCutsSatisfied = false;
00516 
00517   using namespace std;
00518 
00519   GlobalPoint hit1Pos = trackerGeometryHandle->idToDet((*hit1)->geographicalId())->surface().toGlobal((*hit1)->localPosition());
00520   double r1 = sqrt(hit1Pos.x()*hit1Pos.x() + hit1Pos.y()*hit1Pos.y());
00521   double phi1 = hit1Pos.phi();
00522   double z1=hit1Pos.z();
00523 
00524   GlobalPoint hit2Pos = trackerGeometryHandle->idToDet((*hit2)->geographicalId())->surface().toGlobal((*hit2)->localPosition());
00525   double r2 = sqrt(hit2Pos.x()*hit2Pos.x() + hit2Pos.y()*hit2Pos.y());
00526   double phi2 = hit2Pos.phi();
00527   double z2 = hit2Pos.z();
00528 
00529   if(r2 > r1 && (std::abs(z2) > std::abs(z1) || std::abs(scEta) < 0.25)) {
00530 
00531     //Consider the circle made of IP and Hit 1; Calculate it's radius using pT
00532 
00533     double curv = pT*100*.877;
00534 
00535     //Predict phi of hit 2
00536     double a = (r2-r1)/(2*curv);
00537     double b = phiDiff(phi2,phi1);
00538     //UB added '=0' to avoid compiler warning
00539     double phiMissHit2=0;
00540     if(std::abs(b - a)<std::abs(b + a)) phiMissHit2 = b - a;
00541     if(std::abs(b - a)>std::abs(b + a)) phiMissHit2 = b + a;
00542 
00543     double zMissHit2 = z2 - (r2*(zc-z1)-r1*zc+rc*z1)/(rc-r1);
00544 
00545     double rPredHit2 = r1 + (rc-r1)/(zc-z1)*(z2-z1);
00546     double rMissHit2 = r2 - rPredHit2;
00547 
00548     int subdetector = whichSubdetector(hit2);
00549 
00550     bool zDiff = true;
00551     double zVar1 = std::abs(z1);
00552     double zVar2 = std::abs(z2 - z1);
00553     if(zVar1 > 75 && zVar1 < 95 && (zVar2 > 18 || zVar2 < 5)) zDiff = false;
00554     if(zVar1 > 100 && zVar1 < 110 && (zVar2 > 35 || zVar2 < 5)) zDiff = false;
00555     if(zVar1 > 125 && zVar1 < 150 && (zVar2 > 18 || zVar2 < 5)) zDiff = false;
00556 
00557     if(subdetector == 1){
00558       int tibExtraCut = 0;
00559       if(r1 > 23 && r1 < 28 && r2 > 31 && r2 < 37) tibExtraCut = 1;
00560       if(std::abs(phiMissHit2) < tibPhiMissHit2Cut_ && std::abs(zMissHit2) < tibZMissHit2Cut_ && tibExtraCut == 1) seedCutsSatisfied = true;
00561     }else if(subdetector == 2){
00562       int tidExtraCut = 0;
00563       if(r1 > 23 && r1 < 34 && r2 > 26 && r2 < 42) tidExtraCut = 1;
00564       if(std::abs(phiMissHit2) < tidPhiMissHit2Cut_ && std::abs(rMissHit2) < tidRMissHit2Cut_ && tidExtraCut == 1 && zDiff) seedCutsSatisfied = true;
00565     }else if(subdetector == 3){
00566       int tecExtraCut = 0;
00567       if(r1 > 23 && r1 < 32 && r2 > 26 && r2 < 42) tecExtraCut = 1;
00568       if(std::abs(phiMissHit2) < tecPhiMissHit2Cut_ && std::abs(rMissHit2) < tecRMissHit2Cut_ && tecExtraCut == 1 && zDiff) seedCutsSatisfied = true;
00569     }
00570 
00571   }
00572 
00573   if(!seedCutsSatisfied) return false;
00574 
00575   // seed checks borrowed from pixel-based algoritm
00576 
00577 
00578   /* Some of this code could be better optimized.  The Pixel algorithm natively
00579      takes Transient rec hits, so to recycle code we have to build them.
00580   */
00581 
00582   RecHitPointer hit1Trans = TSiStripMatchedRecHit::build(trackerGeometryHandle->idToDet((*hit1)->geographicalId()), *hit1, theMatcher_);
00583   RecHitPointer hit2Trans = TSiStripMatchedRecHit::build(trackerGeometryHandle->idToDet((*hit2)->geographicalId()), *hit2, theMatcher_);
00584 
00585   typedef TrajectoryStateOnSurface TSOS;
00586 
00587   double vertexZ = z1 - (r1 * (zc - z1) ) / (rc - r1);
00588   GlobalPoint eleVertex(0.,0.,vertexZ);
00589 
00590    // FIXME optimize: move outside loop
00591     edm::ESHandle<MagneticField> bfield;
00592     theSetup->get<IdealMagneticFieldRecord>().get(bfield);
00593     float nomField = bfield->nominalValue();
00594 
00595   // make a spiral
00596   FastHelix helix(hit2Pos,hit1Pos,eleVertex,nomField,&*bfield);
00597   if (!helix.isValid()) return false;
00598 
00599   FreeTrajectoryState fts(helix.stateAtVertex());
00600   TSOS propagatedState = thePropagator->propagate(fts,hit1Trans->det()->surface());
00601 
00602   if (!propagatedState.isValid()) return false;
00603 
00604   TSOS updatedState = theUpdator->update(propagatedState, *hit1Trans);
00605   TSOS propagatedState_out = thePropagator->propagate(fts,hit2Trans->det()->surface()) ;
00606 
00607   if (!propagatedState_out.isValid()) return false;
00608 
00609   // the seed has now passed all the cuts
00610 
00611   TSOS updatedState_out = theUpdator->update(propagatedState_out, *hit2Trans);
00612 
00613   pts_ =  trajectoryStateTransform::persistentState(updatedState_out, hit2Trans->geographicalId().rawId());
00614 
00615   return true;
00616 }
00617 
00618 bool SiStripElectronSeedGenerator::altCheckHitsAndTSOS(std::vector<const SiStripMatchedRecHit2D*>::const_iterator hit1,
00619                                                        std::vector<const SiStripRecHit2D*>::const_iterator hit2,
00620                                                        double rc,double zc,double pT,double scEta) {
00621 
00622   bool seedCutSatisfied = false;
00623 
00624   using namespace std;
00625 
00626   GlobalPoint hit1Pos = trackerGeometryHandle->idToDet((*hit1)->geographicalId())->surface().toGlobal((*hit1)->localPosition());
00627   double r1 = sqrt(hit1Pos.x()*hit1Pos.x() + hit1Pos.y()*hit1Pos.y());
00628   double phi1 = hit1Pos.phi();
00629   double z1=hit1Pos.z();
00630 
00631   GlobalPoint hit2Pos = trackerGeometryHandle->idToDet((*hit2)->geographicalId())->surface().toGlobal((*hit2)->localPosition());
00632   double r2 = sqrt(hit2Pos.x()*hit2Pos.x() + hit2Pos.y()*hit2Pos.y());
00633   double phi2 = hit2Pos.phi();
00634   double z2 = hit2Pos.z();
00635 
00636   if(r2 > r1 && std::abs(z2) > std::abs(z1)) {
00637 
00638     //Consider the circle made of IP and Hit 1; Calculate it's radius using pT
00639 
00640     double curv = pT*100*.877;
00641 
00642     //Predict phi of hit 2
00643     double a = (r2-r1)/(2*curv);
00644     double b = phiDiff(phi2,phi1);
00645     double phiMissHit2 = 0;
00646     if(std::abs(b - a)<std::abs(b + a)) phiMissHit2 = b - a;
00647     if(std::abs(b - a)>std::abs(b + a)) phiMissHit2 = b + a;
00648 
00649     if(std::abs(phiMissHit2) < monoPhiMissHit2Cut_) seedCutSatisfied = true;
00650 
00651   }
00652 
00653   if(!seedCutSatisfied) return false;
00654 
00655   // seed checks borrowed from pixel-based algoritm
00656 
00657  
00658 
00659   /* Some of this code could be better optimized.  The Pixel algorithm natively
00660      takes Transient rec hits, so to recycle code we have to build them.
00661   */
00662 
00663   RecHitPointer hit1Trans = TSiStripMatchedRecHit::build(trackerGeometryHandle->idToDet((*hit1)->geographicalId()), *hit1, theMatcher_);
00664   RecHitPointer hit2Trans = TSiStripMatchedRecHit::build(trackerGeometryHandle->idToDet((*hit2)->geographicalId()), *hit2, theMatcher_);
00665 
00666   typedef TrajectoryStateOnSurface TSOS;
00667 
00668   double vertexZ = z1 - (r1 * (zc - z1) ) / (rc - r1);
00669   GlobalPoint eleVertex(0.,0.,vertexZ);
00670 
00671    // FIXME optimize: move outside loop
00672     edm::ESHandle<MagneticField> bfield;
00673     theSetup->get<IdealMagneticFieldRecord>().get(bfield);
00674     float nomField = bfield->nominalValue();
00675 
00676   // make a spiral
00677   FastHelix helix(hit2Pos,hit1Pos,eleVertex,nomField,&*bfield);
00678   if (!helix.isValid()) return false;
00679 
00680   FreeTrajectoryState fts(helix.stateAtVertex());
00681   TSOS propagatedState = thePropagator->propagate(fts,hit1Trans->det()->surface());
00682 
00683   if (!propagatedState.isValid()) return false;
00684 
00685   TSOS updatedState = theUpdator->update(propagatedState, *hit1Trans);
00686   TSOS propagatedState_out = thePropagator->propagate(fts,hit2Trans->det()->surface()) ;
00687 
00688   if (!propagatedState_out.isValid()) return false;
00689 
00690   // the seed has now passed all the cuts
00691 
00692   TSOS updatedState_out = theUpdator->update(propagatedState_out, *hit2Trans);
00693 
00694   pts_ =  trajectoryStateTransform::persistentState(updatedState_out, hit2Trans->geographicalId().rawId());
00695 
00696   return true;
00697 }
00698 
00699 
00700 bool SiStripElectronSeedGenerator::preselection(GlobalPoint position,GlobalPoint superCluster,double phiVsRSlope,int hitLayer){
00701   double r = position.perp();
00702   double phi = position.phi();
00703   double z = position.z();
00704   double scr = superCluster.perp();
00705   double scphi = superCluster.phi();
00706   double scz = superCluster.z();
00707   double psi = phiDiff(phi,scphi);
00708   double deltaPsi = psi - (scr-r)*phiVsRSlope;
00709   double antiDeltaPsi = psi - (r-scr)*phiVsRSlope;
00710   double dP;
00711   if (std::abs(deltaPsi)<std::abs(antiDeltaPsi)){
00712     dP = deltaPsi;
00713   }else{
00714     dP = antiDeltaPsi;
00715   }
00716   double originZ = (scr*z - r*scz)/(scr-r);
00717 
00718   bool result = false;
00719 
00720   if(hitLayer == 1){
00721     if(std::abs(originZ) < tibOriginZCut_ && std::abs(dP) < tibDeltaPsiCut_) result = true;
00722   }else if(hitLayer == 2){
00723     if(std::abs(originZ) < tidOriginZCut_ && std::abs(dP) < tidDeltaPsiCut_) result = true;
00724   }else if(hitLayer == 3){
00725     if(std::abs(originZ) < tecOriginZCut_ && std::abs(dP) < tecDeltaPsiCut_) result = true;
00726   }else if(hitLayer == 4){
00727     if(std::abs(originZ) < monoOriginZCut_ && std::abs(dP) < monoDeltaPsiCut_) result = true;
00728   }
00729 
00730   return result;
00731 }
00732 
00733 // Helper algorithms
00734 
00735 int SiStripElectronSeedGenerator::whichSubdetector(std::vector<const SiStripMatchedRecHit2D*>::const_iterator hit){
00736   int result = 0;
00737   if(((*hit)->geographicalId()).subdetId() == StripSubdetector::TIB){
00738     result = 1;
00739   }else if(((*hit)->geographicalId()).subdetId() == StripSubdetector::TID){
00740     result = 2;
00741   }else if(((*hit)->geographicalId()).subdetId() == StripSubdetector::TEC){
00742     result = 3;
00743   }
00744   return result;
00745 }
00746 
00747 const SiStripMatchedRecHit2D* SiStripElectronSeedGenerator::matchedHitConverter(ConstRecHitPointer crhp){
00748   const TrackingRecHit* trh = crhp->hit();
00749   const SiStripMatchedRecHit2D* matchedHit = dynamic_cast<const SiStripMatchedRecHit2D*>(trh);
00750   return matchedHit;
00751 }
00752 
00753 const SiStripRecHit2D* SiStripElectronSeedGenerator::backupHitConverter(ConstRecHitPointer crhp){
00754   const TrackingRecHit* trh = crhp->hit();
00755   const SiStripRecHit2D* backupHit = dynamic_cast<const SiStripRecHit2D*>(trh);
00756   return backupHit;
00757 }
00758 
00759 std::vector<bool> SiStripElectronSeedGenerator::useDetLayer(double scEta){
00760   std::vector<bool> useDetLayer;
00761   double variable = std::abs(scEta);
00762   if(variable > 0 && variable < 1.8){
00763     useDetLayer.push_back(true);
00764   }else{
00765     useDetLayer.push_back(false);
00766   }
00767   if(variable > 0 && variable < 1.5){
00768     useDetLayer.push_back(true);
00769   }else{
00770     useDetLayer.push_back(false);
00771   }
00772   if(variable > 1 && variable < 2.1){
00773     useDetLayer.push_back(true);
00774   }else{
00775     useDetLayer.push_back(false);
00776   }
00777   if(variable > 1 && variable < 2.2){
00778     useDetLayer.push_back(true);
00779   }else{
00780     useDetLayer.push_back(false);
00781   }
00782   if(variable > 1 && variable < 2.3){
00783     useDetLayer.push_back(true);
00784   }else{
00785     useDetLayer.push_back(false);
00786   }
00787   if(variable > 1.8 && variable < 2.5){
00788     useDetLayer.push_back(true);
00789   }else{
00790     useDetLayer.push_back(false);
00791   }
00792   if(variable > 1.8 && variable < 2.5){
00793     useDetLayer.push_back(true);
00794   }else{
00795     useDetLayer.push_back(false);
00796   }
00797   if(variable > 1.8 && variable < 2.5){
00798     useDetLayer.push_back(true);
00799   }else{
00800     useDetLayer.push_back(false);
00801   }
00802   if(variable > 1.2 && variable < 1.6){
00803     useDetLayer.push_back(true);
00804   }else{
00805     useDetLayer.push_back(false);
00806   }
00807   return useDetLayer;
00808 }
00809 
00810 
00811