File indexing completed on 2024-04-06 12:29:02
0001 #ifndef InclusiveVertexFinder_h
0002 #define InclusiveVertexFinder_h
0003 #include <memory>
0004
0005 #include "FWCore/Framework/interface/stream/EDProducer.h"
0006 #include "FWCore/Framework/interface/Event.h"
0007 #include "FWCore/Framework/interface/MakerMacros.h"
0008 #include "FWCore/Utilities/interface/InputTag.h"
0009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0010 #include "FWCore/Utilities/interface/ESGetToken.h"
0011
0012 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0013 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0014 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0015
0016 #include "DataFormats/Common/interface/Handle.h"
0017 #include "DataFormats/TrackReco/interface/Track.h"
0018 #include "DataFormats/TrackReco/interface/TrackFwd.h"
0019 #include "DataFormats/VertexReco/interface/Vertex.h"
0020 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0021 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0022
0023 #include "RecoVertex/ConfigurableVertexReco/interface/ConfigurableVertexReconstructor.h"
0024 #include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistance.h"
0025 #include "TrackingTools/IPTools/interface/IPTools.h"
0026 #include "RecoVertex/AdaptiveVertexFinder/interface/TracksClusteringFromDisplacedSeed.h"
0027
0028 #include "RecoVertex/AdaptiveVertexFit/interface/AdaptiveVertexFitter.h"
0029 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexUpdator.h"
0030 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexTrackCompatibilityEstimator.h"
0031 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexSmoother.h"
0032 #include "RecoVertex/MultiVertexFit/interface/MultiVertexFitter.h"
0033
0034 #include "RecoVertex/AdaptiveVertexFinder/interface/TTHelpers.h"
0035 #include "RecoVertex/AdaptiveVertexFinder/interface/SVTimeHelpers.h"
0036 #include "FWCore/Utilities/interface/isFinite.h"
0037
0038 #include <type_traits>
0039
0040
0041 template <class InputContainer, class VTX>
0042 class TemplatedInclusiveVertexFinder : public edm::stream::EDProducer<> {
0043 public:
0044 typedef std::vector<VTX> Product;
0045 typedef typename InputContainer::value_type TRK;
0046 TemplatedInclusiveVertexFinder(const edm::ParameterSet ¶ms);
0047
0048 static void fillDescriptions(edm::ConfigurationDescriptions &cdesc) {
0049 edm::ParameterSetDescription pdesc;
0050 pdesc.add<edm::InputTag>("beamSpot", edm::InputTag("offlineBeamSpot"));
0051 pdesc.add<edm::InputTag>("primaryVertices", edm::InputTag("offlinePrimaryVertices"));
0052 if (std::is_same<VTX, reco::Vertex>::value) {
0053 pdesc.add<edm::InputTag>("tracks", edm::InputTag("generalTracks"));
0054 pdesc.add<unsigned int>("minHits", 8);
0055 } else if (std::is_same<VTX, reco::VertexCompositePtrCandidate>::value) {
0056 pdesc.add<edm::InputTag>("tracks", edm::InputTag("particleFlow"));
0057 pdesc.add<unsigned int>("minHits", 0);
0058 } else {
0059 pdesc.add<edm::InputTag>("tracks", edm::InputTag("generalTracks"));
0060 }
0061
0062 pdesc.add<double>("maximumLongitudinalImpactParameter", 0.3);
0063 pdesc.add<double>("maximumTimeSignificance", 3.0);
0064 pdesc.add<double>("minPt", 0.8);
0065 pdesc.add<unsigned int>("maxNTracks", 30);
0066
0067 edm::ParameterSetDescription clusterizer;
0068 clusterizer.add<double>("seedMax3DIPSignificance", 9999.0);
0069 clusterizer.add<double>("seedMax3DIPValue", 9999.0);
0070 clusterizer.add<double>("seedMin3DIPSignificance", 1.2);
0071 clusterizer.add<double>("seedMin3DIPValue", 0.005);
0072 clusterizer.add<double>("clusterMaxDistance", 0.05);
0073 clusterizer.add<double>("clusterMaxSignificance", 4.5);
0074 clusterizer.add<double>("distanceRatio", 20.0);
0075 clusterizer.add<double>("clusterMinAngleCosine", 0.5);
0076 clusterizer.add<double>("maxTimeSignificance", 3.5);
0077 pdesc.add<edm::ParameterSetDescription>("clusterizer", clusterizer);
0078
0079 pdesc.add<double>("vertexMinAngleCosine", 0.95);
0080 pdesc.add<double>("vertexMinDLen2DSig", 2.5);
0081 pdesc.add<double>("vertexMinDLenSig", 0.5);
0082 pdesc.add<double>("fitterSigmacut", 3.0);
0083 pdesc.add<double>("fitterTini", 256.0);
0084 pdesc.add<double>("fitterRatio", 0.25);
0085 pdesc.add<bool>("useDirectVertexFitter", true);
0086 pdesc.add<bool>("useVertexReco", true);
0087
0088 edm::ParameterSetDescription vertexReco;
0089 vertexReco.add<std::string>("finder", std::string("avr"));
0090 vertexReco.add<double>("primcut", 1.0);
0091 vertexReco.add<double>("seccut", 3.0);
0092 vertexReco.add<bool>("smoothing", true);
0093 pdesc.add<edm::ParameterSetDescription>("vertexReco", vertexReco);
0094 if (std::is_same<VTX, reco::Vertex>::value) {
0095 cdesc.add("inclusiveVertexFinderDefault", pdesc);
0096 } else if (std::is_same<VTX, reco::VertexCompositePtrCandidate>::value) {
0097 cdesc.add("inclusiveCandidateVertexFinderDefault", pdesc);
0098 } else {
0099 cdesc.addDefault(pdesc);
0100 }
0101 }
0102
0103 void produce(edm::Event &event, const edm::EventSetup &es) override;
0104
0105 private:
0106 bool trackFilter(const reco::Track &track) const;
0107 std::pair<std::vector<reco::TransientTrack>, GlobalPoint> nearTracks(const reco::TransientTrack &seed,
0108 const std::vector<reco::TransientTrack> &tracks,
0109 const reco::Vertex &primaryVertex) const;
0110
0111 edm::EDGetTokenT<reco::BeamSpot> token_beamSpot;
0112 edm::EDGetTokenT<reco::VertexCollection> token_primaryVertex;
0113 edm::EDGetTokenT<InputContainer> token_tracks;
0114 edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> token_trackBuilder;
0115 unsigned int minHits;
0116 unsigned int maxNTracks;
0117 double maxLIP;
0118 double maxTimeSig;
0119 double minPt;
0120 double vertexMinAngleCosine;
0121 double vertexMinDLen2DSig;
0122 double vertexMinDLenSig;
0123 double fitterSigmacut;
0124 double fitterTini;
0125 double fitterRatio;
0126 bool useVertexFitter;
0127 bool useVertexReco;
0128 std::unique_ptr<VertexReconstructor> vtxReco;
0129 std::unique_ptr<TracksClusteringFromDisplacedSeed> clusterizer;
0130 };
0131 template <class InputContainer, class VTX>
0132 TemplatedInclusiveVertexFinder<InputContainer, VTX>::TemplatedInclusiveVertexFinder(const edm::ParameterSet ¶ms)
0133 : minHits(params.getParameter<unsigned int>("minHits")),
0134 maxNTracks(params.getParameter<unsigned int>("maxNTracks")),
0135 maxLIP(params.getParameter<double>("maximumLongitudinalImpactParameter")),
0136 maxTimeSig(params.getParameter<double>("maximumTimeSignificance")),
0137 minPt(params.getParameter<double>("minPt")),
0138 vertexMinAngleCosine(params.getParameter<double>("vertexMinAngleCosine")),
0139 vertexMinDLen2DSig(params.getParameter<double>("vertexMinDLen2DSig")),
0140 vertexMinDLenSig(params.getParameter<double>("vertexMinDLenSig")),
0141 fitterSigmacut(params.getParameter<double>("fitterSigmacut")),
0142 fitterTini(params.getParameter<double>("fitterTini")),
0143 fitterRatio(params.getParameter<double>("fitterRatio")),
0144 useVertexFitter(params.getParameter<bool>("useDirectVertexFitter")),
0145 useVertexReco(params.getParameter<bool>("useVertexReco")),
0146 vtxReco(new ConfigurableVertexReconstructor(params.getParameter<edm::ParameterSet>("vertexReco"))),
0147 clusterizer(new TracksClusteringFromDisplacedSeed(params.getParameter<edm::ParameterSet>("clusterizer")))
0148
0149 {
0150 token_beamSpot = consumes<reco::BeamSpot>(params.getParameter<edm::InputTag>("beamSpot"));
0151 token_primaryVertex = consumes<reco::VertexCollection>(params.getParameter<edm::InputTag>("primaryVertices"));
0152 token_tracks = consumes<InputContainer>(params.getParameter<edm::InputTag>("tracks"));
0153 token_trackBuilder =
0154 esConsumes<TransientTrackBuilder, TransientTrackRecord>(edm::ESInputTag("", "TransientTrackBuilder"));
0155 produces<Product>();
0156
0157 }
0158 template <class InputContainer, class VTX>
0159 bool TemplatedInclusiveVertexFinder<InputContainer, VTX>::trackFilter(const reco::Track &track) const {
0160 if (track.hitPattern().numberOfValidHits() < (int)minHits)
0161 return false;
0162 if (track.pt() < minPt)
0163 return false;
0164
0165 return true;
0166 }
0167
0168 template <class InputContainer, class VTX>
0169 void TemplatedInclusiveVertexFinder<InputContainer, VTX>::produce(edm::Event &event, const edm::EventSetup &es) {
0170 using namespace reco;
0171
0172 VertexDistance3D vdist;
0173 VertexDistanceXY vdist2d;
0174 MultiVertexFitter theMultiVertexFitter;
0175 AdaptiveVertexFitter theAdaptiveFitter(GeometricAnnealing(fitterSigmacut, fitterTini, fitterRatio),
0176 DefaultLinearizationPointFinder(),
0177 KalmanVertexUpdator<5>(),
0178 KalmanVertexTrackCompatibilityEstimator<5>(),
0179 KalmanVertexSmoother());
0180
0181 edm::Handle<BeamSpot> beamSpot;
0182 event.getByToken(token_beamSpot, beamSpot);
0183
0184 edm::Handle<VertexCollection> primaryVertices;
0185 event.getByToken(token_primaryVertex, primaryVertices);
0186
0187 edm::Handle<InputContainer> tracks;
0188 event.getByToken(token_tracks, tracks);
0189
0190 edm::ESHandle<TransientTrackBuilder> trackBuilder = es.getHandle(token_trackBuilder);
0191
0192 auto recoVertices = std::make_unique<Product>();
0193 if (!primaryVertices->empty()) {
0194 const reco::Vertex &pv = (*primaryVertices)[0];
0195 GlobalPoint ppv(pv.position().x(), pv.position().y(), pv.position().z());
0196
0197 std::vector<TransientTrack> tts;
0198
0199 for (typename InputContainer::const_iterator track = tracks->begin(); track != tracks->end(); ++track) {
0200
0201
0202 TransientTrack tt(tthelpers::buildTT(tracks, trackBuilder, track - tracks->begin()));
0203 if (!tt.isValid())
0204 continue;
0205 if (!trackFilter(tt.track()))
0206 continue;
0207 if (std::abs(tt.track().dz(pv.position())) > maxLIP)
0208 continue;
0209 if (edm::isFinite(tt.timeExt()) && pv.covariance(3, 3) > 0.) {
0210 auto tError = std::sqrt(std::pow(tt.dtErrorExt(), 2) + pv.covariance(3, 3));
0211 auto dtSig = std::abs(tt.timeExt() - pv.t()) / tError;
0212 if (dtSig > maxTimeSig)
0213 continue;
0214 }
0215 tt.setBeamSpot(*beamSpot);
0216 tts.push_back(tt);
0217 }
0218 std::vector<TracksClusteringFromDisplacedSeed::Cluster> clusters = clusterizer->clusters(pv, tts);
0219
0220
0221 BeamSpot::CovarianceMatrix cov;
0222 for (unsigned int i = 0; i < 7; i++) {
0223 for (unsigned int j = 0; j < 7; j++) {
0224 if (i < 3 && j < 3)
0225 cov(i, j) = pv.covariance(i, j);
0226 else
0227 cov(i, j) = 0.0;
0228 }
0229 }
0230 BeamSpot bs(pv.position(), 0.0, 0.0, 0.0, 0.0, cov, BeamSpot::Unknown);
0231
0232 int i = 0;
0233 #ifdef VTXDEBUG
0234
0235 std::cout << "CLUSTERS " << clusters.size() << std::endl;
0236 #endif
0237
0238 for (std::vector<TracksClusteringFromDisplacedSeed::Cluster>::iterator cluster = clusters.begin();
0239 cluster != clusters.end();
0240 ++cluster, ++i) {
0241 if (cluster->tracks.size() < 2 || cluster->tracks.size() > maxNTracks)
0242 continue;
0243 std::vector<TransientVertex> vertices;
0244 if (useVertexReco) {
0245 vertices = vtxReco->vertices(cluster->tracks, bs);
0246 }
0247 TransientVertex singleFitVertex;
0248 if (useVertexFitter) {
0249 singleFitVertex = theAdaptiveFitter.vertex(cluster->tracks, cluster->seedPoint);
0250 if (singleFitVertex.isValid())
0251 vertices.push_back(singleFitVertex);
0252 }
0253
0254
0255 if (pv.covariance(3, 3) > 0.) {
0256 for (auto &vtx : vertices) {
0257 svhelper::updateVertexTime(vtx);
0258 }
0259 }
0260
0261 for (std::vector<TransientVertex>::const_iterator v = vertices.begin(); v != vertices.end(); ++v) {
0262 Measurement1D dlen = vdist.distance(pv, *v);
0263 Measurement1D dlen2 = vdist2d.distance(pv, *v);
0264 #ifdef VTXDEBUG
0265 VTX vv(*v);
0266 std::cout << "V chi2/n: " << v->normalisedChiSquared() << " ndof: " << v->degreesOfFreedom();
0267 std::cout << " dlen: " << dlen.value() << " error: " << dlen.error() << " signif: " << dlen.significance();
0268 std::cout << " dlen2: " << dlen2.value() << " error2: " << dlen2.error()
0269 << " signif2: " << dlen2.significance();
0270 std::cout << " pos: " << vv.position() << " error: " << vv.xError() << " " << vv.yError() << " " << vv.zError()
0271 << std::endl;
0272 std::cout << " time: " << vv.time() << " error: " << vv.tError() << std::endl;
0273 #endif
0274 GlobalVector dir;
0275 std::vector<reco::TransientTrack> ts = v->originalTracks();
0276 for (std::vector<reco::TransientTrack>::const_iterator i = ts.begin(); i != ts.end(); ++i) {
0277 float w = v->trackWeight(*i);
0278 if (w > 0.5)
0279 dir += i->impactPointState().globalDirection();
0280 #ifdef VTXDEBUG
0281 std::cout << "\t[" << (*i).track().pt() << ": " << (*i).track().eta() << ", " << (*i).track().phi() << "], "
0282 << w << std::endl;
0283 #endif
0284 }
0285 GlobalPoint sv((*v).position().x(), (*v).position().y(), (*v).position().z());
0286 float vscal = dir.unit().dot((sv - ppv).unit());
0287 if (dlen.significance() > vertexMinDLenSig &&
0288 ((vertexMinAngleCosine > 0) ? (vscal > vertexMinAngleCosine) : (vscal < vertexMinAngleCosine)) &&
0289 v->normalisedChiSquared() < 10 && dlen2.significance() > vertexMinDLen2DSig) {
0290 recoVertices->push_back(*v);
0291
0292 #ifdef VTXDEBUG
0293 std::cout << "ADDED" << std::endl;
0294 #endif
0295 }
0296 }
0297 }
0298 #ifdef VTXDEBUG
0299
0300 std::cout << "Final put " << recoVertices->size() << std::endl;
0301 #endif
0302 }
0303
0304 event.put(std::move(recoVertices));
0305 }
0306 #endif