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
00021
00022 PrimaryVertexProducerAlgorithm::PrimaryVertexProducerAlgorithm(const edm::ParameterSet& conf)
00023
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;
00037
00038
00039
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
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
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
00095
00096
00097
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
00105
00106
00107
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
00132 std::vector<TransientTrack> seltks = theTrackFilter->select( tracks );
00133
00134
00135
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
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 }
00174
00175 if(fVerbose){
00176 std::cout << "PrimaryVertexProducerAlgorithm::vertices candidates =" << pvCand.size() << std::endl;
00177 }
00178
00179
00180
00181
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
00196 sort(pvs.begin(), pvs.end(), VertexHigherPtSquared());
00197
00198 }else{
00199
00200 if ( fFailsafe
00201 && (seltks.size()>1)
00202 && ( (clusters.size()!=1) || ( (clusters.size()==1) && (clusters.begin()->size()<seltks.size())) )
00203 )
00204 {
00205
00206
00207
00208 TransientVertex v;
00209 if( fUseBeamConstraint && validBS ){
00210 v = theFitter->vertex(seltks, beamSpot);
00211 }else{
00212 v = theFitter->vertex(seltks);
00213 }
00214 if (fVerbose){ std::cout << "PrimaryVertexProducerAlgorithm: failsafe vertex "
00215 <<" tracks=" << seltks.size()
00216 <<" valid()=" << v.isValid() << " ndof()=" << v.degreesOfFreedom()
00217 <<" selected="<< theVertexSelector(v,beamVertexState) << std::endl; }
00218 if ( v.isValid() && (v.degreesOfFreedom()>=fMinNdof) && (theVertexSelector(v,beamVertexState)) ) pvs.push_back(v);
00219 }
00220
00221 }
00222
00223
00224 return pvs;
00225
00226 }