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