Belle II Software  release-06-00-14
TOPWaveformQualityPlotterModule.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 // basf2
10 #include <framework/core/HistoModule.h>
11 #include <top/modules/TOPWaveformQualityPlotter/TOPWaveformQualityPlotterModule.h>
12 
13 // stl
14 #include <utility>
15 
16 //ROOT
17 #include "TDirectory.h"
18 #include "TCanvas.h"
19 #include "TGraphErrors.h"
20 
21 using namespace std;
22 
23 namespace Belle2 {
29  REG_MODULE(TOPWaveformQualityPlotter)
30 
32  : HistoModule()
33  {
34  setDescription("TOP DQM histogram module");
35  addParam("histogramDirectoryName", m_histogramDirectoryName,
36  "histogram directory in ROOT file", string("TOP"));
37  addParam("drawWaves", m_DRAWWAVES, "option to draw waveforms", true);
38  addParam("debugHistos", m_DEBUGGING, "option to draw debug histograms", true);
39  addParam("noisemaps", m_NOISE, "option to draw noisemaps", false);
40  }
41 
42 
43  void TOPWaveformQualityPlotterModule::defineHisto()
44  {
45  TDirectory* oldDir = gDirectory;
46  m_directory = oldDir->mkdir(m_histogramDirectoryName.c_str());
47  m_directory->cd();
48  m_samples = new TH1F("ADCvalues", "ADC values ", 100, -50, 50);
49  m_samples->GetXaxis()->SetTitle("ADC Value");
50  m_samples->GetYaxis()->SetTitle("Number of Samples");
51  m_scrod_id = new TH1F("scrodID", "scrodID", 100, 0, 100);
52  m_asic = new TH1F("IRSX", "IRSX", 4, 0, 4);
53  m_carrier = new TH1F("carrier", "asic col", 4, 0, 4);
54  m_asic_ch = new TH1F("asicCh", "channel", 8, 0, 8);
55  m_errorFlag = new TH1F("errorFlag", "errorFlag", 1000, 0, 1000);
56  m_asic_win = new TH1F("window", "window", 4, 0, 4);
57  m_entries = new TH1F("entries", "entries", 100, 0, 2600);
58  m_moduleID = new TH1F("moduleID", "moduleID", 16, 1, 17);
59  m_pixelID = new TH1F("pixelID", "pixelID", 512, 1, 513);
60  oldDir->cd();
61  }
62 
63 
64  void TOPWaveformQualityPlotterModule::initialize()
65  {
66  // Register histograms (calls back defineHisto)
67  REG_HISTOGRAM;
68  //Get Waveform from datastore
69  m_waveform.isRequired();
70  }
71 
72 
73  void TOPWaveformQualityPlotterModule::basicDebuggingPlots(const TOPRawWaveform& v)
74  {
75  int scrodid = v.getScrodID();
76  int asicid = v.getASICNumber();
77  int channelid = v.getASICChannel();
78  int carrierid = v.getCarrierNumber();
79  m_scrod_id->Fill(scrodid);
80  m_asic_ch->Fill(channelid);
81  m_asic->Fill(asicid);
82  m_carrier->Fill(carrierid);
83  m_asic_win->Fill(v.getStorageWindow());
84  m_entries->Fill(v.getWaveform().size());
85  m_moduleID->Fill(v.getModuleID());
86  m_pixelID->Fill(v.getPixelID());
87 
88  if (m_hitmap.find(scrodid) == m_hitmap.end()) {
89  // cppcheck-suppress stlFindInsert
90  m_hitmap[scrodid] = new TH2F((string("scrod ") + to_string(scrodid) + string("Hitmap")).c_str(),
91  (string("scrod ") + to_string(scrodid) + string("carrier vs. asic;asic;carrier")).c_str(), 4, 0, 4, 4, 0, 4);
92  }
93  m_hitmap[scrodid]->Fill(asicid, carrierid);
94  const vector<short>& waveform = v.getWaveform();
95  if (waveform.empty()) {
96  return;
97  }
98  for (short adc : waveform) {
99  m_samples->Fill(adc);
100  }
101  }
102 
103  void
104  TOPWaveformQualityPlotterModule::drawWaveforms(const TOPRawWaveform& v)
105  {
106  vector<short> waveform = v.getWaveform();
107  if (waveform.empty()) {
108  return;
109  }
110  int scrodid = v.getScrodID();
111  // skip broken events
112  if (scrodid == 0) {
113  return;
114  }
115  int asicNumber = v.getASICNumber();
116  int carrierNumber = v.getCarrierNumber();
117  int iChannel = v.getASICChannel();
118  string gname = string("scrod_") + to_string(scrodid) + string("_carrier") + to_string(carrierNumber) + string("_asic") + to_string(
119  asicNumber) + to_string(iChannel);
120  if (m_waveformHists[scrodid][carrierNumber][asicNumber].find(iChannel) ==
121  m_waveformHists[scrodid][carrierNumber][asicNumber].end()) {
122  // FIXME ? This assumes exactly 256 samples in a waveform (FE data)
123  auto h = new TProfile(gname.c_str(), gname.c_str(), 256, 0, 256);
124  h->Sumw2(false); // unweighted filling.
125  m_waveformHists[scrodid][carrierNumber][asicNumber][iChannel] = h;
126  }
127  // FIXME assumes 256 samples in a waveform
128  for (size_t i = 0; i < 256; ++i) {
129  // exit broken waveforms early
130  if (i >= waveform.size()) {
131  break;
132  }
133  m_waveformHists[scrodid][carrierNumber][asicNumber][iChannel]->Fill(i + 0.5, iChannel * 1500 + waveform[i]);
134  }
135  }
136 
137 
138  void TOPWaveformQualityPlotterModule::event()
139  {
140  if (not m_waveform) {
141  return;
142  }
143  for (auto evtwave : m_waveform) {
144  if (m_DRAWWAVES) {
145  drawWaveforms(evtwave);
146  }
147  if (m_DEBUGGING) {
148  basicDebuggingPlots(evtwave);
149  }
150  if (m_NOISE) {
151  auto channelID = evtwave.getChannel();
152  const vector<short> v_samples = evtwave.getWaveform();
153  size_t nsamples = v_samples.size();
154  if (m_channelNoiseMap.find(channelID) == m_channelNoiseMap.end()) {
155  string idName = string("noise_") + to_string(channelID);
156  m_channelNoiseMap.insert(make_pair(channelID, new TH1F(idName.c_str(), idName.c_str(), 200, -100, 100)));
157  m_channelEventMap.insert(make_pair(channelID, m_iEvent));
158  }
159  TH1F* noise = m_channelNoiseMap[channelID];
160  // Plot all samples in common histogram for quick sanity check
161  for (size_t s = 0; s < nsamples; s++) {
162  double adc = v_samples.at(s);
163  m_samples->Fill(adc);
164  if (s < nsamples - 1) {
165  noise->Fill(v_samples[s + 1] - adc);
166  }
167  }
168  }
169  }
170  m_iEvent += 1;
171  return;
172  }
173 
174  void TOPWaveformQualityPlotterModule::endRun()
175  {
176  if (m_DRAWWAVES) {
177  // Each waveform was stored in a TH1F
178  // This now gets transformed to a TGraph
179  // All 8 channels for a given ASIC are put in the same TMultiGraph
180  // Then we make one canvas of several TMultigraphs for each scrod
181  // FIXME: This is going to get called at the end of the run; the mem leak I am introducing here should be fixed by somebody more patient with ROOT memory management than me.
182  for (auto scrod_it : m_waveformHists) {
183  int scrodid = scrod_it.first;
184  string name = string("scrod_") + to_string(scrodid);
185  TCanvas* c = new TCanvas(name.c_str(), name.c_str());
186  c->Divide(4, 4);
187  int canvasPad = 0;
188  for (auto carrier_it : scrod_it.second) {
189  int carrierNumber = carrier_it.first;
190  for (auto asic_it : carrier_it.second) {
191  int asicNumber = asic_it.first;
192  canvasPad += 1;
193  string gname = string("scrod_") + to_string(scrodid) + string("_carrier") + to_string(carrierNumber) + string("_asic") + to_string(
194  asicNumber);
195  TMultiGraph* mg = new TMultiGraph(gname.c_str(), gname.c_str());
196  for (auto channel_it : asic_it.second) {
197  // read the data from the TProfile
198  TGraphErrors* g = new TGraphErrors(channel_it.second);
199  g->SetMarkerStyle(7);
200  mg->Add(g);
201  }
202  // FIXME nSamples is hard-coded to 256
203  TH2F* h = new TH2F(gname.c_str(), gname.c_str(), 256, 0, 256, 8, -500, -500 + 8 * 1500);
204  for (int ibin = 0; ibin < 8; ibin++) {
205  h->GetYaxis()->SetBinLabel(ibin + 1, to_string(ibin).c_str());
206  }
207  h->GetYaxis()->SetTickSize(0);
208  h->GetYaxis()->SetTickLength(0);
209  h->SetStats(0);
210  c->cd(canvasPad);
211  h->Draw();
212  mg->Draw("P");
213  }
214  }
215  m_directory->WriteTObject(c);
216  }
217  }
218  }
219 
221 } // end Belle2 namespace
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
Definition: HistoModule.h:29
Class to store raw data waveforms.
Plots and histograms of waveforms and feature extracted parameters.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.