File indexing completed on 2025-05-08 02:18:42
0001
0002
0003
0004
0005 #include <algorithm>
0006 #include <limits>
0007 #include <map>
0008 #include <memory>
0009 #include <string>
0010 #include <vector>
0011
0012 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
0013 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0014 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0015 #include "DataFormats/Candidate/interface/VertexCompositeCandidate.h"
0016 #include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h"
0017 #include "DataFormats/Candidate/interface/VertexCompositePtrCandidateFwd.h"
0018 #include "DataFormats/Math/interface/deltaR.h"
0019 #include "DataFormats/PatCandidates/interface/CompositeCandidate.h"
0020 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0021 #include "FWCore/Framework/interface/Event.h"
0022 #include "FWCore/Framework/interface/global/EDProducer.h"
0023 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0025 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0026 #include "FWCore/Utilities/interface/InputTag.h"
0027 #include "KinVtxFitter.h"
0028 #include "MagneticField/Engine/interface/MagneticField.h"
0029 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0030 #include "RecoVertex/KinematicFit/interface/KinematicConstrainedVertexFitter.h"
0031 #include "RecoVertex/KinematicFit/interface/TwoTrackMassKinematicConstraint.h"
0032 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicParticleFactoryFromTransientTrack.h"
0033 #include "RecoVertex/KinematicFitPrimitives/interface/MultiTrackKinematicConstraint.h"
0034 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0035 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0036 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0037 #include "helper.h"
0038
0039 class V0ReBuilder : public edm::global::EDProducer<> {
0040
0041 public:
0042 typedef std::vector<reco::TransientTrack> TransientTrackCollection;
0043 typedef std::vector<reco::VertexCompositePtrCandidate> V0Collection;
0044
0045 explicit V0ReBuilder(const edm::ParameterSet &cfg)
0046 : theB_(esConsumes(edm::ESInputTag{"", "TransientTrackBuilder"})),
0047 trk_selection_{cfg.getParameter<std::string>("trkSelection")},
0048 pre_vtx_selection_{cfg.getParameter<std::string>("V0Selection")},
0049 post_vtx_selection_{cfg.getParameter<std::string>("postVtxSelection")},
0050 v0s_{consumes<V0Collection>(cfg.getParameter<edm::InputTag>("V0s"))},
0051 beamspot_{consumes<reco::BeamSpot>(cfg.getParameter<edm::InputTag>("beamSpot"))},
0052 track_match_{consumes<edm::Association<pat::CompositeCandidateCollection>>(
0053 cfg.getParameter<edm::InputTag>("track_match"))},
0054 isLambda_{cfg.getParameter<bool>("isLambda")} {
0055 produces<pat::CompositeCandidateCollection>("SelectedV0Collection");
0056 produces<TransientTrackCollection>("SelectedV0TransientCollection");
0057 }
0058
0059 ~V0ReBuilder() override {}
0060
0061 void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override;
0062
0063 private:
0064 const edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> theB_;
0065 const StringCutObjectSelector<pat::PackedCandidate> trk_selection_;
0066 const StringCutObjectSelector<reco::VertexCompositePtrCandidate> pre_vtx_selection_;
0067 const StringCutObjectSelector<pat::CompositeCandidate> post_vtx_selection_;
0068 const edm::EDGetTokenT<V0Collection> v0s_;
0069 const edm::EDGetTokenT<reco::BeamSpot> beamspot_;
0070 const edm::EDGetTokenT<edm::Association<pat::CompositeCandidateCollection>> track_match_;
0071 const bool isLambda_;
0072 };
0073
0074 void V0ReBuilder::produce(edm::StreamID, edm::Event &evt, edm::EventSetup const &iSetup) const {
0075
0076 auto const theB = &iSetup.getData(theB_);
0077 edm::Handle<V0Collection> V0s;
0078 evt.getByToken(v0s_, V0s);
0079 edm::Handle<reco::BeamSpot> beamspot;
0080 evt.getByToken(beamspot_, beamspot);
0081
0082 auto &track_match = evt.get(track_match_);
0083
0084
0085 std::unique_ptr<pat::CompositeCandidateCollection> ret_val(new pat::CompositeCandidateCollection());
0086 std::unique_ptr<TransientTrackCollection> trans_out(new TransientTrackCollection);
0087
0088 for (reco::VertexCompositePtrCandidateCollection::const_iterator v0 = V0s->begin(); v0 != V0s->end(); v0++) {
0089
0090 if (v0->numberOfDaughters() != 2)
0091 continue;
0092 if (!pre_vtx_selection_(*v0))
0093 continue;
0094
0095 pat::PackedCandidate v0daughter1 = *(dynamic_cast<const pat::PackedCandidate *>(v0->daughter(0)));
0096 pat::PackedCandidate v0daughter2 = *(dynamic_cast<const pat::PackedCandidate *>(v0->daughter(1)));
0097
0098 if (!v0daughter1.hasTrackDetails())
0099 continue;
0100 if (!v0daughter2.hasTrackDetails())
0101 continue;
0102
0103 if (abs(v0daughter1.pdgId()) != 211)
0104 continue;
0105 if (abs(v0daughter2.pdgId()) != 211)
0106 continue;
0107
0108 if (!trk_selection_(v0daughter1) || !trk_selection_(v0daughter2))
0109 continue;
0110
0111 reco::TransientTrack v0daughter1_ttrack;
0112
0113
0114
0115 reco::TransientTrack v0daughter2_ttrack;
0116
0117
0118 if (v0daughter1.p() > v0daughter2.p()) {
0119 v0daughter1_ttrack = theB->build(v0daughter1.bestTrack());
0120 v0daughter2_ttrack = theB->build(v0daughter2.bestTrack());
0121 } else {
0122 v0daughter1_ttrack = theB->build(v0daughter2.bestTrack());
0123 v0daughter2_ttrack = theB->build(v0daughter1.bestTrack());
0124 }
0125
0126 float Track1_mass = (isLambda_) ? bph::PROT_MASS : bph::PI_MASS;
0127 float Track1_sigma = bph::PI_SIGMA;
0128 float Track2_mass = bph::PI_MASS;
0129 float Track2_sigma = bph::PI_SIGMA;
0130
0131 KinVtxFitter fitter(
0132 {v0daughter1_ttrack, v0daughter2_ttrack}, {Track1_mass, Track2_mass}, {Track1_sigma, Track2_sigma});
0133
0134 if (!fitter.success())
0135 continue;
0136
0137 pat::CompositeCandidate cand;
0138 cand.setVertex(reco::Candidate::Point(fitter.fitted_vtx().x(), fitter.fitted_vtx().y(), fitter.fitted_vtx().z()));
0139 auto fit_p4 = fitter.fitted_p4();
0140 cand.setP4(fit_p4);
0141
0142 cand.setCharge(v0daughter1.charge() + v0daughter2.charge());
0143 cand.addUserFloat("sv_chi2", fitter.chi2());
0144 cand.addUserFloat("sv_prob", fitter.prob());
0145 cand.addUserFloat("fitted_mass", fitter.fitted_candidate().mass());
0146 cand.addUserFloat("massErr", sqrt(fitter.fitted_candidate().kinematicParametersError().matrix()(6, 6)));
0147 cand.addUserFloat("cos_theta_2D", bph::cos_theta_2D(fitter, *beamspot, cand.p4()));
0148 cand.addUserFloat("fitted_cos_theta_2D", bph::cos_theta_2D(fitter, *beamspot, fit_p4));
0149 auto lxy = bph::l_xy(fitter, *beamspot);
0150 cand.addUserFloat("l_xy", lxy.value());
0151 cand.addUserFloat("l_xy_unc", lxy.error());
0152
0153 if (!post_vtx_selection_(cand))
0154 continue;
0155
0156 cand.addUserFloat("vtx_x", cand.vx());
0157 cand.addUserFloat("vtx_y", cand.vy());
0158 cand.addUserFloat("vtx_z", cand.vz());
0159
0160 const auto &covMatrix = fitter.fitted_vtx_uncertainty();
0161 cand.addUserFloat("vtx_cxx", covMatrix.cxx());
0162 cand.addUserFloat("vtx_cyy", covMatrix.cyy());
0163 cand.addUserFloat("vtx_czz", covMatrix.czz());
0164 cand.addUserFloat("vtx_cyx", covMatrix.cyx());
0165 cand.addUserFloat("vtx_czx", covMatrix.czx());
0166 cand.addUserFloat("vtx_czy", covMatrix.czy());
0167
0168 cand.addUserFloat("prefit_mass", v0->mass());
0169 int trk1 = 0;
0170 int trk2 = 1;
0171 if (fitter.daughter_p4(0).pt() < fitter.daughter_p4(1).pt()) {
0172 trk1 = 1;
0173 trk2 = 0;
0174 }
0175 cand.addUserFloat("trk1_pt", fitter.daughter_p4(trk1).pt());
0176 cand.addUserFloat("trk1_eta", fitter.daughter_p4(trk1).eta());
0177 cand.addUserFloat("trk1_phi", fitter.daughter_p4(trk1).phi());
0178 cand.addUserFloat("trk2_pt", fitter.daughter_p4(trk2).pt());
0179 cand.addUserFloat("trk2_eta", fitter.daughter_p4(trk2).eta());
0180 cand.addUserFloat("trk2_phi", fitter.daughter_p4(trk2).phi());
0181
0182
0183 auto trk1_ptr = v0->daughterPtr(trk1);
0184 auto trk1_matched_ref = track_match.get(trk1_ptr.id(), trk1_ptr.key());
0185 auto trk2_ptr = v0->daughterPtr(trk2);
0186 auto trk2_matched_ref = track_match.get(trk2_ptr.id(), trk2_ptr.key());
0187
0188 cand.addUserInt("trk1_idx", trk1_matched_ref.key());
0189 cand.addUserInt("trk2_idx", trk2_matched_ref.key());
0190
0191
0192 ret_val->push_back(cand);
0193 auto V0TT = fitter.fitted_candidate_ttrk();
0194 trans_out->emplace_back(V0TT);
0195 }
0196
0197 evt.put(std::move(ret_val), "SelectedV0Collection");
0198 evt.put(std::move(trans_out), "SelectedV0TransientCollection");
0199 }
0200
0201 #include "FWCore/Framework/interface/MakerMacros.h"
0202 DEFINE_FWK_MODULE(V0ReBuilder);