21 from ROOT
import TMath
22 from plotInterimFEDataNtuple
import plotInterimFEDataNtupleSummary
24 parser = argparse.ArgumentParser(description=
"Create ntuple file and plots from interimFE data")
25 parser.add_argument(
"inputFile", nargs=
'?', default=
"NoInputFile",
26 help=
"input sroot file name")
27 parser.add_argument(
"--outputFile", default=
"NoOutputFile",
28 help=
"output root file name")
29 parser.add_argument(
"--calChannel", type=int, default=0,
30 help=
"asic channel number where calibration signals are injected [0-7]")
35 help=
"lookback windows to redefine rawTime so that t=0 is beginning of search windows."
36 " Give 0 (default) not to allow the redefinition.")
37 parser.add_argument(
"--heightThreshold", type=int, default=40,
38 help=
"pulse height threshold in offline feature extraction in a unit of ADC counts")
39 parser.add_argument(
"--noOfflineFE", action=
"store_true", default=
False,
40 help=
"Use only online FE hits, and do not use waveform data")
41 parser.add_argument(
"--saveWaveform", action=
"store_true", default=
False,
42 help=
"Save waveform data in the output ntuple file")
43 parser.add_argument(
"--globalDAQ", action=
"store_true", default=
False,
44 help=
"Force to assume global DAQ data.")
45 parser.add_argument(
"--pocketDAQ", action=
"store_true", default=
False,
46 help=
"Force to assume global DAQ data.")
47 parser.add_argument(
"--skipPlot", action=
"store_true", default=
False,
48 help=
"Skip making summary plot.")
49 parser.add_argument(
"--interim", action=
"store_true", default=
False,
50 help=
"process data taken with interimFE FW")
51 args = parser.parse_args()
53 if args.inputFile ==
"NoInputFile":
54 print(
"Create a flat ntuple file from sroot data file(s) taken with interimFE firmware and plots for quick data quality check.")
56 print(
"basf2 makeTOPDigitNtuple.py (input_filename.sroot) [--arg --outputFile output_ntuple.root]")
57 print(
" [--arg --calChannel asicCh]")
58 print(
" [--arg --lookbackWindows windows]")
59 print(
" [--arg --heightThreshold threshold]")
60 print(
" [--arg --noOfflineFE] [--arg --saveWaveform]")
61 print(
" [--arg --globalDAQ] [--arg --pocketDAQ]")
62 print(
" [--arg --skipPlot] [--arg --interim]")
63 print(
"*Switching of local/global run and output file name is automatically given as folows if it is not specified:")
64 print(
" runXXXXXX_slotYY_ntuple.root (local run with PocketDAQ)")
65 print(
" or top.XXXXX.YYYYYY_ntuple.root (global run with global DAQ)")
66 print(
"*Deafult asic channel number with calibration signals is 0 (can be changed with \"--calChannel\" option.)")
67 print(
"*Deafult the number of lookback windows is 0, with which timing correction is not applied.")
68 print(
" (rawTime is corrected so that it is measured with respect to the start of search windows when lookbackWindows>0.)")
69 print(
"*Option \"--noOfflineFE\" : disable offline FE from waveform data.")
70 print(
" Calculation of reference timing is based on hit in calibration channel.")
71 print(
"* \"--saveWaveform\" : save waveform data in the output ntuple file")
72 print(
"* \"--globalDAQ\" : force to assume global DAQ data as an input file")
73 print(
"* \"--pocketDAQ\" : force to assume pocketDAQ data as an input file")
74 print(
"* \"--skipPlot\" : only processing sroot data file, do not create summary plot")
75 print(
"* \"--interim\" : process data taken with interimFE FW")
78 inputFile = args.inputFile
80 isOfflineFEDisabled = args.noOfflineFE
81 isGlobalDAQForced = args.globalDAQ
82 isPocketDAQForced = args.pocketDAQ
83 calCh = args.calChannel
84 lookbackWindows = args.lookbackWindows
85 heightThreshold = args.heightThreshold
86 isInterimFE = args.interim
87 if calCh < 0
or calCh > 7:
88 print(
"ERROR : invalid calibration asic channel :" + str(calCh))
89 print(
" (should be [0-7])")
92 if re.search(
r"run[0-9]+_slot[0-1][0-9]", inputFile):
93 outputRoot = re.search(
r"run[0-9]+_slot[0-1][0-9]", inputFile).group() +
"_ntuple.root"
94 elif re.search(
r"(top|cosmic|cdc|ecl|klm|test|debug|beam|physics|hlttest)\.[0-9]+\.[0-9]+", inputFile):
96 outputRoot = re.search(
97 r"(top|cosmic|cdc|ecl|klm|test|debug|beam|physics|hlttest)\.[0-9]+\.[0-9]+",
98 inputFile).group() +
"_ntuple.root"
100 outputRoot = inputFile +
"_ntuple.root"
102 if args.outputFile !=
"NoOutputFile":
103 outputRoot = args.outputFile
105 if isGlobalDAQForced
and (
not isPocketDAQForced):
107 elif (
not isGlobalDAQForced)
and isPocketDAQForced:
109 elif isGlobalDAQForced
and isPocketDAQForced:
110 print(
"ERROR : both of --GlobalDAQ or --PocketDAQ can not be given.")
113 print(inputFile +
" --> " + outputRoot)
114 print(
"Is global DAQ? : " + str(isGlobalDAQ))
115 print(
"OfflineFE : " + str(
not isOfflineFEDisabled))
116 print(
"Save waveform? : " + str(args.saveWaveform))
117 print(
"Cal. asic ch : " + str(calCh))
118 print(
"# of lookback windows : " + str(lookbackWindows))
120 print(
"start process...")
123 b2.use_central_database(
'data_reprocessing_proc8')
126 main = b2.create_path()
128 roinput = b2.register_module(
'SeqRootInput')
129 roinput.param(
'inputFileName', inputFile)
130 main.add_module(roinput)
133 histoman = b2.register_module(
'HistoManager')
134 histoman.param(
'histoFileName', outputRoot)
135 main.add_module(histoman)
139 converter = b2.register_module(
'Convert2RawDet')
140 main.add_module(converter)
143 main.add_module(
'TOPGeometryParInitializer')
146 unpack = b2.register_module(
'TOPUnpacker')
148 unpack.param(
'swapBytes',
True)
149 unpack.param(
'dataFormat', 0x0301)
150 main.add_module(unpack)
153 if not isOfflineFEDisabled:
154 featureExtractor = b2.register_module(
'TOPWaveformFeatureExtractor')
155 featureExtractor.param(
'threshold', heightThreshold)
156 featureExtractor.param(
'hysteresis', TMath.CeilNint(heightThreshold * 0.4 - 0.00001))
157 main.add_module(featureExtractor)
160 converter = b2.register_module(
'TOPRawDigitConverter')
161 converter.param(
'useSampleTimeCalibration',
False)
162 converter.param(
'useChannelT0Calibration',
False)
163 converter.param(
'useModuleT0Calibration',
False)
164 converter.param(
'useCommonT0Calibration',
False)
165 converter.param(
'lookBackWindows', lookbackWindows)
166 converter.param(
'storageDepth', 508)
167 converter.param(
'calibrationChannel', calCh)
169 converter.param(
'calpulseHeightMin', 300)
170 converter.param(
'calpulseHeightMax', 900)
171 converter.param(
'calpulseWidthMin', 1.2)
172 converter.param(
'calpulseWidthMax', 2.8)
173 main.add_module(converter)
175 xtalk = b2.register_module(
'TOPXTalkChargeShareSetter')
176 main.add_module(xtalk)
178 ntuple = b2.register_module(
'TOPInterimFENtuple')
179 ntuple.param(
'saveWaveform', (args.saveWaveform))
181 ntuple.param(
'useDoublePulse', (
not isOfflineFEDisabled))
182 ntuple.param(
'calibrationChannel', calCh)
185 ntuple.param(
'minHeightFirstCalPulse', 300)
186 ntuple.param(
'minHeightSecondCalPulse', 300)
187 ntuple.param(
'nominalDeltaT', 21.5)
188 ntuple.param(
'nominalDeltaTRange', 2)
189 ntuple.param(
'globalRefSlotNum', 1)
190 ntuple.param(
'globalRefAsicNum', 0)
191 ntuple.param(
'timePerWin', 23.581939)
192 main.add_module(ntuple)
195 progress = b2.register_module(
'Progress')
196 main.add_module(progress)
204 if isInterimFE
and not args.skipPlot:
205 plotInterimFEDataNtupleSummary(outputRoot, 2, isOfflineFEDisabled)