CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Alignment/CommonAlignmentProducer/src/AlignmentTrackSelector.cc

Go to the documentation of this file.
00001 #include "Alignment/CommonAlignmentProducer/interface/AlignmentTrackSelector.h"
00002 
00003 #include "FWCore/Framework/interface/ESHandle.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00006 
00007 #include "FWCore/Framework/interface/Event.h"
00008 
00009 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00010 #include "DataFormats/TrackerRecHit2D/interface/SiPixelRecHit.h"
00011 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit1D.h"
00012 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2D.h"
00013 #include "DataFormats/TrackerRecHit2D/interface/ProjectedSiStripRecHit2D.h"
00014 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h"
00015 #include "DataFormats/TrackerRecHit2D/interface/SiTrackerMultiRecHit.h"
00016 #include "DataFormats/SiStripCluster/interface/SiStripCluster.h"
00017 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2DCollection.h"
00018 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2DCollection.h"
00019 #include "DataFormats/Alignment/interface/AlignmentClusterFlag.h"
00020 #include "DataFormats/Alignment/interface/AliClusterValueMap.h"
00021 
00022 #include "DataFormats/DetId/interface/DetId.h"
00023 #include "DataFormats/SiStripDetId/interface/SiStripDetId.h"
00024 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00025 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
00026 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00027 
00028 #include <cmath>
00029 
00030 const int kBPIX = PixelSubdetector::PixelBarrel;
00031 const int kFPIX = PixelSubdetector::PixelEndcap;
00032 
00033 // constructor ----------------------------------------------------------------
00034 
00035 AlignmentTrackSelector::AlignmentTrackSelector(const edm::ParameterSet & cfg) :
00036   applyBasicCuts_( cfg.getParameter<bool>( "applyBasicCuts" ) ),
00037   applyNHighestPt_( cfg.getParameter<bool>( "applyNHighestPt" ) ),
00038   applyMultiplicityFilter_( cfg.getParameter<bool>( "applyMultiplicityFilter" ) ),
00039   seedOnlyFromAbove_( cfg.getParameter<int>( "seedOnlyFrom" ) ),
00040   applyIsolation_( cfg.getParameter<bool>( "applyIsolationCut" ) ),
00041   chargeCheck_( cfg.getParameter<bool>( "applyChargeCheck" ) ),
00042   nHighestPt_( cfg.getParameter<int>( "nHighestPt" ) ),
00043   minMultiplicity_ ( cfg.getParameter<int>( "minMultiplicity" ) ),
00044   maxMultiplicity_ ( cfg.getParameter<int>( "maxMultiplicity" ) ),
00045   multiplicityOnInput_ ( cfg.getParameter<bool>( "multiplicityOnInput" ) ),
00046   ptMin_( cfg.getParameter<double>( "ptMin" ) ),
00047   ptMax_( cfg.getParameter<double>( "ptMax" ) ),
00048   pMin_( cfg.getParameter<double>( "pMin" ) ),
00049   pMax_( cfg.getParameter<double>( "pMax" ) ),
00050   etaMin_( cfg.getParameter<double>( "etaMin" ) ),
00051   etaMax_( cfg.getParameter<double>( "etaMax" ) ),
00052   phiMin_( cfg.getParameter<double>( "phiMin" ) ),
00053   phiMax_( cfg.getParameter<double>( "phiMax" ) ),
00054   nHitMin_( cfg.getParameter<double>( "nHitMin" ) ),
00055   nHitMax_( cfg.getParameter<double>( "nHitMax" ) ),
00056   chi2nMax_( cfg.getParameter<double>( "chi2nMax" ) ),
00057   d0Min_(  cfg.getParameter<double>( "d0Min" ) ),
00058   d0Max_(  cfg.getParameter<double>( "d0Max" ) ),
00059   dzMin_(  cfg.getParameter<double>( "dzMin" ) ),
00060   dzMax_(  cfg.getParameter<double>( "dzMax" ) ),
00061   theCharge_( cfg.getParameter<int>( "theCharge" ) ),
00062   minHitChargeStrip_( cfg.getParameter<double>( "minHitChargeStrip" ) ),
00063   minHitIsolation_( cfg.getParameter<double>( "minHitIsolation" ) ),
00064   rphirecHitsTag_( cfg.getParameter<edm::InputTag>("rphirecHits") ),
00065   matchedrecHitsTag_( cfg.getParameter<edm::InputTag>("matchedrecHits") ),
00066   countStereoHitAs2D_( cfg.getParameter<bool>( "countStereoHitAs2D" ) ),
00067   nHitMin2D_( cfg.getParameter<unsigned int>( "nHitMin2D" ) ),
00068   // Ugly to use the same getParameter n times, but this allows const cut variables...
00069   minHitsinTIB_(cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inTIB" ) ),
00070   minHitsinTOB_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inTOB" ) ),
00071   minHitsinTID_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inTID" ) ),
00072   minHitsinTEC_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inTEC" ) ),
00073   minHitsinBPIX_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inBPIX" ) ),
00074   minHitsinFPIX_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inFPIX" ) ),
00075   minHitsinPIX_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inPIXEL" ) ),
00076   minHitsinTIDplus_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inTIDplus" ) ),
00077   minHitsinTIDminus_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inTIDminus" ) ),
00078   minHitsinTECplus_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inTECplus" ) ),
00079   minHitsinTECminus_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inTECminus" ) ),
00080   minHitsinFPIXplus_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inFPIXplus" ) ),
00081   minHitsinFPIXminus_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inFPIXminus" ) ),
00082   minHitsinENDCAP_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inENDCAP" ) ),
00083   minHitsinENDCAPplus_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inENDCAPplus" ) ),
00084   minHitsinENDCAPminus_ (cfg.getParameter<edm::ParameterSet>( "minHitsPerSubDet" ).getParameter<int>( "inENDCAPminus" ) ),
00085   maxHitDiffEndcaps_( cfg.getParameter<double>( "maxHitDiffEndcaps" ) ),
00086   nLostHitMax_( cfg.getParameter<double>( "nLostHitMax" ) ),
00087   RorZofFirstHitMin_( cfg.getParameter<std::vector<double> >( "RorZofFirstHitMin" ) ),
00088   RorZofFirstHitMax_( cfg.getParameter<std::vector<double> >( "RorZofFirstHitMax" ) ),
00089   RorZofLastHitMin_( cfg.getParameter<std::vector<double> >( "RorZofLastHitMin" ) ),
00090   RorZofLastHitMax_( cfg.getParameter<std::vector<double> >( "RorZofLastHitMax" ) ),
00091   clusterValueMapTag_(cfg.getParameter<edm::InputTag>("hitPrescaleMapTag")),
00092   minPrescaledHits_( cfg.getParameter<int>("minPrescaledHits")),
00093   applyPrescaledHitsFilter_(clusterValueMapTag_.encode().size() && minPrescaledHits_ > 0)
00094 {
00095 
00096   //convert track quality from string to enum
00097   std::vector<std::string> trkQualityStrings(cfg.getParameter<std::vector<std::string> >("trackQualities"));
00098   std::string qualities;
00099   if(trkQualityStrings.size()>0){
00100     applyTrkQualityCheck_=true;
00101     for (unsigned int i = 0; i < trkQualityStrings.size(); ++i) {
00102       (qualities += trkQualityStrings[i]) += ", ";
00103       trkQualities_.push_back(reco::TrackBase::qualityByName(trkQualityStrings[i]));
00104     }
00105   }
00106   else applyTrkQualityCheck_=false;
00107 
00108   std::vector<std::string> trkIterStrings(cfg.getParameter<std::vector<std::string> >("iterativeTrackingSteps"));
00109   if(trkIterStrings.size()>0){
00110     applyIterStepCheck_=true;
00111     std::string tracksteps;
00112     for (unsigned int i = 0; i < trkIterStrings.size(); ++i) {
00113       (tracksteps += trkIterStrings[i]) += ", ";
00114       trkSteps_.push_back(reco::TrackBase::algoByName(trkIterStrings[i]));
00115     }
00116   }
00117   else   applyIterStepCheck_=false;
00118 
00119   if (applyBasicCuts_){
00120       edm::LogInfo("AlignmentTrackSelector") 
00121         << "applying basic track cuts ..."
00122         << "\nptmin,ptmax:     " << ptMin_   << "," << ptMax_ 
00123         << "\npmin,pmax:       " << pMin_    << "," << pMax_ 
00124         << "\netamin,etamax:   " << etaMin_  << "," << etaMax_
00125         << "\nphimin,phimax:   " << phiMin_  << "," << phiMax_
00126         << "\nnhitmin,nhitmax: " << nHitMin_ << "," << nHitMax_
00127         << "\nnlosthitmax:     " << nLostHitMax_
00128         << "\nnhitmin2D:       " << nHitMin2D_
00129         << (countStereoHitAs2D_ ? "," : ", not") << " counting hits on SiStrip stereo modules as 2D" 
00130         << "\nchi2nmax:        " << chi2nMax_;
00131 
00132       if (applyIsolation_)
00133         edm::LogInfo("AlignmentTrackSelector") 
00134           << "only retain tracks isolated at least by " << minHitIsolation_ << 
00135           " cm from other rechits"; 
00136       
00137       if (chargeCheck_)
00138         edm::LogInfo("AlignmentTrackSelector") 
00139           << "only retain hits with at least " << minHitChargeStrip_ <<  
00140           " ADC counts of total cluster charge"; 
00141    
00142       edm::LogInfo("AlignmentTrackSelector") 
00143         << "Minimum number of hits in TIB/TID/TOB/TEC/BPIX/FPIX/PIXEL = " 
00144         << minHitsinTIB_ << "/" << minHitsinTID_ << "/" << minHitsinTOB_
00145         << "/" << minHitsinTEC_ << "/" << minHitsinBPIX_ << "/" << minHitsinFPIX_ << "/" << minHitsinPIX_;
00146 
00147       edm::LogInfo("AlignmentTrackSelector")
00148         << "Minimum number of hits in TID+/TID-/TEC+/TEC-/FPIX+/FPIX- = "
00149         << minHitsinTIDplus_ << "/" << minHitsinTIDminus_
00150         << "/" << minHitsinTECplus_ << "/" << minHitsinTECminus_
00151         << "/" << minHitsinFPIXplus_ << "/" << minHitsinFPIXminus_;
00152 
00153       edm::LogInfo("AlignmentTrackSelector")
00154         << "Minimum number of hits in EndCap (TID+TEC)/EndCap+/EndCap- = "
00155         << minHitsinENDCAP_ << "/" << minHitsinENDCAPplus_ << "/" << minHitsinENDCAPminus_;
00156 
00157       edm::LogInfo("AlignmentTrackSelector")
00158         << "Max value of |nHitsinENDCAPplus - nHitsinENDCAPminus| = "
00159         << maxHitDiffEndcaps_;
00160 
00161       if (trkQualityStrings.size()) {
00162         edm::LogInfo("AlignmentTrackSelector")
00163           << "Select tracks with these qualities: " << qualities;
00164       }    
00165   }
00166   
00167   if (applyNHighestPt_)
00168         edm::LogInfo("AlignmentTrackSelector") 
00169           << "filter N tracks with highest Pt N=" << nHighestPt_;
00170 
00171   if (applyMultiplicityFilter_)
00172         edm::LogInfo("AlignmentTrackSelector") 
00173           << "apply multiplicity filter N>= " << minMultiplicity_ << "and N<= " << maxMultiplicity_
00174           << " on " << (multiplicityOnInput_ ? "input" : "output");
00175 
00176   if (applyPrescaledHitsFilter_) {
00177     edm::LogInfo("AlignmentTrackSelector") 
00178       << "apply cut on number of prescaled hits N>= " << minPrescaledHits_
00179       << " (prescale info from " << clusterValueMapTag_ << ")";
00180     
00181   }
00182 
00183   // Checking whether cuts on positions of first and last track hits are defined properly
00184   if(RorZofFirstHitMin_.size() != 2){
00185       throw cms::Exception("BadConfig") << "@SUB=AlignmentTrackSelector::AlignmentTrackSelector" 
00186           << "Wrong configuration of 'RorZofFirstHitMin'."
00187           << " Must have exactly 2 values instead of configured " << RorZofFirstHitMin_.size() << ")";
00188   } else {
00189     RorZofFirstHitMin_.at(0)=std::fabs(RorZofFirstHitMin_.at(0));
00190     RorZofFirstHitMin_.at(1)=std::fabs(RorZofFirstHitMin_.at(1));
00191   }
00192   if(RorZofFirstHitMax_.size() != 2){
00193       throw cms::Exception("BadConfig") << "@SUB=AlignmentTrackSelector::AlignmentTrackSelector" 
00194           << "Wrong configuration of 'RorZofFirstHitMax'."
00195           << " Must have exactly 2 values instead of configured " << RorZofFirstHitMax_.size() << ")";
00196   } else {
00197     RorZofFirstHitMax_.at(0) = std::fabs(RorZofFirstHitMax_.at(0));
00198     RorZofFirstHitMax_.at(1) = std::fabs(RorZofFirstHitMax_.at(1));
00199   }
00200   if(RorZofLastHitMin_.size() != 2){
00201       throw cms::Exception("BadConfig") << "@SUB=AlignmentTrackSelector::AlignmentTrackSelector" 
00202           << "Wrong configuration of 'RorZofLastHitMin'."
00203           << " Must have exactly 2 values instead of configured " << RorZofLastHitMin_.size() << ")";
00204   } else {
00205     RorZofLastHitMin_.at(0) = std::fabs(RorZofLastHitMin_.at(0));
00206     RorZofLastHitMin_.at(1) = std::fabs(RorZofLastHitMin_.at(1));
00207   }
00208   if(RorZofLastHitMax_.size() != 2){
00209       throw cms::Exception("BadConfig") << "@SUB=AlignmentTrackSelector::AlignmentTrackSelector" 
00210           << "Wrong configuration of 'RorZofLastHitMax'."
00211           << " Must have exactly 2 values instead of configured " << RorZofLastHitMax_.size() << ")";
00212   } else {
00213     RorZofLastHitMax_.at(0) = std::fabs(RorZofLastHitMax_.at(0));
00214     RorZofLastHitMax_.at(1) = std::fabs(RorZofLastHitMax_.at(1));
00215   }
00216   // If first hit set to be at larger distance then the last hit
00217   if(RorZofFirstHitMin_.at(0) > RorZofLastHitMax_.at(0) && RorZofFirstHitMin_.at(1) > RorZofLastHitMax_.at(1)){
00218       throw cms::Exception("BadConfig") << "@SUB=AlignmentTrackSelector::AlignmentTrackSelector" 
00219           << "Position of the first hit is set to larger distance than the last hit:."
00220           << " First hit(min): [" << RorZofFirstHitMin_.at(0) << ", " << RorZofFirstHitMin_.at(1) << "]; Last hit(max): [" 
00221           << RorZofLastHitMax_.at(0) << ", " << RorZofLastHitMax_.at(1) << "];";
00222   }
00223 
00224 }
00225 
00226 // destructor -----------------------------------------------------------------
00227 
00228 AlignmentTrackSelector::~AlignmentTrackSelector()
00229 {}
00230 
00231 
00232 // do selection ---------------------------------------------------------------
00233 
00234 AlignmentTrackSelector::Tracks 
00235 AlignmentTrackSelector::select(const Tracks& tracks, const edm::Event& evt, const edm::EventSetup& eSetup) const 
00236 {
00237   
00238   if (applyMultiplicityFilter_ && multiplicityOnInput_ && 
00239       (tracks.size() < static_cast<unsigned int>(minMultiplicity_) 
00240        || tracks.size() > static_cast<unsigned int>(maxMultiplicity_))) {
00241     return Tracks(); // empty collection
00242   }
00243 
00244   Tracks result = tracks;
00245   // apply basic track cuts (if selected)
00246   if (applyBasicCuts_) result= this->basicCuts(result, evt, eSetup);
00247   
00248   // filter N tracks with highest Pt (if selected)
00249   if (applyNHighestPt_) result = this->theNHighestPtTracks(result);
00250   
00251   // apply minimum multiplicity requirement (if selected)
00252   if (applyMultiplicityFilter_ && !multiplicityOnInput_) {
00253     if (result.size() < static_cast<unsigned int>(minMultiplicity_) 
00254         || result.size() > static_cast<unsigned int>(maxMultiplicity_) ) {
00255 
00256       result.clear();
00257     }
00258   }
00259 
00260   if(applyPrescaledHitsFilter_){
00261     result = this->checkPrescaledHits(result, evt);
00262   }
00263 
00264   return result;
00265 }
00266 
00268 bool AlignmentTrackSelector::useThisFilter()
00269 {
00270   return applyMultiplicityFilter_ || applyBasicCuts_ || applyNHighestPt_ || applyPrescaledHitsFilter_;
00271 
00272 }
00273 
00274 
00275 // make basic cuts ------------------------------------------------------------
00276 
00277 AlignmentTrackSelector::Tracks 
00278 AlignmentTrackSelector::basicCuts(const Tracks& tracks, const edm::Event& evt, const edm::EventSetup& eSetup) const 
00279 {
00280   Tracks result;
00281 
00282   for (Tracks::const_iterator it=tracks.begin(); it != tracks.end(); ++it) {
00283     const reco::Track* trackp=*it;
00284     float pt=trackp->pt();
00285     float p=trackp->p();
00286     float eta=trackp->eta();
00287     float phi=trackp->phi();
00288     int nhit = trackp->numberOfValidHits(); 
00289     int nlosthit = trackp->numberOfLostHits(); 
00290     float chi2n = trackp->normalizedChi2();
00291 
00292     int q = trackp->charge();
00293     bool isChargeOk = false;
00294     if(theCharge_==-1 && q<0)         isChargeOk = true; 
00295     else if (theCharge_==1 && q>0)    isChargeOk = true; 
00296     else if (theCharge_==0)           isChargeOk = true; 
00297 
00298     float d0    = trackp->d0();
00299     float dz    = trackp->dz();
00300 
00301     // edm::LogDebug("AlignmentTrackSelector") << " pt,eta,phi,nhit: "
00302     //  <<pt<<","<<eta<<","<<phi<<","<<nhit;
00303 
00304     if (pt>ptMin_ && pt<ptMax_ 
00305        && p>pMin_ && p<pMax_ 
00306        && eta>etaMin_ && eta<etaMax_ 
00307        && phi>phiMin_ && phi<phiMax_ 
00308        && nhit>=nHitMin_ && nhit<=nHitMax_
00309        && nlosthit<=nLostHitMax_
00310        && chi2n<chi2nMax_
00311        && isChargeOk
00312        && d0>=d0Min_ && d0<=d0Max_
00313        && dz>=dzMin_ && dz<=dzMax_) {
00314       bool trkQualityOk=false ;
00315       if (!applyTrkQualityCheck_ &&!applyIterStepCheck_)trkQualityOk=true ; // nothing required
00316       else trkQualityOk = this->isOkTrkQuality(trackp);
00317 
00318       bool hitsCheckOk=this->detailedHitsCheck(trackp, evt, eSetup);
00319  
00320       if (trkQualityOk && hitsCheckOk )  result.push_back(trackp);
00321     }
00322   }
00323 
00324   return result;
00325 }
00326 
00327 //-----------------------------------------------------------------------------
00328 
00329 bool AlignmentTrackSelector::detailedHitsCheck(const reco::Track *trackp, const edm::Event& evt, const edm::EventSetup& eSetup) const
00330 {
00331 
00332   //Retrieve tracker topology from geometry
00333   edm::ESHandle<TrackerTopology> tTopoHandle;
00334   eSetup.get<IdealGeometryRecord>().get(tTopoHandle);
00335   const TrackerTopology* const tTopo = tTopoHandle.product();
00336 
00337   // checking hit requirements beyond simple number of valid hits
00338 
00339   if (minHitsinTIB_ || minHitsinTOB_ || minHitsinTID_ || minHitsinTEC_
00340       || minHitsinENDCAP_ || minHitsinENDCAPplus_ || minHitsinENDCAPminus_ || (maxHitDiffEndcaps_ < 999)
00341       || minHitsinTIDplus_ || minHitsinTIDminus_
00342       || minHitsinFPIXplus_ || minHitsinFPIXminus_
00343       || minHitsinTECplus_ || minHitsinTECminus_
00344       || minHitsinFPIX_ || minHitsinBPIX_ || minHitsinPIX_ ||nHitMin2D_ || chargeCheck_
00345       || applyIsolation_ || (seedOnlyFromAbove_ == 1 || seedOnlyFromAbove_ == 2)
00346       || RorZofFirstHitMin_.size() > 0 || RorZofFirstHitMax_.size() > 0 || RorZofLastHitMin_.size() > 0 || RorZofLastHitMax_.size() > 0 ) {
00347     // any detailed hit cut is active, so have to check
00348     
00349     int nhitinTIB = 0, nhitinTOB = 0, nhitinTID = 0;
00350     int nhitinTEC = 0, nhitinBPIX = 0, nhitinFPIX = 0, nhitinPIXEL=0;
00351     int nhitinENDCAP = 0, nhitinENDCAPplus = 0, nhitinENDCAPminus = 0;
00352     int nhitinTIDplus = 0, nhitinTIDminus = 0;
00353     int nhitinFPIXplus = 0, nhitinFPIXminus = 0;
00354     int nhitinTECplus = 0, nhitinTECminus = 0;
00355     unsigned int nHit2D = 0;
00356     unsigned int thishit = 0;
00357 
00358     for (trackingRecHit_iterator iHit = trackp->recHitsBegin(); iHit != trackp->recHitsEnd(); ++iHit) {
00359       thishit++;
00360       const DetId detId((*iHit)->geographicalId());
00361       const int subdetId = detId.subdetId(); 
00362 
00363       // *** thishit == 1 means last hit in CTF *** 
00364       // (FIXME: assumption might change or not be valid for all tracking algorthms)
00365       // ==> for cosmics
00366       // seedOnlyFrom = 1 is TIB-TOB-TEC tracks only
00367       // seedOnlyFrom = 2 is TOB-TEC tracks only 
00368       if (seedOnlyFromAbove_ == 1 && thishit == 1 
00369           && (subdetId == int(SiStripDetId::TOB) || subdetId == int(SiStripDetId::TEC))){
00370         return false; 
00371       }
00372       if (seedOnlyFromAbove_ == 2 && thishit == 1 && subdetId == int(SiStripDetId::TIB)) {
00373         return false;
00374       }
00375 
00376       if (!(*iHit)->isValid()) continue; // only real hits count as in trackp->numberOfValidHits()
00377       if (detId.det() != DetId::Tracker) {
00378         edm::LogError("DetectorMismatch") << "@SUB=AlignmentTrackSelector::detailedHitsCheck"
00379                                           << "DetId.det() != DetId::Tracker (=" << DetId::Tracker
00380                                           << "), but " << detId.det() << ".";
00381       }
00382       const TrackingRecHit* therechit = (*iHit).get();
00383       if (chargeCheck_ && !(this->isOkCharge(therechit))) return false;
00384       if (applyIsolation_ && (!this->isIsolated(therechit, evt))) return false;
00385       if      (SiStripDetId::TIB == subdetId) ++nhitinTIB;
00386       else if (SiStripDetId::TOB == subdetId) ++nhitinTOB;
00387       else if (SiStripDetId::TID == subdetId) {
00388         ++nhitinTID;
00389         ++nhitinENDCAP;
00390         
00391         if (tTopo->tidIsZMinusSide(detId)) {
00392           ++nhitinTIDminus;
00393           ++nhitinENDCAPminus;
00394         }
00395         else if (tTopo->tidIsZPlusSide(detId)) {
00396           ++nhitinTIDplus;
00397           ++nhitinENDCAPplus;
00398         }
00399       }
00400       else if (SiStripDetId::TEC == subdetId) {
00401         ++nhitinTEC;
00402         ++nhitinENDCAP;
00403         
00404         if (tTopo->tecIsZMinusSide(detId)) {
00405           ++nhitinTECminus;
00406           ++nhitinENDCAPminus;
00407         }
00408         else if (tTopo->tecIsZPlusSide(detId)) {
00409           ++nhitinTECplus;
00410           ++nhitinENDCAPplus;
00411         }
00412       }
00413       else if (            kBPIX == subdetId) {++nhitinBPIX;++nhitinPIXEL;}
00414       else if (            kFPIX == subdetId) {
00415         ++nhitinFPIX;
00416         ++nhitinPIXEL;
00417         
00418         if (tTopo->pxfSide(detId)==1) ++nhitinFPIXminus;
00419         else if (tTopo->pxfSide(detId)==2) ++nhitinFPIXplus;
00420       }
00421       // Do not call isHit2D(..) if already enough 2D hits for performance reason:
00422       if (nHit2D < nHitMin2D_ && this->isHit2D(**iHit)) ++nHit2D;
00423     } // end loop on hits
00424 
00425 
00426     // Checking whether the track satisfies requirement of the first and last hit positions
00427     bool passedLastHitPositionR = true;
00428     bool passedLastHitPositionZ = true;
00429     bool passedFirstHitPositionR = true;
00430     bool passedFirstHitPositionZ = true;
00431     
00432     if( RorZofFirstHitMin_.at(0) != 0.0 || RorZofFirstHitMin_.at(1) != 0.0 
00433       || RorZofFirstHitMax_.at(0) != 999.0 || RorZofFirstHitMax_.at(1) != 999.0 ) {
00434 
00435       const reco::TrackBase::Point firstPoint(trackp->innerPosition());
00436 
00437       if( (std::fabs(firstPoint.R()) < RorZofFirstHitMin_.at(0) )) passedFirstHitPositionR = false;
00438       if( (std::fabs(firstPoint.R()) > RorZofFirstHitMax_.at(0) )) passedFirstHitPositionR = false;
00439       if( (std::fabs(firstPoint.Z()) < RorZofFirstHitMin_.at(1) )) passedFirstHitPositionZ = false;
00440       if( (std::fabs(firstPoint.Z()) > RorZofFirstHitMax_.at(1) )) passedFirstHitPositionZ = false;
00441     }
00442     
00443     if( RorZofLastHitMin_.at(0) != 0.0 || RorZofLastHitMin_.at(1) != 0.0 
00444       || RorZofLastHitMax_.at(0) != 999.0 || RorZofLastHitMax_.at(1) != 999.0 ) {
00445 
00446       const reco::TrackBase::Point lastPoint(trackp->outerPosition());
00447 
00448       if( (std::fabs(lastPoint.R()) < RorZofLastHitMin_.at(0) )) passedLastHitPositionR = false;
00449       if( (std::fabs(lastPoint.R()) > RorZofLastHitMax_.at(0) )) passedLastHitPositionR = false;
00450       if( (std::fabs(lastPoint.Z()) < RorZofLastHitMin_.at(1) )) passedLastHitPositionZ = false;
00451       if( (std::fabs(lastPoint.Z()) > RorZofLastHitMax_.at(1) )) passedLastHitPositionZ = false;
00452     }
00453 
00454     bool passedFirstHitPosition = passedFirstHitPositionR || passedFirstHitPositionZ;
00455     bool passedLastHitPosition = passedLastHitPositionR || passedLastHitPositionZ;
00456 
00457 
00458   
00459     return (nhitinTIB >= minHitsinTIB_ && nhitinTOB >= minHitsinTOB_ 
00460             && nhitinTID >= minHitsinTID_ && nhitinTEC >= minHitsinTEC_ 
00461             && nhitinENDCAP >= minHitsinENDCAP_ && nhitinENDCAPplus >= minHitsinENDCAPplus_ && nhitinENDCAPminus >= minHitsinENDCAPminus_
00462             && std::abs(nhitinENDCAPplus-nhitinENDCAPminus) <= maxHitDiffEndcaps_
00463             && nhitinTIDplus >= minHitsinTIDplus_ && nhitinTIDminus >= minHitsinTIDminus_
00464             && nhitinFPIXplus >= minHitsinFPIXplus_ && nhitinFPIXminus >= minHitsinFPIXminus_
00465             && nhitinTECplus >= minHitsinTECplus_ && nhitinTECminus >= minHitsinTECminus_
00466             && nhitinBPIX >= minHitsinBPIX_ 
00467             && nhitinFPIX >= minHitsinFPIX_ && nhitinPIXEL>=minHitsinPIX_ 
00468             && nHit2D >= nHitMin2D_ && passedFirstHitPosition && passedLastHitPosition);
00469   } else { // no cuts set, so we are just fine and can avoid loop on hits
00470     return true;
00471   }
00472   
00473 }
00474 
00475 //-----------------------------------------------------------------------------
00476 
00477 bool AlignmentTrackSelector::isHit2D(const TrackingRecHit &hit) const
00478 {
00479   // we count SiStrip stereo modules as 2D if selected via countStereoHitAs2D_
00480   // (since they provide theta information)
00481   if (!hit.isValid() ||
00482       (hit.dimension() < 2 && !countStereoHitAs2D_ && !dynamic_cast<const SiStripRecHit1D*>(&hit))){
00483     return false; // real RecHit1D - but SiStripRecHit1D depends on countStereoHitAs2D_
00484   } else {
00485     const DetId detId(hit.geographicalId());
00486     if (detId.det() == DetId::Tracker) {
00487       if (detId.subdetId() == kBPIX || detId.subdetId() == kFPIX) {
00488         return true; // pixel is always 2D
00489       } else { // should be SiStrip now
00490         const SiStripDetId stripId(detId);
00491         if (stripId.stereo()) return countStereoHitAs2D_; // stereo modules
00492         else if (dynamic_cast<const SiStripRecHit1D*>(&hit)
00493                  || dynamic_cast<const SiStripRecHit2D*>(&hit)) return false; // rphi modules hit
00494         //the following two are not used any more since ages... 
00495         else if (dynamic_cast<const SiStripMatchedRecHit2D*>(&hit)) return true; // matched is 2D
00496         else if (dynamic_cast<const ProjectedSiStripRecHit2D*>(&hit)) {
00497           const ProjectedSiStripRecHit2D* pH = static_cast<const ProjectedSiStripRecHit2D*>(&hit);
00498           return (countStereoHitAs2D_ && this->isHit2D(pH->originalHit())); // depends on original...
00499         } else {
00500           edm::LogError("UnkownType") << "@SUB=AlignmentTrackSelector::isHit2D"
00501                                       << "Tracker hit not in pixel, neither SiStripRecHit[12]D nor "
00502                                       << "SiStripMatchedRecHit2D nor ProjectedSiStripRecHit2D.";
00503           return false;
00504         }
00505       }
00506     } else { // not tracker??
00507       edm::LogWarning("DetectorMismatch") << "@SUB=AlignmentTrackSelector::isHit2D"
00508                                           << "Hit not in tracker with 'official' dimension >=2.";
00509       return true; // dimension() >= 2 so accept that...
00510     }
00511   }
00512   // never reached...
00513 }
00514 
00515 //-----------------------------------------------------------------------------
00516 
00517 bool AlignmentTrackSelector::isOkCharge(const TrackingRecHit* hit) const
00518 {
00519   if (!hit || !hit->isValid()) return true; 
00520 
00521   // check det and subdet
00522   const DetId id(hit->geographicalId());
00523   if (id.det() != DetId::Tracker) {
00524     edm::LogWarning("DetectorMismatch") << "@SUB=isOkCharge" << "Hit not in tracker!";
00525     return true;
00526   }
00527   if (id.subdetId() == kFPIX || id.subdetId() == kBPIX) {
00528     return true; // might add some requirement...
00529   }
00530 
00531   // We are in SiStrip now, so test normal hit:
00532   const std::type_info &type = typeid(*hit);
00533   
00534 
00535   if (type == typeid(SiStripRecHit2D)) {
00536     const SiStripRecHit2D *stripHit2D = dynamic_cast<const SiStripRecHit2D*>(hit);
00537     if (stripHit2D) {
00538       return this->isOkChargeStripHit(*stripHit2D);
00539     }
00540   }
00541   else if(type == typeid(SiStripRecHit1D)){
00542     const SiStripRecHit1D *stripHit1D = dynamic_cast<const SiStripRecHit1D*>(hit);
00543     if (stripHit1D) {
00544       return this->isOkChargeStripHit(*stripHit1D);
00545     } 
00546   }
00547 
00548   else if(type == typeid(SiStripMatchedRecHit2D)){  // or matched (should not occur anymore due to hit splitting since 20X)
00549     const SiStripMatchedRecHit2D *matchedHit = dynamic_cast<const SiStripMatchedRecHit2D*>(hit);
00550     if (matchedHit) {  
00551       return (this->isOkChargeStripHit(matchedHit->monoHit())
00552               && this->isOkChargeStripHit(matchedHit->stereoHit()));
00553     }
00554   }
00555   else if(type == typeid(ProjectedSiStripRecHit2D)){ 
00556     // or projected (should not occur anymore due to hit splitting since 20X):
00557     const ProjectedSiStripRecHit2D *projHit = dynamic_cast<const ProjectedSiStripRecHit2D*>(hit);
00558     if (projHit) {
00559       return this->isOkChargeStripHit(projHit->originalHit());
00560     }
00561   }
00562   else{
00563     edm::LogError("AlignmentTrackSelector")<< "@SUB=isOkCharge" <<"Unknown type of a valid tracker hit in Strips "
00564                                            << " SubDet = "<<id.subdetId();
00565     return false;
00566   }
00567   
00568 
00569 
00570   // and now? SiTrackerMultiRecHit? Not here I guess!
00571   // Should we throw instead?
00572   edm::LogError("AlignmentTrackSelector") 
00573     << "@SUB=isOkCharge" << "Unknown valid tracker hit not in pixel, subdet " << id.subdetId()
00574     << ", SiTrackerMultiRecHit " << dynamic_cast<const SiTrackerMultiRecHit*>(hit)
00575     << ", BaseTrackerRecHit " << dynamic_cast<const BaseTrackerRecHit*>(hit); 
00576   
00577   return true;
00578 } 
00579 
00580 
00581 //-----------------------------------------------------------------------------
00582 
00583 bool AlignmentTrackSelector::isOkChargeStripHit(const SiStripRecHit2D & siStripRecHit2D) const
00584 {
00585   double charge = 0.;
00586 
00587   SiStripRecHit2D::ClusterRef cluster(siStripRecHit2D.cluster());
00588   const std::vector<uint8_t> &amplitudes = cluster->amplitudes();
00589 
00590   for (size_t ia = 0; ia < amplitudes.size(); ++ia) {
00591     charge += amplitudes[ia];
00592   }
00593 
00594   return (charge >= minHitChargeStrip_);
00595 }
00596 
00597 //-----------------------------------------------------------------------------
00598 
00599 bool AlignmentTrackSelector::isOkChargeStripHit(const SiStripRecHit1D & siStripRecHit1D) const
00600 {
00601   double charge = 0.;
00602 
00603   SiStripRecHit1D::ClusterRef cluster(siStripRecHit1D.cluster());
00604   const std::vector<uint8_t> &amplitudes = cluster->amplitudes();
00605 
00606   for (size_t ia = 0; ia < amplitudes.size(); ++ia) {
00607     charge += amplitudes[ia];
00608   }
00609 
00610   return (charge >= minHitChargeStrip_);
00611 }
00612 
00613 //-----------------------------------------------------------------------------
00614 
00615 bool AlignmentTrackSelector::isIsolated(const TrackingRecHit* therechit, const edm::Event& evt) const
00616 {
00617   // FIXME:
00618   // adapt to changes after introduction of SiStripRecHit1D...
00619   //
00620   // edm::ESHandle<TrackerGeometry> tracker;
00621   edm::Handle<SiStripRecHit2DCollection> rphirecHits;
00622   edm::Handle<SiStripMatchedRecHit2DCollection> matchedrecHits;
00623   // es.get<TrackerDigiGeometryRecord>().get(tracker);
00624   evt.getByLabel( rphirecHitsTag_, rphirecHits );
00625   evt.getByLabel( matchedrecHitsTag_, matchedrecHits ); 
00626 
00627   SiStripRecHit2DCollection::DataContainer::const_iterator istripSt; 
00628   SiStripMatchedRecHit2DCollection::DataContainer::const_iterator istripStm; 
00629   const SiStripRecHit2DCollection::DataContainer& stripcollSt = rphirecHits->data();
00630   const SiStripMatchedRecHit2DCollection::DataContainer& stripcollStm = matchedrecHits->data();
00631   
00632   DetId idet = therechit->geographicalId(); 
00633   
00634   // FIXME: instead of looping the full hit collection, we should explore the features of 
00635   // SiStripRecHit2DCollection::rangeRphi = rphirecHits.get(idet) and loop
00636   // only from rangeRphi.first until rangeRphi.second
00637   for( istripSt=stripcollSt.begin(); istripSt!=stripcollSt.end(); ++istripSt ) {
00638     const SiStripRecHit2D *aHit = &*(istripSt);
00639     DetId mydet1 = aHit->geographicalId(); 
00640     if (idet.rawId() != mydet1.rawId()) continue; 
00641     float theDistance = ( therechit->localPosition() - aHit->localPosition() ).mag();
00642     // std::cout << "theDistance1 = " << theDistance << "\n";
00643     if (theDistance > 0.001 && theDistance < minHitIsolation_) return false;
00644   }
00645   
00646   // FIXME: see above
00647   for( istripStm=stripcollStm.begin(); istripStm!=stripcollStm.end(); ++istripStm ) {
00648     const SiStripMatchedRecHit2D *aHit = &*(istripStm);
00649     DetId mydet2 = aHit->geographicalId(); 
00650     if (idet.rawId() != mydet2.rawId()) continue;
00651     float theDistance = (therechit->localPosition() - aHit->localPosition()).mag();
00652     // std::cout << "theDistance1 = " << theDistance << "\n";
00653     if (theDistance > 0.001 && theDistance < minHitIsolation_) return false;
00654   }
00655   return true;
00656 }
00657 
00658 //-----------------------------------------------------------------------------
00659 
00660 AlignmentTrackSelector::Tracks 
00661 AlignmentTrackSelector::theNHighestPtTracks(const Tracks& tracks) const
00662 {
00663   Tracks sortedTracks=tracks;
00664   Tracks result;
00665 
00666   // sort in pt
00667   std::sort(sortedTracks.begin(),sortedTracks.end(),ptComparator);
00668 
00669   // copy theTrackMult highest pt tracks to result vector
00670   int n=0;
00671   for (Tracks::const_iterator it=sortedTracks.begin();
00672            it!=sortedTracks.end(); ++it) {
00673         if (n<nHighestPt_) { result.push_back(*it); n++; }
00674   }
00675 
00676   return result;
00677 }
00678 
00679 //---------
00680 
00681 AlignmentTrackSelector::Tracks 
00682 AlignmentTrackSelector::checkPrescaledHits(const Tracks& tracks, const edm::Event& evt) const 
00683 {
00684   Tracks result;
00685 
00686   //take Cluster-Flag Assomap
00687   edm::Handle<AliClusterValueMap> fMap;
00688   evt.getByLabel( clusterValueMapTag_, fMap);
00689   const AliClusterValueMap &flagMap=*fMap;
00690 
00691   //for each track loop on hits and count the number of taken hits
00692   for (Tracks::const_iterator ittrk=tracks.begin(); ittrk != tracks.end(); ++ittrk) {
00693     const reco::Track* trackp=*ittrk;
00694     int ntakenhits=0;
00695     //    float pt=trackp->pt();
00696 
00697     for (trackingRecHit_iterator ith = trackp->recHitsBegin(), edh = trackp->recHitsEnd(); ith != edh; ++ith) {
00698       const TrackingRecHit *hit = ith->get(); // ith is an iterator on edm::Ref to rechit
00699       if(! hit->isValid())continue;
00700       DetId detid = hit->geographicalId();
00701       int subDet = detid.subdetId();
00702       AlignmentClusterFlag flag;
00703 
00704       bool isPixelHit=(subDet == kFPIX || subDet == kBPIX);
00705 
00706       if (!isPixelHit){
00707         const std::type_info &type = typeid(*hit);
00708 
00709         if (type == typeid(SiStripRecHit2D)) {  
00710           const SiStripRecHit2D* striphit=dynamic_cast<const  SiStripRecHit2D*>(hit); 
00711           if(striphit!=0){
00712             SiStripRecHit2D::ClusterRef stripclust(striphit->cluster());
00713             flag = flagMap[stripclust];
00714           }
00715         }
00716         else if(type == typeid(SiStripRecHit1D)){
00717           const SiStripRecHit1D* striphit = dynamic_cast<const SiStripRecHit1D*>(hit);
00718           if(striphit!=0){
00719             SiStripRecHit1D::ClusterRef stripclust(striphit->cluster());
00720             flag = flagMap[stripclust];
00721           }
00722         } 
00723         else{
00724            edm::LogError("AlignmentTrackSelector")<<"ERROR in <AlignmentTrackSelector::checkPrescaledHits>: Dynamic cast of Strip RecHit failed!"
00725                                                   <<" Skipping this hit.";
00726            continue;
00727         }
00728 
00729           
00730 
00731       }//end if hit in Strips
00732       else{ // test explicitely BPIX/FPIX
00733         const SiPixelRecHit* pixelhit= dynamic_cast<const SiPixelRecHit*>(hit);
00734         if(pixelhit!=0){
00735           SiPixelRecHit::ClusterRef pixclust(pixelhit->cluster());
00736           flag = flagMap[pixclust];
00737         }
00738         else{
00739             edm::LogError("AlignmentTrackSelector")<<"ERROR in <AlignmentTrackSelector::checkPrescaledHits>: Dynamic cast of Pixel RecHit failed!  ";
00740         }
00741       }//end else hit is in Pixel
00742       
00743       if(flag.isTaken())ntakenhits++;
00744 
00745     }//end loop on hits
00746     if(ntakenhits >= minPrescaledHits_)result.push_back(trackp);
00747   }//end loop on tracks
00748 
00749   return result;
00750 }//end checkPrescaledHits
00751 
00752 //-----------------------------------------------------------------
00753 
00754 bool AlignmentTrackSelector::isOkTrkQuality(const reco::Track* track) const
00755 {
00756   bool qualityOk=false;
00757   bool iterStepOk=false;
00758 
00759   //check iterative step
00760   if(applyIterStepCheck_){
00761     for (unsigned int i = 0; i < trkSteps_.size(); ++i) {
00762       if (track->algo()==(trkSteps_[i])) {
00763         iterStepOk=true;
00764       }
00765     }
00766   }
00767   else iterStepOk=true;
00768 
00769   //check track quality
00770   if(applyTrkQualityCheck_){
00771     for (unsigned int i = 0; i < trkQualities_.size(); ++i) {
00772       if (track->quality(trkQualities_[i])) {
00773         qualityOk=true;
00774       }
00775     }
00776   }
00777   else  qualityOk=true;
00778 
00779   return qualityOk&&iterStepOk;
00780 }//end check on track quality