CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/RecoTracker/FinalTrackSelectors/src/MultiTrackSelector.cc

Go to the documentation of this file.
00001 #include "RecoTracker/FinalTrackSelectors/src/MultiTrackSelector.h"
00002 
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 #include "DataFormats/Common/interface/ValueMap.h"
00005 #include <Math/DistFunc.h>
00006 #include "TMath.h"
00007 
00008 using reco::modules::MultiTrackSelector;
00009 
00010 MultiTrackSelector::MultiTrackSelector( const edm::ParameterSet & cfg ) :
00011   src_( cfg.getParameter<edm::InputTag>( "src" ) ),
00012   beamspot_( cfg.getParameter<edm::InputTag>( "beamspot" ) ),
00013   useVertices_( cfg.getParameter<bool>( "useVertices" ) ),
00014   useVtxError_( cfg.getParameter<bool>( "useVtxError" ) ),
00015   vertices_( useVertices_ ? cfg.getParameter<edm::InputTag>( "vertices" ) : edm::InputTag("NONE"))
00016   // now get the pset for each selector
00017 {
00018 
00019   std::vector<edm::ParameterSet> trkSelectors( cfg.getParameter<std::vector< edm::ParameterSet> >("trackSelectors") );
00020   qualityToSet_.reserve(trkSelectors.size());
00021   vtxNumber_.reserve(trkSelectors.size());
00022   vertexCut_.reserve(trkSelectors.size());
00023   res_par_.reserve(trkSelectors.size());
00024   chi2n_par_.reserve(trkSelectors.size());
00025   chi2n_no1Dmod_par_.reserve(trkSelectors.size());
00026   d0_par1_.reserve(trkSelectors.size());
00027   dz_par1_.reserve(trkSelectors.size());
00028   d0_par2_.reserve(trkSelectors.size());
00029   dz_par2_.reserve(trkSelectors.size());
00030   applyAdaptedPVCuts_.reserve(trkSelectors.size());
00031   max_d0_.reserve(trkSelectors.size());
00032   max_z0_.reserve(trkSelectors.size());
00033   nSigmaZ_.reserve(trkSelectors.size());
00034   min_layers_.reserve(trkSelectors.size());
00035   min_3Dlayers_.reserve(trkSelectors.size());
00036   max_lostLayers_.reserve(trkSelectors.size());
00037   applyAbsCutsIfNoPV_.reserve(trkSelectors.size());
00038   max_d0NoPV_.reserve(trkSelectors.size());
00039   max_z0NoPV_.reserve(trkSelectors.size());
00040   preFilter_.reserve(trkSelectors.size());
00041   max_relpterr_.reserve(trkSelectors.size());
00042   min_nhits_.reserve(trkSelectors.size());
00043 
00044   for ( unsigned int i=0; i<trkSelectors.size(); i++) {
00045 
00046     qualityToSet_.push_back( TrackBase::undefQuality );
00047     // parameters for vertex selection
00048     vtxNumber_.push_back( useVertices_ ? trkSelectors[i].getParameter<int32_t>("vtxNumber") : 0 );
00049     vertexCut_.push_back( useVertices_ ? trkSelectors[i].getParameter<std::string>("vertexCut") : 0);
00050     //  parameters for adapted optimal cuts on chi2 and primary vertex compatibility
00051     res_par_.push_back(trkSelectors[i].getParameter< std::vector<double> >("res_par") );
00052     chi2n_par_.push_back( trkSelectors[i].getParameter<double>("chi2n_par") );
00053     chi2n_no1Dmod_par_.push_back( trkSelectors[i].getParameter<double>("chi2n_no1Dmod_par") );
00054     d0_par1_.push_back(trkSelectors[i].getParameter< std::vector<double> >("d0_par1"));
00055     dz_par1_.push_back(trkSelectors[i].getParameter< std::vector<double> >("dz_par1"));
00056     d0_par2_.push_back(trkSelectors[i].getParameter< std::vector<double> >("d0_par2"));
00057     dz_par2_.push_back(trkSelectors[i].getParameter< std::vector<double> >("dz_par2"));
00058     // Boolean indicating if adapted primary vertex compatibility cuts are to be applied.
00059     applyAdaptedPVCuts_.push_back(trkSelectors[i].getParameter<bool>("applyAdaptedPVCuts"));
00060     // Impact parameter absolute cuts.
00061     max_d0_.push_back(trkSelectors[i].getParameter<double>("max_d0"));
00062     max_z0_.push_back(trkSelectors[i].getParameter<double>("max_z0"));
00063     nSigmaZ_.push_back(trkSelectors[i].getParameter<double>("nSigmaZ"));
00064     // Cuts on numbers of layers with hits/3D hits/lost hits.
00065     min_layers_.push_back(trkSelectors[i].getParameter<uint32_t>("minNumberLayers") );
00066     min_3Dlayers_.push_back(trkSelectors[i].getParameter<uint32_t>("minNumber3DLayers") );
00067     max_lostLayers_.push_back(trkSelectors[i].getParameter<uint32_t>("maxNumberLostLayers"));
00068     // Flag to apply absolute cuts if no PV passes the selection
00069     applyAbsCutsIfNoPV_.push_back(trkSelectors[i].getParameter<bool>("applyAbsCutsIfNoPV"));
00070     keepAllTracks_.push_back( trkSelectors[i].getParameter<bool>("keepAllTracks")); 
00071     max_relpterr_.push_back(trkSelectors[i].getParameter<double>("max_relpterr"));
00072     min_nhits_.push_back(trkSelectors[i].getParameter<uint32_t>("min_nhits"));
00073 
00074   
00075     setQualityBit_.push_back( false );
00076     std::string qualityStr = trkSelectors[i].getParameter<std::string>("qualityBit");
00077     if (qualityStr != "") {
00078       setQualityBit_[i] = true;
00079       qualityToSet_[i]  = TrackBase::qualityByName(trkSelectors[i].getParameter<std::string>("qualityBit"));
00080     }
00081   
00082     if (setQualityBit_[i] && (qualityToSet_[i] == TrackBase::undefQuality)) throw cms::Exception("Configuration") <<
00083     "You can't set the quality bit " << trkSelectors[i].getParameter<std::string>("qualityBit") << " as it is 'undefQuality' or unknown.\n";
00084 
00085     if (applyAbsCutsIfNoPV_[i]) {
00086       max_d0NoPV_.push_back(trkSelectors[i].getParameter<double>("max_d0NoPV"));
00087       max_z0NoPV_.push_back(trkSelectors[i].getParameter<double>("max_z0NoPV"));
00088     }
00089     else{//dummy values
00090       max_d0NoPV_.push_back(0.);
00091       max_z0NoPV_.push_back(0.);
00092     }
00093   
00094     name_.push_back( trkSelectors[i].getParameter<std::string>("name") );
00095 
00096     preFilter_[i]=trkSelectors.size(); // no prefilter
00097 
00098     std::string pfName=trkSelectors[i].getParameter<std::string>("preFilterName");
00099     if (pfName!="") {
00100       bool foundPF=false;
00101       for ( unsigned int j=0; j<i; j++) 
00102         if (name_[j]==pfName ) {
00103           foundPF=true;
00104           preFilter_[i]=j;
00105         }
00106       if ( !foundPF)
00107         throw cms::Exception("Configuration") << "Invalid prefilter name in MultiTrackSelector " 
00108                                               << trkSelectors[i].getParameter<std::string>("preFilterName");
00109           
00110     }
00111 
00112     //    produces<std::vector<int> >(name_[i]).setBranchAlias( name_[i] + "TrackQuals");
00113     produces<edm::ValueMap<int> >(name_[i]).setBranchAlias( name_[i] + "TrackQuals");
00114   }
00115 }
00116 
00117 MultiTrackSelector::~MultiTrackSelector() {
00118 }
00119 
00120 void MultiTrackSelector::produce( edm::Event& evt, const edm::EventSetup& es ) 
00121 {
00122   using namespace std; 
00123   using namespace edm;
00124   using namespace reco;
00125 
00126   // Get tracks 
00127   Handle<TrackCollection> hSrcTrack;
00128   evt.getByLabel( src_, hSrcTrack );
00129 
00130   // looking for the beam spot
00131   edm::Handle<reco::BeamSpot> hBsp;
00132   evt.getByLabel(beamspot_, hBsp);
00133   reco::BeamSpot vertexBeamSpot;
00134   vertexBeamSpot = *hBsp;
00135         
00136   // Select good primary vertices for use in subsequent track selection
00137   edm::Handle<reco::VertexCollection> hVtx;
00138   if (useVertices_) evt.getByLabel(vertices_, hVtx);
00139 
00140   unsigned int trkSize=hSrcTrack->size();
00141   std::vector<int> selTracksSave( qualityToSet_.size()*trkSize,0);
00142   
00143   //loop over all of the selectors...
00144   for (unsigned int i=0; i<qualityToSet_.size(); i++) {  
00145     std::vector<int> selTracks(trkSize,0);
00146     auto_ptr<edm::ValueMap<int> > selTracksValueMap = auto_ptr<edm::ValueMap<int> >(new edm::ValueMap<int>);
00147     edm::ValueMap<int>::Filler filler(*selTracksValueMap);
00148 
00149     std::vector<Point> points;
00150     std::vector<double> vterr;
00151     std::vector<double> vzerr;
00152     if (useVertices_) selectVertices(i,*hVtx, points, vterr, vzerr);
00153 
00154     // Loop over tracks
00155     size_t current = 0;
00156     for (TrackCollection::const_iterator it = hSrcTrack->begin(), ed = hSrcTrack->end(); it != ed; ++it, ++current) {
00157       const Track & trk = * it;
00158       // Check if this track passes cuts
00159 
00160       LogTrace("TrackSelection") << "ready to check track with pt="<< trk.pt() ;
00161 
00162       //already removed
00163       bool ok=true;
00164       if (preFilter_[i]<i && selTracksSave[preFilter_[i]*trkSize+current] < 0) {
00165         selTracks.at(current)=-1;
00166         ok=false;
00167         if ( !keepAllTracks_[i]) 
00168           continue;
00169       }
00170       else {
00171         ok = select(i,vertexBeamSpot, trk, points, vterr, vzerr);
00172         if (!ok) { 
00173           LogTrace("TrackSelection") << "track with pt="<< trk.pt() << " NOT selected";
00174           if (!keepAllTracks_[i]) { 
00175             selTracks.at(current)=-1;
00176             continue;
00177           }
00178         }
00179         else
00180           LogTrace("TrackSelection") << "track with pt="<< trk.pt() << " selected";
00181       }
00182 
00183       if (preFilter_[i]<i ) {
00184         selTracks.at(current)=selTracksSave[preFilter_[i]*trkSize+current];
00185       }
00186       else {
00187         selTracks.at(current)=trk.qualityMask();
00188       }
00189       if ( ok && setQualityBit_[i]) {
00190         selTracks.at(current)= (selTracks.at(current) | (1<<qualityToSet_[i]));
00191         if (!points.empty()) {
00192           if (qualityToSet_[i]==TrackBase::loose) {
00193             selTracks.at(current)=(selTracks.at(current) | (1<<TrackBase::looseSetWithPV));
00194           }
00195           else if (qualityToSet_[i]==TrackBase::highPurity) {
00196             selTracks.at(current)=(selTracks.at(current) | (1<<TrackBase::highPuritySetWithPV));
00197           }
00198         }
00199       }
00200     }
00201     for ( unsigned int j=0; j< trkSize; j++ ) selTracksSave[j+i*trkSize]=selTracks.at(j);
00202     filler.insert(hSrcTrack, selTracks.begin(),selTracks.end());
00203     filler.fill();
00204 
00205     //    evt.put(selTracks,name_[i]);
00206     evt.put(selTracksValueMap,name_[i]);
00207   }
00208 }
00209 
00210 
00211  bool MultiTrackSelector::select(unsigned int tsNum, 
00212                                  const reco::BeamSpot &vertexBeamSpot, 
00213                                  const reco::Track &tk, 
00214                                  const std::vector<Point> &points,
00215                                  std::vector<double> &vterr,
00216                                  std::vector<double> &vzerr) {
00217   // Decide if the given track passes selection cuts.
00218 
00219   using namespace std; 
00220 
00221   if ( tk.ndof() < 1E-5 ) return false;
00222 
00223   // Cuts on numbers of layers with hits/3D hits/lost hits.
00224   uint32_t nlayers     = tk.hitPattern().trackerLayersWithMeasurement();
00225   uint32_t nlayers3D   = tk.hitPattern().pixelLayersWithMeasurement() +
00226     tk.hitPattern().numberOfValidStripLayersWithMonoAndStereo();
00227   uint32_t nlayersLost = tk.hitPattern().trackerLayersWithoutMeasurement();
00228   LogDebug("TrackSelection") << "cuts on nlayers: " << nlayers << " " << nlayers3D << " " << nlayersLost << " vs " 
00229                              << min_layers_[tsNum] << " " << min_3Dlayers_[tsNum] << " " << max_lostLayers_[tsNum];
00230   if (nlayers < min_layers_[tsNum]) return false;
00231   if (nlayers3D < min_3Dlayers_[tsNum]) return false;
00232   if (nlayersLost > max_lostLayers_[tsNum]) return false;
00233   LogTrace("TrackSelection") << "cuts on nlayers passed";
00234 
00235   double chi2n =  tk.normalizedChi2();
00236   double chi2n_no1Dmod = chi2n;
00237 
00238   int count1dhits = 0;
00239   for (trackingRecHit_iterator ith = tk.recHitsBegin(), edh = tk.recHitsEnd(); ith != edh; ++ith) {
00240     const TrackingRecHit * hit = ith->get();
00241     DetId detid = hit->geographicalId();
00242     if (hit->isValid()) {
00243       if (typeid(*hit) == typeid(SiStripRecHit1D)) ++count1dhits;
00244     }
00245   }
00246   if (count1dhits > 0) {
00247     double chi2 = tk.chi2();
00248     double ndof = tk.ndof();
00249     chi2n = (chi2+count1dhits)/double(ndof+count1dhits);
00250   }
00251   // For each 1D rechit, the chi^2 and ndof is increased by one.  This is a way of retaining approximately
00252   // the same normalized chi^2 distribution as with 2D rechits.
00253   if (chi2n > chi2n_par_[tsNum]*nlayers) return false;
00254 
00255   if (chi2n_no1Dmod > chi2n_no1Dmod_par_[tsNum]*nlayers) return false;
00256 
00257   // Get track parameters
00258   double pt = tk.pt(), eta = tk.eta();
00259 
00260   //cuts on relative error on pt and number of valid hits
00261   double relpterr = tk.ptError()/max(pt,1e-9);
00262   uint32_t nhits = tk.numberOfValidHits();
00263   if(relpterr > max_relpterr_[tsNum]) return false;
00264   if(nhits < min_nhits_[tsNum]) return false;
00265 
00266 
00267   //other track parameters
00268   double d0 = -tk.dxy(vertexBeamSpot.position()), d0E =  tk.d0Error(),
00269     dz = tk.dz(vertexBeamSpot.position()), dzE =  tk.dzError();
00270 
00271   // parametrized d0 resolution for the track pt
00272   double nomd0E = sqrt(res_par_[tsNum][0]*res_par_[tsNum][0]+(res_par_[tsNum][1]/max(pt,1e-9))*(res_par_[tsNum][1]/max(pt,1e-9)));
00273   // parametrized z0 resolution for the track pt and eta
00274   double nomdzE = nomd0E*(std::cosh(eta));
00275 
00276   double dzCut = min( pow(dz_par1_[tsNum][0]*nlayers,dz_par1_[tsNum][1])*nomdzE, 
00277                       pow(dz_par2_[tsNum][0]*nlayers,dz_par2_[tsNum][1])*dzE );
00278   double d0Cut = min( pow(d0_par1_[tsNum][0]*nlayers,d0_par1_[tsNum][1])*nomd0E, 
00279                       pow(d0_par2_[tsNum][0]*nlayers,d0_par2_[tsNum][1])*d0E );
00280 
00281 
00282   // ---- PrimaryVertex compatibility cut
00283   bool primaryVertexZCompatibility(false);   
00284   bool primaryVertexD0Compatibility(false);   
00285 
00286   if (points.empty()) { //If not primaryVertices are reconstructed, check just the compatibility with the BS
00287     //z0 within (n sigma + dzCut) of the beam spot z, if no good vertex is found
00288     if ( abs(dz) < hypot(vertexBeamSpot.sigmaZ()*nSigmaZ_[tsNum],dzCut) ) primaryVertexZCompatibility = true;  
00289     // d0 compatibility with beam line
00290     if (abs(d0) < d0Cut) primaryVertexD0Compatibility = true;     
00291   }
00292 
00293   int iv=0;
00294   for (std::vector<Point>::const_iterator point = points.begin(), end = points.end(); point != end; ++point) {
00295     LogTrace("TrackSelection") << "Test track w.r.t. vertex with z position " << point->z();
00296     if(primaryVertexZCompatibility && primaryVertexD0Compatibility) break;
00297     double dzPV = tk.dz(*point); //re-evaluate the dz with respect to the vertex position
00298     double d0PV = tk.dxy(*point); //re-evaluate the dxy with respect to the vertex position
00299     if(useVtxError_){
00300        double dzErrPV = sqrt(dzE*dzE+vzerr[iv]*vzerr[iv]); // include vertex error in z
00301        double d0ErrPV = sqrt(d0E*d0E+vterr[iv]*vterr[iv]); // include vertex error in xy
00302        iv++;
00303        if (abs(dzPV) < dz_par1_[tsNum][0]*pow(nlayers,dz_par1_[tsNum][1])*nomdzE &&
00304            abs(dzPV) < dz_par2_[tsNum][0]*pow(nlayers,dz_par2_[tsNum][1])*dzErrPV &&
00305            abs(dzPV) < max_z0_[tsNum])  primaryVertexZCompatibility = true;
00306        if (abs(d0PV) < d0_par1_[tsNum][0]*pow(nlayers,d0_par1_[tsNum][1])*nomd0E &&
00307            abs(d0PV) < d0_par2_[tsNum][0]*pow(nlayers,d0_par2_[tsNum][1])*d0ErrPV &&
00308            abs(d0PV) < max_d0_[tsNum]) primaryVertexD0Compatibility = true; 
00309     }else{
00310        if (abs(dzPV) < dzCut)  primaryVertexZCompatibility = true;
00311        if (abs(d0PV) < d0Cut) primaryVertexD0Compatibility = true;     
00312     }
00313     LogTrace("TrackSelection") << "distances " << dzPV << " " << d0PV << " vs " << dzCut << " " << d0Cut;
00314   }
00315 
00316   if (points.empty() && applyAbsCutsIfNoPV_[tsNum]) {
00317     if ( abs(dz) > max_z0NoPV_[tsNum] || abs(d0) > max_d0NoPV_[tsNum]) return false;
00318   }  else {
00319     // Absolute cuts on all tracks impact parameters with respect to beam-spot.
00320     // If BS is not compatible, verify if at least the reco-vertex is compatible (useful for incorrect BS settings)
00321     if (abs(d0) > max_d0_[tsNum] && !primaryVertexD0Compatibility) return false;
00322     LogTrace("TrackSelection") << "absolute cuts on d0 passed";
00323     if (abs(dz) > max_z0_[tsNum] && !primaryVertexZCompatibility) return false;
00324     LogTrace("TrackSelection") << "absolute cuts on dz passed";
00325   }
00326 
00327   LogTrace("TrackSelection") << "cuts on PV: apply adapted PV cuts? " << applyAdaptedPVCuts_[tsNum] 
00328                              << " d0 compatibility? " << primaryVertexD0Compatibility  
00329                              << " z compatibility? " << primaryVertexZCompatibility ;
00330 
00331   if (applyAdaptedPVCuts_[tsNum]) {
00332     return (primaryVertexD0Compatibility && primaryVertexZCompatibility);
00333   } else {
00334     return true;     
00335   }
00336 
00337 }
00338 
00339  void MultiTrackSelector::selectVertices(unsigned int tsNum, 
00340                                          const reco::VertexCollection &vtxs, 
00341                                          std::vector<Point> &points,
00342                                          std::vector<double> &vterr, 
00343                                          std::vector<double> &vzerr) {
00344   // Select good primary vertices
00345   using namespace reco;
00346   int32_t toTake = vtxNumber_[tsNum]; 
00347   for (VertexCollection::const_iterator it = vtxs.begin(), ed = vtxs.end(); it != ed; ++it) {
00348 
00349     LogDebug("SelectVertex") << " select vertex with z position " << it->z() << " " 
00350                              << it->chi2() << " " << it->ndof() << " " << TMath::Prob(it->chi2(), static_cast<int32_t>(it->ndof()));
00351     Vertex vtx = *it;
00352     bool pass = vertexCut_[tsNum]( vtx );
00353     if( pass ) { 
00354       points.push_back(it->position()); 
00355       vterr.push_back(sqrt(it->yError()*it->xError()));
00356       vzerr.push_back(it->zError());
00357       LogTrace("SelectVertex") << " SELECTED vertex with z position " << it->z();
00358       toTake--; if (toTake == 0) break;
00359     }
00360   }
00361 }