File indexing completed on 2024-04-06 12:24:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <memory>
0022
0023
0024 #include "FWCore/Framework/interface/Frameworkfwd.h"
0025 #include "FWCore/Framework/interface/stream/EDProducer.h"
0026
0027 #include "FWCore/Framework/interface/Event.h"
0028 #include "FWCore/Framework/interface/MakerMacros.h"
0029
0030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0031 #include "FWCore/Utilities/interface/StreamID.h"
0032 #include "FWCore/Utilities/interface/isFinite.h"
0033 #include "FWCore/Utilities/interface/ESGetToken.h"
0034
0035 #include "DataFormats/BTauReco/interface/CandIPTagInfo.h"
0036 #include "DataFormats/BTauReco/interface/CandSecondaryVertexTagInfo.h"
0037 #include "DataFormats/BTauReco/interface/BoostedDoubleSVTagInfo.h"
0038 #include "DataFormats/BTauReco/interface/TaggingVariable.h"
0039 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0040 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0041 #include "DataFormats/VertexReco/interface/Vertex.h"
0042 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0043 #include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h"
0044
0045 #include "RecoBTag/SecondaryVertex/interface/TrackKinematics.h"
0046 #include "RecoBTag/SecondaryVertex/interface/V0Filter.h"
0047 #include "RecoBTag/SecondaryVertex/interface/TrackSelector.h"
0048 #include "RecoVertex/VertexPrimitives/interface/ConvertToFromReco.h"
0049 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0050 #include "TrackingTools/IPTools/interface/IPTools.h"
0051 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0052
0053 #include "fastjet/PseudoJet.hh"
0054 #include "fastjet/contrib/Njettiness.hh"
0055
0056 #include <map>
0057
0058
0059
0060
0061
0062 class BoostedDoubleSVProducer : public edm::stream::EDProducer<> {
0063 public:
0064 explicit BoostedDoubleSVProducer(const edm::ParameterSet&);
0065 ~BoostedDoubleSVProducer() override;
0066
0067 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0068
0069 private:
0070 void beginStream(edm::StreamID) override;
0071 void produce(edm::Event&, const edm::EventSetup&) override;
0072 void endStream() override;
0073
0074 void calcNsubjettiness(const reco::JetBaseRef& jet,
0075 float& tau1,
0076 float& tau2,
0077 std::vector<fastjet::PseudoJet>& currentAxes) const;
0078 void setTracksPVBase(const reco::TrackRef& trackRef, const reco::VertexRef& vertexRef, float& PVweight) const;
0079 void setTracksPV(const reco::CandidatePtr& trackRef, const reco::VertexRef& vertexRef, float& PVweight) const;
0080 void etaRelToTauAxis(const reco::VertexCompositePtrCandidate& vertex,
0081 const fastjet::PseudoJet& tauAxis,
0082 std::vector<float>& tau_trackEtaRel) const;
0083
0084
0085 const edm::EDGetTokenT<std::vector<reco::CandSecondaryVertexTagInfo>> svTagInfos_;
0086
0087 const double beta_;
0088 const double R0_;
0089
0090 const double maxSVDeltaRToJet_;
0091 const double maxDistToAxis_;
0092 const double maxDecayLen_;
0093 reco::V0Filter trackPairV0Filter;
0094 reco::TrackSelector trackSelector;
0095
0096 edm::EDGetTokenT<edm::ValueMap<float>> weightsToken_;
0097 edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> trackBuilderToken_;
0098 edm::Handle<edm::ValueMap<float>> weightsHandle_;
0099
0100
0101 static constexpr float dummyZ_ratio = -3.0f;
0102 static constexpr float dummyTrackSip3dSig = -50.0f;
0103 static constexpr float dummyTrackSip2dSigAbove = -19.0f;
0104 static constexpr float dummyTrackEtaRel = -1.0f;
0105 static constexpr float dummyVertexMass = -1.0f;
0106 static constexpr float dummyVertexEnergyRatio = -1.0f;
0107 static constexpr float dummyVertexDeltaR = -1.0f;
0108 static constexpr float dummyFlightDistance2dSig = -1.0f;
0109
0110 static constexpr float charmThreshold = 1.5f;
0111 static constexpr float bottomThreshold = 5.2f;
0112 };
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 BoostedDoubleSVProducer::BoostedDoubleSVProducer(const edm::ParameterSet& iConfig)
0126 : svTagInfos_(
0127 consumes<std::vector<reco::CandSecondaryVertexTagInfo>>(iConfig.getParameter<edm::InputTag>("svTagInfos"))),
0128 beta_(iConfig.getParameter<double>("beta")),
0129 R0_(iConfig.getParameter<double>("R0")),
0130 maxSVDeltaRToJet_(iConfig.getParameter<double>("maxSVDeltaRToJet")),
0131 maxDistToAxis_(iConfig.getParameter<edm::ParameterSet>("trackSelection").getParameter<double>("maxDistToAxis")),
0132 maxDecayLen_(iConfig.getParameter<edm::ParameterSet>("trackSelection").getParameter<double>("maxDecayLen")),
0133 trackPairV0Filter(iConfig.getParameter<edm::ParameterSet>("trackPairV0Filter")),
0134 trackSelector(iConfig.getParameter<edm::ParameterSet>("trackSelection")) {
0135 edm::InputTag srcWeights = iConfig.getParameter<edm::InputTag>("weights");
0136 trackBuilderToken_ =
0137 esConsumes<TransientTrackBuilder, TransientTrackRecord>(edm::ESInputTag("", "TransientTrackBuilder"));
0138 if (!srcWeights.label().empty())
0139 weightsToken_ = consumes<edm::ValueMap<float>>(srcWeights);
0140 produces<std::vector<reco::BoostedDoubleSVTagInfo>>();
0141 }
0142
0143 BoostedDoubleSVProducer::~BoostedDoubleSVProducer() {
0144
0145
0146 }
0147
0148
0149
0150
0151
0152
0153 void BoostedDoubleSVProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0154
0155 edm::ESHandle<TransientTrackBuilder> trackBuilder = iSetup.getHandle(trackBuilderToken_);
0156
0157
0158 edm::Handle<std::vector<reco::CandSecondaryVertexTagInfo>> svTagInfos;
0159 iEvent.getByToken(svTagInfos_, svTagInfos);
0160
0161 if (!weightsToken_.isUninitialized())
0162 iEvent.getByToken(weightsToken_, weightsHandle_);
0163
0164
0165 auto tagInfos = std::make_unique<std::vector<reco::BoostedDoubleSVTagInfo>>();
0166
0167
0168 for (std::vector<reco::CandSecondaryVertexTagInfo>::const_iterator iterTI = svTagInfos->begin();
0169 iterTI != svTagInfos->end();
0170 ++iterTI) {
0171
0172 const reco::CandIPTagInfo& ipTagInfo = *(iterTI->trackIPTagInfoRef().get());
0173 const reco::CandSecondaryVertexTagInfo& svTagInfo = *(iterTI);
0174
0175
0176 float z_ratio = dummyZ_ratio;
0177 float trackSip3dSig_3 = dummyTrackSip3dSig, trackSip3dSig_2 = dummyTrackSip3dSig,
0178 trackSip3dSig_1 = dummyTrackSip3dSig, trackSip3dSig_0 = dummyTrackSip3dSig;
0179 float tau2_trackSip3dSig_0 = dummyTrackSip3dSig, tau1_trackSip3dSig_0 = dummyTrackSip3dSig,
0180 tau2_trackSip3dSig_1 = dummyTrackSip3dSig, tau1_trackSip3dSig_1 = dummyTrackSip3dSig;
0181 float trackSip2dSigAboveCharm_0 = dummyTrackSip2dSigAbove, trackSip2dSigAboveBottom_0 = dummyTrackSip2dSigAbove,
0182 trackSip2dSigAboveBottom_1 = dummyTrackSip2dSigAbove;
0183 float tau1_trackEtaRel_0 = dummyTrackEtaRel, tau1_trackEtaRel_1 = dummyTrackEtaRel,
0184 tau1_trackEtaRel_2 = dummyTrackEtaRel;
0185 float tau2_trackEtaRel_0 = dummyTrackEtaRel, tau2_trackEtaRel_1 = dummyTrackEtaRel,
0186 tau2_trackEtaRel_2 = dummyTrackEtaRel;
0187 float tau1_vertexMass = dummyVertexMass, tau1_vertexEnergyRatio = dummyVertexEnergyRatio,
0188 tau1_vertexDeltaR = dummyVertexDeltaR, tau1_flightDistance2dSig = dummyFlightDistance2dSig;
0189 float tau2_vertexMass = dummyVertexMass, tau2_vertexEnergyRatio = dummyVertexEnergyRatio,
0190 tau2_vertexDeltaR = dummyVertexDeltaR, tau2_flightDistance2dSig = dummyFlightDistance2dSig;
0191 float jetNTracks = 0, nSV = 0, tau1_nSecondaryVertices = 0, tau2_nSecondaryVertices = 0;
0192
0193
0194 const reco::JetBaseRef jet = svTagInfo.jet();
0195
0196 std::vector<fastjet::PseudoJet> currentAxes;
0197 float tau2, tau1;
0198
0199 calcNsubjettiness(jet, tau1, tau2, currentAxes);
0200
0201 const reco::VertexRef& vertexRef = ipTagInfo.primaryVertex();
0202 GlobalPoint pv(0., 0., 0.);
0203 if (ipTagInfo.primaryVertex().isNonnull())
0204 pv = GlobalPoint(vertexRef->x(), vertexRef->y(), vertexRef->z());
0205
0206 const std::vector<reco::CandidatePtr>& selectedTracks = ipTagInfo.selectedTracks();
0207 const std::vector<reco::btag::TrackIPData>& ipData = ipTagInfo.impactParameterData();
0208 size_t trackSize = selectedTracks.size();
0209
0210 reco::TrackKinematics allKinematics;
0211 std::vector<float> IP3Ds, IP3Ds_1, IP3Ds_2;
0212 int contTrk = 0;
0213
0214
0215 for (size_t itt = 0; itt < trackSize; ++itt) {
0216 const reco::CandidatePtr trackRef = selectedTracks[itt];
0217
0218 float track_PVweight = 0.;
0219 setTracksPV(trackRef, vertexRef, track_PVweight);
0220 if (track_PVweight > 0.5)
0221 allKinematics.add(trackRef);
0222
0223 const reco::btag::TrackIPData& data = ipData[itt];
0224 bool isSelected = false;
0225 if (trackSelector(trackRef, data, *jet, pv))
0226 isSelected = true;
0227
0228
0229 bool isfromV0 = false, isfromV0Tight = false;
0230 std::vector<reco::CandidatePtr> trackPairV0Test(2);
0231
0232 trackPairV0Test[0] = trackRef;
0233
0234 for (size_t jtt = 0; jtt < trackSize; ++jtt) {
0235 if (itt == jtt)
0236 continue;
0237
0238 const reco::btag::TrackIPData& pairTrackData = ipData[jtt];
0239 const reco::CandidatePtr pairTrackRef = selectedTracks[jtt];
0240
0241 trackPairV0Test[1] = pairTrackRef;
0242
0243 if (!trackPairV0Filter(trackPairV0Test)) {
0244 isfromV0 = true;
0245
0246 if (trackSelector(pairTrackRef, pairTrackData, *jet, pv))
0247 isfromV0Tight = true;
0248 }
0249
0250 if (isfromV0 && isfromV0Tight)
0251 break;
0252 }
0253
0254 if (isSelected && !isfromV0Tight)
0255 jetNTracks += 1.;
0256
0257 reco::TransientTrack transientTrack = trackBuilder->build(trackRef);
0258 GlobalVector direction(jet->px(), jet->py(), jet->pz());
0259
0260 int index = 0;
0261 if (currentAxes.size() > 1 &&
0262 reco::deltaR2(trackRef->momentum(), currentAxes[1]) < reco::deltaR2(trackRef->momentum(), currentAxes[0]))
0263 index = 1;
0264 direction = GlobalVector(currentAxes[index].px(), currentAxes[index].py(), currentAxes[index].pz());
0265
0266
0267 float decayLengthTau = -1;
0268 float distTauAxis = -1;
0269
0270 TrajectoryStateOnSurface closest = IPTools::closestApproachToJet(
0271 transientTrack.impactPointState(), *vertexRef, direction, transientTrack.field());
0272 if (closest.isValid())
0273 decayLengthTau = (closest.globalPosition() - RecoVertex::convertPos(vertexRef->position())).mag();
0274
0275 distTauAxis = std::abs(IPTools::jetTrackDistance(transientTrack, direction, *vertexRef).second.value());
0276
0277 float IP3Dsig = ipTagInfo.impactParameterData()[itt].ip3d.significance();
0278
0279 if (!isfromV0 && decayLengthTau < maxDecayLen_ && distTauAxis < maxDistToAxis_) {
0280 IP3Ds.push_back(IP3Dsig < -50. ? -50. : IP3Dsig);
0281 ++contTrk;
0282 if (currentAxes.size() > 1) {
0283 if (reco::deltaR2(trackRef->momentum(), currentAxes[0]) < reco::deltaR2(trackRef->momentum(), currentAxes[1]))
0284 IP3Ds_1.push_back(IP3Dsig < -50. ? -50. : IP3Dsig);
0285 else
0286 IP3Ds_2.push_back(IP3Dsig < -50. ? -50. : IP3Dsig);
0287 } else
0288 IP3Ds_1.push_back(IP3Dsig < -50. ? -50. : IP3Dsig);
0289 }
0290 }
0291
0292 std::vector<size_t> indices = ipTagInfo.sortedIndexes(reco::btag::IP2DSig);
0293 bool charmThreshSet = false;
0294
0295 reco::TrackKinematics kin;
0296 for (size_t i = 0; i < indices.size(); ++i) {
0297 size_t idx = indices[i];
0298 const reco::btag::TrackIPData& data = ipData[idx];
0299 const reco::CandidatePtr trackRef = selectedTracks[idx];
0300
0301 kin.add(trackRef);
0302
0303 if (kin.vectorSum().M() > charmThreshold
0304 && !charmThreshSet) {
0305 trackSip2dSigAboveCharm_0 = data.ip2d.significance();
0306
0307 charmThreshSet = true;
0308 }
0309
0310 if (kin.vectorSum().M() > bottomThreshold)
0311 {
0312 trackSip2dSigAboveBottom_0 = data.ip2d.significance();
0313 if ((i + 1) < indices.size())
0314 trackSip2dSigAboveBottom_1 = (ipData[indices[i + 1]]).ip2d.significance();
0315
0316 break;
0317 }
0318 }
0319
0320 float dummyTrack = -50.;
0321
0322 std::sort(IP3Ds.begin(), IP3Ds.end(), std::greater<float>());
0323 std::sort(IP3Ds_1.begin(), IP3Ds_1.end(), std::greater<float>());
0324 std::sort(IP3Ds_2.begin(), IP3Ds_2.end(), std::greater<float>());
0325 int num_1 = IP3Ds_1.size();
0326 int num_2 = IP3Ds_2.size();
0327
0328 switch (contTrk) {
0329 case 0:
0330
0331 trackSip3dSig_0 = dummyTrack;
0332 trackSip3dSig_1 = dummyTrack;
0333 trackSip3dSig_2 = dummyTrack;
0334 trackSip3dSig_3 = dummyTrack;
0335
0336 break;
0337
0338 case 1:
0339
0340 trackSip3dSig_0 = IP3Ds.at(0);
0341 trackSip3dSig_1 = dummyTrack;
0342 trackSip3dSig_2 = dummyTrack;
0343 trackSip3dSig_3 = dummyTrack;
0344
0345 break;
0346
0347 case 2:
0348
0349 trackSip3dSig_0 = IP3Ds.at(0);
0350 trackSip3dSig_1 = IP3Ds.at(1);
0351 trackSip3dSig_2 = dummyTrack;
0352 trackSip3dSig_3 = dummyTrack;
0353
0354 break;
0355
0356 case 3:
0357
0358 trackSip3dSig_0 = IP3Ds.at(0);
0359 trackSip3dSig_1 = IP3Ds.at(1);
0360 trackSip3dSig_2 = IP3Ds.at(2);
0361 trackSip3dSig_3 = dummyTrack;
0362
0363 break;
0364
0365 default:
0366
0367 trackSip3dSig_0 = IP3Ds.at(0);
0368 trackSip3dSig_1 = IP3Ds.at(1);
0369 trackSip3dSig_2 = IP3Ds.at(2);
0370 trackSip3dSig_3 = IP3Ds.at(3);
0371 }
0372
0373 switch (num_1) {
0374 case 0:
0375
0376 tau1_trackSip3dSig_0 = dummyTrack;
0377 tau1_trackSip3dSig_1 = dummyTrack;
0378
0379 break;
0380
0381 case 1:
0382
0383 tau1_trackSip3dSig_0 = IP3Ds_1.at(0);
0384 tau1_trackSip3dSig_1 = dummyTrack;
0385
0386 break;
0387
0388 default:
0389
0390 tau1_trackSip3dSig_0 = IP3Ds_1.at(0);
0391 tau1_trackSip3dSig_1 = IP3Ds_1.at(1);
0392 }
0393
0394 switch (num_2) {
0395 case 0:
0396
0397 tau2_trackSip3dSig_0 = dummyTrack;
0398 tau2_trackSip3dSig_1 = dummyTrack;
0399
0400 break;
0401
0402 case 1:
0403 tau2_trackSip3dSig_0 = IP3Ds_2.at(0);
0404 tau2_trackSip3dSig_1 = dummyTrack;
0405
0406 break;
0407
0408 default:
0409
0410 tau2_trackSip3dSig_0 = IP3Ds_2.at(0);
0411 tau2_trackSip3dSig_1 = IP3Ds_2.at(1);
0412 }
0413
0414 math::XYZVector jetDir = jet->momentum().Unit();
0415 reco::TrackKinematics tau1Kinematics;
0416 reco::TrackKinematics tau2Kinematics;
0417 std::vector<float> tau1_trackEtaRels, tau2_trackEtaRels;
0418
0419 std::map<double, size_t> VTXmap;
0420 for (size_t vtx = 0; vtx < svTagInfo.nVertices(); ++vtx) {
0421 const reco::VertexCompositePtrCandidate& vertex = svTagInfo.secondaryVertex(vtx);
0422
0423 reco::TrackKinematics vertexKinematic(vertex);
0424
0425 if (currentAxes.size() > 1) {
0426 if (reco::deltaR2(svTagInfo.flightDirection(vtx), currentAxes[1]) <
0427 reco::deltaR2(svTagInfo.flightDirection(vtx), currentAxes[0])) {
0428 tau2Kinematics = tau2Kinematics + vertexKinematic;
0429 if (tau2_flightDistance2dSig < 0) {
0430 tau2_flightDistance2dSig = svTagInfo.flightDistance(vtx, true).significance();
0431 tau2_vertexDeltaR = reco::deltaR(svTagInfo.flightDirection(vtx), currentAxes[1]);
0432 }
0433 etaRelToTauAxis(vertex, currentAxes[1], tau2_trackEtaRels);
0434 tau2_nSecondaryVertices += 1.;
0435 } else {
0436 tau1Kinematics = tau1Kinematics + vertexKinematic;
0437 if (tau1_flightDistance2dSig < 0) {
0438 tau1_flightDistance2dSig = svTagInfo.flightDistance(vtx, true).significance();
0439 tau1_vertexDeltaR = reco::deltaR(svTagInfo.flightDirection(vtx), currentAxes[0]);
0440 }
0441 etaRelToTauAxis(vertex, currentAxes[0], tau1_trackEtaRels);
0442 tau1_nSecondaryVertices += 1.;
0443 }
0444
0445 } else if (!currentAxes.empty()) {
0446 tau1Kinematics = tau1Kinematics + vertexKinematic;
0447 if (tau1_flightDistance2dSig < 0) {
0448 tau1_flightDistance2dSig = svTagInfo.flightDistance(vtx, true).significance();
0449 tau1_vertexDeltaR = reco::deltaR(svTagInfo.flightDirection(vtx), currentAxes[0]);
0450 }
0451 etaRelToTauAxis(vertex, currentAxes[0], tau1_trackEtaRels);
0452 tau1_nSecondaryVertices += 1.;
0453 }
0454
0455 const GlobalVector& flightDir = svTagInfo.flightDirection(vtx);
0456 if (reco::deltaR2(flightDir, jetDir) < (maxSVDeltaRToJet_ * maxSVDeltaRToJet_))
0457 VTXmap[svTagInfo.flightDistance(vtx).error()] = vtx;
0458 }
0459 nSV = VTXmap.size();
0460
0461 math::XYZTLorentzVector allSum = allKinematics.weightedVectorSum();
0462 if (tau1_nSecondaryVertices > 0.) {
0463 const math::XYZTLorentzVector& tau1_vertexSum = tau1Kinematics.weightedVectorSum();
0464 if (allSum.E() > 0.)
0465 tau1_vertexEnergyRatio = tau1_vertexSum.E() / allSum.E();
0466 if (tau1_vertexEnergyRatio > 50.)
0467 tau1_vertexEnergyRatio = 50.;
0468
0469 tau1_vertexMass = tau1_vertexSum.M();
0470 }
0471
0472 if (tau2_nSecondaryVertices > 0.) {
0473 const math::XYZTLorentzVector& tau2_vertexSum = tau2Kinematics.weightedVectorSum();
0474 if (allSum.E() > 0.)
0475 tau2_vertexEnergyRatio = tau2_vertexSum.E() / allSum.E();
0476 if (tau2_vertexEnergyRatio > 50.)
0477 tau2_vertexEnergyRatio = 50.;
0478
0479 tau2_vertexMass = tau2_vertexSum.M();
0480 }
0481
0482 float dummyEtaRel = -1.;
0483
0484 std::sort(tau1_trackEtaRels.begin(), tau1_trackEtaRels.end());
0485 std::sort(tau2_trackEtaRels.begin(), tau2_trackEtaRels.end());
0486
0487 switch (tau2_trackEtaRels.size()) {
0488 case 0:
0489
0490 tau2_trackEtaRel_0 = dummyEtaRel;
0491 tau2_trackEtaRel_1 = dummyEtaRel;
0492 tau2_trackEtaRel_2 = dummyEtaRel;
0493
0494 break;
0495
0496 case 1:
0497
0498 tau2_trackEtaRel_0 = tau2_trackEtaRels.at(0);
0499 tau2_trackEtaRel_1 = dummyEtaRel;
0500 tau2_trackEtaRel_2 = dummyEtaRel;
0501
0502 break;
0503
0504 case 2:
0505
0506 tau2_trackEtaRel_0 = tau2_trackEtaRels.at(0);
0507 tau2_trackEtaRel_1 = tau2_trackEtaRels.at(1);
0508 tau2_trackEtaRel_2 = dummyEtaRel;
0509
0510 break;
0511
0512 default:
0513
0514 tau2_trackEtaRel_0 = tau2_trackEtaRels.at(0);
0515 tau2_trackEtaRel_1 = tau2_trackEtaRels.at(1);
0516 tau2_trackEtaRel_2 = tau2_trackEtaRels.at(2);
0517 }
0518
0519 switch (tau1_trackEtaRels.size()) {
0520 case 0:
0521
0522 tau1_trackEtaRel_0 = dummyEtaRel;
0523 tau1_trackEtaRel_1 = dummyEtaRel;
0524 tau1_trackEtaRel_2 = dummyEtaRel;
0525
0526 break;
0527
0528 case 1:
0529
0530 tau1_trackEtaRel_0 = tau1_trackEtaRels.at(0);
0531 tau1_trackEtaRel_1 = dummyEtaRel;
0532 tau1_trackEtaRel_2 = dummyEtaRel;
0533
0534 break;
0535
0536 case 2:
0537
0538 tau1_trackEtaRel_0 = tau1_trackEtaRels.at(0);
0539 tau1_trackEtaRel_1 = tau1_trackEtaRels.at(1);
0540 tau1_trackEtaRel_2 = dummyEtaRel;
0541
0542 break;
0543
0544 default:
0545
0546 tau1_trackEtaRel_0 = tau1_trackEtaRels.at(0);
0547 tau1_trackEtaRel_1 = tau1_trackEtaRels.at(1);
0548 tau1_trackEtaRel_2 = tau1_trackEtaRels.at(2);
0549 }
0550
0551 int cont = 0;
0552 GlobalVector flightDir_0, flightDir_1;
0553 reco::Candidate::LorentzVector SV_p4_0, SV_p4_1;
0554 double vtxMass = 0.;
0555
0556 for (std::map<double, size_t>::iterator iVtx = VTXmap.begin(); iVtx != VTXmap.end(); ++iVtx) {
0557 ++cont;
0558 const reco::VertexCompositePtrCandidate& vertex = svTagInfo.secondaryVertex(iVtx->second);
0559 if (cont == 1) {
0560 flightDir_0 = svTagInfo.flightDirection(iVtx->second);
0561 SV_p4_0 = vertex.p4();
0562 vtxMass = SV_p4_0.mass();
0563
0564 if (vtxMass > 0.)
0565 z_ratio = reco::deltaR(currentAxes[1], currentAxes[0]) * SV_p4_0.pt() / vtxMass;
0566 }
0567 if (cont == 2) {
0568 flightDir_1 = svTagInfo.flightDirection(iVtx->second);
0569 SV_p4_1 = vertex.p4();
0570 vtxMass = (SV_p4_1 + SV_p4_0).mass();
0571
0572 if (vtxMass > 0.)
0573 z_ratio = reco::deltaR(flightDir_0, flightDir_1) * SV_p4_1.pt() / vtxMass;
0574
0575 break;
0576 }
0577 }
0578
0579
0580
0581 if ((tau1_vertexMass < 0 && tau2_vertexMass > 0)) {
0582 float temp = tau1_trackEtaRel_0;
0583 tau1_trackEtaRel_0 = tau2_trackEtaRel_0;
0584 tau2_trackEtaRel_0 = temp;
0585
0586 temp = tau1_trackEtaRel_1;
0587 tau1_trackEtaRel_1 = tau2_trackEtaRel_1;
0588 tau2_trackEtaRel_1 = temp;
0589
0590 temp = tau1_trackEtaRel_2;
0591 tau1_trackEtaRel_2 = tau2_trackEtaRel_2;
0592 tau2_trackEtaRel_2 = temp;
0593
0594 temp = tau1_flightDistance2dSig;
0595 tau1_flightDistance2dSig = tau2_flightDistance2dSig;
0596 tau2_flightDistance2dSig = temp;
0597
0598 tau1_vertexDeltaR = tau2_vertexDeltaR;
0599
0600 temp = tau1_vertexEnergyRatio;
0601 tau1_vertexEnergyRatio = tau2_vertexEnergyRatio;
0602 tau2_vertexEnergyRatio = temp;
0603
0604 temp = tau1_vertexMass;
0605 tau1_vertexMass = tau2_vertexMass;
0606 tau2_vertexMass = temp;
0607 }
0608
0609 reco::TaggingVariableList vars;
0610
0611 vars.insert(reco::btau::jetNTracks, jetNTracks, true);
0612 vars.insert(reco::btau::jetNSecondaryVertices, nSV, true);
0613 vars.insert(reco::btau::trackSip3dSig_0, trackSip3dSig_0, true);
0614 vars.insert(reco::btau::trackSip3dSig_1, trackSip3dSig_1, true);
0615 vars.insert(reco::btau::trackSip3dSig_2, trackSip3dSig_2, true);
0616 vars.insert(reco::btau::trackSip3dSig_3, trackSip3dSig_3, true);
0617 vars.insert(reco::btau::tau1_trackSip3dSig_0, tau1_trackSip3dSig_0, true);
0618 vars.insert(reco::btau::tau1_trackSip3dSig_1, tau1_trackSip3dSig_1, true);
0619 vars.insert(reco::btau::tau2_trackSip3dSig_0, tau2_trackSip3dSig_0, true);
0620 vars.insert(reco::btau::tau2_trackSip3dSig_1, tau2_trackSip3dSig_1, true);
0621 vars.insert(reco::btau::trackSip2dSigAboveCharm, trackSip2dSigAboveCharm_0, true);
0622 vars.insert(reco::btau::trackSip2dSigAboveBottom_0, trackSip2dSigAboveBottom_0, true);
0623 vars.insert(reco::btau::trackSip2dSigAboveBottom_1, trackSip2dSigAboveBottom_1, true);
0624 vars.insert(reco::btau::tau1_trackEtaRel_0, tau1_trackEtaRel_0, true);
0625 vars.insert(reco::btau::tau1_trackEtaRel_1, tau1_trackEtaRel_1, true);
0626 vars.insert(reco::btau::tau1_trackEtaRel_2, tau1_trackEtaRel_2, true);
0627 vars.insert(reco::btau::tau2_trackEtaRel_0, tau2_trackEtaRel_0, true);
0628 vars.insert(reco::btau::tau2_trackEtaRel_1, tau2_trackEtaRel_1, true);
0629 vars.insert(reco::btau::tau2_trackEtaRel_2, tau2_trackEtaRel_2, true);
0630 vars.insert(reco::btau::tau1_vertexMass, tau1_vertexMass, true);
0631 vars.insert(reco::btau::tau1_vertexEnergyRatio, tau1_vertexEnergyRatio, true);
0632 vars.insert(reco::btau::tau1_flightDistance2dSig, tau1_flightDistance2dSig, true);
0633 vars.insert(reco::btau::tau1_vertexDeltaR, tau1_vertexDeltaR, true);
0634 vars.insert(reco::btau::tau2_vertexMass, tau2_vertexMass, true);
0635 vars.insert(reco::btau::tau2_vertexEnergyRatio, tau2_vertexEnergyRatio, true);
0636 vars.insert(reco::btau::tau2_flightDistance2dSig, tau2_flightDistance2dSig, true);
0637 vars.insert(reco::btau::z_ratio, z_ratio, true);
0638
0639 vars.finalize();
0640
0641 tagInfos->push_back(reco::BoostedDoubleSVTagInfo(
0642 vars, edm::Ref<std::vector<reco::CandSecondaryVertexTagInfo>>(svTagInfos, iterTI - svTagInfos->begin())));
0643 }
0644
0645
0646 iEvent.put(std::move(tagInfos));
0647 }
0648
0649 void BoostedDoubleSVProducer::calcNsubjettiness(const reco::JetBaseRef& jet,
0650 float& tau1,
0651 float& tau2,
0652 std::vector<fastjet::PseudoJet>& currentAxes) const {
0653 std::vector<fastjet::PseudoJet> fjParticles;
0654
0655
0656 for (const reco::CandidatePtr& daughter : jet->daughterPtrVector()) {
0657 if (daughter.isNonnull() && daughter.isAvailable()) {
0658 const reco::Jet* subjet = dynamic_cast<const reco::Jet*>(daughter.get());
0659
0660 if (subjet && daughter->numberOfDaughters() > 1) {
0661
0662 for (size_t i = 0; i < daughter->numberOfDaughters(); ++i) {
0663 const reco::CandidatePtr& constit = subjet->daughterPtr(i);
0664
0665 if (constit.isNonnull() && constit->pt() > std::numeric_limits<double>::epsilon()) {
0666
0667 float valcheck = constit->px() + constit->py() + constit->pz() + constit->energy();
0668 if (edm::isNotFinite(valcheck)) {
0669 edm::LogWarning("FaultyJetConstituent")
0670 << "Jet constituent required for N-subjettiness computation contains Nan/Inf values!";
0671 continue;
0672 }
0673 if (subjet->isWeighted()) {
0674 float w = 0.0;
0675 if (!weightsToken_.isUninitialized())
0676 w = (*weightsHandle_)[constit];
0677 else {
0678 throw cms::Exception("MissingConstituentWeight")
0679 << "BoostedDoubleSVProducer: No weights (e.g. PUPPI) given for weighted jet collection"
0680 << std::endl;
0681 }
0682 if (w > 0) {
0683 fjParticles.push_back(
0684 fastjet::PseudoJet(constit->px() * w, constit->py() * w, constit->pz() * w, constit->energy() * w));
0685 }
0686 } else {
0687 fjParticles.push_back(fastjet::PseudoJet(constit->px(), constit->py(), constit->pz(), constit->energy()));
0688 }
0689 } else
0690 edm::LogWarning("MissingJetConstituent")
0691 << "Jet constituent required for N-subjettiness computation is missing!";
0692 }
0693 } else {
0694
0695 float valcheck = daughter->px() + daughter->py() + daughter->pz() + daughter->energy();
0696 if (edm::isNotFinite(valcheck)) {
0697 edm::LogWarning("FaultyJetConstituent")
0698 << "Jet constituent required for N-subjettiness computation contains Nan/Inf values!";
0699 continue;
0700 }
0701 if (jet->isWeighted()) {
0702 float w = 0.0;
0703 if (!weightsToken_.isUninitialized())
0704 w = (*weightsHandle_)[daughter];
0705 else {
0706 throw cms::Exception("MissingConstituentWeight")
0707 << "BoostedDoubleSVProducer: No weights (e.g. PUPPI) given for weighted jet collection" << std::endl;
0708 }
0709 if (w > 0 && daughter->pt() > std::numeric_limits<double>::epsilon()) {
0710 fjParticles.push_back(
0711 fastjet::PseudoJet(daughter->px() * w, daughter->py() * w, daughter->pz() * w, daughter->energy() * w));
0712 }
0713 } else {
0714 fjParticles.push_back(fastjet::PseudoJet(daughter->px(), daughter->py(), daughter->pz(), daughter->energy()));
0715 }
0716 }
0717 } else
0718 edm::LogWarning("MissingJetConstituent") << "Jet constituent required for N-subjettiness computation is missing!";
0719 }
0720
0721
0722 fastjet::contrib::Njettiness njettiness(fastjet::contrib::OnePass_KT_Axes(),
0723 fastjet::contrib::NormalizedMeasure(beta_, R0_));
0724
0725
0726 tau1 = njettiness.getTau(1, fjParticles);
0727 tau2 = njettiness.getTau(2, fjParticles);
0728 currentAxes = njettiness.currentAxes();
0729 }
0730
0731 void BoostedDoubleSVProducer::setTracksPVBase(const reco::TrackRef& trackRef,
0732 const reco::VertexRef& vertexRef,
0733 float& PVweight) const {
0734 PVweight = 0.;
0735
0736 const reco::TrackBaseRef trackBaseRef(trackRef);
0737
0738 typedef reco::Vertex::trackRef_iterator IT;
0739
0740 const reco::Vertex& vtx = *(vertexRef);
0741
0742 for (IT it = vtx.tracks_begin(); it != vtx.tracks_end(); ++it) {
0743 const reco::TrackBaseRef& baseRef = *it;
0744
0745 if (baseRef == trackBaseRef) {
0746 PVweight = vtx.trackWeight(baseRef);
0747 break;
0748 }
0749 }
0750 }
0751
0752 void BoostedDoubleSVProducer::setTracksPV(const reco::CandidatePtr& trackRef,
0753 const reco::VertexRef& vertexRef,
0754 float& PVweight) const {
0755 PVweight = 0.;
0756
0757 const pat::PackedCandidate* pcand = dynamic_cast<const pat::PackedCandidate*>(trackRef.get());
0758
0759 if (pcand)
0760 {
0761 if (pcand->fromPV() == pat::PackedCandidate::PVUsedInFit) {
0762 PVweight = 1.;
0763 }
0764 } else {
0765 const reco::PFCandidate* pfcand = dynamic_cast<const reco::PFCandidate*>(trackRef.get());
0766
0767 setTracksPVBase(pfcand->trackRef(), vertexRef, PVweight);
0768 }
0769 }
0770
0771 void BoostedDoubleSVProducer::etaRelToTauAxis(const reco::VertexCompositePtrCandidate& vertex,
0772 const fastjet::PseudoJet& tauAxis,
0773 std::vector<float>& tau_trackEtaRel) const {
0774 math::XYZVector direction(tauAxis.px(), tauAxis.py(), tauAxis.pz());
0775 const std::vector<reco::CandidatePtr>& tracks = vertex.daughterPtrVector();
0776
0777 for (std::vector<reco::CandidatePtr>::const_iterator track = tracks.begin(); track != tracks.end(); ++track)
0778 tau_trackEtaRel.push_back(std::abs(reco::btau::etaRel(direction.Unit(), (*track)->momentum())));
0779 }
0780
0781
0782 void BoostedDoubleSVProducer::beginStream(edm::StreamID) {}
0783
0784
0785 void BoostedDoubleSVProducer::endStream() {}
0786
0787
0788 void BoostedDoubleSVProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0789 edm::ParameterSetDescription desc;
0790 desc.add<double>("beta", 1.0);
0791 desc.add<double>("R0", 0.8);
0792 desc.add<double>("maxSVDeltaRToJet", 0.7);
0793 {
0794 edm::ParameterSetDescription trackSelection;
0795 trackSelection.setAllowAnything();
0796 desc.add<edm::ParameterSetDescription>("trackSelection", trackSelection);
0797 }
0798 {
0799 edm::ParameterSetDescription trackPairV0Filter;
0800 trackPairV0Filter.add<double>("k0sMassWindow", 0.03);
0801 desc.add<edm::ParameterSetDescription>("trackPairV0Filter", trackPairV0Filter);
0802 }
0803 desc.add<edm::InputTag>("svTagInfos", edm::InputTag("pfInclusiveSecondaryVertexFinderAK8TagInfos"));
0804 desc.add<edm::InputTag>("weights", edm::InputTag(""));
0805 descriptions.addDefault(desc);
0806 }
0807
0808
0809 DEFINE_FWK_MODULE(BoostedDoubleSVProducer);