CMS 3D CMS Logo

CTPPSProtonReconstructionEfficiencyEstimatorMC.cc
Go to the documentation of this file.
1 /****************************************************************************
2  * Authors:
3  * Jan Kašpar
4  ****************************************************************************/
5 
12 
14 
16 
18 
26 
27 #include "TFile.h"
28 #include "TH1D.h"
29 #include "TH2D.h"
30 #include "TProfile.h"
31 #include "TGraphErrors.h"
32 
33 #include <map>
34 #include <string>
35 
36 //----------------------------------------------------------------------------------------------------
37 
39 public:
41 
42  static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
43 
44 private:
45  void analyze(const edm::Event &, const edm::EventSetup &) override;
46  void endJob() override;
47 
49 
52 
54 
56 
60  const bool useNewLHCInfo_;
61 
62  unsigned int rpId_45_N_, rpId_45_F_;
63  unsigned int rpId_56_N_, rpId_56_F_;
64 
65  std::map<unsigned int, unsigned int> rpDecId_near_, rpDecId_far_;
66 
68 
69  unsigned int verbosity_;
70 
71  struct PlotGroup {
72  std::unique_ptr<TProfile> p_eff_vs_xi;
73 
74  std::unique_ptr<TH1D> h_n_part_acc_nr, h_n_part_acc_fr;
75 
77  : p_eff_vs_xi(new TProfile("", ";#xi_{simu};efficiency", 19, 0.015, 0.205)),
78  h_n_part_acc_nr(new TH1D("", ";n particles in acceptance", 6, -0.5, +5.5)),
79  h_n_part_acc_fr(new TH1D("", ";n particles in acceptance", 6, -0.5, +5.5)) {}
80 
81  void write() const {
82  p_eff_vs_xi->Write("p_eff_vs_xi");
83  h_n_part_acc_nr->Write("h_n_part_acc_nr");
84  h_n_part_acc_fr->Write("h_n_part_acc_fr");
85  }
86  };
87 
88  std::map<unsigned int, std::map<unsigned int, PlotGroup>> plots_; // map: arm, n(particles in acceptance) --> plots
89 };
90 
91 //----------------------------------------------------------------------------------------------------
92 
93 using namespace std;
94 using namespace edm;
95 using namespace HepMC;
96 
97 //----------------------------------------------------------------------------------------------------
98 
100  const edm::ParameterSet &iConfig)
101  : tokenHepMCAfterSmearing_(
102  consumes<edm::HepMCProduct>(iConfig.getParameter<edm::InputTag>("tagHepMCAfterSmearing"))),
103  tokenStripRecHitsPerParticle_(consumes<std::map<int, edm::DetSetVector<TotemRPRecHit>>>(
104  iConfig.getParameter<edm::InputTag>("tagStripRecHitsPerParticle"))),
105  tokenPixelRecHitsPerParticle_(consumes<std::map<int, edm::DetSetVector<CTPPSPixelRecHit>>>(
106  iConfig.getParameter<edm::InputTag>("tagPixelRecHitsPerParticle"))),
107  tracksToken_(consumes<CTPPSLocalTrackLiteCollection>(iConfig.getParameter<edm::InputTag>("tagTracks"))),
108  tokenRecoProtonsMultiRP_(
109  consumes<reco::ForwardProtonCollection>(iConfig.getParameter<InputTag>("tagRecoProtonsMultiRP"))),
110 
111  lhcInfoToken_(esConsumes(ESInputTag("", iConfig.getParameter<std::string>("lhcInfoLabel")))),
112  lhcInfoPerLSToken_(esConsumes(ESInputTag("", iConfig.getParameter<std::string>("lhcInfoPerLSLabel")))),
113  lhcInfoPerFillToken_(esConsumes(ESInputTag("", iConfig.getParameter<std::string>("lhcInfoPerFillLabel")))),
114  useNewLHCInfo_(iConfig.getParameter<bool>("useNewLHCInfo")),
115 
116  rpId_45_N_(iConfig.getParameter<unsigned int>("rpId_45_N")),
117  rpId_45_F_(iConfig.getParameter<unsigned int>("rpId_45_F")),
118  rpId_56_N_(iConfig.getParameter<unsigned int>("rpId_56_N")),
119  rpId_56_F_(iConfig.getParameter<unsigned int>("rpId_56_F")),
120 
121  outputFile_(iConfig.getParameter<string>("outputFile")),
122 
123  verbosity_(iConfig.getUntrackedParameter<unsigned int>("verbosity", 0)) {
126 
129 
130  // book plots
131  for (unsigned int arm = 0; arm < 2; ++arm) {
132  for (unsigned int np = 1; np <= 5; ++np)
133  plots_[arm][np] = PlotGroup();
134  }
135 }
136 
137 //----------------------------------------------------------------------------------------------------
138 
141 
142  desc.add<edm::InputTag>("tagTracks", edm::InputTag())->setComment("input tag for local lite tracks");
143  desc.add<edm::InputTag>("tagRecoProtonsMultiRP", edm::InputTag())->setComment("input tag for multi-RP reco protons");
144 
145  desc.add<std::string>("lhcInfoLabel", "")->setComment("label of the LHCInfo record");
146  desc.add<std::string>("lhcInfoPerLSLabel", "")->setComment("label of the LHCInfoPerLS record");
147  desc.add<std::string>("lhcInfoPerFillLabel", "")->setComment("label of the LHCInfoPerFill record");
148  desc.add<bool>("useNewLHCInfo", false)->setComment("flag whether to use new LHCInfoPer* records or old LHCInfo");
149 
150  desc.add<unsigned int>("rpId_45_N", 0)->setComment("decimal RP id for 45 near");
151  desc.add<unsigned int>("rpId_45_F", 0)->setComment("decimal RP id for 45 far");
152  desc.add<unsigned int>("rpId_56_N", 0)->setComment("decimal RP id for 56 near");
153  desc.add<unsigned int>("rpId_56_F", 0)->setComment("decimal RP id for 56 far");
154 
155  desc.add<std::string>("outputFile", "output.root")->setComment("output file name");
156 
157  desc.addUntracked<unsigned int>("verbosity", 0)->setComment("verbosity level");
158 
159  descriptions.add("ctppsProtonReconstructionEfficiencyEstimatorMCDefault", desc);
160 }
161 
162 //----------------------------------------------------------------------------------------------------
163 
165  std::ostringstream os;
166 
167  // get conditions
168  const LHCInfoCombined lhcInfoCombined(
170 
171  // get input
172  edm::Handle<edm::HepMCProduct> hHepMCAfterSmearing;
173  iEvent.getByToken(tokenHepMCAfterSmearing_, hHepMCAfterSmearing);
174  HepMC::GenEvent *hepMCEventAfterSmearing = (HepMC::GenEvent *)hHepMCAfterSmearing->GetEvent();
175 
177  iEvent.getByToken(tokenStripRecHitsPerParticle_, hStripRecHitsPerParticle);
178 
180  iEvent.getByToken(tokenPixelRecHitsPerParticle_, hPixelRecHitsPerParticle);
181 
183  iEvent.getByToken(tracksToken_, tracks);
184 
185  Handle<reco::ForwardProtonCollection> hRecoProtonsMultiRP;
186  iEvent.getByToken(tokenRecoProtonsMultiRP_, hRecoProtonsMultiRP);
187 
188  // buffer for particle information
189  struct ParticleInfo {
190  unsigned int arm = 2;
191  double xi = 0.;
192  std::map<unsigned int, unsigned int> recHitsPerRP;
193  bool inAcceptanceNear = false, inAcceptanceFar = false, inAcceptance = false;
194  };
195 
196  std::map<int, ParticleInfo> particleInfo; // barcode --> info
197 
198  // process HepMC
199  for (auto it = hepMCEventAfterSmearing->particles_begin(); it != hepMCEventAfterSmearing->particles_end(); ++it) {
200  const auto &part = *it;
201 
202  // accept only stable non-beam protons
203  if (part->pdg_id() != 2212)
204  continue;
205 
206  if (part->status() != 1)
207  continue;
208 
209  if (part->is_beam())
210  continue;
211 
212  const auto &mom = part->momentum();
213 
214  if (mom.e() < 4500.)
215  continue;
216 
217  ParticleInfo info;
218 
219  info.arm = (mom.z() > 0.) ? 0 : 1;
220 
221  const double p_nom = lhcInfoCombined.energy;
222  info.xi = (p_nom - mom.rho()) / p_nom;
223 
224  particleInfo[part->barcode()] = std::move(info);
225  }
226 
227  // check acceptance
228  for (const auto &pp : *hStripRecHitsPerParticle) {
229  const auto barcode = pp.first;
230 
231  for (const auto &ds : pp.second) {
232  CTPPSDetId detId(ds.detId());
233  CTPPSDetId rpId = detId.rpId();
234  particleInfo[barcode].recHitsPerRP[rpId] += ds.size();
235  }
236  }
237 
238  for (const auto &pp : *hPixelRecHitsPerParticle) {
239  const auto barcode = pp.first;
240 
241  for (const auto &ds : pp.second) {
242  CTPPSDetId detId(ds.detId());
243  CTPPSDetId rpId = detId.rpId();
244  particleInfo[barcode].recHitsPerRP[rpId] += ds.size();
245  }
246  }
247 
248  std::map<unsigned int, bool> isStripRPNear, isStripRPFar;
249 
250  for (auto &pp : particleInfo) {
251  if (verbosity_)
252  os << "* barcode=" << pp.first << ", arm=" << pp.second.arm << ", xi=" << pp.second.xi << std::endl;
253 
254  for (const auto &rpp : pp.second.recHitsPerRP) {
255  CTPPSDetId rpId(rpp.first);
256  unsigned int needed_rec_hits = 1000;
257  if (rpId.subdetId() == CTPPSDetId::sdTrackingStrip)
258  needed_rec_hits = 6;
259  if (rpId.subdetId() == CTPPSDetId::sdTrackingPixel)
260  needed_rec_hits = 3;
261 
262  unsigned int rpDecId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
263 
264  if (rpId.subdetId() == CTPPSDetId::sdTrackingStrip) {
265  if (rpDecId == rpDecId_near_[rpId.arm()])
266  isStripRPNear[rpId.arm()] = true;
267  if (rpDecId == rpDecId_far_[rpId.arm()])
268  isStripRPFar[rpId.arm()] = true;
269  }
270 
271  if (rpp.second >= needed_rec_hits) {
272  if (rpDecId == rpDecId_near_[rpId.arm()])
273  pp.second.inAcceptanceNear = true;
274  if (rpDecId == rpDecId_far_[rpId.arm()])
275  pp.second.inAcceptanceFar = true;
276  }
277 
278  if (verbosity_)
279  os << " RP " << rpDecId << ": " << rpp.second << " hits" << std::endl;
280  }
281 
282  pp.second.inAcceptance = pp.second.inAcceptanceNear && pp.second.inAcceptanceFar;
283 
284  if (verbosity_)
285  os << " inAcceptance: near=" << pp.second.inAcceptanceNear << ", far=" << pp.second.inAcceptanceFar
286  << ", global=" << pp.second.inAcceptance << std::endl;
287  }
288 
289  // count particles in acceptance
290  struct ArmCounter {
291  unsigned int near = 0, far = 0, global = 0;
292  };
293  std::map<unsigned int, ArmCounter> nParticlesInAcceptance;
294  for (auto &pp : particleInfo) {
295  auto &counter = nParticlesInAcceptance[pp.second.arm];
296  if (pp.second.inAcceptanceNear)
297  counter.near++;
298  if (pp.second.inAcceptanceFar)
299  counter.far++;
300  if (pp.second.inAcceptance)
301  counter.global++;
302  }
303 
304  // count reconstructed tracks
305  std::map<unsigned int, ArmCounter> nReconstructedTracks;
306  for (const auto &tr : *tracks) {
307  CTPPSDetId rpId(tr.rpId());
308  unsigned int rpDecId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
309 
310  if (rpDecId == rpDecId_near_[rpId.arm()])
311  nReconstructedTracks[rpId.arm()].near++;
312  if (rpDecId == rpDecId_far_[rpId.arm()])
313  nReconstructedTracks[rpId.arm()].far++;
314  }
315 
316  // count reconstructed protons
317  std::map<unsigned int, unsigned int> nReconstructedProtons;
318  for (const auto &pr : *hRecoProtonsMultiRP) {
319  if (!pr.validFit())
320  continue;
321 
322  unsigned int arm = 2;
323  if (pr.lhcSector() == reco::ForwardProton::LHCSector::sector45)
324  arm = 0;
325  if (pr.lhcSector() == reco::ForwardProton::LHCSector::sector56)
326  arm = 1;
327 
328  nReconstructedProtons[arm]++;
329  }
330 
331  // fill plots
332  for (unsigned int arm = 0; arm < 2; arm++) {
333  const auto &npa = nParticlesInAcceptance[arm];
334  const auto &nrt = nReconstructedTracks[arm];
335 
336  if (verbosity_)
337  os << "* arm " << arm << ": nRecoProtons=" << nReconstructedProtons[arm]
338  << " (tracks near=" << nReconstructedTracks[arm].near << ", far=" << nReconstructedTracks[arm].far
339  << "), nAcc=" << npa.global << " (near=" << npa.near << ", far=" << npa.far << ")" << std::endl;
340 
341  // skip event if no track in global acceptance
342  if (npa.global < 1)
343  continue;
344 
345  const auto &p = plots_[arm][npa.global];
346 
347  p.h_n_part_acc_nr->Fill(npa.near);
348  p.h_n_part_acc_fr->Fill(npa.far);
349 
350  // skip events with some local reconstruction inefficiency
351  if (nrt.near != npa.near || nrt.far != npa.far)
352  continue;
353 
354  const double eff = double(nReconstructedProtons[arm]) / npa.global;
355 
356  if (verbosity_)
357  os << " eff=" << eff << std::endl;
358 
359  for (auto &pp : particleInfo) {
360  if (pp.second.arm != arm || !pp.second.inAcceptance)
361  continue;
362 
363  p.p_eff_vs_xi->Fill(pp.second.xi, eff);
364  }
365  }
366 
367  if (verbosity_)
368  edm::LogInfo("CTPPSProtonReconstructionEfficiencyEstimatorMC") << os.str();
369 }
370 
371 //----------------------------------------------------------------------------------------------------
372 
374  auto f_out = std::make_unique<TFile>(outputFile_.c_str(), "recreate");
375 
376  for (const auto &ait : plots_) {
377  char buf[100];
378  sprintf(buf, "arm%u", ait.first);
379  TDirectory *d_arm = f_out->mkdir(buf);
380 
381  for (const auto &npit : ait.second) {
382  sprintf(buf, "%u", npit.first);
383  TDirectory *d_np = d_arm->mkdir(buf);
384  gDirectory = d_np;
385 
386  npit.second.write();
387  }
388  }
389 }
390 
391 //----------------------------------------------------------------------------------------------------
392 
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
static const TGPicture * info(bool iBackgroundIsBlack)
std::map< unsigned int, std::map< unsigned int, PlotGroup > > plots_
const edm::ESGetToken< LHCInfoPerLS, LHCInfoPerLSRcd > lhcInfoPerLSToken_
edm::EDGetTokenT< reco::ForwardProtonCollection > tokenRecoProtonsMultiRP_
edm::EDGetTokenT< std::map< int, edm::DetSetVector< CTPPSPixelRecHit > > > tokenPixelRecHitsPerParticle_
int iEvent
Definition: GenABIO.cc:224
int np
Definition: AMPTWrapper.h:43
void analyze(const edm::Event &, const edm::EventSetup &) override
Reconstructed hit in TOTEM RP.
Definition: TotemRPRecHit.h:18
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const HepMC::GenEvent * GetEvent() const
Definition: HepMCProduct.h:37
Log< level::Info, false > LogInfo
std::vector< CTPPSLocalTrackLite > CTPPSLocalTrackLiteCollection
Collection of CTPPSLocalTrackLite objects.
part
Definition: HCALResponse.h:20
void add(std::string const &label, ParameterSetDescription const &psetDescription)
Base class for CTPPS detector IDs.
Definition: CTPPSDetId.h:32
fixed size matrix
HLT enums.
const edm::ESGetToken< LHCInfoPerFill, LHCInfoPerFillRcd > lhcInfoPerFillToken_
edm::EDGetTokenT< std::map< int, edm::DetSetVector< TotemRPRecHit > > > tokenStripRecHitsPerParticle_
std::vector< ForwardProton > ForwardProtonCollection
Collection of ForwardProton objects.
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
def move(src, dest)
Definition: eostools.py:511