00001 #include "RecoVertex/GaussianSumVertexFit/interface/GsfVertexUpdator.h"
00002 #include "RecoVertex/GaussianSumVertexFit/interface/BasicMultiVertexState.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 #include <cfloat>
00005
00006 GsfVertexUpdator::GsfVertexUpdator(bool limit, const GsfVertexMerger * merger) :
00007 limitComponents (limit)
00008 {
00009 if (limitComponents) theMerger = merger->clone();
00010 }
00011
00012
00013 CachingVertex<5> GsfVertexUpdator::add(const CachingVertex<5> & oldVertex,
00014 const RefCountedVertexTrack track) const
00015 {
00016
00017 VSC prevVtxComponents = oldVertex.vertexState().components();
00018
00019
00020
00021
00022
00023 if (prevVtxComponents.empty()) {
00024 throw VertexException
00025 ("GsfVertexUpdator::(Previous) Vertex to update has no components");
00026 }
00027
00028 LTC ltComponents = track->linearizedTrack()->components();
00029 if (ltComponents.empty()) {
00030 throw VertexException
00031 ("GsfVertexUpdator::Track to add to vertex has no components");
00032 }
00033
00034 if ((ltComponents.size()==1) && (prevVtxComponents.size()==1))
00035 return kalmanVertexUpdator.add(oldVertex, track);
00036
00037 float trackWeight = track->weight();
00038
00039 vector<VertexComponent> newVertexComponents;
00040 newVertexComponents.reserve(prevVtxComponents.size()*ltComponents.size());
00041
00042
00043
00044
00045
00046
00047 for (VSC::iterator vertexCompIter = prevVtxComponents.begin();
00048 vertexCompIter != prevVtxComponents.end(); vertexCompIter++ ) {
00049 for (LTC::iterator trackCompIter = ltComponents.begin();
00050 trackCompIter != ltComponents.end(); trackCompIter++ ) {
00051 newVertexComponents.push_back(
00052 createNewComponent(*vertexCompIter, *trackCompIter, trackWeight, +1));
00053 if (!newVertexComponents.back().first.isValid()) return CachingVertex<5>();
00054 }
00055 }
00056
00057
00058
00059
00060 vector<RefCountedVertexTrack> newVertexTracks = oldVertex.tracks();
00061 newVertexTracks.push_back(track);
00062
00063
00064
00065
00066 VertexChi2Pair vertexChi2Pair = assembleVertexComponents(newVertexComponents);
00067
00068 VertexState newVertexState = vertexChi2Pair.first;
00069
00070 double chi2 = oldVertex.totalChiSquared() + vertexChi2Pair.second;
00071
00072
00073 if (limitComponents) newVertexState = theMerger->merge(newVertexState);
00074
00075 if (oldVertex.hasPrior()) {
00076 return CachingVertex<5>(oldVertex.priorPosition(), oldVertex.priorError(),
00077 newVertexState.weightTimesPosition(),
00078 newVertexState.weight(), newVertexTracks, chi2);
00079 } else {
00080 return CachingVertex<5>(newVertexState, newVertexTracks, chi2);
00081 }
00082
00083
00084 }
00085
00086
00087
00088
00089 CachingVertex<5> GsfVertexUpdator::remove(const CachingVertex<5> & oldVertex,
00090 const RefCountedVertexTrack track) const
00091 {
00092 throw VertexException("GsfVertexUpdator::Remove Methode not yet done");
00093
00094 }
00095
00096
00102 GsfVertexUpdator::VertexComponent
00103 GsfVertexUpdator::createNewComponent(const VertexState & oldVertex,
00104 const RefCountedLinearizedTrackState linTrack, float weight, int sign) const
00105 {
00106
00107 if(abs(sign) != 1)
00108 throw VertexException ("GsfVertexUpdator::sign not equal to 1.");
00109
00110 if(sign == -1)
00111 throw VertexException("GsfVertexUpdator::sign of -1 not yet implemented.");
00112
00113
00114
00115 double weightInMixture = theWeightCalculator.calculate(oldVertex, linTrack, 1.E9);
00116 if (weightInMixture < 0.) return VertexComponent(VertexState(), WeightChi2Pair(0.,0.));
00117
00118
00119 VertexState newVertex = kalmanVertexUpdator.positionUpdate(oldVertex,
00120 linTrack, weight, sign);
00121 if (!newVertex.isValid()) return VertexComponent(newVertex, WeightChi2Pair(0.,0.));
00122
00123
00124 pair <bool, double> chi2P = kalmanVertexUpdator.chi2Increment(oldVertex, newVertex,
00125 linTrack, weight);
00126 if (!chi2P.first) return VertexComponent(VertexState(), WeightChi2Pair(0.,0.));
00127
00128
00129
00130 return VertexComponent(newVertex, WeightChi2Pair(weightInMixture, chi2P.second));
00131 }
00132
00133 GsfVertexUpdator::VertexChi2Pair GsfVertexUpdator::assembleVertexComponents(
00134 const vector<GsfVertexUpdator::VertexComponent> & newVertexComponents) const
00135 {
00136 VSC vertexComponents;
00137 vertexComponents.reserve(newVertexComponents.size());
00138
00139
00140
00141 double totalWeight = 0.;
00142 double totalChi2 = 0.;
00143
00144 for (vector<VertexComponent>::const_iterator iter = newVertexComponents.begin();
00145 iter != newVertexComponents.end(); iter ++) {
00146 totalWeight += iter->second.first;
00147 cout << iter->first.position()<<iter->second.first<<" "<<iter->second.second<<endl;
00148 }
00149
00150 if (totalWeight<DBL_MIN) {
00151 edm::LogWarning("GsfVertexUpdator") << "Updated Vertex has total weight of 0. "
00152 <<"The track is probably very far away.";
00153 return VertexChi2Pair( VertexState(), 0.);
00154 }
00155
00156 for (vector<VertexComponent>::const_iterator iter = newVertexComponents.begin();
00157 iter != newVertexComponents.end(); iter ++) {
00158 double weight = iter->second.first/totalWeight;
00159 if (iter->second.first>DBL_MIN) {
00160 vertexComponents.push_back(VertexState(iter->first.weightTimesPosition(),
00161 iter->first.weight(), weight));
00162 totalChi2 += iter->second.second * weight;
00163 }
00164 }
00165
00166
00167
00168 if (vertexComponents.empty()){
00169 edm::LogWarning("GsfVertexUpdator") << "No Vertex State left after reweighting.";
00170 return VertexChi2Pair( VertexState(), 0.);
00171 }
00172
00173 return VertexChi2Pair( VertexState( new BasicMultiVertexState( vertexComponents)),
00174 totalChi2);
00175 }