Belle II Software  release-08-01-10
TRGTOPWaveformPlotterModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 //---------------------------------------------------------------
9 // $Id$
10 //---------------------------------------------------------------
11 // Filename : TRGTOPWaveformPlotterModule.cc
12 // Section : TRG TOP
13 // Owner :
14 // Email :
15 //---------------------------------------------------------------
16 // Description : TOP-CDC matching studies module for TRGTOP
17 //---------------------------------------------------------------
18 // 1.00 : 2020/09/20 : First version
19 //
20 // Modeled after / heavily borrowing from GDL, GRL and ECL DQM modules
21 //---------------------------------------------------------------
22 #include <trg/top/modules/trgtopWaveformPlotter/TRGTOPWaveformPlotterModule.h>
23 //#include <mdst/dataobjects/SoftwareTriggerResult.h>
24 
25 #include <framework/datastore/StoreObjPtr.h>
26 #include <framework/datastore/StoreArray.h>
27 
28 #include "trg/top/dataobjects/TRGTOPTimeStampsSlot.h"
29 #include "trg/top/dataobjects/TRGTOPTimeStamp.h"
30 
31 #include "trg/top/dataobjects/TRGTOPWaveFormTimeStampsSlot.h"
32 #include "trg/top/dataobjects/TRGTOPWaveFormTimeStamp.h"
33 
34 #include "trg/top/dataobjects/TRGTOPSlotTiming.h"
35 
36 #include "trg/top/dataobjects/TRGTOPTimingISimSlot.h"
37 
38 #include <framework/datastore/RelationVector.h>
39 
40 #include <framework/logging/Logger.h>
41 #include <boost/algorithm/string.hpp>
42 
43 #include <iostream>
44 
45 //using namespace std;
46 using namespace Belle2;
47 
48 REG_MODULE(TRGTOPWaveformPlotter);
49 
51 {
52 
53  setDescription("TRGTOP Waveform Plotter");
54 
56 
57  // Parameter definitions
58 
59  addParam("plottingMode", m_plottingMode,
60  "Plotting mode: 0 (forced ranges for x and y), 1 (slot-level zoom-in), 2 (global zoom-in; default), 3 (global zoom-in for y and xmax, forced left-side edge for x), 4 (global zoom-in for y, forced range for x), anything else (full ranges)",
61  2);
62 
63  addParam("firstAssumedClockCycle", m_firstAssumedClockCycle,
64  "First assumed clock cycle for main readout hits",
65  108);
66 
67  addParam("cutPlotMinNumberTriggerReadoutHits", m_cutPlotMinNumberTriggerReadoutHits,
68  "Minimum number of trigger timestamps cut for drawing the waveform",
69  5);
70 
71  addParam("cutPlotMinNumberMainReadoutHits", m_cutPlotMinNumberMainReadoutHits,
72  "Minimum number of main readout hits cut for drawing the hits",
73  5);
74 
75  addParam("markerSizeHits", m_markerSizeHits,
76  "Marker size (default: 0.85) used to plot main readout hits",
77  0.85);
78 
79  addParam("markerSizeTimestamps", m_markerSizeTimestamps,
80  "Marker size (default: 0.65) used to plot trigger readout timestamps",
81  0.65);
82 
83  addParam("markerTypeHits", m_markerTypeHits,
84  "Marker type (default: 21) used to plot main readout hits",
85  21);
86 
87  addParam("markerTypeTimestamps", m_markerTypeTimestamps,
88  "Marker type (default: 20) used to plot trigger readout timestamps",
89  20);
90 
91  addParam("xMin", m_xMin,
92  "xMin for plotting (default: 100)",
93  100);
94 
95  addParam("xMax", m_xMax,
96  "xMax for plotting (default: 200)",
97  200);
98 
99  addParam("yMin", m_yMin,
100  "yMin for plotting (default: 0)",
101  0);
102 
103  addParam("yMax", m_yMax,
104  "yMax for plotting (default: 47000)",
105  47000);
106 
107  addParam("showGridx", m_showGridx,
108  "Show grid x (default: 0 (no))",
109  0);
110 
111  addParam("showGridy", m_showGridy,
112  "Show grid y (default: 1 (yes))",
113  1);
114 
115  addParam("canvasXMin", m_canvasXMin,
116  "TCanvas x min (default: 0))",
117  0);
118 
119  addParam("canvasYMin", m_canvasYMin,
120  "TCanvas y min (default: 0))",
121  0);
122 
123  addParam("canvasXSize", m_canvasXSize,
124  "TCanvas x size (default: 900))",
125  900);
126 
127  addParam("canvasYSize", m_canvasYSize,
128  "TCanvas y size (default: 600))",
129  600);
130 
131  addParam("shiftCanvas", m_shiftCanvas,
132  "Shift canvases (default: 1 (yes)))",
133  1);
134 
135  addParam("xShiftCanvas", m_xShiftCanvas,
136  "x shift canvases (default: 900))",
137  910);
138 
139  addParam("yShiftCanvas", m_yShiftCanvas,
140  "y shift canvases (default: 600))",
141  610);
142 
143 }
144 
146 {
147 
148  // myROOTDir->cd();
149 
150  // oldROOTDir->cd();
151 
152 }
153 
155 {
156 
157  // oldROOTDir = gDirectory;
158 
159  // m_file = new TFile(m_outputTTreeFileName.c_str(), "RECREATE");
160 
161  // myROOTDir = gDirectory;
162 
163  for (int slot = 1; slot <= NUMBER_OF_TOP_SLOTS; slot++) {
164  m_timeStampsGraphMainReadout[slot - 1] = 0;
165  m_timeStampsGraphTriggerReadout[slot - 1] = 0;
166  m_myMultiGraph[slot - 1] = 0;
167  m_myPaveText[slot - 1] = 0;
168  m_myCanvas[slot - 1] = 0;
169  }
170 
171  // if (!oldROOTDir) oldROOTDir->cd();
172 
173 }
174 
176 {
177 
178 }
179 
181 {
182 
183  // oldROOTDir = gDirectory;
184  // myROOTDir->cd();
185 
186  for (int slot = 1; slot <= NUMBER_OF_TOP_SLOTS; slot++) {
187 
188  //
189  // The code below assumes that none of the higher-level object (such as TCanvas) own any of the embedded objects (such as TGraph's)
190  //
191 
192  if (m_timeStampsGraphMainReadout[slot - 1]) {
193  delete m_timeStampsGraphMainReadout[slot - 1];
194  m_timeStampsGraphMainReadout[slot - 1] = NULL;
195  }
196 
197  if (m_timeStampsGraphTriggerReadout[slot - 1]) {
198  delete m_timeStampsGraphTriggerReadout[slot - 1];
199  m_timeStampsGraphTriggerReadout[slot - 1] = NULL;
200  }
201 
202  if (m_myMultiGraph[slot - 1]) {
203  delete m_myMultiGraph[slot - 1];
204  m_myMultiGraph[slot - 1] = NULL;
205  }
206 
207  if (m_myPaveText[slot - 1]) {
208  delete m_myPaveText[slot - 1];
209  m_myPaveText[slot - 1] = NULL;
210  }
211 
212  if (m_myCanvas[slot - 1]) {
213  delete m_myCanvas[slot - 1];
214  m_myCanvas[slot - 1] = NULL;
215  }
216 
217  }
218 
219  // TOP timestamps made from TOPRawDigits
220  StoreArray<TRGTOPTimeStamp> trgtopTimeStamps("TRGTOPTimeStamps");
221  StoreArray<TRGTOPTimeStampsSlot> trgtopTimeStampsSlots("TRGTOPTimeStampsSlots");
222 
223  // TRG TOP waveform readout
224  StoreArray<TRGTOPWaveFormTimeStamp> trgtopWaveFormTimeStamps("TRGTOPWaveFormTimeStamps");
225  StoreArray<TRGTOPWaveFormTimeStampsSlot> trgtopWaveFormTimeStampsSlots("TRGTOPWaveFormTimeStampsSlots");
226 
227  // TOP TRG slot-level t0 decisions
228  StoreArray<TRGTOPSlotTiming> trgtopSlotTimingAll("TRGTOPSlotTimings");
229 
230  // ISim results for main readout (for all slots and all decisions for each slot)
231  StoreArray<TRGTOPTimingISim> trgtopTimingISimMainReadoutAll("TRGTOPTimingISimMainReadouts");
232 
233  // ISim results for trigger readout (for all slots and all decisions for each slot)
234  StoreArray<TRGTOPTimingISim> trgtopTimingISimTriggerReadoutAll("TRGTOPTimingISimTriggerReadouts");
235 
236 
237  // if (!trgtopWaveFormTimeStamps) return;
238  // if (!trgtopWaveFormTimeStampsSlots) return;
239 
240  // ISim results for main readout hits
241 
242  bool topTRGISimMRODecisionPresent[NUMBER_OF_TOP_SLOTS] = {false};
243  int topTRGISimMRODecisionTiming[NUMBER_OF_TOP_SLOTS] = {0};
244  int topTRGISimMRODecisionNTS[NUMBER_OF_TOP_SLOTS] = {0};
245  int topTRGISimMRODecisionNumber[NUMBER_OF_TOP_SLOTS] = {0};
246 
247  std::string topTRGIsimMRODecisionText[NUMBER_OF_TOP_SLOTS];
248  for (int slot = 1; slot <= NUMBER_OF_TOP_SLOTS; slot++) topTRGIsimMRODecisionText[slot - 1] = "All iSim TOP decisions: ";
249 
250  for (const auto& slotDecision : trgtopTimingISimMainReadoutAll) {
251 
252  int slot = slotDecision.getSlotId();
253 
254  topTRGISimMRODecisionPresent[slot - 1] = true;
255  topTRGISimMRODecisionTiming[slot - 1] = slotDecision.getSlotTiming();
256  topTRGISimMRODecisionNTS[slot - 1] = topTRGISimMRODecisionNTS[slot - 1] + slotDecision.getSlotNHits();
257  topTRGISimMRODecisionNumber[slot - 1] = topTRGISimMRODecisionNumber[slot - 1] + 1;
258 
259  std::stringstream ss1;
260  ss1 << slotDecision.getSlotNHits();
261  std::stringstream ss2;
262  ss2 << slotDecision.getSlotTiming();
263  std::stringstream ss3;
264  ss3 << slotDecision.getSlotDecisionClockCycle();
265  topTRGIsimMRODecisionText[slot - 1] = topTRGIsimMRODecisionText[slot - 1] + " " + ss2.str() + " ( " + ss1.str() + " [" + ss3.str() +
266  "]" + " ); ";
267 
268  }
269 
270  // ISim results for trigger readout hits
271 
272  bool topTRGISimWFRODecisionPresent[NUMBER_OF_TOP_SLOTS] = {false};
273  int topTRGISimWFRODecisionTiming[NUMBER_OF_TOP_SLOTS] = {0};
274  int topTRGISimWFRODecisionNTS[NUMBER_OF_TOP_SLOTS] = {0};
275  int topTRGISimWFRODecisionNumber[NUMBER_OF_TOP_SLOTS] = {0};
276 
277  std::string topTRGIsimWFRODecisionText[NUMBER_OF_TOP_SLOTS];
278  for (int slot = 1; slot <= NUMBER_OF_TOP_SLOTS; slot++) topTRGIsimWFRODecisionText[slot - 1] = "All iSim TRG decisions: ";
279 
280  for (const auto& slotDecision : trgtopTimingISimTriggerReadoutAll) {
281 
282  int slot = slotDecision.getSlotId();
283 
284  topTRGISimWFRODecisionPresent[slot - 1] = true;
285  topTRGISimWFRODecisionTiming[slot - 1] = slotDecision.getSlotTiming();
286  topTRGISimWFRODecisionNTS[slot - 1] = topTRGISimWFRODecisionNTS[slot - 1] + slotDecision.getSlotNHits();
287  topTRGISimWFRODecisionNumber[slot - 1] = topTRGISimWFRODecisionNumber[slot - 1] + 1;
288 
289  std::stringstream ss1;
290  ss1 << slotDecision.getSlotNHits();
291  std::stringstream ss2;
292  ss2 << slotDecision.getSlotTiming();
293  std::stringstream ss3;
294  ss3 << slotDecision.getSlotDecisionClockCycle();
295  topTRGIsimWFRODecisionText[slot - 1] = topTRGIsimWFRODecisionText[slot - 1] + " " + ss2.str() + " ( " + ss1.str() + " [" + ss3.str()
296  + "]" + " ); ";
297 
298  }
299 
300  // slot-level online trigger decisions
301 
302  bool topTRGDecisionPresent[NUMBER_OF_TOP_SLOTS] = {false};
303  int topTRGDecisionTiming[NUMBER_OF_TOP_SLOTS] = {0};
304  int topTRGDecisionNTS[NUMBER_OF_TOP_SLOTS] = {0};
305  int topTRGDecisionNumber[NUMBER_OF_TOP_SLOTS] = {0};
306  // int topTRGDecisionClockCycle[NUMBER_OF_TOP_SLOTS] = {0};
307 
308  std::string topTRGDecisionText[NUMBER_OF_TOP_SLOTS];
309  for (int slot = 1; slot <= NUMBER_OF_TOP_SLOTS; slot++) topTRGDecisionText[slot - 1] = "All online TRG decisions: ";
310 
311  for (const auto& slotDecision : trgtopSlotTimingAll) {
312 
313  // for purposes of visualization do not display information received from the OTHER board
314  if (slotDecision.isThisBoard()) {
315 
316  int slot = slotDecision.getSlotId();
317 
318  topTRGDecisionPresent[slot - 1] = true;
319  topTRGDecisionTiming[slot - 1] = slotDecision.getSlotTiming();
320  topTRGDecisionNTS[slot - 1] = topTRGDecisionNTS[slot - 1] + slotDecision.getSlotNHits();
321  // topTRGDecisionClockCycle[slot-1] = slotDecision.getSlotDecisionClockCycle();
322  topTRGDecisionNumber[slot - 1] = topTRGDecisionNumber[slot - 1] + 1;
323 
324  std::stringstream ss1;
325  ss1 << slotDecision.getSlotNHits();
326  std::stringstream ss2;
327  ss2 << slotDecision.getSlotTiming() / 2;
328  std::stringstream ss3;
329  ss3 << slotDecision.getSlotDecisionClockCycle();
330  topTRGDecisionText[slot - 1] = topTRGDecisionText[slot - 1] + " " + ss2.str() + " ( " + ss1.str() + " [" + ss3.str() + "]" + " ); ";
331 
332  }
333  }
334 
335  // main readout
336 
337  bool topTRGMROPresent[NUMBER_OF_TOP_SLOTS] = {false};
338  int topTRGMRONTS[NUMBER_OF_TOP_SLOTS] = {0};
339 
340  int clockCycleMainReadout[NUMBER_OF_TOP_SLOTS] = {0};
341  int indexClockCycleMainReadout[NUMBER_OF_TOP_SLOTS] = {0};
342 
343  int xMinMRO[NUMBER_OF_TOP_SLOTS] = {0};
344  int xMaxMRO[NUMBER_OF_TOP_SLOTS] = {0};
345 
346  int yMinMRO[NUMBER_OF_TOP_SLOTS] = {0};
347  int yMaxMRO[NUMBER_OF_TOP_SLOTS] = {0};
348 
349  for (const auto& slotTSS : trgtopTimeStampsSlots) {
350 
351  int slot = slotTSS.getSlotId();
352 
353  clockCycleMainReadout[slot - 1] = m_firstAssumedClockCycle;
354 
355  xMinMRO[slot - 1] = -1;
356  xMaxMRO[slot - 1] = -1;
357 
358  yMinMRO[slot - 1] = -1;
359  yMaxMRO[slot - 1] = -1;
360 
361  int nHits = slotTSS.getNumberOfTimeStamps();
362 
363  if (nHits != 0) {
364 
365  topTRGMROPresent[slot - 1] = true;
366  topTRGMRONTS[slot - 1] = nHits;
367 
368  if (topTRGMRONTS[slot - 1] > MAX_NUMBER_OF_CLOCK_CYCLES) topTRGMRONTS[slot - 1] = MAX_NUMBER_OF_CLOCK_CYCLES;
369 
370  for (const auto& timeStamp : slotTSS.getRelationsTo<TRGTOPTimeStamp>()) {
371  int value = timeStamp.getTimeStamp();
372 
373  m_clockCyclesMainReadout[slot - 1][indexClockCycleMainReadout[slot - 1]] = clockCycleMainReadout[slot - 1];
374  m_timeStampsMainReadout[slot - 1][indexClockCycleMainReadout[slot - 1]] = value;
375 
376  if (xMinMRO[slot - 1] == -1
377  || clockCycleMainReadout[slot - 1] < xMinMRO[slot - 1]) xMinMRO[slot - 1] = clockCycleMainReadout[slot - 1];
378  if (xMaxMRO[slot - 1] == -1
379  || clockCycleMainReadout[slot - 1] > xMaxMRO[slot - 1]) xMaxMRO[slot - 1] = clockCycleMainReadout[slot - 1];
380 
381  if (yMinMRO[slot - 1] == -1 || value < yMinMRO[slot - 1]) yMinMRO[slot - 1] = value;
382  if (yMaxMRO[slot - 1] == -1 || value > yMaxMRO[slot - 1]) yMaxMRO[slot - 1] = value;
383 
384  if (indexClockCycleMainReadout[slot - 1] < MAX_NUMBER_OF_CLOCK_CYCLES) {
385  indexClockCycleMainReadout[slot - 1]++;
386  clockCycleMainReadout[slot - 1]++;
387  }
388  }
389  }
390  }
391 
392  // waveform readout
393 
394  bool topTRGWFROPresent[NUMBER_OF_TOP_SLOTS] = {false};
395  int topTRGWFRONTS[NUMBER_OF_TOP_SLOTS] = {0};
396 
397  int clockCycleTriggerReadout[NUMBER_OF_TOP_SLOTS] = {0};
398  int indexClockCycleTriggerReadout[NUMBER_OF_TOP_SLOTS] = {0};
399 
400  int xMinWFRO[NUMBER_OF_TOP_SLOTS] = {0};
401  int xMaxWFRO[NUMBER_OF_TOP_SLOTS] = {0};
402 
403  int yMinWFRO[NUMBER_OF_TOP_SLOTS] = {0};
404  int yMaxWFRO[NUMBER_OF_TOP_SLOTS] = {0};
405 
406  for (auto& slotWaveFormTSS : trgtopWaveFormTimeStampsSlots) {
407 
408  int slot = slotWaveFormTSS.getSlotId();
409 
410  xMinWFRO[slot - 1] = -1;
411  xMaxWFRO[slot - 1] = -1;
412 
413  yMinWFRO[slot - 1] = -1;
414  yMaxWFRO[slot - 1] = -1;
415 
416  int nHits = slotWaveFormTSS.getNumberOfActualTimeStamps();
417 
418  if (nHits != 0) {
419 
420  topTRGWFROPresent[slot - 1] = true;
421  topTRGWFRONTS[slot - 1] = nHits;
422 
423  if (topTRGWFRONTS[slot - 1] > MAX_NUMBER_OF_CLOCK_CYCLES) topTRGWFRONTS[slot - 1] = MAX_NUMBER_OF_CLOCK_CYCLES;
424 
425  for (auto& timeStamp : slotWaveFormTSS.getRelationsTo<TRGTOPWaveFormTimeStamp>()) {
426 
427  if (!timeStamp.isEmptyClockCycle()) {
428 
429  int value = timeStamp.getTimeStamp();
430 
431  m_clockCyclesTriggerReadout[slot - 1][indexClockCycleTriggerReadout[slot - 1]] = clockCycleTriggerReadout[slot - 1];
432  m_timeStampsTriggerReadout[slot - 1][indexClockCycleTriggerReadout[slot - 1]] = value;
433 
434  if (xMinWFRO[slot - 1] == -1
435  || clockCycleTriggerReadout[slot - 1] < xMinWFRO[slot - 1]) xMinWFRO[slot - 1] = clockCycleTriggerReadout[slot - 1];
436  if (xMaxWFRO[slot - 1] == -1
437  || clockCycleTriggerReadout[slot - 1] > xMaxWFRO[slot - 1]) xMaxWFRO[slot - 1] = clockCycleTriggerReadout[slot - 1];
438 
439  if (yMinWFRO[slot - 1] == -1 || value < yMinWFRO[slot - 1]) yMinWFRO[slot - 1] = value;
440  if (yMaxWFRO[slot - 1] == -1 || value > yMaxWFRO[slot - 1]) yMaxWFRO[slot - 1] = value;
441 
442  if (indexClockCycleTriggerReadout[slot - 1] < MAX_NUMBER_OF_CLOCK_CYCLES) {
443  indexClockCycleTriggerReadout[slot - 1]++;
444  }
445  }
446  clockCycleTriggerReadout[slot - 1]++;
447  }
448  }
449  }
450 
451  // plotting
452 
453  // for each slot
454  // decide if there is anything available (and requested) to plot for this slot
455  // then create a TMultiGraph
456  // then create at least one TGraph and add it to the list in TMultiGraph
457  // finally, decide how to plot this TMultiGraph and do that
458 
459  bool plotMyCanvas[NUMBER_OF_TOP_SLOTS] = {false};
460 
461  int xMin = -1;
462  int xMax = -1;
463  int yMin = -1;
464  int yMax = -1;
465 
466  for (int slot = 1; slot <= NUMBER_OF_TOP_SLOTS; slot++) {
467  if (topTRGMRONTS[slot - 1] > 0 || topTRGWFRONTS[slot - 1] > 0) {
468  if (topTRGMRONTS[slot - 1] >= m_cutPlotMinNumberMainReadoutHits) {
469  if (topTRGWFRONTS[slot - 1] >= m_cutPlotMinNumberTriggerReadoutHits) {
470  plotMyCanvas[slot - 1] = true;
471  if (xMinMRO[slot - 1] != -1 && (xMin == -1 || xMinMRO[slot - 1] < xMin)) xMin = xMinMRO[slot - 1];
472  if (xMaxMRO[slot - 1] != -1 && (xMax == -1 || xMaxMRO[slot - 1] > xMax)) xMax = xMaxMRO[slot - 1];
473  if (yMinMRO[slot - 1] != -1 && (yMin == -1 || yMinMRO[slot - 1] < yMin)) yMin = yMinMRO[slot - 1];
474  if (yMaxMRO[slot - 1] != -1 && (yMax == -1 || yMaxMRO[slot - 1] > yMax)) yMax = yMaxMRO[slot - 1];
475 
476  if (xMinWFRO[slot - 1] != -1 && (xMin == -1 || xMinWFRO[slot - 1] < xMin)) xMin = xMinWFRO[slot - 1];
477  if (xMaxWFRO[slot - 1] != -1 && (xMax == -1 || xMaxWFRO[slot - 1] > xMax)) xMax = xMaxWFRO[slot - 1];
478  if (yMinWFRO[slot - 1] != -1 && (yMin == -1 || yMinWFRO[slot - 1] < yMin)) yMin = yMinWFRO[slot - 1];
479  if (yMaxWFRO[slot - 1] != -1 && (yMax == -1 || yMaxWFRO[slot - 1] > yMax)) yMax = yMaxWFRO[slot - 1];
480  }
481  }
482  }
483  }
484 
485  xMin = std::max(xMin - 10, 0);
486  xMax = xMax + 10;
487  yMin = std::max(yMin - 10, 0);
488  yMax = yMax + 10;
489 
490  std::string myMultiGraphTitle[NUMBER_OF_TOP_SLOTS];
491 
492  std::string myPaveTextInfo[NUMBER_OF_TOP_SLOTS][8];
493 
494  for (int slot = 1; slot <= NUMBER_OF_TOP_SLOTS; slot++) {
495 
496  if (plotMyCanvas[slot - 1]) {
497 
498  m_myMultiGraph[slot - 1] = new TMultiGraph();
499  // In principle, we can allow TCanvas (where this TMultiGraph will be plotted) to assume the ownership over this graph.
500  // Then, when memory is freed, it should be sufficient to delete TCanvas only, as it would delete the graph also.
501  // m_myMultiGraph[slot-1]->SetBit(kCanDelete);
502  std::stringstream slotInfo;
503  slotInfo << slot;
504  myMultiGraphTitle[slot - 1] = "Slot " + slotInfo.str() + " : ";
505 
506  m_myPaveText[slot - 1] = new TPaveText(0.40, 0.10, 0.90, 0.30, "bl NDC");
507  // m_myPaveText[slot-1]->SetHeader(myMultiGraphTitle[slot-1].c_str(),"C");;
508 
509  if (topTRGMROPresent[slot - 1]) {
510 
511  m_timeStampsGraphMainReadout[slot - 1] = new TGraph(topTRGMRONTS[slot - 1], &m_clockCyclesMainReadout[slot - 1][0],
512  &m_timeStampsMainReadout[slot - 1][0]);
513  // In principle, we can allow TCanvas (where this TGraph will be plotted) to assume the ownership over this graph.
514  // Then, when memory is freed, it should be sufficient to delete TCanvas only, as it would delete the graph also.
515  // m_timeStampsGraphMainReadout[slot-1]->SetBit(kCanDelete);
516 
517  m_timeStampsGraphMainReadout[slot - 1]->SetMarkerStyle(m_markerTypeHits);
518  m_timeStampsGraphMainReadout[slot - 1]->SetMarkerSize(m_markerSizeHits);
519  m_timeStampsGraphMainReadout[slot - 1]->SetMarkerColor(kRed);
520 
521  m_myMultiGraph[slot - 1]->Add(m_timeStampsGraphMainReadout[slot - 1], "AP");
522  }
523 
524 
525  if (topTRGWFROPresent[slot - 1]) {
526 
527  m_timeStampsGraphTriggerReadout[slot - 1] = new TGraph(topTRGWFRONTS[slot - 1], &m_clockCyclesTriggerReadout[slot - 1][0],
528  &m_timeStampsTriggerReadout[slot - 1][0]);
529  // In principle, we can allow TCanvas (where this TGraph will be plotted) to assume the ownership over this graph.
530  // Then, when memory is freed, it should be sufficient to delete TCanvas only, as it would delete the graph also.
531  // m_timeStampsGraphTriggerReadout[slot-1]->SetBit(kCanDelete);
532 
533  m_timeStampsGraphTriggerReadout[slot - 1]->SetMarkerStyle(m_markerTypeTimestamps);
534  m_timeStampsGraphTriggerReadout[slot - 1]->SetMarkerSize(m_markerSizeTimestamps);
535  m_timeStampsGraphTriggerReadout[slot - 1]->SetLineWidth(3);
536 
537  int color = kBlue;
538  if (!topTRGDecisionPresent[slot - 1]) color = kBlack;
539 
540  m_timeStampsGraphTriggerReadout[slot - 1]->SetMarkerColor(color);
541 
542  m_myMultiGraph[slot - 1]->Add(m_timeStampsGraphTriggerReadout[slot - 1], "AP");
543  }
544  }
545  }
546 
547  int canvasXMin = m_canvasXMin;
548  int canvasYMin = m_canvasYMin;
549  int canvasXSize = m_canvasXSize;
550  int canvasYSize = m_canvasYSize;
551 
552  for (int slot = 1; slot <= NUMBER_OF_TOP_SLOTS; slot++) {
553 
554  if (plotMyCanvas[slot - 1]) {
555 
556  myMultiGraphTitle[slot - 1] = myMultiGraphTitle[slot - 1] + " TOP / TRG / L1 / iSim TOP / iSim TRG hits:";
557 
558  std::stringstream nHitInfoMainReadout;
559  nHitInfoMainReadout << topTRGMRONTS[slot - 1];
560  myMultiGraphTitle[slot - 1] = myMultiGraphTitle[slot - 1] + " " + nHitInfoMainReadout.str();
561 
562  myPaveTextInfo[slot - 1][0] = "N hits (TOP readout): " + nHitInfoMainReadout.str();
563 
564  std::stringstream nHitInfoTriggerReadout;
565  nHitInfoTriggerReadout << topTRGWFRONTS[slot - 1];
566  myMultiGraphTitle[slot - 1] = myMultiGraphTitle[slot - 1] + " / " + nHitInfoTriggerReadout.str();
567 
568  myPaveTextInfo[slot - 1][1] = "N timestamps (TRG readout): " + nHitInfoTriggerReadout.str();
569 
570  std::stringstream nHitInfoTriggerDecision;
571  nHitInfoTriggerDecision << topTRGDecisionNTS[slot - 1];
572  myMultiGraphTitle[slot - 1] = myMultiGraphTitle[slot - 1] + " / " + nHitInfoTriggerDecision.str();
573 
574  myPaveTextInfo[slot - 1][2] = "N timestamps TRG online: " + nHitInfoTriggerDecision.str();
575 
576  std::stringstream nHitInfoISimTriggerDecisionMainReadout;
577  nHitInfoISimTriggerDecisionMainReadout << topTRGISimMRODecisionNTS[slot - 1];
578  myMultiGraphTitle[slot - 1] = myMultiGraphTitle[slot - 1] + " / " + nHitInfoISimTriggerDecisionMainReadout.str();
579 
580  myPaveTextInfo[slot - 1][3] = "N timestamps TRG ISim (all, TOP readout): " + nHitInfoISimTriggerDecisionMainReadout.str();
581 
582  std::stringstream nHitInfoISimTriggerDecisionTriggerReadout;
583  nHitInfoISimTriggerDecisionTriggerReadout << topTRGISimWFRODecisionNTS[slot - 1];
584  myMultiGraphTitle[slot - 1] = myMultiGraphTitle[slot - 1] + " / " + nHitInfoISimTriggerDecisionTriggerReadout.str();
585 
586  myPaveTextInfo[slot - 1][4] = "N timestamps TRG ISim (all, TRG readout): " + nHitInfoISimTriggerDecisionTriggerReadout.str();
587 
588  // myMultiGraphTitle[slot-1] = myMultiGraphTitle[slot-1] + ", t0 online/ISim main/TRG: ";
589 
590  if (topTRGDecisionPresent[slot - 1]) {
591  std::stringstream nTimingInfoTriggerDecision;
592  nTimingInfoTriggerDecision << topTRGDecisionTiming[slot - 1] / 2;
593  std::stringstream nNumberInfoTriggerDecision;
594  nNumberInfoTriggerDecision << topTRGDecisionNumber[slot - 1];
595  myPaveTextInfo[slot - 1][5] = "Number of online TRG decisions: " + nNumberInfoTriggerDecision.str() + ", most recent t0: " +
596  nTimingInfoTriggerDecision.str();
597  // myMultiGraphTitle[slot-1] = myMultiGraphTitle[slot-1] + nNumberInfoTriggerDecision.str() + " ( ";
598  // myMultiGraphTitle[slot-1] = myMultiGraphTitle[slot-1] + nTimingInfoTriggerDecision.str() + " ) / ";
599  } else {
600  myPaveTextInfo[slot - 1][5] = "No online TRG decisions";
601  // myMultiGraphTitle[slot-1] = myMultiGraphTitle[slot-1] + "none / ";
602  }
603 
604  if (topTRGISimMRODecisionPresent[slot - 1]) {
605  std::stringstream nTimingInfoTriggerDecision;
606  nTimingInfoTriggerDecision << topTRGISimMRODecisionTiming[slot - 1];
607  std::stringstream nNumberInfoTriggerDecision;
608  nNumberInfoTriggerDecision << topTRGISimMRODecisionNumber[slot - 1];
609  myPaveTextInfo[slot - 1][6] = "Number of ISim TOP readout TRG decisions: " + nNumberInfoTriggerDecision.str() + ", most recent t0: "
610  + nTimingInfoTriggerDecision.str();
611  // myMultiGraphTitle[slot-1] = myMultiGraphTitle[slot-1] + nNumberInfoTriggerDecision.str() + " ( ";
612  // myMultiGraphTitle[slot-1] = myMultiGraphTitle[slot-1] + nTimingInfoTriggerDecision.str() + " ) / ";
613  } else {
614  myPaveTextInfo[slot - 1][6] = "No iSim TOP readout TRG decisions";
615  // myMultiGraphTitle[slot-1] = myMultiGraphTitle[slot-1] + " none / ";
616  }
617 
618  if (topTRGISimWFRODecisionPresent[slot - 1]) {
619  std::stringstream nTimingInfoTriggerDecision;
620  nTimingInfoTriggerDecision << topTRGISimWFRODecisionTiming[slot - 1];
621  std::stringstream nNumberInfoTriggerDecision;
622  nNumberInfoTriggerDecision << topTRGISimWFRODecisionNumber[slot - 1];
623  myPaveTextInfo[slot - 1][7] = "Number of ISim TRG readout TRG decisions: " + nNumberInfoTriggerDecision.str() + ", most recent t0: "
624  + nTimingInfoTriggerDecision.str();
625  // myMultiGraphTitle[slot-1] = myMultiGraphTitle[slot-1] + nNumberInfoTriggerDecision.str() + " ( ";
626  // myMultiGraphTitle[slot-1] = myMultiGraphTitle[slot-1] + nTimingInfoTriggerDecision.str() + " )";
627  } else {
628  myPaveTextInfo[slot - 1][7] = "No iSim TRG readout TRG decisions";
629  // myMultiGraphTitle[slot-1] = myMultiGraphTitle[slot-1] + "none";
630  }
631 
632  myMultiGraphTitle[slot - 1] = myMultiGraphTitle[slot - 1] + "; Clock cycle (8ns units); Hit time (2ns units)";
633  m_myMultiGraph[slot - 1]->SetTitle(myMultiGraphTitle[slot - 1].c_str());
634 
635  std::stringstream slotInfo;
636  slotInfo << slot;
637  std::string name = "c_" + slotInfo.str();
638  std::string title = "Main readout hits (red) and trigger readout timestamps (blue/black) for slot " + slotInfo.str();
639  m_myCanvas[slot - 1] = new TCanvas(name.c_str(), title.c_str(), canvasXMin, canvasYMin, canvasXSize, canvasYSize);
640  if (m_shiftCanvas) {
641  canvasXMin = canvasXMin + m_xShiftCanvas;
642  if (canvasXMin >= 1000) {
643  canvasXMin = m_canvasXMin;
644  canvasYMin = canvasYMin + m_yShiftCanvas;
645  if (canvasYMin >= 700) {
646  canvasYMin = m_canvasYMin;
647  }
648  }
649  }
650 
651  m_myMultiGraph[slot - 1]->Draw("AP");
652 
653  TAxis* xAxis = m_myMultiGraph[slot - 1]->GetXaxis();
654 
655  if (m_plottingMode == 0) {
656  m_myMultiGraph[slot - 1]->SetMinimum(m_yMin);
657  m_myMultiGraph[slot - 1]->SetMaximum(m_yMax);
658  xAxis->SetLimits(m_xMin, m_xMax);
659  } else if (m_plottingMode == 1) {
660  m_myMultiGraph[slot - 1]->SetMinimum(std::min(yMinMRO[slot - 1], yMinWFRO[slot - 1]));
661  m_myMultiGraph[slot - 1]->SetMaximum(std::max(yMaxMRO[slot - 1], yMaxWFRO[slot - 1]));
662  xAxis->SetLimits(std::min(xMinMRO[slot - 1], xMinWFRO[slot - 1]), std::max(xMaxMRO[slot - 1], xMaxWFRO[slot - 1]));
663  } else if (m_plottingMode == 2) {
664  m_myMultiGraph[slot - 1]->SetMinimum(yMin);
665  m_myMultiGraph[slot - 1]->SetMaximum(yMax);
666  xAxis->SetLimits(xMin, xMax);
667  } else if (m_plottingMode == 3) {
668  m_myMultiGraph[slot - 1]->SetMinimum(yMin);
669  m_myMultiGraph[slot - 1]->SetMaximum(yMax);
670  xAxis->SetLimits(m_xMin, xMax);
671  } else if (m_plottingMode == 4) {
672  m_myMultiGraph[slot - 1]->SetMinimum(yMin);
673  m_myMultiGraph[slot - 1]->SetMaximum(yMax);
674  xAxis->SetLimits(m_xMin, m_xMax);
675  } else {
676  m_myMultiGraph[slot - 1]->SetMinimum(0);
677  m_myMultiGraph[slot - 1]->SetMaximum(MAX_TIMESTAMP_RANGE);
678  xAxis->SetLimits(0, MAX_NUMBER_OF_CLOCK_CYCLES);
679  }
680 
681  m_myMultiGraph[slot - 1]->Draw("AP");
682  m_myCanvas[slot - 1]->SetGridx(m_showGridx);
683  m_myCanvas[slot - 1]->SetGridy(m_showGridy);
684 
685  // m_myPaveText[slot-1]->AddText(myPaveTextInfo[slot-1][0].c_str());
686  // m_myPaveText[slot-1]->AddText(myPaveTextInfo[slot-1][1].c_str());
687  // m_myPaveText[slot-1]->AddText(myPaveTextInfo[slot-1][2].c_str());
688  // m_myPaveText[slot-1]->AddText(myPaveTextInfo[slot-1][3].c_str());
689  // m_myPaveText[slot-1]->AddText(myPaveTextInfo[slot-1][4].c_str());
690  m_myPaveText[slot - 1]->AddText(myPaveTextInfo[slot - 1][5].c_str());
691  m_myPaveText[slot - 1]->AddText(myPaveTextInfo[slot - 1][6].c_str());
692  m_myPaveText[slot - 1]->AddText(myPaveTextInfo[slot - 1][7].c_str());
693 
694  m_myPaveText[slot - 1]->AddText(topTRGDecisionText[slot - 1].c_str());
695  m_myPaveText[slot - 1]->AddText(topTRGIsimMRODecisionText[slot - 1].c_str());
696  m_myPaveText[slot - 1]->AddText(topTRGIsimWFRODecisionText[slot - 1].c_str());
697 
698  m_myPaveText[slot - 1]->SetBorderSize(1);
699  // m_myPaveText[slot-1]->SetFillColor(19);
700  m_myPaveText[slot - 1]->SetFillStyle(0);
701  m_myPaveText[slot - 1]->SetTextFont(40);
702  m_myPaveText[slot - 1]->SetTextAlign(12);
703  m_myPaveText[slot - 1]->Draw();
704 
705  m_myCanvas[slot - 1]->Update();
706 
707  }
708  }
709 
710  // if (!oldROOTDir) oldROOTDir->cd();
711 }
712 
714 {
715  // oldROOTDir = gDirectory;
716  // myROOTDir->cd();
717 
718  // if (!oldROOTDir) oldROOTDir->cd();
719 }
720 
721 //TRGTOPWaveformPlotterModule::~TRGTOPWaveformPlotterModule()
722 //{
723 //}
724 
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
Example Detector.
TCanvas * m_myCanvas[NUMBER_OF_TOP_SLOTS]
TDirectory.
virtual void initialize() override
initialize
virtual void terminate() override
terminate
virtual void beginRun() override
begin Run
REG_MODULE(arichBtest)
Register the Module.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
Abstract base class for different kinds of events.