Belle II Software development
bklm-dst.py
1#!/usr/bin/env python3
2
3
10
11# Purpose:
12# Analyze a DST ROOT file or an SROOT file and write resulting histograms/scatterplots to
13# ROOT and PDF files. This script cannot analyze MDST files because they don't contain RawKLMs.
14#
15# Prerequisite (on kekcc):
16# Before running this script, type
17# source /cvmfs/belle.cern.ch/tools/b2setup release-02-01-00 <or higher release>
18# then verify that the corresponding proper global tag is used near the end of this script.
19# (Global tags are tabulated at https://xwiki.desy.de/xwiki/rest/p/88ebe)
20# The external python script bklmDB.py must be in the same folder as this script.
21#
22# Usage:
23# basf2 bklm-dst.py -- -e # -r # -i infilename -n # -d # -m # -t tagname
24# You need the '--' before these options to tell basf2 that these are options to this script.
25# Required arguments:
26# either -i infilename or -e # -r # (can supply all three)
27# -i infilename to specify the full pathname of the input ROOT DST file (no default)
28# -e # to specify the experiment number (no default)
29# -r # to specify the run number (no default)
30# Optional arguments:
31# -s # to select events with all (0) or exactly one (1) or two or more (2) entries/channel (default is 0)
32# -n # to specify the maximum number of events to analyze (no default -> all events)
33# --verbosity # to specify how many histograms to save in the PDF file (0=minimal, 1=all) [default is 0]
34# -d # to specify the maximum number of event displays (default is 0)
35# -m # to specify the minimum number of RPC BKLMHit2ds in any one sector (default is 4)
36# -t tagName to specify the name of conditions-database global tag (no default)
37# -l # to specify whether to use legacy time calculations (1) or not (0) (default is 0)
38#
39# Input:
40# ROOT DST file written by basf2 (may include multiple folios for one expt/run). For example,
41# /ghi/fs01/belle2/bdata/Data/Raw/e0003/r04794/sub00/physics.0003.r04794.HLT1.f*.root
42# /ghi/fs01/belle2/bdata/Data/Raw/e0004/r06380/sub00/cosmic.0004.r06380.HLT1.f00000.root
43# /ghi/fs01/belle2/bdata/Data/Raw/e0007/r01650/sub00/cosmic.0007.r01650.HLT1.f*.root
44#
45# Output:
46# ROOT histogram file named bklmHists-e#r#.root, using the experiment number and run number
47# PDF file named bklmHists-e#r#.pdf, using the experiment number and run number
48#
49
50import basf2
51import sys
52import re
53import EventInspector
54import rawdata
55from optparse import OptionParser
56import glob
57
58parser = OptionParser()
59parser.add_option('-i', '--inputfile',
60 dest='infilename', default='',
61 help='Input [S]ROOT filename [no default]')
62parser.add_option('-e', '--experiment',
63 dest='eNumber', default='',
64 help='Experiment number [no default]')
65parser.add_option('-r', '--run',
66 dest='rNumber', default='',
67 help='Run number [no default]')
68parser.add_option('-n', '--nEvents',
69 dest='nEvents', default='',
70 help='Max # of analyzed events [no default]')
71parser.add_option('-s', '--singleEntry', type="int",
72 dest='singleEntry', default=0,
73 help='Select events with any (0) or exactly one (1) or more than one (2) entries/channel [0]')
74parser.add_option('--verbosity', type="int",
75 dest='verbosity', default=0,
76 help='How many histograms to save (0=minimal, 1=all) [0]')
77parser.add_option('-d', '--displays', type="int",
78 dest='displays', default=0,
79 help='Max # of displayed events [0]')
80parser.add_option('-v', '--view', type="int",
81 dest='view', default=2,
82 help='View event displays using one-dimensional (1) or two-dimensional (2) hits [2]')
83parser.add_option('-m', '--minRPCHits', type="int",
84 dest='minRPCHits', default=4,
85 help='Min # of RPC hits in any one sector to display the event [4]')
86parser.add_option('-l', '--legacyTimes', type="int",
87 dest='legacyTimes', default=0,
88 help='Perform legacy time calculations (1) or not (0) for BKLMHit1ds,2ds [0]')
89parser.add_option('-t', '--tagName',
90 dest='tagName', default='data_reprocessing_prompt',
91 help='Conditions-database global-tag name [data_reprocessing_prompt]')
92(options, args) = parser.parse_args()
93
94singleEntry = options.singleEntry
95if singleEntry < 0 or singleEntry > 2:
96 singleEntry = 0
97
98maxCount = -1
99if options.nEvents != '':
100 maxCount = int(options.nEvents)
101 if maxCount <= 0:
102 print("Maximum number of events to analyze is", maxCount, " - nothing to do.")
103 sys.exit()
104
105verbosity = options.verbosity
106
107view = options.view
108
109maxDisplays = options.displays
110
111minRPCHits = options.minRPCHits
112
113legacyTimes = options.legacyTimes
114
115tagName = options.tagName
116
117inputName = ''
118exp = ''
119run = ''
120if options.infilename != '':
121 inputName = re.sub(r"HLT.\.f0....", "HLT*.f*", options.infilename)
122 fileList = glob.glob(inputName)
123 if len(fileList) == 0:
124 print(f"No file(s) match {inputName}")
125 sys.exit()
126if options.eNumber != '':
127 if not options.eNumber.isdecimal():
128 print(f"Experiment number ({options.eNumber}) is not valid")
129 sys.exit()
130 exp = f'{int(options.eNumber):04d}'
131else:
132 eStart = inputName.find('/e') + 2
133 if eStart < 0:
134 print("Input filename does not contain the required experiment number")
135 sys.exit()
136 eEnd = inputName.find('/', eStart)
137 exp = inputName[eStart:eEnd]
138 if not exp.isdecimal():
139 print(f"Input filename's experiment number ({exp}) is not valid")
140 sys.exit()
141if options.rNumber != '':
142 if not options.rNumber.isdecimal():
143 print(f"Run number ({options.rNumber}) is not valid")
144 sys.exit()
145 run = f'{int(options.rNumber):05d}'
146else:
147 rStart = inputName.find('/r') + 2
148 if rStart < 0:
149 print("Input filename does not contain the required run number")
150 sys.exit()
151 rEnd = inputName.find('/', rStart)
152 run = inputName[rStart:rEnd]
153 if not run.isdecimal():
154 print(f"Input filename's run number ({run}) is not valid")
155 sys.exit()
156if len(inputName) == 0:
157 inputName = f'/ghi/fs01/belle2/bdata/Data/Raw/e{exp}/r{run}/sub00/*.{exp}.{run}.HLT*.f*.root'
158 fileList = glob.glob(inputName)
159 if len(fileList) == 0:
160 print(f"No file(s) found for experiment <{options.eNumber}> run <{options.rNumber}>")
161 sys.exit()
162
163suffix = '' if singleEntry == 0 else '-singleEntry' if singleEntry == 1 else '-multipleEntries'
164histName = f'bklmHists-e{exp}r{run}{suffix}.root'
165pdfName = f'bklmPlots-e{exp}r{run}{suffix}.pdf'
166eventPdfName = f'bklmEvents{view}D-e{exp}r{run}{suffix}.pdf'
167
168if maxCount >= 0:
169 print('bklm-dst: exp=' + exp + ' run=' + run + ' input=' + inputName + '. Analyze', maxCount, 'events using ' + tagName)
170else:
171 print('bklm-dst: exp=' + exp + ' run=' + run + ' input=' + inputName + '. Analyze all events using ' + tagName)
172
173basf2.conditions.prepend_globaltag(tagName)
174
175main = basf2.create_path()
176if inputName.find(".sroot") >= 0:
177 main.add_module('SeqRootInput', inputFileNames=inputName)
178else:
179 main.add_module('RootInput', inputFileName=inputName)
180main.add_module('ProgressBar')
181
182eventInspector = EventInspector(exp, run, histName, pdfName, eventPdfName, verbosity,
183 maxDisplays, minRPCHits, legacyTimes, singleEntry, view)
184rawdata.add_unpackers(main, components=['KLM'])
185main.add_module('KLMReconstructor')
186main.add_module(eventInspector)
187
188basf2.process(main, max_event=maxCount)
189print(basf2.statistics)
def add_unpackers(path, components=None, writeKLMDigitRaws=False, addTOPRelations=False)
Definition: rawdata.py:67