Belle II Software  release-08-01-10
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://confluence.desy.de/display/BI/Global+Tag+%28GT%29+page)
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 
50 import basf2
51 import sys
52 import re
53 import EventInspector
54 import rawdata
55 from optparse import OptionParser
56 import glob
57 
58 parser = OptionParser()
59 parser.add_option('-i', '--inputfile',
60  dest='infilename', default='',
61  help='Input [S]ROOT filename [no default]')
62 parser.add_option('-e', '--experiment',
63  dest='eNumber', default='',
64  help='Experiment number [no default]')
65 parser.add_option('-r', '--run',
66  dest='rNumber', default='',
67  help='Run number [no default]')
68 parser.add_option('-n', '--nEvents',
69  dest='nEvents', default='',
70  help='Max # of analyzed events [no default]')
71 parser.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]')
74 parser.add_option('--verbosity', type="int",
75  dest='verbosity', default=0,
76  help='How many histograms to save (0=minimal, 1=all) [0]')
77 parser.add_option('-d', '--displays', type="int",
78  dest='displays', default=0,
79  help='Max # of displayed events [0]')
80 parser.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]')
83 parser.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]')
86 parser.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]')
89 parser.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 
94 singleEntry = options.singleEntry
95 if singleEntry < 0 or singleEntry > 2:
96  singleEntry = 0
97 
98 maxCount = -1
99 if 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 
105 verbosity = options.verbosity
106 
107 view = options.view
108 
109 maxDisplays = options.displays
110 
111 minRPCHits = options.minRPCHits
112 
113 legacyTimes = options.legacyTimes
114 
115 tagName = options.tagName
116 
117 inputName = ''
118 exp = ''
119 run = ''
120 if 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()
126 if 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}'
131 else:
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()
141 if 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}'
146 else:
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()
156 if 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 
163 suffix = '' if singleEntry == 0 else '-singleEntry' if singleEntry == 1 else '-multipleEntries'
164 histName = f'bklmHists-e{exp}r{run}{suffix}.root'
165 pdfName = f'bklmPlots-e{exp}r{run}{suffix}.pdf'
166 eventPdfName = f'bklmEvents{view}D-e{exp}r{run}{suffix}.pdf'
167 
168 if maxCount >= 0:
169  print('bklm-dst: exp=' + exp + ' run=' + run + ' input=' + inputName + '. Analyze', maxCount, 'events using ' + tagName)
170 else:
171  print('bklm-dst: exp=' + exp + ' run=' + run + ' input=' + inputName + '. Analyze all events using ' + tagName)
172 
173 basf2.conditions.prepend_globaltag(tagName)
174 
175 main = basf2.create_path()
176 if inputName.find(".sroot") >= 0:
177  main.add_module('SeqRootInput', inputFileNames=inputName)
178 else:
179  main.add_module('RootInput', inputFileName=inputName)
180 main.add_module('ProgressBar')
181 
182 eventInspector = EventInspector(exp, run, histName, pdfName, eventPdfName, verbosity,
183  maxDisplays, minRPCHits, legacyTimes, singleEntry, view)
184 rawdata.add_unpackers(main, components=['KLM'])
185 main.add_module('KLMReconstructor')
186 main.add_module(eventInspector)
187 
188 basf2.process(main, max_event=maxCount)
189 print(basf2.statistics)
def add_unpackers(path, components=None, writeKLMDigitRaws=False, addTOPRelations=False)
Definition: rawdata.py:67