CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/RecoVertex/PrimaryVertexProducer/src/PrimaryVertexProducerAlgorithm.cc

Go to the documentation of this file.
00001 
00002 #include "RecoVertex/PrimaryVertexProducer/interface/PrimaryVertexProducerAlgorithm.h"
00003 #include "RecoVertex/PrimaryVertexProducer/interface/VertexHigherPtSquared.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 
00006 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00007 #include "RecoVertex/PrimaryVertexProducer/interface/TrackFilterForPVFinding.h"
00008 #include "RecoVertex/PrimaryVertexProducer/interface/HITrackFilterForPVFinding.h"
00009 #include "RecoVertex/PrimaryVertexProducer/interface/GapClusterizerInZ.h"
00010 #include "RecoVertex/PrimaryVertexProducer/interface/DAClusterizerInZ.h"
00011 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexFitter.h"
00012 #include "RecoVertex/AdaptiveVertexFit/interface/AdaptiveVertexFitter.h"
00013 #include "RecoVertex/VertexTools/interface/VertexDistanceXY.h"
00014 #include "RecoVertex/VertexPrimitives/interface/VertexException.h"
00015 #include <algorithm>
00016 
00017 using namespace reco;
00018 
00019 //
00020 // constructors and destructor
00021 //
00022 PrimaryVertexProducerAlgorithm::PrimaryVertexProducerAlgorithm(const edm::ParameterSet& conf)
00023   // extract relevant parts of config for components
00024   : theConfig(conf), 
00025     theVertexSelector(VertexDistanceXY(), 
00026                       conf.getParameter<edm::ParameterSet>("PVSelParameters").getParameter<double>("maxDistanceToBeam"))
00027 {
00028   edm::LogInfo("PVDebugInfo") 
00029     << "PVSelParameters::maxDistanceToBeam = " 
00030     << conf.getParameter<edm::ParameterSet>("PVSelParameters").getParameter<double>("maxDistanceToBeam") << "\n";
00031 
00032 
00033   fUseBeamConstraint = conf.getParameter<bool>("useBeamConstraint");
00034   fVerbose           = conf.getUntrackedParameter<bool>("verbose", false);
00035   fMinNdof           = conf.getParameter<double>("minNdof");
00036   fFailsafe          = true; //conf.getUntrackedParameter<bool>("failsafe",true);
00037 
00038 
00039   // select and configure the track selection
00040   std::string trackSelectionAlgorithm=conf.getParameter<edm::ParameterSet>("TkFilterParameters").getParameter<std::string>("algorithm");
00041   if(trackSelectionAlgorithm=="filter"){
00042     theTrackFilter= new TrackFilterForPVFinding( conf.getParameter<edm::ParameterSet>("TkFilterParameters") );
00043   }else if (trackSelectionAlgorithm=="filterWithThreshold"){
00044     theTrackFilter= new HITrackFilterForPVFinding(conf.getParameter<edm::ParameterSet>("TkFilterParameters"));
00045   }else{
00046     throw VertexException("PrimaryVertexProducerAlgorithm: unknown track selection algorithm: " + trackSelectionAlgorithm);  
00047   }
00048 
00049 
00050   // select and configure the track clusterizer
00051   std::string clusteringAlgorithm=conf.getParameter<edm::ParameterSet>("TkClusParameters").getParameter<std::string>("algorithm");
00052   if (clusteringAlgorithm=="gap"){
00053     theTrackClusterizer = new GapClusterizerInZ(conf.getParameter<edm::ParameterSet>("TkClusParameters").getParameter<edm::ParameterSet>("TkGapClusParameters"));
00054   }else if(clusteringAlgorithm=="DA"){
00055     theTrackClusterizer = new DAClusterizerInZ(conf.getParameter<edm::ParameterSet>("TkClusParameters").getParameter<edm::ParameterSet>("TkDAClusParameters"));
00056   }else{
00057     throw VertexException("PrimaryVertexProducerAlgorithm: unknown clustering algorithm: " + clusteringAlgorithm);  
00058   }
00059 
00060   // select and configure the vertex fitter
00061   std::string algorithm = conf.getParameter<std::string>("algorithm");
00062   fapply_finder = false;
00063   if (algorithm == "TrimmedKalmanFinder") {
00064     fapply_finder = true;
00065     theFinder.setParameters(conf.getParameter<edm::ParameterSet>("VtxFinderParameters"));
00066   } else if (algorithm=="KalmanVertexFitter") {
00067     theFitter=new KalmanVertexFitter();
00068   } else if( algorithm=="AdaptiveVertexFitter") {
00069     theFitter=new AdaptiveVertexFitter();
00070   } else {
00071     throw VertexException("PrimaryVertexProducerAlgorithm: unknown algorithm: " + algorithm);  
00072   }
00073 
00074   edm::LogInfo("PVDebugInfo") 
00075     << "Using " << algorithm << "\n";
00076   edm::LogInfo("PVDebugInfo") 
00077     << "beam-constraint  " << fUseBeamConstraint << "\n"; 
00078 
00079   edm::LogInfo("PVDebugInfo") 
00080     << "PV producer algorithm initialization: done" << "\n";
00081 
00082 }
00083 
00084 
00085 PrimaryVertexProducerAlgorithm::~PrimaryVertexProducerAlgorithm() 
00086 {
00087   if (theFitter) delete theFitter;
00088   if (theTrackFilter) delete theTrackFilter;
00089   if (theTrackClusterizer) delete theTrackClusterizer;
00090 }
00091 
00092 
00093 //
00094 // member functions
00095 //
00096 
00097 // obsolete method, unfortunately required throgh inheritance from  VertexReconstructor
00098 std::vector<TransientVertex> 
00099 PrimaryVertexProducerAlgorithm::vertices(const std::vector<reco::TransientTrack> & tracks) const
00100 {
00101 
00102    throw VertexException("PrimaryVertexProducerAlgorithm: cannot make a Primary Vertex without a beam spot constraint " );
00103 
00104   /*  std::cout<< "PrimaryVertexProducer::vertices> Obsolete function, using dummy beamspot " << std::endl;
00105     reco::BeamSpot dummyBeamSpot;
00106     dummyBeamSpot.dummy();
00107     return vertices(tracks,dummyBeamSpot); */
00108    return std::vector<TransientVertex>();
00109 }
00110 
00111 
00112 std::vector<TransientVertex> 
00113 PrimaryVertexProducerAlgorithm::vertices(const std::vector<reco::TransientTrack> & tracks,
00114                                          const reco::BeamSpot & beamSpot) const
00115 {
00116   bool validBS = true;
00117   VertexState beamVertexState(beamSpot);
00118   if ( (beamVertexState.error().cxx() <= 0.) || 
00119        (beamVertexState.error().cyy() <= 0.) ||
00120        (beamVertexState.error().czz() <= 0.) ) {
00121     validBS = false;
00122     edm::LogError("UnusableBeamSpot") << "Beamspot with invalid errors "<<beamVertexState.error().matrix();
00123   }
00124 
00125   if ( fapply_finder) {
00126         return theFinder.vertices( tracks );
00127   }
00128   std::vector<TransientVertex> pvs;
00129 
00130 
00131   // select tracks
00132   std::vector<TransientTrack> seltks = theTrackFilter->select( tracks );
00133 
00134 
00135   // clusterize tracks in Z
00136   std::vector< std::vector<reco::TransientTrack> > clusters =  theTrackClusterizer->clusterize(seltks);
00137   if (fVerbose){std::cout <<  " clustering returned  "<< clusters.size() << " clusters  from " << seltks.size() << " selected tracks" <<std::endl;}
00138 
00139 
00140   // look for primary vertices in each cluster
00141   std::vector<TransientVertex> pvCand;
00142   int nclu=0;
00143   for (std::vector< std::vector<reco::TransientTrack> >::const_iterator iclus
00144          = clusters.begin(); iclus != clusters.end(); iclus++) {
00145 
00146 
00147     TransientVertex v;
00148     if( fUseBeamConstraint && validBS &&((*iclus).size()>1) ){
00149       if (fVerbose){std::cout <<  " constrained fit with "<< (*iclus).size() << " tracks"  <<std::endl;}
00150       v = theFitter->vertex(*iclus, beamSpot);
00151       if (v.isValid() && (v.degreesOfFreedom()>=fMinNdof)) pvCand.push_back(v);
00152 
00153       if (fVerbose){
00154         if (v.isValid()) std::cout << "x,y,z=" << v.position().x() <<" " << v.position().y() << " " <<  v.position().z() << std::endl;
00155         else std::cout <<"Invalid fitted vertex\n";
00156       }
00157 
00158     }else if((*iclus).size()>1){
00159       if (fVerbose){std::cout <<  " unconstrained fit with "<< (*iclus).size() << " tracks"  << std::endl;}
00160 
00161       v = theFitter->vertex(*iclus); 
00162       if (v.isValid() && (v.degreesOfFreedom()>=fMinNdof)) pvCand.push_back(v);
00163 
00164       if (fVerbose){
00165         if (v.isValid()) std::cout << "x,y,z=" << v.position().x() <<" " << v.position().y() << " " <<  v.position().z() << std::endl;
00166         else std::cout <<"Invalid fitted vertex\n";
00167       }
00168 
00169     }
00170 
00171     nclu++;
00172 
00173   }// end of cluster loop
00174 
00175   if(fVerbose){
00176     std::cout << "PrimaryVertexProducerAlgorithm::vertices  candidates =" << pvCand.size() << std::endl;
00177   }
00178 
00179 
00180 
00181   // select vertices compatible with beam
00182   int npv=0;
00183   for (std::vector<TransientVertex>::const_iterator ipv = pvCand.begin();
00184        ipv != pvCand.end(); ipv++) {
00185     if(fVerbose){
00186       std::cout << "PrimaryVertexProducerAlgorithm::vertices cand " << npv++ << " sel=" <<
00187         (validBS && theVertexSelector(*ipv,beamVertexState)) << "   z="  << ipv->position().z() << std::endl;
00188     }
00189     if (!validBS || theVertexSelector(*ipv,beamVertexState)) pvs.push_back(*ipv);
00190   }
00191 
00192 
00193   if(pvs.size()>0){
00194 
00195     // sort vertices by pt**2  vertex (aka signal vertex tagging)
00196     // sort(pvs.begin(), pvs.end(), VertexHigherPtSquared());
00197 
00198     // avoid re-evaluating sumptsquared for each comparison
00199     VertexHigherPtSquared V;
00200     std::vector< std::pair< double , unsigned int > > ptsqpv;
00201     for(unsigned int i=0; i<pvs.size(); i++){ ptsqpv.push_back( std::make_pair(V.sumPtSquared(pvs.at(i)), i));}
00202     std::stable_sort(ptsqpv.begin(), ptsqpv.end());
00203     std::vector<TransientVertex> pvsorted( pvs.size());
00204     for(unsigned int i=0; i<pvs.size(); i++){ pvsorted.push_back(pvs.at(ptsqpv[i].second));}
00205     return pvsorted;
00206 
00207   }else{
00208 
00209     if (    fFailsafe 
00210             && (seltks.size()>1) 
00211             && ( (clusters.size()!=1)  ||  ( (clusters.size()==1) && (clusters.begin()->size()<seltks.size())) )
00212         )
00213       { 
00214         // if no vertex was found, try fitting all selected tracks, unless this has already been tried
00215         // in low/no pile-up situations with low multiplicity vertices, this can recover vertices lost in clustering
00216         // with very small zSep. Only makes sense when used with a robust fitter, like the AdaptiveVertexFitter
00217         TransientVertex v;
00218         if( fUseBeamConstraint && validBS ){
00219           v = theFitter->vertex(seltks, beamSpot);
00220         }else{
00221           v = theFitter->vertex(seltks); 
00222         }
00223         if (fVerbose){ std::cout << "PrimaryVertexProducerAlgorithm: failsafe vertex "
00224                             <<"  tracks="  << seltks.size()
00225                             <<"  valid()=" << v.isValid() << " ndof()=" << v.degreesOfFreedom() 
00226                             <<"  selected="<< theVertexSelector(v,beamVertexState) << std::endl; }
00227         if ( v.isValid() && (v.degreesOfFreedom()>=fMinNdof) && (theVertexSelector(v,beamVertexState)) )  pvs.push_back(v);
00228       }
00229     
00230   }
00231 
00232 
00233   return pvs;
00234   
00235 }