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