CMS 3D CMS Logo

CTPPSProtonReconstructionEfficiencyEstimator.cc
Go to the documentation of this file.
1 /****************************************************************************
2  * Authors:
3  * Jan Kašpar
4  ****************************************************************************/
5 
12 
14 
17 
19 
27 
28 #include "TFile.h"
29 #include "TH1D.h"
30 #include "TH2D.h"
31 #include "TProfile.h"
32 #include "TGraphErrors.h"
33 
34 #include <map>
35 #include <string>
36 
37 //----------------------------------------------------------------------------------------------------
38 
40 public:
42 
43 private:
44  void analyze(const edm::Event &, const edm::EventSetup &) override;
45  void endJob() override;
46 
48 
51 
53 
55 
57 
58  unsigned int rpId_45_N_, rpId_45_F_;
59  unsigned int rpId_56_N_, rpId_56_F_;
60 
61  std::map<unsigned int, unsigned int> rpDecId_near_, rpDecId_far_;
62 
64 
65  struct PlotGroup {
66  std::unique_ptr<TProfile> p_eff_vs_xi;
67 
68  std::unique_ptr<TH1D> h_n_part_acc_nr, h_n_part_acc_fr;
69 
71  : p_eff_vs_xi(new TProfile("", ";#xi_{simu};efficiency", 19, 0.015, 0.205)),
72  h_n_part_acc_nr(new TH1D("", ";n particles in acceptance", 6, -0.5, +5.5)),
73  h_n_part_acc_fr(new TH1D("", ";n particles in acceptance", 6, -0.5, +5.5)) {}
74 
75  void write() const {
76  p_eff_vs_xi->Write("p_eff_vs_xi");
77  h_n_part_acc_nr->Write("h_n_part_acc_nr");
78  h_n_part_acc_fr->Write("h_n_part_acc_fr");
79  }
80  };
81 
82  std::map<unsigned int, std::map<unsigned int, PlotGroup>> plots_; // map: arm, n(particles in acceptance) --> plots
83 };
84 
85 //----------------------------------------------------------------------------------------------------
86 
87 using namespace std;
88 using namespace edm;
89 using namespace HepMC;
90 
91 //----------------------------------------------------------------------------------------------------
92 
94  const edm::ParameterSet &iConfig)
96  consumes<edm::HepMCProduct>(iConfig.getParameter<edm::InputTag>("tagHepMCAfterSmearing"))),
98  iConfig.getParameter<edm::InputTag>("tagStripRecHitsPerParticle"))),
100  iConfig.getParameter<edm::InputTag>("tagPixelRecHitsPerParticle"))),
101  tracksToken_(consumes<CTPPSLocalTrackLiteCollection>(iConfig.getParameter<edm::InputTag>("tagTracks"))),
103  consumes<reco::ForwardProtonCollection>(iConfig.getParameter<InputTag>("tagRecoProtonsMultiRP"))),
104  lhcInfoLabel_(iConfig.getParameter<std::string>("lhcInfoLabel")),
105 
106  rpId_45_N_(iConfig.getParameter<unsigned int>("rpId_45_N")),
107  rpId_45_F_(iConfig.getParameter<unsigned int>("rpId_45_F")),
108  rpId_56_N_(iConfig.getParameter<unsigned int>("rpId_56_N")),
109  rpId_56_F_(iConfig.getParameter<unsigned int>("rpId_56_F")),
110 
111  outputFile_(iConfig.getParameter<string>("outputFile")) {
114 
117 
118  // book plots
119  for (unsigned int arm = 0; arm < 2; ++arm) {
120  for (unsigned int np = 1; np <= 5; ++np)
121  plots_[arm][np] = PlotGroup();
122  }
123 }
124 
125 //----------------------------------------------------------------------------------------------------
126 
128  bool verbosity = false;
129 
130  const auto eid = iEvent.id().event();
131  //if (eid == 46 || eid == 741 || eid == 1649 || eid == 4223 || eid == 4279)
132  // verbosity = true;
133 
134  if (verbosity) {
135  printf("--------------------------------------------------\n");
136  printf("event %llu\n", eid);
137  }
138 
139  // get conditions
140  edm::ESHandle<LHCInfo> hLHCInfo;
141  iSetup.get<LHCInfoRcd>().get(lhcInfoLabel_, hLHCInfo);
142 
143  // get input
144  edm::Handle<edm::HepMCProduct> hHepMCAfterSmearing;
145  iEvent.getByToken(tokenHepMCAfterSmearing_, hHepMCAfterSmearing);
146  HepMC::GenEvent *hepMCEventAfterSmearing = (HepMC::GenEvent *)hHepMCAfterSmearing->GetEvent();
147 
149  iEvent.getByToken(tokenStripRecHitsPerParticle_, hStripRecHitsPerParticle);
150 
152  iEvent.getByToken(tokenPixelRecHitsPerParticle_, hPixelRecHitsPerParticle);
153 
155  iEvent.getByToken(tracksToken_, tracks);
156 
157  Handle<reco::ForwardProtonCollection> hRecoProtonsMultiRP;
158  iEvent.getByToken(tokenRecoProtonsMultiRP_, hRecoProtonsMultiRP);
159 
160  // buffer for particle information
161  struct ParticleInfo {
162  unsigned int arm = 2;
163  double xi = 0.;
164  std::map<unsigned int, unsigned int> recHitsPerRP;
165  bool inAcceptanceNear = false, inAcceptanceFar = false, inAcceptance = false;
166  };
167 
168  std::map<int, ParticleInfo> particleInfo; // barcode --> info
169 
170  // process HepMC
171  for (auto it = hepMCEventAfterSmearing->particles_begin(); it != hepMCEventAfterSmearing->particles_end(); ++it) {
172  const auto &part = *it;
173 
174  // accept only stable non-beam protons
175  if (part->pdg_id() != 2212)
176  continue;
177 
178  if (part->status() != 1)
179  continue;
180 
181  if (part->is_beam())
182  continue;
183 
184  const auto &mom = part->momentum();
185 
186  if (mom.e() < 4500.)
187  continue;
188 
190 
191  info.arm = (mom.z() > 0.) ? 0 : 1;
192 
193  const double p_nom = hLHCInfo->energy();
194  info.xi = (p_nom - mom.rho()) / p_nom;
195 
196  particleInfo[part->barcode()] = std::move(info);
197  }
198 
199  // check acceptance
200  for (const auto &pp : *hStripRecHitsPerParticle) {
201  const auto barcode = pp.first;
202 
203  for (const auto &ds : pp.second) {
204  CTPPSDetId detId(ds.detId());
205  CTPPSDetId rpId = detId.getRPId();
206  particleInfo[barcode].recHitsPerRP[rpId] += ds.size();
207  }
208  }
209 
210  for (const auto &pp : *hPixelRecHitsPerParticle) {
211  const auto barcode = pp.first;
212 
213  for (const auto &ds : pp.second) {
214  CTPPSDetId detId(ds.detId());
215  CTPPSDetId rpId = detId.getRPId();
216  particleInfo[barcode].recHitsPerRP[rpId] += ds.size();
217  }
218  }
219 
220  std::map<unsigned int, bool> isStripRPNear, isStripRPFar;
221 
222  for (auto &pp : particleInfo) {
223  if (verbosity)
224  printf("* barcode=%i, arm=%u, xi=%.3f\n", pp.first, pp.second.arm, pp.second.xi);
225 
226  for (const auto &rpp : pp.second.recHitsPerRP) {
227  CTPPSDetId rpId(rpp.first);
228  unsigned int needed_rec_hits = 1000;
230  needed_rec_hits = 6;
232  needed_rec_hits = 3;
233 
234  unsigned int rpDecId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
235 
236  if (rpId.subdetId() == CTPPSDetId::sdTrackingStrip) {
237  if (rpDecId == rpDecId_near_[rpId.arm()])
238  isStripRPNear[rpId.arm()] = true;
239  if (rpDecId == rpDecId_far_[rpId.arm()])
240  isStripRPFar[rpId.arm()] = true;
241  }
242 
243  if (rpp.second >= needed_rec_hits) {
244  if (rpDecId == rpDecId_near_[rpId.arm()])
245  pp.second.inAcceptanceNear = true;
246  if (rpDecId == rpDecId_far_[rpId.arm()])
247  pp.second.inAcceptanceFar = true;
248  }
249 
250  if (verbosity)
251  printf(" RP %u: %u hits\n", rpDecId, rpp.second);
252  }
253 
254  pp.second.inAcceptance = pp.second.inAcceptanceNear && pp.second.inAcceptanceFar;
255 
256  if (verbosity) {
257  printf(" inAcceptance: near=%u, far=%u, global=%u\n",
258  pp.second.inAcceptanceNear,
259  pp.second.inAcceptanceFar,
260  pp.second.inAcceptance);
261  }
262  }
263 
264  // count particles in acceptance
265  struct ArmCounter {
266  unsigned int near = 0, far = 0, global = 0;
267  };
268  std::map<unsigned int, ArmCounter> nParticlesInAcceptance;
269  for (auto &pp : particleInfo) {
270  auto &counter = nParticlesInAcceptance[pp.second.arm];
271  if (pp.second.inAcceptanceNear)
272  counter.near++;
273  if (pp.second.inAcceptanceFar)
274  counter.far++;
275  if (pp.second.inAcceptance)
276  counter.global++;
277  }
278 
279  // count reconstructed tracks
280  std::map<unsigned int, ArmCounter> nReconstructedTracks;
281  for (const auto &tr : *tracks) {
282  CTPPSDetId rpId(tr.getRPId());
283  unsigned int rpDecId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
284 
285  if (rpDecId == rpDecId_near_[rpId.arm()])
286  nReconstructedTracks[rpId.arm()].near++;
287  if (rpDecId == rpDecId_far_[rpId.arm()])
288  nReconstructedTracks[rpId.arm()].far++;
289  }
290 
291  // count reconstructed protons
292  std::map<unsigned int, unsigned int> nReconstructedProtons;
293  for (const auto &pr : *hRecoProtonsMultiRP) {
294  if (!pr.validFit())
295  continue;
296 
297  unsigned int arm = 2;
298  if (pr.lhcSector() == reco::ForwardProton::LHCSector::sector45)
299  arm = 0;
300  if (pr.lhcSector() == reco::ForwardProton::LHCSector::sector56)
301  arm = 1;
302 
303  nReconstructedProtons[arm]++;
304  }
305 
306  // fill plots
307  for (unsigned int arm = 0; arm < 2; arm++) {
308  const auto &npa = nParticlesInAcceptance[arm];
309  const auto &nrt = nReconstructedTracks[arm];
310 
311  if (verbosity) {
312  printf("* arm %u: nRecoProtons=%u (tracks near=%u, far=%u), nAcc=%u (near=%u, far=%u)\n",
313  arm,
314  nReconstructedProtons[arm],
315  nReconstructedTracks[arm].near,
316  nReconstructedTracks[arm].far,
317  npa.global,
318  npa.near,
319  npa.far);
320  }
321 
322  // skip event if no track in global acceptance
323  if (npa.global < 1)
324  continue;
325 
326  const auto &p = plots_[arm][npa.global];
327 
328  p.h_n_part_acc_nr->Fill(npa.near);
329  p.h_n_part_acc_fr->Fill(npa.far);
330 
331  // skip events with some local reconstruction inefficiency
332  if (nrt.near != npa.near || nrt.far != npa.far)
333  continue;
334 
335  const double eff = double(nReconstructedProtons[arm]) / npa.global;
336 
337  if (verbosity)
338  printf(" eff=%.3f\n", eff);
339 
340  for (auto &pp : particleInfo) {
341  if (pp.second.arm != arm || !pp.second.inAcceptance)
342  continue;
343 
344  p.p_eff_vs_xi->Fill(pp.second.xi, eff);
345  }
346  }
347 }
348 
349 //----------------------------------------------------------------------------------------------------
350 
352  auto f_out = std::make_unique<TFile>(outputFile_.c_str(), "recreate");
353 
354  for (const auto &ait : plots_) {
355  char buf[100];
356  sprintf(buf, "arm%u", ait.first);
357  TDirectory *d_arm = f_out->mkdir(buf);
358 
359  for (const auto &npit : ait.second) {
360  sprintf(buf, "%u", npit.first);
361  TDirectory *d_np = d_arm->mkdir(buf);
362  gDirectory = d_np;
363 
364  npit.second.write();
365  }
366  }
367 }
368 
369 //----------------------------------------------------------------------------------------------------
370 
uint32_t station() const
Definition: CTPPSDetId.h:58
EventNumber_t event() const
Definition: EventID.h:41
static const TGPicture * info(bool iBackgroundIsBlack)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
edm::EDGetTokenT< std::map< int, edm::DetSetVector< TotemRPRecHit > > > tokenStripRecHitsPerParticle_
edm::EDGetTokenT< reco::ForwardProtonCollection > tokenRecoProtonsMultiRP_
edm::EDGetTokenT< std::map< int, edm::DetSetVector< CTPPSPixelRecHit > > > tokenPixelRecHitsPerParticle_
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
int np
Definition: AMPTWrapper.h:33
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
Reconstructed hit in TOTEM RP.
Definition: TotemRPRecHit.h:18
uint32_t arm() const
Definition: CTPPSDetId.h:51
edm::EDGetTokenT< CTPPSLocalTrackLiteCollection > tracksToken_
std::map< unsigned int, std::map< unsigned int, PlotGroup > > plots_
const HepMC::GenEvent * GetEvent() const
Definition: HepMCProduct.h:38
std::vector< CTPPSLocalTrackLite > CTPPSLocalTrackLiteCollection
Collection of CTPPSLocalTrackLite objects.
part
Definition: HCALResponse.h:20
Base class for CTPPS detector IDs.
Definition: CTPPSDetId.h:32
edm::EventID id() const
Definition: EventBase.h:59
fixed size matrix
HLT enums.
T get() const
Definition: EventSetup.h:71
float const energy() const
Definition: LHCInfo.cc:192
std::vector< ForwardProton > ForwardProtonCollection
Collection of ForwardProton objects.
void analyze(const edm::Event &, const edm::EventSetup &) override
def move(src, dest)
Definition: eostools.py:511
uint32_t rp() const
Definition: CTPPSDetId.h:65