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 {
28
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);
91 m_asic_win->Fill(v.getStorageWindow());
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()
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.