Belle II Software development
showFEWaveforms.py
1#!/usr/bin/env python3
2
3
10
11# ---------------------------------------------------------------------------------------
12# Display of waveforms with feature extraction points superimposed
13# Usage: basf2 showFEWaveforms.py -i <file_name.root>
14# ---------------------------------------------------------------------------------------
15
16# avoid race conditions beetween pyroot and GUI thread
17from ROOT import PyConfig
18PyConfig.StartGuiThread = False # noqa
19
20import basf2 as b2
21from ROOT import Belle2
22from ROOT import TH1F, TCanvas, TGraph
23
24
25class WFDisplay(b2.Module):
26
27 '''
28 Simple event display of waveforms with feature extraction points
29 '''
30
31
32 hist = [TH1F('h' + str(i), 'wf', 64 * 4, 0.0, 64.0 * 4) for i in range(4)]
33 for i in range(4):
34 hist[i].SetXTitle("sample number")
35 hist[i].SetYTitle("sample value [ADC counts]")
36 hist[i].SetLabelSize(0.06, "XY")
37 hist[i].SetTitleSize(0.07, "XY")
38 hist[i].SetTitleOffset(0.7, "XY")
39
40 gpaint = [TGraph() for i in range(4)]
41
42 graphs = [[TGraph(5)] for i in range(4)]
43
44 tlpfgraphs = [[TGraph(2)] for i in range(4)]
45
46 c1 = TCanvas('c1', 'WF event display', 800, 800)
47
48 pdfFile = 'waveforms'
49
50 def initialize(self):
51 ''' Initialize the Module: open the canvas. '''
52
53 self.c1.Divide(1, 4)
54 self.c1.Show()
55 print('WARNING: Template Fit is still under development and currently returns wrong position for rising edge!.')
56
57 def wait(self):
58 ''' wait for user respond '''
59
60 user_input = input("Press Enter to continue, P to print, or Q to quit ").lower().strip()
61 if user_input == "p":
62 filename = self.pdfFilepdfFile + '.pdf'
63 self.c1.SaveAs(filename)
64 print('Canvas saved to file:', filename)
65 return False
66 elif user_input == "q":
67 evtMetaData = Belle2.PyStoreObj('EventMetaData')
68 evtMetaData.obj().setEndOfData()
69 return True
70 else:
71 return False
72
73 def draw(self, k, event, run):
74 ''' Draw histograms and wait for user respond '''
75
76 self.c1.Clear()
77 self.c1.Divide(1, 4)
78 title = 'WF event display:' + ' run ' + str(run) + ' event ' \
79 + str(event)
80 self.c1.SetTitle(title)
81 for i in range(k):
82 self.c1.cd(i + 1)
83 self.hist[i].Draw()
84 if self.gpaint[i].GetN() > 0:
85 self.gpaint[i].Draw("same")
86 for graph in self.graphs[i]:
87 graph.Draw("sameP")
88 for tlpfgraph in self.tlpfgraphs[i]:
89 tlpfgraph.Draw("sameP")
90 self.c1.Update()
91 stat = self.wait()
92 return stat
93
94 def set_gpaint(self, waveform, k):
95 ''' construct a graph to paint waveform differently after window discontinuity '''
96
97 if waveform.areWindowsInOrder():
98 self.gpaint[k].Set(0)
99
100 windows = waveform.getStorageWindows()
101 i0 = windows.size()
102 for i in range(1, windows.size()):
103 diff = windows[i] - windows[i - 1]
104 if diff < 0:
105 diff += 512
106 if diff != 1:
107 i0 = i
108 break
109 n = (windows.size() - i0) * 64 * 2
110 self.gpaint[k].Set(n)
111 low = i0 * 64
112 for i in range(low, self.hist[k].GetNbinsX()):
113 x = self.hist[k].GetBinCenter(i + 1)
114 dx = self.hist[k].GetBinWidth(i + 1) / 2
115 y = self.hist[k].GetBinContent(i + 1)
116 ii = (i - low) * 2
117 self.gpaint[k].SetPoint(ii, x - dx, y)
118 self.gpaint[k].SetPoint(ii + 1, x + dx, y)
119
120 def event(self):
121 '''
122 Event processor: fill the histograms, display them,
123 wait for user respond.
124 '''
125
126 evtMetaData = Belle2.PyStoreObj('EventMetaData')
127 event = evtMetaData.obj().getEvent()
128 run = evtMetaData.obj().getRun()
129
130 waveforms = Belle2.PyStoreArray('TOPRawWaveforms')
131
132 k = 0
133 # nHits = 0
134 fname = 'waveforms_run' + str(run) + '_event' + str(event) + '_chan'
135
136 self.pdfFilepdfFile = fname
137 for waveform in waveforms:
138 slot = waveform.getModuleID()
139 chan = waveform.getChannel()
140 self.pdfFilepdfFile = self.pdfFilepdfFile + '-S' + str(slot) + '_' + str(chan)
141 wf = waveform.getWaveform()
142 self.hist[k].Reset()
143 numSamples = waveform.getSize()
144 startSample = waveform.getStartSample()
145 self.hist[k].SetBins(numSamples, float(startSample), float(startSample + numSamples))
146 title = 'S' + str(slot) + ' chan ' + str(chan) + ' win'
147 if waveform.getStorageWindows().empty():
148 title += ' ' + str(waveform.getStorageWindow())
149 else:
150 for window in waveform.getStorageWindows():
151 title += ' ' + str(window)
152 self.hist[k].SetTitle(title)
153 self.hist[k].SetStats(False)
154 self.hist[k].SetLineColor(8)
155
156 i = 0
157 for sample in wf:
158 i = i + 1
159 self.hist[k].SetBinContent(i, sample)
160
161 self.gpaint[k].SetLineColor(9)
162 self.set_gpaint(waveform, k)
163
164 rawDigits = waveform.getRelationsWith("TOPRawDigits")
165 self.graphs[k].clear()
166 self.tlpfgraphs[k].clear()
167 for raw in rawDigits:
168 graph = TGraph(5)
169 graph.SetMarkerStyle(24)
170 graph.SetPoint(0, raw.getSampleRise() + 0.5, raw.getValueRise0())
171 graph.SetPoint(1, raw.getSampleRise() + 1.5, raw.getValueRise1())
172 graph.SetPoint(2, raw.getSamplePeak() + 0.5, raw.getValuePeak())
173 graph.SetPoint(3, raw.getSampleFall() + 0.5, raw.getValueFall0())
174 graph.SetPoint(4, raw.getSampleFall() + 1.5, raw.getValueFall1())
175 if raw.isMadeOffline():
176 graph.SetMarkerStyle(5)
177 if raw.isFEValid() and not raw.isAtWindowDiscontinuity():
178 graph.SetMarkerColor(2)
179 if raw.isPedestalJump():
180 graph.SetMarkerColor(3)
181 else:
182 graph.SetMarkerColor(4)
183 self.graphs[k].append(graph)
184
185 tlpfResult = raw.getRelated("TOPTemplateFitResults")
186 if tlpfResult:
187 tlpfgraph = TGraph(2)
188 tlpfgraph.SetMarkerStyle(25)
189 tlpfgraph.SetPoint(0, tlpfResult.getRisingEdge(),
190 tlpfResult.getAmplitude() / 2 + tlpfResult.getBackgroundOffset())
191 tlpfgraph.SetPoint(1, tlpfResult.getRisingEdge(), tlpfResult.getBackgroundOffset())
192 print('Template Fit Chisquare: ', tlpfResult.getChisquare())
193 self.tlpfgraphs[k].append(tlpfgraph)
194
195 k = k + 1
196 if k == 4:
197 stat = self.draw(k, event, run)
198 if stat:
199 return
200 k = 0
201 self.pdfFilepdfFile = fname
202
203 if k > 0:
204 self.draw(k, event, run)
205
206
207b2.set_log_level(b2.LogLevel.INFO)
208
209# Define a global tag
210b2.conditions.override_globaltags()
211b2.conditions.append_globaltag('online')
212
213# Create path
214main = b2.create_path()
215
216# input
217# roinput = b2.register_module('SeqRootInput') # sroot files
218roinput = b2.register_module('RootInput') # root files
219main.add_module(roinput)
220
221# conversion from RawCOPPER or RawDataBlock to RawTOP (needed only in PocketDAQ)
222rawconverter = b2.register_module('Convert2RawDet')
223main.add_module(rawconverter)
224
225# Initialize TOP geometry parameters (creation of Geant geometry is not needed)
226main.add_module('TOPGeometryParInitializer')
227
228# Unpacking
229unpack = b2.register_module('TOPUnpacker')
230main.add_module(unpack)
231
232# Add multiple hits from waveforms
233featureExtractor = b2.register_module('TOPWaveformFeatureExtractor')
234main.add_module(featureExtractor)
235
236# Convert to TOPDigits
237converter = b2.register_module('TOPRawDigitConverter')
238converter.param('useSampleTimeCalibration', False)
239converter.param('useChannelT0Calibration', False)
240converter.param('useModuleT0Calibration', False)
241converter.param('useCommonT0Calibration', False)
242main.add_module(converter)
243
244# Display waveforms
245main.add_module(WFDisplay())
246
247# Print progress
248progress = b2.register_module('Progress')
249main.add_module(progress)
250
251# Process events
252b2.process(main)
253
254# Print statistics
255print(b2.statistics)
A (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:72
a (simplified) python wrapper for StoreObjPtr.
Definition: PyStoreObj.h:67
def draw(self, k, event, run)
str pdfFile
output file name
list graphs
graphs for FE points
list gpaint
graphs for painting waveforms after the gap in window number
list tlpfgraphs
graphs for template fit points
list hist
1D histograms
def set_gpaint(self, waveform, k)