Belle II Software development
bklm-pocketdaq.py
1#!/usr/bin/env python3
2
3
10
11# Purpose:
12# Analyze PocketDAQ data created by the test stand at Indiana University
13# and write a PDF file of the resulting histograms/scatterplots.
14#
15# Prerequisites (on kekcc):
16# Before running this script, type
17# source /cvmfs/belle.cern.ch/tools/b2setup release-02-01-00 <or higher release>
18# and translate the test-stand raw data file to a ROOT file using Richard Peschke's app
19#
20# Usage:
21# basf2 bklm-pocketdaq.py -- -i infilename -e # -r # -n # -f #
22# You need the '--' before these options to tell basf2 that these are options to this script.
23# Required argument:
24# -i infilename to specify the full pathname of the input ROOT file
25# Optional arguments:
26# -e # to specify the experiment number, e.g., -e 1 (no default)
27# -r # to specify the run number, e.g., -r 0109 (no default)
28# -n # to specify the number of events in the run to be processed (no default -> all events)
29# -f # to filter only the even-numbered events (-f 0) or the odd-numbered events (-f 1) (no default -> all events)
30#
31# Input:
32# ROOT file written by Richard Peschke's translator app whose input was a test-stand raw data file. For example,
33# /home/belle2/dbiswas/Documents/PocketDAQ/klm_offline_entpacker/build/klm_unpacker/brandon_data/dblpls_30k_fine_20190109.root
34#
35# Output:
36# ROOT histogram file named bklmHists-e#r#.root, using the experiment number and run number
37# PDF file named bklmPlots-e#r#.pdf, using the experiment number and run number
38#
39
40import EventInspectorPocketDAQ
41from ROOT import TFile
42import sys
43from optparse import OptionParser
44import glob
45
46parser = OptionParser()
47parser.add_option('-i', '--inputfile',
48 dest='infilename', default='',
49 help='Input ROOT filename [no default]')
50parser.add_option('-e', '--experiment',
51 dest='eNumber', default='',
52 help='Experiment number [no default]')
53parser.add_option('-r', '--run',
54 dest='rNumber', default='',
55 help='Run number [no default]')
56parser.add_option('-n', '--nEvents',
57 dest='nEvents', default='',
58 help='# of events to process [no default]')
59parser.add_option('-f', '--filter',
60 dest='eventFilter', default='',
61 help='Event filter (0=evens, 1=odds) [no default]')
62(options, args) = parser.parse_args()
63
64maxCount = -1
65if options.nEvents != '':
66 maxCount = int(options.nEvents)
67 if maxCount <= 0:
68 print("Maximum number of events to analyze is", maxCount, " - nothing to do.")
69 sys.exit()
70
71eventFilter = -1
72if (options.eventFilter == '0') or (options.eventFilter == '1'):
73 eventFilter = int(options.eventFilter)
74
75inputName = ''
76exp = ''
77run = ''
78if options.infilename != '':
79 inputName = options.infilename
80 fileList = glob.glob(inputName)
81 if len(fileList) == 0:
82 print(f"No file(s) match {inputName}")
83 sys.exit()
84 inputName = fileList[0].replace("f00000", "f*")
85else:
86 print(f"Missing input filename (required parameter) for experiment <{options.eNumber}> run <{options.rNumber}>")
87 sys.exit()
88if not options.eNumber.isdecimal():
89 print(f"Experiment number ({options.eNumber}) is not valid")
90 sys.exit()
91exp = f'{int(options.eNumber):04d}'
92if not options.rNumber.isdecimal():
93 print(f"Run number ({options.rNumber}) is not valid")
94 sys.exit()
95run = f'{int(options.rNumber):05d}'
96
97infile = TFile(fileList[0])
98histName = f'bklmHists-e{exp}r{run}.root'
99pdfName = f'bklmPlots-e{exp}r{run}.pdf'
100
101if eventFilter == 0:
102 print('bklm-pocketdaq: exp=' + exp + ' run=' + run + ' input=', options.infilename + ' - processing even-numbered events')
103elif eventFilter == 1:
104 print('bklm-pocketdaq: exp=' + exp + ' run=' + run + ' input=', options.infilename + ' - processing odd-numbered events')
105else:
106 print('bklm-pocketdaq: exp=' + exp + ' run=' + run + ' input=', options.infilename)
107
108inspector = EventInspectorPocketDAQ(exp, run, histName, pdfName)
109inspector.initialize()
110inspector.beginRun()
111count = 0
112eventNumber = -1
113eventHits = []
114tt_ctime = 0
115raw_time = 0
116for row in infile.Get('KLM_raw_hits'):
117 # (optional) stop processing after maxCount
118 if (maxCount > 0) and (row.eventNr >= maxCount):
119 break
120 # (optional) process only the filtered events
121 if (eventFilter >= 0) and (row.eventNr % 2) != eventFilter:
122 continue
123 items = (row.lane, row.channel, row.axis, row.ctime, row.tdc, row.charge)
124 newEventNumber = row.eventNr
125 if newEventNumber == eventNumber:
126 eventHits.append(items)
127 else:
128 if eventNumber >= 0:
129 inspector.event(eventHits, tt_ctime, raw_time)
130 count = count + 1
131 eventNumber = newEventNumber
132 if row.broken != 0:
133 print(f'*** Event {eventNumber} is broken!')
134 eventHits.clear()
135 eventHits.append(items)
136 tt_ctime = row.tt_ctime << 3
137 raw_time = (row.raw_time >> 16) << 3
138if eventNumber >= 0:
139 inspector.event(eventHits, tt_ctime, raw_time)
140inspector.endRun()
141inspector.terminate()
142print('# of analyzed events = ', count)