File indexing completed on 2024-04-06 12:24:00
0001 #include <algorithm>
0002 #include <iostream>
0003 #include <cmath>
0004 #include <vector>
0005 #include <string>
0006
0007 #include <TH1.h>
0008 #include <TProfile.h>
0009
0010 #include <Math/VectorUtil.h>
0011
0012 #include "FWCore/Framework/interface/Frameworkfwd.h"
0013 #include "FWCore/Framework/interface/Event.h"
0014 #include "FWCore/Framework/interface/EventSetup.h"
0015 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0016 #include "FWCore/Utilities/interface/InputTag.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "FWCore/ServiceRegistry/interface/Service.h"
0019
0020 #include "CommonTools/UtilAlgos/interface/TFileService.h"
0021
0022 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0023 #include "DataFormats/VertexReco/interface/Vertex.h"
0024 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0025 #include "DataFormats/TrackReco/interface/Track.h"
0026 #include "DataFormats/TrackReco/interface/TrackFwd.h"
0027 #include "DataFormats/PatCandidates/interface/Jet.h"
0028 #include "DataFormats/GeometryCommonDetAlgo/interface/Measurement1D.h"
0029
0030 class PatBJetTrackAnalyzer : public edm::one::EDAnalyzer<edm::one::SharedResources> {
0031 public:
0032
0033 PatBJetTrackAnalyzer(const edm::ParameterSet ¶ms);
0034 ~PatBJetTrackAnalyzer() override;
0035
0036
0037 void beginJob() override;
0038 void analyze(const edm::Event &event, const edm::EventSetup &es) override;
0039
0040 private:
0041
0042 edm::EDGetTokenT<pat::JetCollection> jetsToken_;
0043 edm::EDGetTokenT<reco::TrackCollection> tracksToken_;
0044 edm::EDGetTokenT<reco::BeamSpot> beamSpotToken_;
0045 edm::EDGetTokenT<reco::VertexCollection> primaryVerticesToken_;
0046
0047 double jetPtCut_;
0048 double jetEtaCut_;
0049 double maxDeltaR_;
0050
0051 double minPt_;
0052 unsigned int minPixelHits_;
0053 unsigned int minTotalHits_;
0054
0055 unsigned int nThTrack_;
0056
0057
0058
0059 enum Flavour { ALL_JETS = 0, UDSG_JETS, C_JETS, B_JETS, NONID_JETS, N_JET_TYPES };
0060
0061 TH1 *flavours_;
0062
0063
0064 struct Plots {
0065 TH1 *allIP, *allIPErr, *allIPSig;
0066 TH1 *trackIP, *trackIPErr, *trackIPSig;
0067 TH1 *negativeIP, *negativeIPErr, *negativeIPSig;
0068 TH1 *nTracks, *allDeltaR;
0069 } plots_[N_JET_TYPES];
0070 };
0071
0072 PatBJetTrackAnalyzer::PatBJetTrackAnalyzer(const edm::ParameterSet ¶ms)
0073 : jetsToken_(consumes<pat::JetCollection>(params.getParameter<edm::InputTag>("jets"))),
0074 tracksToken_(consumes<reco::TrackCollection>(params.getParameter<edm::InputTag>("tracks"))),
0075 beamSpotToken_(consumes<reco::BeamSpot>(params.getParameter<edm::InputTag>("beamSpot"))),
0076 primaryVerticesToken_(consumes<reco::VertexCollection>(params.getParameter<edm::InputTag>("primaryVertices"))),
0077 jetPtCut_(params.getParameter<double>("jetPtCut")),
0078 jetEtaCut_(params.getParameter<double>("jetEtaCut")),
0079 maxDeltaR_(params.getParameter<double>("maxDeltaR")),
0080 minPt_(params.getParameter<double>("minPt")),
0081 minPixelHits_(params.getParameter<unsigned int>("minPixelHits")),
0082 minTotalHits_(params.getParameter<unsigned int>("minTotalHits")),
0083 nThTrack_(params.getParameter<unsigned int>("nThTrack")) {
0084 usesResource(TFileService::kSharedResource);
0085 }
0086
0087 PatBJetTrackAnalyzer::~PatBJetTrackAnalyzer() {}
0088
0089 void PatBJetTrackAnalyzer::beginJob() {
0090
0091
0092 edm::Service<TFileService> fs;
0093
0094 flavours_ = fs->make<TH1F>("flavours", "jet flavours", 5, 0, 5);
0095
0096
0097 for (unsigned int i = 0; i < N_JET_TYPES; i++) {
0098 Plots &plots = plots_[i];
0099 const char *flavour, *name;
0100
0101 switch ((Flavour)i) {
0102 case ALL_JETS:
0103 flavour = "all jets";
0104 name = "all";
0105 break;
0106 case UDSG_JETS:
0107 flavour = "light flavour jets";
0108 name = "udsg";
0109 break;
0110 case C_JETS:
0111 flavour = "charm jets";
0112 name = "c";
0113 break;
0114 case B_JETS:
0115 flavour = "bottom jets";
0116 name = "b";
0117 break;
0118 default:
0119 flavour = "unidentified jets";
0120 name = "ni";
0121 break;
0122 }
0123
0124 plots.allIP =
0125 fs->make<TH1F>(Form("allIP_%s", name), Form("signed IP for all tracks in %s", flavour), 100, -0.1, 0.2);
0126 plots.allIPErr = fs->make<TH1F>(
0127 Form("allIPErr_%s", name), Form("error of signed IP for all tracks in %s", flavour), 100, 0, 0.05);
0128 plots.allIPSig = fs->make<TH1F>(
0129 Form("allIPSig_%s", name), Form("signed IP significance for all tracks in %s", flavour), 100, -10, 20);
0130
0131 plots.trackIP = fs->make<TH1F>(
0132 Form("trackIP_%s", name), Form("signed IP for selected positive track in %s", flavour), 100, -0.1, 0.2);
0133 plots.trackIPErr = fs->make<TH1F>(Form("trackIPErr_%s", name),
0134 Form("error of signed IP for selected positive track in %s", flavour),
0135 100,
0136 0,
0137 0.05);
0138 plots.trackIPSig = fs->make<TH1F>(Form("trackIPSig_%s", name),
0139 Form("signed IP significance for selected positive track in %s", flavour),
0140 100,
0141 -10,
0142 20);
0143
0144 plots.negativeIP = fs->make<TH1F>(
0145 Form("negativeIP_%s", name), Form("signed IP for selected negative track in %s", flavour), 100, -0.2, 0.1);
0146 plots.negativeIPErr = fs->make<TH1F>(Form("negativeIPErr_%s", name),
0147 Form("error of signed IP for selected negative track in %s", flavour),
0148 100,
0149 0,
0150 0.05);
0151 plots.negativeIPSig = fs->make<TH1F>(Form("negativeIPSig_%s", name),
0152 Form("signed IP significance for selected negative track in %s", flavour),
0153 100,
0154 -20,
0155 10);
0156
0157 plots.nTracks = fs->make<TH1F>(Form("nTracks_%s", name), Form("number of usable tracks in %s", flavour), 30, 0, 30);
0158 plots.allDeltaR =
0159 fs->make<TH1F>(Form("allDeltaR_%s", name), Form("\\DeltaR between track and %s", flavour), 100, 0, 1);
0160 }
0161 }
0162
0163
0164
0165 static bool significanceHigher(const Measurement1D &meas1, const Measurement1D &meas2) {
0166 return meas1.significance() > meas2.significance();
0167 }
0168
0169 void PatBJetTrackAnalyzer::analyze(const edm::Event &event, const edm::EventSetup &es) {
0170
0171 edm::Handle<reco::VertexCollection> pvHandle;
0172 event.getByToken(primaryVerticesToken_, pvHandle);
0173
0174
0175 edm::Handle<reco::TrackCollection> tracksHandle;
0176 event.getByToken(tracksToken_, tracksHandle);
0177
0178
0179 edm::Handle<pat::JetCollection> jetsHandle;
0180 event.getByToken(jetsToken_, jetsHandle);
0181
0182
0183 edm::Handle<reco::BeamSpot> beamSpot;
0184 event.getByToken(beamSpotToken_, beamSpot);
0185
0186
0187 if (pvHandle->empty())
0188 return;
0189
0190
0191 math::XYZPoint pv = (*pvHandle)[0].position();
0192
0193
0194 for (pat::JetCollection::const_iterator jet = jetsHandle->begin(); jet != jetsHandle->end(); ++jet) {
0195
0196 if (jet->pt() < jetPtCut_ || std::abs(jet->eta()) > jetEtaCut_)
0197 continue;
0198
0199 Flavour flavour;
0200
0201 switch (std::abs(jet->partonFlavour())) {
0202 case 1:
0203 case 2:
0204 case 3:
0205 case 21:
0206 flavour = UDSG_JETS;
0207 break;
0208 case 4:
0209 flavour = C_JETS;
0210 break;
0211 case 5:
0212 flavour = B_JETS;
0213 break;
0214 default:
0215 flavour = NONID_JETS;
0216 }
0217
0218
0219 flavours_->Fill(ALL_JETS);
0220 flavours_->Fill(flavour);
0221
0222
0223 std::vector<Measurement1D> ipValErr;
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233 for (reco::TrackCollection::const_iterator track = tracksHandle->begin(); track != tracksHandle->end(); ++track) {
0234
0235 if (track->pt() < minPt_ || track->hitPattern().numberOfValidHits() < (int)minTotalHits_ ||
0236 track->hitPattern().numberOfValidPixelHits() < (int)minPixelHits_)
0237 continue;
0238
0239
0240
0241 double deltaR = ROOT::Math::VectorUtil::DeltaR(jet->momentum(), track->momentum());
0242
0243 plots_[ALL_JETS].allDeltaR->Fill(deltaR);
0244 plots_[flavour].allDeltaR->Fill(deltaR);
0245
0246
0247 if (deltaR > maxDeltaR_)
0248 continue;
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268 double ipError = track->dxyError();
0269 double ipValue = std::abs(track->dxy(pv));
0270
0271
0272
0273
0274
0275
0276
0277
0278 math::XYZVector closestPoint = track->referencePoint() - beamSpot->position();
0279
0280 closestPoint.SetZ(0.);
0281 double sign = closestPoint.Dot(jet->momentum());
0282
0283 if (sign < 0)
0284 ipValue = -ipValue;
0285
0286 ipValErr.push_back(Measurement1D(ipValue, ipError));
0287 }
0288
0289
0290 std::sort(ipValErr.begin(), ipValErr.end(), significanceHigher);
0291
0292 plots_[ALL_JETS].nTracks->Fill(ipValErr.size());
0293 plots_[flavour].nTracks->Fill(ipValErr.size());
0294
0295
0296
0297 for (std::vector<Measurement1D>::const_iterator iter = ipValErr.begin(); iter != ipValErr.end(); ++iter) {
0298 plots_[ALL_JETS].allIP->Fill(iter->value());
0299 plots_[flavour].allIP->Fill(iter->value());
0300
0301 plots_[ALL_JETS].allIPErr->Fill(iter->error());
0302 plots_[flavour].allIPErr->Fill(iter->error());
0303
0304
0305 plots_[ALL_JETS].allIPSig->Fill(iter->significance());
0306 plots_[flavour].allIPSig->Fill(iter->significance());
0307 }
0308
0309
0310
0311 if (ipValErr.size() < nThTrack_)
0312 continue;
0313
0314
0315 const Measurement1D *trk = &ipValErr[nThTrack_ - 1];
0316
0317 plots_[ALL_JETS].trackIP->Fill(trk->value());
0318 plots_[flavour].trackIP->Fill(trk->value());
0319
0320 plots_[ALL_JETS].trackIPErr->Fill(trk->error());
0321 plots_[flavour].trackIPErr->Fill(trk->error());
0322
0323 plots_[ALL_JETS].trackIPSig->Fill(trk->significance());
0324 plots_[flavour].trackIPSig->Fill(trk->significance());
0325
0326
0327
0328
0329
0330
0331
0332 trk = &ipValErr[ipValErr.size() - nThTrack_];
0333
0334 plots_[ALL_JETS].negativeIP->Fill(trk->value());
0335 plots_[flavour].negativeIP->Fill(trk->value());
0336
0337 plots_[ALL_JETS].negativeIPErr->Fill(trk->error());
0338 plots_[flavour].negativeIPErr->Fill(trk->error());
0339
0340 plots_[ALL_JETS].negativeIPSig->Fill(trk->significance());
0341 plots_[flavour].negativeIPSig->Fill(trk->significance());
0342 }
0343 }
0344
0345 #include "FWCore/Framework/interface/MakerMacros.h"
0346
0347 DEFINE_FWK_MODULE(PatBJetTrackAnalyzer);