00001 #include "RecoVertex/TrimmedKalmanVertexFinder/interface/ConfigurableTrimmedVertexFinder.h"
00002 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
00003
00004 using namespace reco;
00005
00006 ConfigurableTrimmedVertexFinder::ConfigurableTrimmedVertexFinder(
00007 const VertexFitter<5> * vf,
00008 const VertexUpdator<5> * vu,
00009 const VertexTrackCompatibilityEstimator<5> * ve)
00010 : theClusterFinder(vf, vu, ve), theVtxFitProbCut(0.01),
00011 theTrackCompatibilityToPV(0.05), theTrackCompatibilityToSV(0.01),
00012 theMaxNbOfVertices(0)
00013 {
00014
00015 theFilter.setPtCut(1.5);
00016 }
00017
00018
00019 vector<TransientVertex> ConfigurableTrimmedVertexFinder::vertices(
00020 const vector<TransientTrack> & tracks) const
00021 {
00022 vector<TransientTrack> remaining;
00023
00024 return vertices(tracks, remaining);
00025
00026 }
00027
00028
00029 vector<TransientVertex> ConfigurableTrimmedVertexFinder::vertices(
00030 const vector<TransientTrack> & tracks, vector<TransientTrack> & unused)
00031 const
00032 {
00033 resetEvent(tracks);
00034 analyseInputTracks(tracks);
00035
00036 vector<TransientTrack> filtered;
00037 for (vector<TransientTrack>::const_iterator it = tracks.begin();
00038 it != tracks.end(); it++) {
00039 if (theFilter(*it)) {
00040 filtered.push_back(*it);
00041 }
00042 else {
00043 unused.push_back(*it);
00044 }
00045 }
00046
00047 vector<TransientVertex> all = vertexCandidates(filtered, unused);
00048
00049 analyseVertexCandidates(all);
00050
00051 vector<TransientVertex> sel = clean(all);
00052
00053 analyseFoundVertices(sel);
00054
00055 return sel;
00056
00057 }
00058
00059
00060 vector<TransientVertex> ConfigurableTrimmedVertexFinder::vertexCandidates(
00061 const vector<TransientTrack> & tracks, vector<TransientTrack> & unused) const
00062 {
00063
00064 vector<TransientVertex> cand;
00065
00066 vector<TransientTrack> remain = tracks;
00067
00068 while (true) {
00069
00070 float tkCompCut = (cand.size() == 0 ?
00071 theTrackCompatibilityToPV
00072 : theTrackCompatibilityToSV);
00073
00074
00075 theClusterFinder.setTrackCompatibilityCut(tkCompCut);
00076
00077
00078
00079 vector<TransientVertex> newVertices = theClusterFinder.vertices(remain);
00080 if (newVertices.empty()) break;
00081
00082 analyseClusterFinder(newVertices, remain);
00083
00084 for (vector<TransientVertex>::const_iterator iv = newVertices.begin();
00085 iv != newVertices.end(); iv++) {
00086 if ( iv->originalTracks().size() > 1 ) {
00087 cand.push_back(*iv);
00088 }
00089 else {
00090
00091 for ( vector< TransientTrack >::const_iterator trk
00092 = iv->originalTracks().begin();
00093 trk != iv->originalTracks().end(); ++trk ) {
00094 unused.push_back ( *trk );
00095 }
00096 }
00097 }
00098
00099
00100 if (theMaxNbOfVertices != 0) {
00101 if (cand.size() >= theMaxNbOfVertices) break;
00102 }
00103 }
00104
00105 for (vector<TransientTrack>::const_iterator it = remain.begin();
00106 it != remain.end(); it++) {
00107 unused.push_back(*it);
00108 }
00109
00110 return cand;
00111 }
00112
00113
00114 vector<TransientVertex>
00115 ConfigurableTrimmedVertexFinder::clean(const vector<TransientVertex> & candidates) const
00116 {
00117 vector<TransientVertex> sel;
00118 for (vector<TransientVertex>::const_iterator i = candidates.begin();
00119 i != candidates.end(); i++) {
00120
00121 if (ChiSquaredProbability((*i).totalChiSquared(), (*i).degreesOfFreedom())
00122 > theVtxFitProbCut) { sel.push_back(*i); }
00123 }
00124
00125 return sel;
00126 }