CMS 3D CMS Logo

TotemT2DQMSource.cc
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * This is a part of TOTEM offline software.
4  * Authors:
5  * Laurent Forthomme
6  * Arkadiusz Cwikla
7  * Fredrik Oljemark
8  *
9  ****************************************************************************/
10 
17 
20 
22 
25 
28 
29 #include <string>
30 #include <bitset>
31 
33 public:
35  ~TotemT2DQMSource() override = default;
36 
37 protected:
38  void dqmBeginRun(const edm::Run&, const edm::EventSetup&) override;
39  void bookHistograms(DQMStore::IBooker&, const edm::Run&, const edm::EventSetup&) override;
40  void analyze(const edm::Event&, const edm::EventSetup&) override;
41 
42 private:
43  void fillActivePlanes(std::unordered_map<unsigned int, std::set<unsigned int>>&, const TotemT2DetId&);
44  void fillTriggerBitset(const TotemT2DetId&);
45  void clearTriggerBitset();
49  void fillEdges(const TotemT2Digi&, const TotemT2DetId&);
50  void fillBX(const TotemT2Digi&, const TotemT2DetId&, const int);
51  void fillToT(const TotemT2Digi&, const TotemT2DetId&);
52  void fillFlags(const TotemT2Digi&, const TotemT2DetId&);
53 
55 
56  std::unique_ptr<TotemT2Segmentation> segm_;
57 
58  static constexpr double T2_BIN_WIDTH_NS_ = 25. / 4;
60 
61  static constexpr int t2TE = 0, t2LE = 1, t2MT = 2, t2ML = 3;
62 
63  const unsigned int nbinsx_, nbinsy_;
64  const unsigned int windowsNum_;
65 
66  struct SectorPlots {
70 
72  std::bitset<(TotemT2DetId::maxPlane + 1) * (TotemT2DetId::maxChannel + 1)> hitTilesArray;
73  static const unsigned int MINIMAL_TRIGGER = 3;
74 
75  MonitorElement *leadingEdge = nullptr, *trailingEdge = nullptr, *timeOverTreshold = nullptr, *eventFlags = nullptr;
76 
77  SectorPlots() = default;
79  DQMStore::IBooker& ibooker, unsigned int id, unsigned int nbinsx, unsigned int nbinsy, unsigned int windowsNum);
80  };
81 
82  struct PlanePlots {
86 
87  PlanePlots() = default;
88  PlanePlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int nbinsx, unsigned int nbinsy);
89  };
90  struct ChannelPlots {
96 
97  ChannelPlots() = default;
98  ChannelPlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum);
99  };
100 
101  std::unordered_map<unsigned int, SectorPlots> sectorPlots_;
102  std::unordered_map<unsigned int, PlanePlots> planePlots_;
103  std::unordered_map<unsigned int, ChannelPlots> channelPlots_;
104 };
105 
107  DQMStore::IBooker& ibooker, unsigned int id, unsigned int nbinsx, unsigned int nbinsy, unsigned int windowsNum) {
109 
111  ibooker.setCurrentFolder(path);
112 
114 
115  activePlanes =
116  ibooker.book1D("active planes", title + " which planes are active (LE+TE digis);plane number", 8, -0.5, 7.5);
117 
118  activePlanesCount = ibooker.book1D("number of active planes",
119  title + " how many planes are active (LE+TE digis);number of active planes",
120  9,
121  -0.5,
122  8.5);
123 
124  activityPerBX =
125  ibooker.book1D("activity per BX CMS", title + " Activity (=LE) per BX;Event.BX", 3600, -1.5, 3598. + 0.5);
126 
127  triggerEmulator = ibooker.book2DD("trigger emulator",
128  title + " trigger emulator (LE+TE digis);arbitrary unit;arbitrary unit",
129  nbinsx,
130  -0.5,
131  double(nbinsx) - 0.5,
132  nbinsy,
133  -0.5,
134  double(nbinsy) - 0.5);
135  leadingEdge = ibooker.book1D(
136  "leading edge", title + " leading edge (all DIGIs); leading edge (ns)", 25 * windowsNum, 0, 25 * windowsNum);
137  trailingEdge = ibooker.book1D(
138  "trailing edge", title + " trailing edge (all DIGIs); trailing edge (ns)", 25 * windowsNum, 0, 25 * windowsNum);
139 
140  timeOverTreshold = ibooker.book1D("time over threshold",
141  title + " time over threshold (digi, =0 if LE or TE=0);time over threshold (ns)",
142  500,
143  -50,
144  200);
145 
146  eventFlags = ibooker.book1D(
147  "event flags", title + " event flags (digi);Event flags (TE/LE valid, TE/LE multiple)", 4, -0.5, 3.5);
148 
149  for (unsigned short flag_index = 1; flag_index <= 4; ++flag_index)
150  eventFlags->setBinLabel(flag_index, "Flag " + std::to_string(flag_index));
151 }
152 
154  unsigned int id,
155  unsigned int nbinsx,
156  unsigned int nbinsy) {
160  ibooker.setCurrentFolder(path);
161 
162  digisMultiplicity = ibooker.book2DD("digis multiplicity",
163  title + " digis multiplicity (=LE);arbitrary unit;arbitrary unit",
164  nbinsx,
165  -0.5,
166  double(nbinsx) - 0.5,
167  nbinsy,
168  -0.5,
169  double(nbinsy) - 0.5);
170  rechitMultiplicity = ibooker.book2DD("rechits multiplicity",
171  title + " rechits multiplicity;x;y",
172  nbinsx,
173  -0.5,
174  double(nbinsx) - 0.5,
175  nbinsy,
176  -0.5,
177  double(nbinsy) - 0.5);
178 
179  eventFlagsPl = ibooker.book1D(
180  "event flags", title + " event flags (digi);Event flags (TE/LE valid, TE/LE multiple)", 4, -0.5, 3.5);
181 
182  for (unsigned short flag_index = 1; flag_index <= 4; ++flag_index)
183  eventFlagsPl->setBinLabel(flag_index, "Flag " + std::to_string(flag_index));
184 }
185 
190  ibooker.setCurrentFolder(path);
191 
192  leadingEdgeCh = ibooker.book1D(
193  "leading edge", title + " leading edge (all DIGIs); leading edge (ns)", 25 * windowsNum, 0, 25 * windowsNum);
194  trailingEdgeCh = ibooker.book1D(
195  "trailing edge", title + " trailing edge (all DIGIs); trailing edge (ns)", 25 * windowsNum, 0, 25 * windowsNum);
196 
197  timeOverTresholdCh = ibooker.book1D("time over threshold",
198  title + " time over threshold (digi, =0 if LE or TE=0);time over threshold (ns)",
199  500,
200  -50,
201  200);
202 
203  eventFlagsCh = ibooker.book1D(
204  "event flags", title + " event flags (digi);Event flags (TE/LE valid, TE/LE multiple)", 4, -0.5, 3.5);
205 
206  activityPerBXCh =
207  ibooker.book1D("activity per BX", title + " Activity (=LE) per BX;Event.BX", 1000, -1.5, 998. + 0.5);
208 
209  for (unsigned short flag_index = 1; flag_index <= 4; ++flag_index)
210  eventFlagsCh->setBinLabel(flag_index, "Flag " + std::to_string(flag_index));
211 }
212 
214  : digiToken_(consumes<edmNew::DetSetVector<TotemT2Digi>>(iConfig.getParameter<edm::InputTag>("digisTag"))),
215  nbinsx_(iConfig.getParameter<unsigned int>("nbinsx")),
216  nbinsy_(iConfig.getParameter<unsigned int>("nbinsy")),
217  windowsNum_(iConfig.getParameter<unsigned int>("windowsNum")) {}
218 
220 
222  ibooker.cd();
223  ibooker.setCurrentFolder("TotemT2");
224 
225  bookErrorFlagsHistogram(ibooker);
226 
227  for (unsigned int arm = 0; arm <= CTPPSDetId::maxArm; ++arm) {
228  for (unsigned int pl = 0; pl <= TotemT2DetId::maxPlane; ++pl) {
229  const TotemT2DetId detid(arm, pl, 0);
230  const TotemT2DetId planeId(detid.planeId());
231  planePlots_[planeId] = PlanePlots(ibooker, planeId, nbinsx_, nbinsy_);
232  for (unsigned int ch = 0; ch <= TotemT2DetId::maxChannel; ++ch) {
233  const TotemT2DetId detidCh(arm, pl, ch);
234  channelPlots_[detidCh] = ChannelPlots(ibooker, detidCh, windowsNum_);
235  }
236  }
237  const TotemT2DetId detid(arm, 0, 0);
238  const TotemT2DetId secId(detid.armId());
239  sectorPlots_[secId] = SectorPlots(ibooker, secId, nbinsx_, nbinsy_, windowsNum_);
240  }
241 
242  // build a segmentation helper for the size of histograms previously booked
243  segm_ = std::make_unique<TotemT2Segmentation>(nbinsx_, nbinsy_);
244 }
245 
247  // fill digis information
248  std::unordered_map<unsigned int, std::set<unsigned int>> planes;
249 
250  for (const auto& ds_digis : iEvent.get(digiToken_)) {
251  if (!ds_digis.empty()) {
252  const TotemT2DetId detid(ds_digis.detId());
253  const TotemT2DetId planeId(detid.planeId());
254  for (const auto& digi : ds_digis) {
255  if (digi.hasLE()) {
256  segm_->fill(planePlots_[planeId].digisMultiplicity->getTH2D(), detid);
257  if (digi.hasTE())
258  fillTriggerBitset(detid);
259  }
260  fillErrorFlagsHistogram(digi, detid);
261  fillEdges(digi, detid);
262  fillToT(digi, detid);
263  fillFlags(digi, detid);
264  int bx = iEvent.bunchCrossing();
265  fillBX(digi, detid, bx);
266  if (digi.hasLE() && digi.hasTE()) //good digi
267  fillActivePlanes(planes, detid);
268  }
269  }
270  }
271 
272  for (const auto& plt : sectorPlots_)
273  plt.second.activePlanesCount->Fill(planes[plt.first].size());
274 
275  for (unsigned short arm = 0; arm <= CTPPSDetId::maxArm; ++arm)
276  for (unsigned short plane = 0; plane <= 1; ++plane)
277  for (unsigned short id = 0; id <= TotemT2DetId::maxChannel; ++id) {
278  const TotemT2DetId detid(arm, plane, id);
279  if (areChannelsTriggered(detid)) {
280  const TotemT2DetId secId(detid.armId());
281  segm_->fill(sectorPlots_[secId].triggerEmulator->getTH2D(), detid);
282  }
283  }
284 
285  // fill rechits information
286 
288 }
289 
290 void TotemT2DQMSource::fillActivePlanes(std::unordered_map<unsigned int, std::set<unsigned int>>& planes,
291  const TotemT2DetId& detid) {
292  const TotemT2DetId secId(detid.armId());
293  unsigned short pl = detid.plane();
294 
295  planes[secId].insert(pl);
296 
297  sectorPlots_[secId].activePlanes->Fill(pl);
298 }
299 
301  const TotemT2DetId secId(detid.armId());
302  unsigned short pl = detid.plane();
303  unsigned short ch = detid.channel();
304  sectorPlots_[secId].hitTilesArray[4 * pl + ch] = true;
305 }
306 
308  for (auto& sectorPlot : sectorPlots_)
309  sectorPlot.second.hitTilesArray.reset();
310 }
311 
313  unsigned int channel = detid.channel();
314 
315  // prepare mask
316  std::bitset<(TotemT2DetId::maxPlane + 1) * (TotemT2DetId::maxChannel + 1)> mask;
317  // check if plane is even or not
318  unsigned int pl = detid.plane() % 2 == 0 ? 0 : 1;
319  // set only even or only odd plane bits for this channel
320  for (; pl <= TotemT2DetId::maxPlane; pl += 2)
321  mask[4 * pl + channel] = true;
322  const TotemT2DetId secId(detid.armId());
323  // check how many masked channels were hit
324  unsigned int triggeredChannelsNumber = (mask & sectorPlots_[secId].hitTilesArray).count();
325 
326  return triggeredChannelsNumber >= SectorPlots::MINIMAL_TRIGGER;
327 }
328 
330  totemT2ErrorFlags_2D_ = ibooker.book2D("nt2 readout flags", " nt2 readout flags", 4, -0.5, 3.5, 2, -0.5, 1.5);
331  for (unsigned short error_index = 1; error_index <= 4; ++error_index)
332  totemT2ErrorFlags_2D_->setBinLabel(error_index, "Flag " + std::to_string(error_index));
333 
334  int tmpIndex = 0;
335  totemT2ErrorFlags_2D_->setBinLabel(++tmpIndex, "arm 4-5", /* axis */ 2);
336  totemT2ErrorFlags_2D_->setBinLabel(++tmpIndex, "arm 5-6", /* axis */ 2);
337 }
338 
340  // readout flags histogram filling
341  for (unsigned int i = 0; i < 4; i++) {
342  if (digi.status() & (1 << i))
343  totemT2ErrorFlags_2D_->Fill(i + 0.0, detid.arm() + 0.0);
344  }
345 }
346 
347 void TotemT2DQMSource::fillEdges(const TotemT2Digi& digi, const TotemT2DetId& detid) {
348  const TotemT2DetId secId(detid.armId());
349  sectorPlots_[secId].leadingEdge->Fill(T2_BIN_WIDTH_NS_ * digi.leadingEdge());
350  sectorPlots_[secId].trailingEdge->Fill(T2_BIN_WIDTH_NS_ * digi.trailingEdge());
351  channelPlots_[detid].leadingEdgeCh->Fill(T2_BIN_WIDTH_NS_ * digi.leadingEdge());
352  channelPlots_[detid].trailingEdgeCh->Fill(T2_BIN_WIDTH_NS_ * digi.trailingEdge());
353 }
354 
355 void TotemT2DQMSource::fillBX(const TotemT2Digi& digi, const TotemT2DetId& detid, const int bx) {
356  const TotemT2DetId secId(detid.armId());
357  if (digi.hasLE()) {
358  sectorPlots_[secId].activityPerBX->Fill(bx);
359  channelPlots_[detid].activityPerBXCh->Fill(bx);
360  }
361 }
362 
363 void TotemT2DQMSource::fillToT(const TotemT2Digi& digi, const TotemT2DetId& detid) {
364  const TotemT2DetId secId(detid.armId());
365 
366  const int t_lead = digi.leadingEdge(), t_trail = digi.trailingEdge();
367  // don't skip no-edge digis
368  double toT = 0.;
369  if (digi.hasLE() && digi.hasTE()) {
370  toT = (t_trail - t_lead) * T2_BIN_WIDTH_NS_; // in ns
371  }
372 
373  sectorPlots_[secId].timeOverTreshold->Fill(toT);
374  channelPlots_[detid].timeOverTresholdCh->Fill(toT);
375 }
376 
377 void TotemT2DQMSource::fillFlags(const TotemT2Digi& digi, const TotemT2DetId& detid) {
378  const TotemT2DetId secId(detid.armId());
379  const TotemT2DetId planeId(detid.planeId());
380  if (digi.hasTE()) {
381  sectorPlots_[secId].eventFlags->Fill(t2TE + 0.0);
382  planePlots_[planeId].eventFlagsPl->Fill(t2TE + 0.0);
383  channelPlots_[detid].eventFlagsCh->Fill(t2TE + 0.0);
384  }
385 
386  if (digi.hasLE()) {
387  sectorPlots_[secId].eventFlags->Fill(t2LE + 0.0);
388  planePlots_[planeId].eventFlagsPl->Fill(t2LE + 0.0);
389  channelPlots_[detid].eventFlagsCh->Fill(t2LE + 0.0);
390  }
391 
392  if (digi.hasManyTE()) {
393  sectorPlots_[secId].eventFlags->Fill(t2MT + 0.0);
394  planePlots_[planeId].eventFlagsPl->Fill(t2MT + 0.0);
395  channelPlots_[detid].eventFlagsCh->Fill(t2MT + 0.0);
396  }
397 
398  if (digi.hasManyLE()) {
399  sectorPlots_[secId].eventFlags->Fill(t2ML + 0.0);
400  planePlots_[planeId].eventFlagsPl->Fill(t2ML + 0.0);
401  channelPlots_[detid].eventFlagsCh->Fill(t2ML + 0.0);
402  }
403 }
404 
static constexpr int t2TE
void fillActivePlanes(std::unordered_map< unsigned int, std::set< unsigned int >> &, const TotemT2DetId &)
MonitorElement * digisMultiplicity
Detector ID class for Totem T2 detectors. Bits [19:31] : Base CTPPSDetId class attributes Bits [16:18...
Definition: TotemT2DetId.h:25
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
std::unique_ptr< TotemT2Segmentation > segm_
uint32_t arm() const
Definition: CTPPSDetId.h:57
void fillEdges(const TotemT2Digi &, const TotemT2DetId &)
static constexpr uint32_t maxChannel
Definition: TotemT2DetId.h:35
TotemT2DetId planeId() const
Definition: TotemT2DetId.h:60
static const unsigned int MINIMAL_TRIGGER
const unsigned int nbinsx_
void fillFlags(const TotemT2Digi &, const TotemT2DetId &)
TotemT2DQMSource(const edm::ParameterSet &)
static constexpr uint32_t maxPlane
Definition: TotemT2DetId.h:34
bool hasLE() const
Definition: TotemT2Digi.h:22
static std::string to_string(const XMLCh *ch)
static constexpr int t2ML
void bookHistograms(DQMStore::IBooker &, const edm::Run &, const edm::EventSetup &) override
void Fill(long long x)
uint32_t plane() const
Definition: TotemT2DetId.h:44
MonitorElement * rechitMultiplicity
bool hasManyTE() const
Definition: TotemT2Digi.h:25
unsigned char status() const
Definition: TotemT2Digi.h:21
static constexpr int t2MT
int iEvent
Definition: GenABIO.cc:224
static constexpr int t2LE
bool hasManyLE() const
Definition: TotemT2Digi.h:24
const edm::EDGetTokenT< edmNew::DetSetVector< TotemT2Digi > > digiToken_
const unsigned int nbinsy_
MonitorElement * totemT2ErrorFlags_2D_
static const uint32_t maxArm
Definition: CTPPSDetId.h:51
void planeName(std::string &name, NameFlag flag=nFull) const
Definition: TotemT2DetId.cc:39
void armName(std::string &name, NameFlag flag=nFull) const
Definition: CTPPSDetId.h:98
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void fillBX(const TotemT2Digi &, const TotemT2DetId &, const int)
virtual void setBinLabel(int bin, const std::string &label, int axis=1)
set bin label for x, y or z axis (axis=1, 2, 3 respectively)
const unsigned int windowsNum_
void analyze(const edm::Event &, const edm::EventSetup &) override
static constexpr double T2_BIN_WIDTH_NS_
std::bitset<(TotemT2DetId::maxPlane+1) *(TotemT2DetId::maxChannel+1)> hitTilesArray
CTPPSDetId armId() const
Definition: CTPPSDetId.h:80
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:221
bool areChannelsTriggered(const TotemT2DetId &)
MonitorElement * book2DD(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:347
std::unordered_map< unsigned int, PlanePlots > planePlots_
HLT enums.
~TotemT2DQMSource() override=default
unsigned short trailingEdge() const
Definition: TotemT2Digi.h:20
std::unordered_map< unsigned int, ChannelPlots > channelPlots_
bool hasTE() const
Definition: TotemT2Digi.h:23
void fillTriggerBitset(const TotemT2DetId &)
unsigned short leadingEdge() const
Definition: TotemT2Digi.h:18
std::unordered_map< unsigned int, SectorPlots > sectorPlots_
void channelName(std::string &name, NameFlag flag=nFull) const
Definition: TotemT2DetId.cc:58
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
void dqmBeginRun(const edm::Run &, const edm::EventSetup &) override
void bookErrorFlagsHistogram(DQMStore::IBooker &)
uint32_t channel() const
Definition: TotemT2DetId.h:51
void fillErrorFlagsHistogram(const TotemT2Digi &, const TotemT2DetId &)
Definition: Run.h:45
void fillToT(const TotemT2Digi &, const TotemT2DetId &)