00001 #include "RecoVertex/TrimmedKalmanVertexFinder/interface/TrimmedVertexFinder.h"
00002 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
00003 #include "RecoVertex/VertexTools/interface/PerigeeLinearizedTrackState.h"
00004 #include "FWCore/Utilities/interface/Exception.h"
00005
00006 using namespace reco;
00007
00008 TrimmedVertexFinder::TrimmedVertexFinder(
00009 const VertexFitter<5> * vf, const VertexUpdator<5> * vu,
00010 const VertexTrackCompatibilityEstimator<5> * ve)
00011 : theFitter(vf->clone()), theUpdator(vu->clone()),
00012 theEstimator(ve->clone()), theMinProb(0.05)
00013 {}
00014
00015
00016 TrimmedVertexFinder::TrimmedVertexFinder(
00017 const TrimmedVertexFinder & other)
00018 : theFitter(other.theFitter->clone()),
00019 theUpdator(other.theUpdator->clone()),
00020 theEstimator(other.theEstimator->clone()),
00021 theMinProb(other.theMinProb)
00022 {}
00023
00024
00025 TrimmedVertexFinder::~TrimmedVertexFinder() {
00026 delete theFitter;
00027 delete theUpdator;
00028 delete theEstimator;
00029 }
00030
00031
00032 vector<TransientVertex>
00033 TrimmedVertexFinder::vertices(vector<TransientTrack> & tks)
00034 const
00035 {
00036 vector<TransientVertex> all;
00037 if (tks.size() < 2) return all;
00038
00039
00040 CachingVertex<5> vtx = theFitter->vertex(tks);
00041 if (!vtx.isValid()) {
00042 cout << "TrimmedVertexFinder::WARNING: initial vertex invalid"
00043 << endl << "vertex finding stops here." << endl;
00044 return all;
00045 }
00046
00047 vector<RefCountedVertexTrack> selected = vtx.tracks();
00048
00049
00050 vector<RefCountedVertexTrack> remain;
00051 bool found = false;
00052 while (!found && selected.size() >= 2) {
00053
00054
00055 vector<RefCountedVertexTrack>::iterator iWorst = theWorst(vtx,
00056 selected,
00057 theMinProb);
00058
00059 if (iWorst != selected.end()) {
00060
00061 remain.push_back(*iWorst);
00062 selected.erase(iWorst);
00063
00064 if (selected.size() == 1) {
00065
00066 remain.push_back(selected.front());
00067 }
00068 else {
00069
00070
00071
00072
00073
00074 vtx = theFitter->vertex(selected);
00075 if (!vtx.isValid()) {
00076 cout << "TrimmedVertexFinder::WARNING: current vertex invalid"
00077 << endl << "vertex finding stops here." << endl;
00078 return all;
00079 }
00080
00081
00082
00083 selected = vtx.tracks();
00084 }
00085
00086 } else {
00087
00088 found = true;
00089 int n_tracks_in_vertex = selected.size();
00090
00091
00092 for ( vector< RefCountedVertexTrack >::const_iterator t=selected.begin();
00093 t!=selected.end() ; ++t )
00094 {
00095 if ( (**t).weight() < 0.5 )
00096 {
00097
00098
00099
00100 remain.push_back ( *t );
00101 n_tracks_in_vertex--;
00102 };
00103 };
00104
00105 if ( n_tracks_in_vertex > 1 ) {
00106 all.push_back(vtx);
00107 }
00108 else {
00109 cout << "[TrimmedVertexFinder] ERROR: found vertex ";
00110 cout << "has less than 2 tracks " << endl;
00111 }
00112 }
00113 }
00114
00115
00116 tks.clear();
00117 for (vector<RefCountedVertexTrack>::const_iterator i = remain.begin();
00118 i != remain.end(); i++) {
00119 const PerigeeLinearizedTrackState* plts =
00120 dynamic_cast<const PerigeeLinearizedTrackState*>
00121 ((**i).linearizedTrack().get());
00122 if (plts == 0) {
00123 throw cms::Exception("TrimmedVertexFinder: can't take track from non-perigee track state");
00124 }
00125
00126 tks.push_back(plts->track());
00127 }
00128
00129
00130 return all;
00131 }
00132
00133
00134 vector<TrimmedVertexFinder::RefCountedVertexTrack>::iterator
00135 TrimmedVertexFinder::theWorst(const CachingVertex<5> & vtx,
00136 vector<RefCountedVertexTrack> & vtxTracks, float cut) const
00137 {
00138
00139
00140
00141
00142 vector<RefCountedVertexTrack>::iterator iWorst = vtxTracks.end();
00143 float worseChi2 = 0.;
00144 for (vector<RefCountedVertexTrack>::iterator itr = vtxTracks.begin();
00145 itr != vtxTracks.end(); itr++) {
00146
00147 float chi2 = 0;
00148 try {
00149
00150 CachingVertex<5> newV = theUpdator->remove(vtx, *itr);
00151
00152 chi2 = theEstimator->estimate(newV, *itr);
00153 }
00154 catch ( cms::Exception & e) {
00155
00156 cout << "[TrimmedVertexFinder] warning: "
00157 << "exception caught for this track, causing its rejection:"
00158 << e.what() << endl;
00159 iWorst = itr;
00160 break;
00161 }
00162
00163
00164 if ( chi2 > 0. ) {
00165
00166
00167 int ndf = 2;
00168 if (vtx.tracks().size() == 2) ndf = 1;
00169
00170 float prob = ChiSquaredProbability(chi2, ndf);
00171 if (prob < cut && chi2 >= worseChi2) {
00172
00173
00174
00175
00176
00177 iWorst = itr;
00178 worseChi2 = chi2;
00179 }
00180 }
00181 }
00182
00183 return iWorst;
00184 }