00001 #include <memory>
00002
00003 #include "FWCore/Framework/interface/EDProducer.h"
00004 #include "FWCore/Framework/interface/Event.h"
00005 #include "FWCore/Framework/interface/MakerMacros.h"
00006 #include "FWCore/Utilities/interface/InputTag.h"
00007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00008
00009 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00010 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00011 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00012
00013 #include "DataFormats/Common/interface/Handle.h"
00014 #include "DataFormats/TrackReco/interface/Track.h"
00015 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00016 #include "DataFormats/VertexReco/interface/Vertex.h"
00017 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00018 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00019
00020 #include "RecoVertex/ConfigurableVertexReco/interface/ConfigurableVertexReconstructor.h"
00021 #include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistance.h"
00022 #include "TrackingTools/IPTools/interface/IPTools.h"
00023 #include "RecoVertex/AdaptiveVertexFit/interface/AdaptiveVertexFitter.h"
00024 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexUpdator.h"
00025 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexTrackCompatibilityEstimator.h"
00026 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexSmoother.h"
00027 #include "RecoVertex/MultiVertexFit/interface/MultiVertexFitter.h"
00028
00029 class InclusiveVertexFinder : public edm::EDProducer {
00030 public:
00031 InclusiveVertexFinder(const edm::ParameterSet ¶ms);
00032
00033 virtual void produce(edm::Event &event, const edm::EventSetup &es);
00034
00035 private:
00036 bool trackFilter(const reco::TrackRef &track) const;
00037 std::pair<std::vector<reco::TransientTrack>,GlobalPoint> nearTracks(const reco::TransientTrack &seed, const std::vector<reco::TransientTrack> & tracks, const reco::Vertex & primaryVertex) const;
00038
00039 edm::InputTag beamSpotCollection;
00040 edm::InputTag primaryVertexCollection;
00041 edm::InputTag trackCollection;
00042 unsigned int minHits;
00043 double minPt;
00044 double min3DIPSignificance;
00045 double min3DIPValue;
00046 double clusterMaxDistance;
00047 double clusterMaxSignificance;
00048 double clusterScale;
00049 double clusterMinAngleCosine;
00050 double vertexMinAngleCosine;
00051 double vertexMinDLen2DSig;
00052 double vertexMinDLenSig;
00053
00054 std::auto_ptr<VertexReconstructor> vtxReco;
00055
00056 };
00057
00058 InclusiveVertexFinder::InclusiveVertexFinder(const edm::ParameterSet ¶ms) :
00059 beamSpotCollection(params.getParameter<edm::InputTag>("beamSpot")),
00060 primaryVertexCollection(params.getParameter<edm::InputTag>("primaryVertices")),
00061 trackCollection(params.getParameter<edm::InputTag>("tracks")),
00062 minHits(params.getParameter<unsigned int>("minHits")),
00063 minPt(params.getParameter<double>("minPt")),
00064 min3DIPSignificance(params.getParameter<double>("seedMin3DIPSignificance")),
00065 min3DIPValue(params.getParameter<double>("seedMin3DIPValue")),
00066 clusterMaxDistance(params.getParameter<double>("clusterMaxDistance")),
00067 clusterMaxSignificance(params.getParameter<double>("clusterMaxSignificance")),
00068 clusterScale(params.getParameter<double>("clusterScale")),
00069 clusterMinAngleCosine(params.getParameter<double>("clusterMinAngleCosine")),
00070 vertexMinAngleCosine(params.getParameter<double>("vertexMinAngleCosine")),
00071 vertexMinDLen2DSig(params.getParameter<double>("vertexMinDLen2DSig")),
00072 vertexMinDLenSig(params.getParameter<double>("vertexMinDLenSig")),
00073 vtxReco(new ConfigurableVertexReconstructor(params.getParameter<edm::ParameterSet>("vertexReco")))
00074
00075 {
00076 produces<reco::VertexCollection>();
00077
00078 }
00079
00080 bool InclusiveVertexFinder::trackFilter(const reco::TrackRef &track) const
00081 {
00082 if (track->hitPattern().trackerLayersWithMeasurement() < (int)minHits)
00083 return false;
00084 if (track->pt() < minPt )
00085 return false;
00086
00087 return true;
00088 }
00089
00090 std::pair<std::vector<reco::TransientTrack>,GlobalPoint> InclusiveVertexFinder::nearTracks(const reco::TransientTrack &seed, const std::vector<reco::TransientTrack> & tracks, const reco::Vertex & primaryVertex) const
00091 {
00092 VertexDistance3D distanceComputer;
00093 GlobalPoint pv(primaryVertex.position().x(),primaryVertex.position().y(),primaryVertex.position().z());
00094 std::vector<reco::TransientTrack> result;
00095 TwoTrackMinimumDistance dist;
00096 GlobalPoint seedingPoint;
00097 float sumWeights=0;
00098 std::pair<bool,Measurement1D> ipSeed = IPTools::absoluteImpactParameter3D(seed,primaryVertex);
00099 float pvDistance = ipSeed.second.value();
00100
00101 for(std::vector<reco::TransientTrack>::const_iterator tt = tracks.begin();tt!=tracks.end(); ++tt ) {
00102
00103 if(*tt==seed) continue;
00104
00105 std::pair<bool,Measurement1D> ip = IPTools::absoluteImpactParameter3D(*tt,primaryVertex);
00106 if(dist.calculate(tt->impactPointState(),seed.impactPointState()))
00107 {
00108 GlobalPoint ttPoint = dist.points().first;
00109 GlobalError ttPointErr = tt->impactPointState().cartesianError().position();
00110 GlobalPoint seedPosition = dist.points().second;
00111 GlobalError seedPositionErr = seed.impactPointState().cartesianError().position();
00112 Measurement1D m = distanceComputer.distance(VertexState(seedPosition,seedPositionErr), VertexState(ttPoint, ttPointErr));
00113 GlobalPoint cp(dist.crossingPoint());
00114
00115
00116 float distanceFromPV = (dist.points().second-pv).mag();
00117 float distance = dist.distance();
00118 GlobalVector trackDir2D(tt->impactPointState().globalDirection().x(),tt->impactPointState().globalDirection().y(),0.);
00119 GlobalVector seedDir2D(seed.impactPointState().globalDirection().x(),seed.impactPointState().globalDirection().y(),0.);
00120 float dotprodTrackSeed2D = trackDir2D.unit().dot(seedDir2D.unit());
00121
00122 float dotprodTrack = (dist.points().first-pv).unit().dot(tt->impactPointState().globalDirection().unit());
00123 float dotprodSeed = (dist.points().second-pv).unit().dot(seed.impactPointState().globalDirection().unit());
00124
00125 float w = distanceFromPV*distanceFromPV/(pvDistance*distance);
00126
00127 if(m.significance() < clusterMaxSignificance &&
00128 dotprodSeed > clusterMinAngleCosine &&
00129 dotprodTrack > clusterMinAngleCosine &&
00130 dotprodTrackSeed2D > clusterMinAngleCosine &&
00131 distance*clusterScale < distanceFromPV*distanceFromPV/pvDistance &&
00132 distance < clusterMaxDistance)
00133 {
00134 result.push_back(*tt);
00135 seedingPoint = GlobalPoint(cp.x()*w+seedingPoint.x(),cp.y()*w+seedingPoint.y(),cp.z()*w+seedingPoint.z());
00136 sumWeights+=w;
00137 }
00138 }
00139 }
00140
00141 seedingPoint = GlobalPoint(seedingPoint.x()/sumWeights,seedingPoint.y()/sumWeights,seedingPoint.z()/sumWeights);
00142 return std::pair<std::vector<reco::TransientTrack>,GlobalPoint>(result,seedingPoint);
00143
00144 }
00145
00146
00147 void InclusiveVertexFinder::produce(edm::Event &event, const edm::EventSetup &es)
00148 {
00149 using namespace reco;
00150
00151 double sigmacut = 3.0;
00152 double Tini = 256.;
00153 double ratio = 0.25;
00154 VertexDistance3D vdist;
00155 VertexDistanceXY vdist2d;
00156 MultiVertexFitter theMultiVertexFitter;
00157 AdaptiveVertexFitter theAdaptiveFitter(
00158 GeometricAnnealing(sigmacut, Tini, ratio),
00159 DefaultLinearizationPointFinder(),
00160 KalmanVertexUpdator<5>(),
00161 KalmanVertexTrackCompatibilityEstimator<5>(),
00162 KalmanVertexSmoother() );
00163
00164
00165 edm::Handle<BeamSpot> beamSpot;
00166 event.getByLabel(beamSpotCollection, beamSpot);
00167
00168 edm::Handle<VertexCollection> primaryVertices;
00169 event.getByLabel(primaryVertexCollection, primaryVertices);
00170
00171 edm::Handle<TrackCollection> tracks;
00172 event.getByLabel(trackCollection, tracks);
00173
00174 edm::ESHandle<TransientTrackBuilder> trackBuilder;
00175 es.get<TransientTrackRecord>().get("TransientTrackBuilder",
00176 trackBuilder);
00177
00178
00179 const reco::Vertex &pv = (*primaryVertices)[0];
00180
00181 std::vector<TransientTrack> tts;
00182 std::vector<TransientTrack> seeds;
00183
00184 for(TrackCollection::const_iterator track = tracks->begin();
00185 track != tracks->end(); ++track) {
00186 TrackRef ref(tracks, track - tracks->begin());
00187 if (!trackFilter(ref))
00188 continue;
00189
00190 TransientTrack tt = trackBuilder->build(ref);
00191 tt.setBeamSpot(*beamSpot);
00192 tts.push_back(tt);
00193 std::pair<bool,Measurement1D> ip = IPTools::absoluteImpactParameter3D(tt,pv);
00194
00195 if(ip.first && ip.second.value() >= min3DIPValue && ip.second.significance() >= min3DIPSignificance)
00196 {
00197
00198 seeds.push_back(tt);
00199 }
00200
00201 }
00202
00203
00204
00205 BeamSpot::CovarianceMatrix cov;
00206 for(unsigned int i = 0; i < 7; i++) {
00207 for(unsigned int j = 0; j < 7; j++) {
00208 if (i < 3 && j < 3)
00209 cov(i, j) = pv.covariance(i, j);
00210 else
00211 cov(i, j) = 0.0;
00212 }
00213 }
00214 BeamSpot bs(pv.position(), 0.0, 0.0, 0.0, 0.0, cov, BeamSpot::Unknown);
00215 std::auto_ptr<VertexCollection> recoVertices(new VertexCollection);
00216 int i=0;
00217 std::vector< std::vector<TransientTrack> > clusters;
00218 for(std::vector<TransientTrack>::const_iterator s = seeds.begin();
00219 s != seeds.end(); ++s,++i)
00220 {
00221
00222
00223 std::pair<std::vector<reco::TransientTrack>,GlobalPoint> ntracks = nearTracks(*s,tts,pv);
00224 if(ntracks.first.size() == 0 ) continue;
00225 ntracks.first.push_back(*s);
00226 clusters.push_back(ntracks.first);
00227 std::vector<TransientVertex> vertices;
00228
00229 vertices = vtxReco->vertices(ntracks.first, bs);
00230 TransientVertex singleFitVertex;
00231 singleFitVertex = theAdaptiveFitter.vertex(ntracks.first,ntracks.second);
00232 if(singleFitVertex.isValid())
00233 vertices.push_back(singleFitVertex);
00234
00235
00236
00237
00238
00239 for(std::vector<TransientVertex>::const_iterator v = vertices.begin();
00240 v != vertices.end(); ++v) {
00241
00242 {
00243 Measurement1D dlen= vdist.distance(pv,*v);
00244 Measurement1D dlen2= vdist2d.distance(pv,*v);
00245 reco::Vertex vv(*v);
00246
00247
00248
00249
00250 GlobalVector dir;
00251 std::vector<reco::TransientTrack> ts = v->originalTracks();
00252 for(std::vector<reco::TransientTrack>::const_iterator i = ts.begin();
00253 i != ts.end(); ++i) {
00254 reco::TrackRef t = i->trackBaseRef().castTo<reco::TrackRef>();
00255 float w = v->trackWeight(*i);
00256 if (w > 0.5) dir+=i->impactPointState().globalDirection();
00257
00258
00259
00260
00261 }
00262 GlobalPoint ppv(pv.position().x(),pv.position().y(),pv.position().z());
00263 GlobalPoint sv((*v).position().x(),(*v).position().y(),(*v).position().z());
00264 float vscal = dir.unit().dot((sv-ppv).unit()) ;
00265
00266 if(dlen.significance() > vertexMinDLenSig && vscal > vertexMinAngleCosine && v->normalisedChiSquared() < 10 && dlen2.significance() > vertexMinDLen2DSig)
00267 recoVertices->push_back(*v);
00268
00269
00270 }
00271 }
00272 }
00273 event.put(recoVertices);
00274
00275 }
00276
00277 DEFINE_FWK_MODULE(InclusiveVertexFinder);