File indexing completed on 2025-05-08 02:18:41
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 BToV0LLBuilder : public edm::global::EDProducer<> {
0040
0041 public:
0042 typedef std::vector<reco::TransientTrack> TransientTrackCollection;
0043
0044 explicit BToV0LLBuilder(const edm::ParameterSet &cfg)
0045 : bFieldToken_{esConsumes<MagneticField, IdealMagneticFieldRecord>()},
0046 pre_vtx_selection_{cfg.getParameter<std::string>("preVtxSelection")},
0047 post_vtx_selection_{cfg.getParameter<std::string>("postVtxSelection")},
0048 dileptons_{consumes<pat::CompositeCandidateCollection>(cfg.getParameter<edm::InputTag>("dileptons"))},
0049 leptons_ttracks_{consumes<TransientTrackCollection>(cfg.getParameter<edm::InputTag>("leptonTransientTracks"))},
0050 v0s_{consumes<pat::CompositeCandidateCollection>(cfg.getParameter<edm::InputTag>("v0s"))},
0051 v0_ttracks_{consumes<TransientTrackCollection>(cfg.getParameter<edm::InputTag>("v0TransientTracks"))},
0052 pu_tracks_(consumes<pat::CompositeCandidateCollection>(cfg.getParameter<edm::InputTag>("PUtracks"))),
0053 beamspot_{consumes<reco::BeamSpot>(cfg.getParameter<edm::InputTag>("beamSpot"))},
0054 dilepton_constraint_{cfg.getParameter<bool>("dileptonMassContraint")} {
0055 produces<pat::CompositeCandidateCollection>();
0056 }
0057
0058 ~BToV0LLBuilder() override {}
0059
0060 void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override;
0061
0062 private:
0063 const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> bFieldToken_;
0064
0065
0066 const StringCutObjectSelector<pat::CompositeCandidate> pre_vtx_selection_;
0067 const StringCutObjectSelector<pat::CompositeCandidate> post_vtx_selection_;
0068
0069
0070 const edm::EDGetTokenT<pat::CompositeCandidateCollection> dileptons_;
0071 const edm::EDGetTokenT<TransientTrackCollection> leptons_ttracks_;
0072 const edm::EDGetTokenT<pat::CompositeCandidateCollection> v0s_;
0073 const edm::EDGetTokenT<TransientTrackCollection> v0_ttracks_;
0074 const edm::EDGetTokenT<pat::CompositeCandidateCollection> pu_tracks_;
0075 const edm::EDGetTokenT<reco::BeamSpot> beamspot_;
0076 const bool dilepton_constraint_;
0077 };
0078
0079 void BToV0LLBuilder::produce(edm::StreamID, edm::Event &evt, edm::EventSetup const &iSetup) const {
0080
0081 edm::Handle<pat::CompositeCandidateCollection> dileptons;
0082 evt.getByToken(dileptons_, dileptons);
0083 edm::Handle<TransientTrackCollection> leptons_ttracks;
0084 evt.getByToken(leptons_ttracks_, leptons_ttracks);
0085
0086 edm::Handle<pat::CompositeCandidateCollection> v0s;
0087 evt.getByToken(v0s_, v0s);
0088 edm::Handle<TransientTrackCollection> v0_ttracks;
0089 evt.getByToken(v0_ttracks_, v0_ttracks);
0090
0091 edm::Handle<pat::CompositeCandidateCollection> pu_tracks;
0092 evt.getByToken(pu_tracks_, pu_tracks);
0093
0094 edm::Handle<reco::BeamSpot> beamspot;
0095 evt.getByToken(beamspot_, beamspot);
0096
0097 edm::ESHandle<MagneticField> fieldHandle;
0098 const auto &bField = iSetup.getData(bFieldToken_);
0099 AnalyticalImpactPointExtrapolator extrapolator(&bField);
0100
0101
0102 std::unique_ptr<pat::CompositeCandidateCollection> ret_val(new pat::CompositeCandidateCollection());
0103
0104
0105 for (size_t v0_idx = 0; v0_idx < v0s->size(); ++v0_idx) {
0106 edm::Ptr<pat::CompositeCandidate> v0_ptr(v0s, v0_idx);
0107
0108
0109 for (size_t ll_idx = 0; ll_idx < dileptons->size(); ++ll_idx) {
0110 edm::Ptr<pat::CompositeCandidate> ll_ptr(dileptons, ll_idx);
0111 edm::Ptr<reco::Candidate> l1_ptr = ll_ptr->userCand("l1");
0112 edm::Ptr<reco::Candidate> l2_ptr = ll_ptr->userCand("l2");
0113 int l1_idx = ll_ptr->userInt("l1_idx");
0114 int l2_idx = ll_ptr->userInt("l2_idx");
0115
0116 pat::CompositeCandidate cand;
0117 cand.setP4(ll_ptr->p4() + v0_ptr->p4());
0118 cand.setCharge(ll_ptr->charge() + v0_ptr->charge());
0119
0120 cand.addUserInt("l1_idx", l1_idx);
0121 cand.addUserInt("l2_idx", l2_idx);
0122 cand.addUserInt("ll_idx", ll_idx);
0123 cand.addUserInt("v0_idx", v0_idx);
0124
0125 auto dr_info = bph::min_max_dr({l1_ptr, l2_ptr, v0_ptr});
0126 cand.addUserFloat("min_dr", dr_info.first);
0127 cand.addUserFloat("max_dr", dr_info.second);
0128
0129
0130 if (!pre_vtx_selection_(cand))
0131 continue;
0132
0133 KinVtxFitter fitter({leptons_ttracks->at(l1_idx), leptons_ttracks->at(l2_idx), v0_ttracks->at(v0_idx)},
0134 {l1_ptr->mass(), l2_ptr->mass(), v0_ptr->mass()},
0135 {bph::LEP_SIGMA, bph::LEP_SIGMA, v0_ptr->userFloat("massErr")});
0136
0137 if (!fitter.success())
0138 continue;
0139
0140 cand.setVertex(reco::Candidate::Point(fitter.fitted_vtx().x(), fitter.fitted_vtx().y(), fitter.fitted_vtx().z()));
0141
0142 cand.addUserFloat("sv_chi2", fitter.chi2());
0143 cand.addUserFloat("sv_ndof", fitter.dof());
0144 cand.addUserFloat("sv_prob", fitter.prob());
0145 cand.addUserFloat("fitted_mll", (fitter.daughter_p4(0) + fitter.daughter_p4(1)).mass());
0146 cand.addUserFloat("fitted_v0_mass", fitter.daughter_p4(2).mass());
0147
0148 auto fit_p4 = fitter.fitted_p4();
0149 cand.addUserFloat("fitted_pt", fit_p4.pt());
0150 cand.addUserFloat("fitted_eta", fit_p4.eta());
0151 cand.addUserFloat("fitted_phi", fit_p4.phi());
0152 cand.addUserFloat("fitted_mass", fitter.fitted_candidate().mass());
0153 cand.addUserFloat("fitted_massErr", sqrt(fitter.fitted_candidate().kinematicParametersError().matrix()(6, 6)));
0154 cand.addUserFloat("cos_theta_2D", bph::cos_theta_2D(fitter, *beamspot, cand.p4()));
0155 cand.addUserFloat("fitted_cos_theta_2D", bph::cos_theta_2D(fitter, *beamspot, fit_p4));
0156
0157 auto lxy = bph::l_xy(fitter, *beamspot);
0158 cand.addUserFloat("l_xy", lxy.value());
0159 cand.addUserFloat("l_xy_unc", lxy.error());
0160
0161 TrajectoryStateOnSurface tsos =
0162 extrapolator.extrapolate(v0_ttracks->at(v0_idx).impactPointState(), fitter.fitted_vtx());
0163 std::pair<bool, Measurement1D> cur2DIP =
0164 bph::signedTransverseImpactParameter(tsos, fitter.fitted_refvtx(), *beamspot);
0165 cand.addUserFloat("v0_svip2d", cur2DIP.second.value());
0166 cand.addUserFloat("v0_svip2d_err", cur2DIP.second.error());
0167
0168 if (!post_vtx_selection_(cand))
0169 continue;
0170
0171 cand.addUserFloat("vtx_x", cand.vx());
0172 cand.addUserFloat("vtx_y", cand.vy());
0173 cand.addUserFloat("vtx_z", cand.vz());
0174
0175 const auto &covMatrix = fitter.fitted_vtx_uncertainty();
0176 cand.addUserFloat("vtx_cxx", covMatrix.cxx());
0177 cand.addUserFloat("vtx_cyy", covMatrix.cyy());
0178 cand.addUserFloat("vtx_czz", covMatrix.czz());
0179 cand.addUserFloat("vtx_cyx", covMatrix.cyx());
0180 cand.addUserFloat("vtx_czx", covMatrix.czx());
0181 cand.addUserFloat("vtx_czy", covMatrix.czy());
0182
0183
0184 std::vector<std::string> dnames{"l1", "l2", "v0"};
0185 for (size_t idaughter = 0; idaughter < dnames.size(); idaughter++) {
0186 cand.addUserFloat("fitted_" + dnames[idaughter] + "_pt", fitter.daughter_p4(idaughter).pt());
0187 cand.addUserFloat("fitted_" + dnames[idaughter] + "_eta", fitter.daughter_p4(idaughter).eta());
0188 cand.addUserFloat("fitted_" + dnames[idaughter] + "_phi", fitter.daughter_p4(idaughter).phi());
0189 }
0190
0191
0192 std::vector<float> isos = bph::TrackerIsolation(pu_tracks, cand, dnames);
0193 for (size_t idaughter = 0; idaughter < dnames.size(); idaughter++) {
0194 cand.addUserFloat(dnames[idaughter] + "_iso04", isos[idaughter]);
0195 }
0196
0197 float cstr_pt = -99;
0198 float cstr_eta = -99;
0199 float cstr_phi = -99;
0200 float cstr_sv_prob = -99;
0201 float cstr_mass = -99;
0202 float cstr_massErr = -99;
0203 float cstr_vtx_x = -99;
0204 float cstr_vtx_y = -99;
0205 float cstr_vtx_z = -99;
0206 float cstr_vtx_cxx = -99;
0207 float cstr_vtx_cyy = -99;
0208 float cstr_vtx_czz = -99;
0209 float cstr_vtx_cyx = -99;
0210 float cstr_vtx_czx = -99;
0211 float cstr_vtx_czy = -99;
0212 float cstr_fitted_l1_pt = -99;
0213 float cstr_fitted_l1_eta = -99;
0214 float cstr_fitted_l1_phi = -99;
0215 float cstr_fitted_l2_pt = -99;
0216 float cstr_fitted_l2_eta = -99;
0217 float cstr_fitted_l2_phi = -99;
0218 float cstr_fitted_v0_pt = -99;
0219 float cstr_fitted_v0_eta = -99;
0220 float cstr_fitted_v0_phi = -99;
0221 float cstr_v0_mass = -99;
0222 float cstr_cos_theta_2D = -99;
0223
0224 const double dilepton_mass = ll_ptr->userFloat("fitted_mass");
0225 const double jpsi_bin[2] = {2.8, 3.35};
0226 const double psi2s_bin[2] = {3.45, 3.85};
0227 if (dilepton_constraint_ && ((dilepton_mass > jpsi_bin[0] && dilepton_mass < jpsi_bin[1]) ||
0228 (dilepton_mass > psi2s_bin[0] && dilepton_mass < psi2s_bin[1]))) {
0229 ParticleMass JPsi_mass = 3.0969;
0230 ParticleMass Psi2S_mass = 3.6861;
0231 ParticleMass mass_constraint = (dilepton_mass < jpsi_bin[1]) ? JPsi_mass : Psi2S_mass;
0232
0233
0234
0235
0236 KinVtxFitter constraint_fitter(
0237 {leptons_ttracks->at(l1_idx), leptons_ttracks->at(l2_idx), v0_ttracks->at(v0_idx)},
0238 {l1_ptr->mass(), l2_ptr->mass(), v0_ptr->mass()},
0239 {bph::LEP_SIGMA, bph::LEP_SIGMA, v0_ptr->userFloat("massErr")},
0240 mass_constraint);
0241 if (constraint_fitter.success()) {
0242 auto constraint_p4 = constraint_fitter.fitted_p4();
0243 cstr_vtx_x = constraint_fitter.fitted_vtx().x();
0244 cstr_vtx_y = constraint_fitter.fitted_vtx().y();
0245 cstr_vtx_z = constraint_fitter.fitted_vtx().z();
0246
0247 const auto &constrained_covMatrix = constraint_fitter.fitted_vtx_uncertainty();
0248 cstr_vtx_cxx = constrained_covMatrix.cxx();
0249 cstr_vtx_cyy = constrained_covMatrix.cyy();
0250 cstr_vtx_czz = constrained_covMatrix.czz();
0251 cstr_vtx_cyx = constrained_covMatrix.cyx();
0252 cstr_vtx_czx = constrained_covMatrix.czx();
0253 cstr_vtx_czy = constrained_covMatrix.czy();
0254
0255
0256 cstr_fitted_l1_pt = constraint_fitter.daughter_p4(0).pt();
0257 cstr_fitted_l1_eta = constraint_fitter.daughter_p4(0).eta();
0258 cstr_fitted_l1_phi = constraint_fitter.daughter_p4(0).phi();
0259 cstr_fitted_l2_pt = constraint_fitter.daughter_p4(1).pt();
0260 cstr_fitted_l2_eta = constraint_fitter.daughter_p4(1).eta();
0261 cstr_fitted_l2_phi = constraint_fitter.daughter_p4(1).phi();
0262 cstr_fitted_v0_pt = constraint_fitter.daughter_p4(2).pt();
0263 cstr_fitted_v0_eta = constraint_fitter.daughter_p4(2).eta();
0264 cstr_fitted_v0_phi = constraint_fitter.daughter_p4(2).phi();
0265
0266 cstr_v0_mass = constraint_fitter.daughter_p4(2).mass();
0267
0268 cstr_sv_prob = constraint_fitter.prob();
0269 cstr_pt = constraint_p4.pt();
0270 cstr_eta = constraint_p4.eta();
0271 cstr_phi = constraint_p4.phi();
0272 cstr_mass = constraint_fitter.fitted_candidate().mass();
0273 cstr_massErr = sqrt(constraint_fitter.fitted_candidate().kinematicParametersError().matrix()(6, 6));
0274 cstr_cos_theta_2D = bph::cos_theta_2D(constraint_fitter, *beamspot, constraint_p4);
0275 }
0276 }
0277
0278 cand.addUserFloat("cstr_vtx_x", cstr_vtx_x);
0279 cand.addUserFloat("cstr_vtx_y", cstr_vtx_y);
0280 cand.addUserFloat("cstr_vtx_z", cstr_vtx_z);
0281
0282 cand.addUserFloat("cstr_vtx_cxx", cstr_vtx_cxx);
0283 cand.addUserFloat("cstr_vtx_cyy", cstr_vtx_cyy);
0284 cand.addUserFloat("cstr_vtx_czz", cstr_vtx_czz);
0285 cand.addUserFloat("cstr_vtx_cyx", cstr_vtx_cyx);
0286 cand.addUserFloat("cstr_vtx_czx", cstr_vtx_czx);
0287 cand.addUserFloat("cstr_vtx_czy", cstr_vtx_czy);
0288
0289
0290 cand.addUserFloat("cstr_fitted_l1_pt", cstr_fitted_l1_pt);
0291 cand.addUserFloat("cstr_fitted_l1_eta", cstr_fitted_l1_eta);
0292 cand.addUserFloat("cstr_fitted_l1_phi", cstr_fitted_l1_phi);
0293 cand.addUserFloat("cstr_fitted_l2_pt", cstr_fitted_l2_pt);
0294 cand.addUserFloat("cstr_fitted_l2_eta", cstr_fitted_l2_eta);
0295 cand.addUserFloat("cstr_fitted_l2_phi", cstr_fitted_l2_phi);
0296 cand.addUserFloat("cstr_fitted_v0_pt", cstr_fitted_v0_pt);
0297 cand.addUserFloat("cstr_fitted_v0_eta", cstr_fitted_v0_eta);
0298 cand.addUserFloat("cstr_fitted_v0_phi", cstr_fitted_v0_phi);
0299 cand.addUserFloat("cstr_v0_mass", cstr_v0_mass);
0300
0301 cand.addUserFloat("cstr_sv_prob", cstr_sv_prob);
0302 cand.addUserFloat("cstr_pt", cstr_pt);
0303 cand.addUserFloat("cstr_eta", cstr_eta);
0304 cand.addUserFloat("cstr_phi", cstr_phi);
0305 cand.addUserFloat("cstr_mass", cstr_mass);
0306 cand.addUserFloat("cstr_massErr", cstr_massErr);
0307 cand.addUserFloat("cstr_cos_theta_2D", cstr_cos_theta_2D);
0308
0309 ret_val->push_back(cand);
0310 }
0311 }
0312 evt.put(std::move(ret_val));
0313 }
0314
0315 #include "FWCore/Framework/interface/MakerMacros.h"
0316 DEFINE_FWK_MODULE(BToV0LLBuilder);