Belle II Software  release-05-01-25
studyLaserLight.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 # ------------------------------------------------------------------------
5 # Module to produce the laser time histograms that serve as input to the laser
6 # resolution fitter
7 #
8 # Contributors: Umberto Tamponi (tamponi@to.infn.it)
9 #
10 # usage: basf2 studyLaserResolution.py dbaddress (path|none) type (local|pocket|root)
11 # output_name.root path_to_sroot run1 run2 ... runN
12 # The run number accepts wildcards
13 # ------------------------------------------------------------------------
14 
15 
16 from basf2 import *
17 import sys
18 import glob
19 from ROOT import Belle2
20 from ROOT import TH1F, TH2F, TF1, TFile, TGraphErrors, TSpectrum, TCanvas
21 import ROOT
22 import pylab
23 import numpy
24 import time
25 from laserResolutionTools import fitLaserResolution, plotLaserResolution
26 
27 
29 
30  ''' Module to study resolution and performance of the top laser calibration.'''
31 
32 
33  h_LaserTimingVSChannel = TH2F(
34  'LaserTimingVSChannel',
35  'Laser timing in as function of the channel number',
36  512 * 16,
37  0,
38  512 * 16,
39  10000,
40  0.,
41  100) # 10 ps binning
42 
43  h_LaserTimingVSChannelOneSlot = TH2F(
44  'LaserTimingVSChannelOneSlot',
45  'Laser timing in as function of the channel number',
46  512,
47  0,
48  512,
49  10000,
50  0.,
51  100) # 10 ps binning
52 
53 
54  h_crossOccupancy = [[TH2F(
55  'crossOccupancy_' + str(slotA) + '_' + str(slotB),
56  ' ',
57  200,
58  0,
59  200,
60  200,
61  0.,
62  200) for slotA in range(16)] for slotB in range(16)]
63 
64 
65  outname = 'outStudyLaserResolution.root'
66 
67 
68  m_ignoreNotCalibrated = True
69 
70  m_runOnData = True
71 
72 
73  m_maxWidth = 3.
74 
75  m_minWidth = 0.5
76 
77  m_maxAmp = 700.
78 
79  m_minAmp = 250.
80 
81  m_mcCorrectionsFile = '/group/belle2/group/detector/TOP/calibration/MCreferences/t0MC.root'
82 
83  m_MCPeaks = [[]]
84 
85  def setOutputName(self, outputname):
86  ''' Sets the output file name '''
87 
88  self.outname = outputname
89 
90  def setMaxWidth(self, maxWidth):
91  ''' Sets the maximum calpulse width '''
92 
93  self.m_maxWidth = maxWidth
94 
95  def setMinWidth(self, minWidth):
96  ''' Sets the minimum calpulse width '''
97 
98  self.m_minWidth = minWidth
99 
100  def setMaxAmp(self, maxAmp):
101  ''' Sets the maximum calpulse amplitude '''
102 
103  self.m_maxAmp = maxAmp
104 
105  def setMinAmp(self, minAmp):
106  ''' Sets the minimum calpulse amplitude '''
107 
108  self.m_minAmp = minAmp
109 
110  def setMCCorrectionsFile(self, MCfile):
111  ''' Sets the file containing the MC correction'''
112 
113  self.m_mcCorrectionsFile = MCfile
114 
115  def ignoreNotCalibrated(self, ignoreNotCal):
116  ''' Sets the flag to ingore the hits without calibration '''
117 
118  self.m_ignoreNotCalibrated = ignoreNotCal
119 
120  def event(self):
121  ''' Event processor: fill histograms '''
122 
123  digits = Belle2.PyStoreArray('TOPDigits')
124  nhits = [0 for i in range(16)]
125  for digit in digits:
126  if(not self.ignoreNotCalibrated and not digit.isTimeBaseCalibrated()):
127  continue
128  if (digit.getHitQuality() == 1 and
129  digit.getPulseWidth() > self.m_minWidth and digit.getPulseWidth() < self.m_maxWidth and
130  digit.getPulseHeight() > self.m_minAmp and digit.getPulseHeight() < self.m_maxAmp):
131  slotID = digit.getModuleID()
132  hwchan = digit.getChannel()
133  self.h_LaserTimingVSChannel.Fill(512 * (slotID - 1) + hwchan, digit.getTime())
134  simhits = digit.getRelationsWith('TOPSimHits')
135  nhits[slotID - 1] = nhits[slotID - 1] + 1
136  for simhit in simhits:
137  self.h_LaserTimingVSChannelOneSlot.Fill(hwchan, simhit.getTime())
138  for slotA in range(16):
139  for slotB in range(16):
140  self.h_crossOccupancy[slotA][slotB].Fill(nhits[slotA], nhits[slotB])
141 
142  def terminate(self):
143  ''' Write histograms to file, fills and fits the resolution plots'''
144  tfile = TFile(self.outname, 'recreate')
145  self.h_LaserTimingVSChannel.Write()
146  self.h_LaserTimingVSChannelOneSlot.Write()
147  for slotA in range(16):
148  for slotB in range(16):
149  self.h_crossOccupancy[slotA][slotB].Write()
150  tfile.Close()
151 
152 
153 argvs = sys.argv
154 print('usage: basf2', argvs[0], 'runNumber outfileName')
155 
156 lookBack = argvs[1] # lookbackWindows setting
157 dbaddress = argvs[2] # path to the calibration DB (absolute path or 'none')
158 datatype = argvs[3] # data type ('pocket' or 'local' or 'root', if root files have to be analyzed)
159 outfile = argvs[4] # output name
160 folder = argvs[5] # folder containing the sroot files
161 runnumbers = sys.argv[6:] # run numbers
162 
163 files = []
164 for runnumber in runnumbers:
165  if datatype == 'root':
166  files += [f for f in glob.glob(str(folder) + '/*' + str(runnumber) + '*.root')]
167  else:
168  # print('running on sroot files in folder ' + glob.glob(str(folder))
169  files += [f for f in glob.glob(str(folder) + '/*' + str(runnumber) + '*.sroot')]
170 for fname in files:
171  print("file: " + fname)
172 
173 if dbaddress != 'none':
174  print("using local DB " + dbaddress)
175  reset_database()
176  use_local_database(dbaddress + "/localDB.txt", dbaddress)
177 else:
178  print("database not set. Continuing without calibrations")
179 
180 # Suppress messages and warnings during processing
181 set_log_level(LogLevel.ERROR)
182 
183 # Define a global tag (note: the one given bellow can be out-dated!)
184 use_central_database('data_reprocessing_proc8')
185 
186 # Create path
187 main = create_path()
188 
189 # input
190 if datatype == 'root':
191  roinput = register_module('RootInput')
192  roinput.param('inputFileNames', files)
193  main.add_module(roinput)
194 else:
195  roinput = register_module('SeqRootInput')
196  roinput.param('inputFileNames', files)
197  main.add_module(roinput)
198 
199 # conversion from RawCOPPER or RawDataBlock to RawDetector objects
200 if datatype == 'pocket':
201  print('pocket DAQ data assumed')
202  converter = register_module('Convert2RawDet')
203  main.add_module(converter)
204 
205 # Initialize TOP geometry parameters (creation of Geant geometry is not needed)
206 main.add_module('TOPGeometryParInitializer')
207 
208 if datatype != 'root':
209  # Unpacking (format auto detection works now)
210  unpack = register_module('TOPUnpacker')
211  main.add_module(unpack)
212 
213  # Add multiple hits by running feature extraction offline
214  featureExtractor = register_module('TOPWaveformFeatureExtractor')
215  main.add_module(featureExtractor)
216 
217  # Convert to TOPDigits
218  converter = register_module('TOPRawDigitConverter')
219  if dbaddress == 'none':
220  print("Not using Calibrations")
221  converter.param('useSampleTimeCalibration', False)
222  converter.param('useAsicShiftCalibration', False)
223  converter.param('useChannelT0Calibration', False)
224  converter.param('useModuleT0Calibration', False)
225  else:
226  print("Using Calibrations")
227  converter.param('useSampleTimeCalibration', True)
228  converter.param('useAsicShiftCalibration', True)
229  converter.param('useChannelT0Calibration', True)
230  converter.param('useModuleT0Calibration', True)
231  converter.param('useCommonT0Calibration', False)
232  converter.param('calibrationChannel', -1) # do not specify the calpulse channel
233  converter.param('lookBackWindows', int(lookBack)) # in number of windows
234  main.add_module(converter)
235 
236 # resolution plotter
237 resolutionModule = TOPLaserHistogrammerModule()
238 resolutionModule.setOutputName(outfile)
239 resolutionModule.setMinWidth(0.1) # good TOPDigit selection
240 resolutionModule.setMaxWidth(999) # good TOPDigit selection
241 resolutionModule.setMinAmp(100) # good TOPDigit selection
242 resolutionModule.setMaxAmp(999) # good TOPDigit selection
243 if dbaddress == 'none':
244  resolutionModule.ignoreNotCalibrated(True)
245 else:
246  resolutionModule.ignoreNotCalibrated(False)
247 main.add_module(resolutionModule)
248 
249 # Show progress of processing
250 progress = register_module('Progress')
251 main.add_module(progress)
252 
253 # Process events
254 process(main)
255 
256 # Print call statistics
257 print(statistics)
258 print(statistics(statistics.TERM))
259 
260 
261 fitLaserResolution(dataFile=outfile, outputFile='laserResolutionResults.root', pdfType='cb', saveFits=True)
262 plotLaserResolution()
studyLaserLight.TOPLaserHistogrammerModule.h_LaserTimingVSChannel
h_LaserTimingVSChannel
Width as function of the sample number in each channel.
Definition: studyLaserLight.py:33
studyLaserLight.TOPLaserHistogrammerModule.setOutputName
def setOutputName(self, outputname)
Definition: studyLaserLight.py:85
studyLaserLight.TOPLaserHistogrammerModule.m_maxAmp
int m_maxAmp
minimum amplitude to accept a TOPDigit
Definition: studyLaserLight.py:77
studyLaserLight.TOPLaserHistogrammerModule.h_crossOccupancy
list h_crossOccupancy
cross occupancy
Definition: studyLaserLight.py:54
studyLaserLight.TOPLaserHistogrammerModule.m_maxWidth
int m_maxWidth
maximum width to accept a TOPDigit
Definition: studyLaserLight.py:73
studyLaserLight.TOPLaserHistogrammerModule.ignoreNotCalibrated
def ignoreNotCalibrated(self, ignoreNotCal)
Definition: studyLaserLight.py:115
studyLaserLight.TOPLaserHistogrammerModule.setMaxWidth
def setMaxWidth(self, maxWidth)
Definition: studyLaserLight.py:90
studyLaserLight.TOPLaserHistogrammerModule.setMinAmp
def setMinAmp(self, minAmp)
Definition: studyLaserLight.py:105
studyLaserLight.TOPLaserHistogrammerModule.outname
string outname
output root file
Definition: studyLaserLight.py:65
studyLaserLight.TOPLaserHistogrammerModule.m_minWidth
float m_minWidth
minimum width to accept a TOPDigit
Definition: studyLaserLight.py:75
studyLaserLight.TOPLaserHistogrammerModule.m_mcCorrectionsFile
string m_mcCorrectionsFile
root file with the MC distribution of the laser light, to get the light path corrections
Definition: studyLaserLight.py:81
studyLaserLight.TOPLaserHistogrammerModule.event
def event(self)
Definition: studyLaserLight.py:120
studyLaserLight.TOPLaserHistogrammerModule.setMCCorrectionsFile
def setMCCorrectionsFile(self, MCfile)
Definition: studyLaserLight.py:110
studyLaserLight.TOPLaserHistogrammerModule.m_ignoreNotCalibrated
bool m_ignoreNotCalibrated
ignores the hits wthout calibration
Definition: studyLaserLight.py:68
studyLaserLight.TOPLaserHistogrammerModule.m_minAmp
int m_minAmp
minimum amplitude to accept a TOPDigit
Definition: studyLaserLight.py:79
studyLaserLight.TOPLaserHistogrammerModule.h_LaserTimingVSChannelOneSlot
h_LaserTimingVSChannelOneSlot
Laser timing in as function of the channel number.
Definition: studyLaserLight.py:43
studyLaserLight.TOPLaserHistogrammerModule.setMaxAmp
def setMaxAmp(self, maxAmp)
Definition: studyLaserLight.py:100
studyLaserLight.TOPLaserHistogrammerModule
Definition: studyLaserLight.py:28
studyLaserLight.TOPLaserHistogrammerModule.terminate
def terminate(self)
Definition: studyLaserLight.py:142
Belle2::PyStoreArray
a (simplified) python wrapper for StoreArray.
Definition: PyStoreArray.h:58
studyLaserLight.TOPLaserHistogrammerModule.setMinWidth
def setMinWidth(self, minWidth)
Definition: studyLaserLight.py:95