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