00001 #include <algorithm>
00002 #include <iostream>
00003 #include <cmath>
00004 #include <vector>
00005 #include <string>
00006
00007 #include <TH1.h>
00008 #include <TProfile.h>
00009
00010 #include <Math/VectorUtil.h>
00011
00012 #include "FWCore/Framework/interface/Frameworkfwd.h"
00013 #include "FWCore/Framework/interface/Event.h"
00014 #include "FWCore/Framework/interface/EventSetup.h"
00015 #include "FWCore/Framework/interface/EDAnalyzer.h"
00016 #include "FWCore/Utilities/interface/InputTag.h"
00017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00018 #include "FWCore/ServiceRegistry/interface/Service.h"
00019
00020 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00021
00022 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00023 #include "DataFormats/VertexReco/interface/Vertex.h"
00024 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00025 #include "DataFormats/TrackReco/interface/Track.h"
00026 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00027 #include "DataFormats/PatCandidates/interface/Jet.h"
00028 #include "DataFormats/GeometryCommonDetAlgo/interface/Measurement1D.h"
00029
00030 class PatBJetTrackAnalyzer : public edm::EDAnalyzer {
00031 public:
00033 PatBJetTrackAnalyzer(const edm::ParameterSet ¶ms);
00034 ~PatBJetTrackAnalyzer();
00035
00036
00037 virtual void beginJob();
00038 virtual void analyze(const edm::Event &event, const edm::EventSetup &es);
00039
00040 private:
00041
00042 edm::InputTag jets_;
00043 edm::InputTag tracks_;
00044 edm::InputTag beamSpot_;
00045 edm::InputTag primaryVertices_;
00046
00047 double jetPtCut_;
00048 double jetEtaCut_;
00049 double maxDeltaR_;
00050
00051 double minPt_;
00052 unsigned int minPixelHits_;
00053 unsigned int minTotalHits_;
00054
00055 unsigned int nThTrack_;
00056
00057
00058
00059 enum Flavour {
00060 ALL_JETS = 0,
00061 UDSG_JETS,
00062 C_JETS,
00063 B_JETS,
00064 NONID_JETS,
00065 N_JET_TYPES
00066 };
00067
00068 TH1 *flavours_;
00069
00070
00071 struct Plots {
00072 TH1 *allIP, *allIPErr, *allIPSig;
00073 TH1 *trackIP, *trackIPErr, *trackIPSig;
00074 TH1 *negativeIP, *negativeIPErr, *negativeIPSig;
00075 TH1 *nTracks, *allDeltaR;
00076 } plots_[N_JET_TYPES];
00077 };
00078
00079 PatBJetTrackAnalyzer::PatBJetTrackAnalyzer(const edm::ParameterSet ¶ms) :
00080 jets_(params.getParameter<edm::InputTag>("jets")),
00081 tracks_(params.getParameter<edm::InputTag>("tracks")),
00082 beamSpot_(params.getParameter<edm::InputTag>("beamSpot")),
00083 primaryVertices_(params.getParameter<edm::InputTag>("primaryVertices")),
00084 jetPtCut_(params.getParameter<double>("jetPtCut")),
00085 jetEtaCut_(params.getParameter<double>("jetEtaCut")),
00086 maxDeltaR_(params.getParameter<double>("maxDeltaR")),
00087 minPt_(params.getParameter<double>("minPt")),
00088 minPixelHits_(params.getParameter<unsigned int>("minPixelHits")),
00089 minTotalHits_(params.getParameter<unsigned int>("minTotalHits")),
00090 nThTrack_(params.getParameter<unsigned int>("nThTrack"))
00091 {
00092 }
00093
00094 PatBJetTrackAnalyzer::~PatBJetTrackAnalyzer()
00095 {
00096 }
00097
00098 void PatBJetTrackAnalyzer::beginJob()
00099 {
00100
00101
00102 edm::Service<TFileService> fs;
00103
00104 flavours_ = fs->make<TH1F>("flavours", "jet flavours", 5, 0, 5);
00105
00106
00107 for(unsigned int i = 0; i < N_JET_TYPES; i++) {
00108 Plots &plots = plots_[i];
00109 const char *flavour, *name;
00110
00111 switch((Flavour)i) {
00112 case ALL_JETS:
00113 flavour = "all jets";
00114 name = "all";
00115 break;
00116 case UDSG_JETS:
00117 flavour = "light flavour jets";
00118 name = "udsg";
00119 break;
00120 case C_JETS:
00121 flavour = "charm jets";
00122 name = "c";
00123 break;
00124 case B_JETS:
00125 flavour = "bottom jets";
00126 name = "b";
00127 break;
00128 default:
00129 flavour = "unidentified jets";
00130 name = "ni";
00131 break;
00132 }
00133
00134 plots.allIP = fs->make<TH1F>(Form("allIP_%s", name),
00135 Form("signed IP for all tracks in %s", flavour),
00136 100, -0.1, 0.2);
00137 plots.allIPErr = fs->make<TH1F>(Form("allIPErr_%s", name),
00138 Form("error of signed IP for all tracks in %s", flavour),
00139 100, 0, 0.05);
00140 plots.allIPSig = fs->make<TH1F>(Form("allIPSig_%s", name),
00141 Form("signed IP significance for all tracks in %s", flavour),
00142 100, -10, 20);
00143
00144 plots.trackIP = fs->make<TH1F>(Form("trackIP_%s", name),
00145 Form("signed IP for selected positive track in %s", flavour),
00146 100, -0.1, 0.2);
00147 plots.trackIPErr = fs->make<TH1F>(Form("trackIPErr_%s", name),
00148 Form("error of signed IP for selected positive track in %s", flavour),
00149 100, 0, 0.05);
00150 plots.trackIPSig = fs->make<TH1F>(Form("trackIPSig_%s", name),
00151 Form("signed IP significance for selected positive track in %s", flavour),
00152 100, -10, 20);
00153
00154 plots.negativeIP = fs->make<TH1F>(Form("negativeIP_%s", name),
00155 Form("signed IP for selected negative track in %s", flavour),
00156 100, -0.2, 0.1);
00157 plots.negativeIPErr = fs->make<TH1F>(Form("negativeIPErr_%s", name),
00158 Form("error of signed IP for selected negative track in %s", flavour),
00159 100, 0, 0.05);
00160 plots.negativeIPSig = fs->make<TH1F>(Form("negativeIPSig_%s", name),
00161 Form("signed IP significance for selected negative track in %s", flavour),
00162 100, -20, 10);
00163
00164 plots.nTracks = fs->make<TH1F>(Form("nTracks_%s", name),
00165 Form("number of usable tracks in %s", flavour),
00166 30, 0, 30);
00167 plots.allDeltaR = fs->make<TH1F>(Form("allDeltaR_%s", name),
00168 Form("\\DeltaR between track and %s", flavour),
00169 100, 0, 1);
00170 }
00171 }
00172
00173
00174
00175 static bool significanceHigher(const Measurement1D &meas1,
00176 const Measurement1D &meas2)
00177 { return meas1.significance() > meas2.significance(); }
00178
00179 void PatBJetTrackAnalyzer::analyze(const edm::Event &event, const edm::EventSetup &es)
00180 {
00181
00182 edm::Handle<reco::VertexCollection> pvHandle;
00183 event.getByLabel(primaryVertices_, pvHandle);
00184
00185
00186 edm::Handle<reco::TrackCollection> tracksHandle;
00187 event.getByLabel(tracks_, tracksHandle);
00188
00189
00190 edm::Handle<pat::JetCollection> jetsHandle;
00191 event.getByLabel(jets_, jetsHandle);
00192
00193
00194 edm::Handle<reco::BeamSpot> beamSpot;
00195 event.getByLabel(beamSpot_, beamSpot);
00196
00197
00198 if (pvHandle->empty())
00199 return;
00200
00201
00202 math::XYZPoint pv = (*pvHandle)[0].position();
00203
00204
00205 for(pat::JetCollection::const_iterator jet = jetsHandle->begin();
00206 jet != jetsHandle->end(); ++jet) {
00207
00208
00209 if (jet->pt() < jetPtCut_ ||
00210 std::abs(jet->eta()) > jetEtaCut_)
00211 continue;
00212
00213 Flavour flavour;
00214
00215 switch(std::abs(jet->partonFlavour())) {
00216 case 1:
00217 case 2:
00218 case 3:
00219 case 21:
00220 flavour = UDSG_JETS;
00221 break;
00222 case 4:
00223 flavour = C_JETS;
00224 break;
00225 case 5:
00226 flavour = B_JETS;
00227 break;
00228 default:
00229 flavour = NONID_JETS;
00230 }
00231
00232
00233 flavours_->Fill(ALL_JETS);
00234 flavours_->Fill(flavour);
00235
00236
00237 std::vector<Measurement1D> ipValErr;
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 for(reco::TrackCollection::const_iterator track = tracksHandle->begin();
00248 track != tracksHandle->end(); ++track) {
00249
00250
00251 if (track->pt() < minPt_ ||
00252 track->hitPattern().numberOfValidHits() < (int)minTotalHits_ ||
00253 track->hitPattern().numberOfValidPixelHits() < (int)minPixelHits_)
00254 continue;
00255
00256
00257
00258 double deltaR = ROOT::Math::VectorUtil::DeltaR(
00259 jet->momentum(), track->momentum());
00260
00261 plots_[ALL_JETS].allDeltaR->Fill(deltaR);
00262 plots_[flavour].allDeltaR->Fill(deltaR);
00263
00264
00265 if (deltaR > maxDeltaR_)
00266 continue;
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 double ipError = track->dxyError();
00287 double ipValue = std::abs(track->dxy(pv));
00288
00289
00290
00291
00292
00293
00294
00295
00296 math::XYZVector closestPoint = track->referencePoint() - beamSpot->position();
00297
00298 closestPoint.SetZ(0.);
00299 double sign = closestPoint.Dot(jet->momentum());
00300
00301 if (sign < 0)
00302 ipValue = -ipValue;
00303
00304 ipValErr.push_back(Measurement1D(ipValue, ipError));
00305 }
00306
00307
00308 std::sort(ipValErr.begin(), ipValErr.end(), significanceHigher);
00309
00310 plots_[ALL_JETS].nTracks->Fill(ipValErr.size());
00311 plots_[flavour].nTracks->Fill(ipValErr.size());
00312
00313
00314
00315 for(std::vector<Measurement1D>::const_iterator iter = ipValErr.begin();
00316 iter != ipValErr.end(); ++iter) {
00317 plots_[ALL_JETS].allIP->Fill(iter->value());
00318 plots_[flavour].allIP->Fill(iter->value());
00319
00320 plots_[ALL_JETS].allIPErr->Fill(iter->error());
00321 plots_[flavour].allIPErr->Fill(iter->error());
00322
00323
00324 plots_[ALL_JETS].allIPSig->Fill(iter->significance());
00325 plots_[flavour].allIPSig->Fill(iter->significance());
00326 }
00327
00328
00329
00330 if (ipValErr.size() < nThTrack_)
00331 continue;
00332
00333
00334 const Measurement1D *trk = &ipValErr[nThTrack_ - 1];
00335
00336 plots_[ALL_JETS].trackIP->Fill(trk->value());
00337 plots_[flavour].trackIP->Fill(trk->value());
00338
00339 plots_[ALL_JETS].trackIPErr->Fill(trk->error());
00340 plots_[flavour].trackIPErr->Fill(trk->error());
00341
00342 plots_[ALL_JETS].trackIPSig->Fill(trk->significance());
00343 plots_[flavour].trackIPSig->Fill(trk->significance());
00344
00345
00346
00347
00348
00349
00350
00351 trk = &ipValErr[ipValErr.size() - nThTrack_];
00352
00353 plots_[ALL_JETS].negativeIP->Fill(trk->value());
00354 plots_[flavour].negativeIP->Fill(trk->value());
00355
00356 plots_[ALL_JETS].negativeIPErr->Fill(trk->error());
00357 plots_[flavour].negativeIPErr->Fill(trk->error());
00358
00359 plots_[ALL_JETS].negativeIPSig->Fill(trk->significance());
00360 plots_[flavour].negativeIPSig->Fill(trk->significance());
00361 }
00362 }
00363
00364 #include "FWCore/Framework/interface/MakerMacros.h"
00365
00366 DEFINE_FWK_MODULE(PatBJetTrackAnalyzer);