CMS 3D CMS Logo

CTPPSProtonReconstructionEfficiencyEstimatorMC.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  unsigned int verbosity_;
66 
67  struct PlotGroup {
68  std::unique_ptr<TProfile> p_eff_vs_xi;
69 
70  std::unique_ptr<TH1D> h_n_part_acc_nr, h_n_part_acc_fr;
71 
73  : p_eff_vs_xi(new TProfile("", ";#xi_{simu};efficiency", 19, 0.015, 0.205)),
74  h_n_part_acc_nr(new TH1D("", ";n particles in acceptance", 6, -0.5, +5.5)),
75  h_n_part_acc_fr(new TH1D("", ";n particles in acceptance", 6, -0.5, +5.5)) {}
76 
77  void write() const {
78  p_eff_vs_xi->Write("p_eff_vs_xi");
79  h_n_part_acc_nr->Write("h_n_part_acc_nr");
80  h_n_part_acc_fr->Write("h_n_part_acc_fr");
81  }
82  };
83 
84  std::map<unsigned int, std::map<unsigned int, PlotGroup>> plots_; // map: arm, n(particles in acceptance) --> plots
85 };
86 
87 //----------------------------------------------------------------------------------------------------
88 
89 using namespace std;
90 using namespace edm;
91 using namespace HepMC;
92 
93 //----------------------------------------------------------------------------------------------------
94 
96  const edm::ParameterSet &iConfig)
98  consumes<edm::HepMCProduct>(iConfig.getParameter<edm::InputTag>("tagHepMCAfterSmearing"))),
100  iConfig.getParameter<edm::InputTag>("tagStripRecHitsPerParticle"))),
102  iConfig.getParameter<edm::InputTag>("tagPixelRecHitsPerParticle"))),
103  tracksToken_(consumes<CTPPSLocalTrackLiteCollection>(iConfig.getParameter<edm::InputTag>("tagTracks"))),
105  consumes<reco::ForwardProtonCollection>(iConfig.getParameter<InputTag>("tagRecoProtonsMultiRP"))),
106  lhcInfoLabel_(iConfig.getParameter<std::string>("lhcInfoLabel")),
107 
108  rpId_45_N_(iConfig.getParameter<unsigned int>("rpId_45_N")),
109  rpId_45_F_(iConfig.getParameter<unsigned int>("rpId_45_F")),
110  rpId_56_N_(iConfig.getParameter<unsigned int>("rpId_56_N")),
111  rpId_56_F_(iConfig.getParameter<unsigned int>("rpId_56_F")),
112 
113  outputFile_(iConfig.getParameter<string>("outputFile")),
114 
115  verbosity_(iConfig.getUntrackedParameter<unsigned int>("verbosity", 0))
116 {
119 
122 
123  // book plots
124  for (unsigned int arm = 0; arm < 2; ++arm) {
125  for (unsigned int np = 1; np <= 5; ++np)
126  plots_[arm][np] = PlotGroup();
127  }
128 }
129 
130 //----------------------------------------------------------------------------------------------------
131 
133  std::ostringstream os;
134 
135  // get conditions
136  edm::ESHandle<LHCInfo> hLHCInfo;
137  iSetup.get<LHCInfoRcd>().get(lhcInfoLabel_, hLHCInfo);
138 
139  // get input
140  edm::Handle<edm::HepMCProduct> hHepMCAfterSmearing;
141  iEvent.getByToken(tokenHepMCAfterSmearing_, hHepMCAfterSmearing);
142  HepMC::GenEvent *hepMCEventAfterSmearing = (HepMC::GenEvent *)hHepMCAfterSmearing->GetEvent();
143 
145  iEvent.getByToken(tokenStripRecHitsPerParticle_, hStripRecHitsPerParticle);
146 
148  iEvent.getByToken(tokenPixelRecHitsPerParticle_, hPixelRecHitsPerParticle);
149 
151  iEvent.getByToken(tracksToken_, tracks);
152 
153  Handle<reco::ForwardProtonCollection> hRecoProtonsMultiRP;
154  iEvent.getByToken(tokenRecoProtonsMultiRP_, hRecoProtonsMultiRP);
155 
156  // buffer for particle information
157  struct ParticleInfo {
158  unsigned int arm = 2;
159  double xi = 0.;
160  std::map<unsigned int, unsigned int> recHitsPerRP;
161  bool inAcceptanceNear = false, inAcceptanceFar = false, inAcceptance = false;
162  };
163 
164  std::map<int, ParticleInfo> particleInfo; // barcode --> info
165 
166  // process HepMC
167  for (auto it = hepMCEventAfterSmearing->particles_begin(); it != hepMCEventAfterSmearing->particles_end(); ++it) {
168  const auto &part = *it;
169 
170  // accept only stable non-beam protons
171  if (part->pdg_id() != 2212)
172  continue;
173 
174  if (part->status() != 1)
175  continue;
176 
177  if (part->is_beam())
178  continue;
179 
180  const auto &mom = part->momentum();
181 
182  if (mom.e() < 4500.)
183  continue;
184 
186 
187  info.arm = (mom.z() > 0.) ? 0 : 1;
188 
189  const double p_nom = hLHCInfo->energy();
190  info.xi = (p_nom - mom.rho()) / p_nom;
191 
192  particleInfo[part->barcode()] = std::move(info);
193  }
194 
195  // check acceptance
196  for (const auto &pp : *hStripRecHitsPerParticle) {
197  const auto barcode = pp.first;
198 
199  for (const auto &ds : pp.second) {
200  CTPPSDetId detId(ds.detId());
201  CTPPSDetId rpId = detId.getRPId();
202  particleInfo[barcode].recHitsPerRP[rpId] += ds.size();
203  }
204  }
205 
206  for (const auto &pp : *hPixelRecHitsPerParticle) {
207  const auto barcode = pp.first;
208 
209  for (const auto &ds : pp.second) {
210  CTPPSDetId detId(ds.detId());
211  CTPPSDetId rpId = detId.getRPId();
212  particleInfo[barcode].recHitsPerRP[rpId] += ds.size();
213  }
214  }
215 
216  std::map<unsigned int, bool> isStripRPNear, isStripRPFar;
217 
218  for (auto &pp : particleInfo) {
219  if (verbosity_)
220  os << "* barcode=" << pp.first << ", arm=" << pp.second.arm << ", xi=" << pp.second.xi << std::endl;
221 
222  for (const auto &rpp : pp.second.recHitsPerRP) {
223  CTPPSDetId rpId(rpp.first);
224  unsigned int needed_rec_hits = 1000;
226  needed_rec_hits = 6;
228  needed_rec_hits = 3;
229 
230  unsigned int rpDecId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
231 
232  if (rpId.subdetId() == CTPPSDetId::sdTrackingStrip) {
233  if (rpDecId == rpDecId_near_[rpId.arm()])
234  isStripRPNear[rpId.arm()] = true;
235  if (rpDecId == rpDecId_far_[rpId.arm()])
236  isStripRPFar[rpId.arm()] = true;
237  }
238 
239  if (rpp.second >= needed_rec_hits) {
240  if (rpDecId == rpDecId_near_[rpId.arm()])
241  pp.second.inAcceptanceNear = true;
242  if (rpDecId == rpDecId_far_[rpId.arm()])
243  pp.second.inAcceptanceFar = true;
244  }
245 
246  if (verbosity_)
247  os << " RP " << rpDecId << ": " << rpp.second << " hits" << std::endl;
248  }
249 
250  pp.second.inAcceptance = pp.second.inAcceptanceNear && pp.second.inAcceptanceFar;
251 
252  if (verbosity_)
253  os << " inAcceptance: near=" << pp.second.inAcceptanceNear << ", far=" << pp.second.inAcceptanceFar << ", global=" << pp.second.inAcceptance << std::endl;
254  }
255 
256  // count particles in acceptance
257  struct ArmCounter {
258  unsigned int near = 0, far = 0, global = 0;
259  };
260  std::map<unsigned int, ArmCounter> nParticlesInAcceptance;
261  for (auto &pp : particleInfo) {
262  auto &counter = nParticlesInAcceptance[pp.second.arm];
263  if (pp.second.inAcceptanceNear)
264  counter.near++;
265  if (pp.second.inAcceptanceFar)
266  counter.far++;
267  if (pp.second.inAcceptance)
268  counter.global++;
269  }
270 
271  // count reconstructed tracks
272  std::map<unsigned int, ArmCounter> nReconstructedTracks;
273  for (const auto &tr : *tracks) {
274  CTPPSDetId rpId(tr.getRPId());
275  unsigned int rpDecId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
276 
277  if (rpDecId == rpDecId_near_[rpId.arm()])
278  nReconstructedTracks[rpId.arm()].near++;
279  if (rpDecId == rpDecId_far_[rpId.arm()])
280  nReconstructedTracks[rpId.arm()].far++;
281  }
282 
283  // count reconstructed protons
284  std::map<unsigned int, unsigned int> nReconstructedProtons;
285  for (const auto &pr : *hRecoProtonsMultiRP) {
286  if (!pr.validFit())
287  continue;
288 
289  unsigned int arm = 2;
290  if (pr.lhcSector() == reco::ForwardProton::LHCSector::sector45)
291  arm = 0;
292  if (pr.lhcSector() == reco::ForwardProton::LHCSector::sector56)
293  arm = 1;
294 
295  nReconstructedProtons[arm]++;
296  }
297 
298  // fill plots
299  for (unsigned int arm = 0; arm < 2; arm++) {
300  const auto &npa = nParticlesInAcceptance[arm];
301  const auto &nrt = nReconstructedTracks[arm];
302 
303  if (verbosity_)
304  os << "* arm " << arm << ": nRecoProtons="
305  << nReconstructedProtons[arm] << " (tracks near=" << nReconstructedTracks[arm].near << ", far=" << nReconstructedTracks[arm].far
306  << "), nAcc=" << npa.global << " (near=" << npa.near << ", far=" << npa.far << ")" << std::endl;
307 
308  // skip event if no track in global acceptance
309  if (npa.global < 1)
310  continue;
311 
312  const auto &p = plots_[arm][npa.global];
313 
314  p.h_n_part_acc_nr->Fill(npa.near);
315  p.h_n_part_acc_fr->Fill(npa.far);
316 
317  // skip events with some local reconstruction inefficiency
318  if (nrt.near != npa.near || nrt.far != npa.far)
319  continue;
320 
321  const double eff = double(nReconstructedProtons[arm]) / npa.global;
322 
323  if (verbosity_)
324  os << " eff=" << eff << std::endl;
325 
326  for (auto &pp : particleInfo) {
327  if (pp.second.arm != arm || !pp.second.inAcceptance)
328  continue;
329 
330  p.p_eff_vs_xi->Fill(pp.second.xi, eff);
331  }
332  }
333 
334  if (verbosity_)
335  edm::LogInfo("CTPPSProtonReconstructionEfficiencyEstimatorMC") << os.str();
336 }
337 
338 //----------------------------------------------------------------------------------------------------
339 
341  auto f_out = std::make_unique<TFile>(outputFile_.c_str(), "recreate");
342 
343  for (const auto &ait : plots_) {
344  char buf[100];
345  sprintf(buf, "arm%u", ait.first);
346  TDirectory *d_arm = f_out->mkdir(buf);
347 
348  for (const auto &npit : ait.second) {
349  sprintf(buf, "%u", npit.first);
350  TDirectory *d_np = d_arm->mkdir(buf);
351  gDirectory = d_np;
352 
353  npit.second.write();
354  }
355  }
356 }
357 
358 //----------------------------------------------------------------------------------------------------
359 
uint32_t station() const
Definition: CTPPSDetId.h:58
static const TGPicture * info(bool iBackgroundIsBlack)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
std::map< unsigned int, std::map< unsigned int, PlotGroup > > plots_
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
edm::EDGetTokenT< reco::ForwardProtonCollection > tokenRecoProtonsMultiRP_
edm::EDGetTokenT< std::map< int, edm::DetSetVector< CTPPSPixelRecHit > > > tokenPixelRecHitsPerParticle_
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
int np
Definition: AMPTWrapper.h:33
void analyze(const edm::Event &, const edm::EventSetup &) override
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
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
fixed size matrix
HLT enums.
T get() const
Definition: EventSetup.h:71
float const energy() const
Definition: LHCInfo.cc:192
edm::EDGetTokenT< std::map< int, edm::DetSetVector< TotemRPRecHit > > > tokenStripRecHitsPerParticle_
std::vector< ForwardProton > ForwardProtonCollection
Collection of ForwardProton objects.
def move(src, dest)
Definition: eostools.py:511
uint32_t rp() const
Definition: CTPPSDetId.h:65