13 from ROOT
import TMath
14 from plotInterimFEDataNtuple
import plotInterimFEDataNtupleSummary
16 parser = argparse.ArgumentParser(description=
"Create ntuple file and plots from interimFE data")
17 parser.add_argument(
"inputFile", nargs=
'?', default=
"NoInputFile",
18 help=
"input sroot file name")
19 parser.add_argument(
"--outputFile", default=
"NoOutputFile",
20 help=
"output root file name")
21 parser.add_argument(
"--calChannel", type=int, default=0,
22 help=
"asic channel number where calibration signals are injected [0-7]")
27 help=
"lookback windows to redefine rawTime so that t=0 is beginning of search windows."
28 " Give 0 (default) not to allow the redefinition.")
29 parser.add_argument(
"--heightThreshold", type=int, default=40,
30 help=
"pulse height threshold in offline feature extraction in a unit of ADC counts")
31 parser.add_argument(
"--noOfflineFE", action=
"store_true", default=
False,
32 help=
"Use only online FE hits, and do not use waveform data")
33 parser.add_argument(
"--saveWaveform", action=
"store_true", default=
False,
34 help=
"Save waveform data in the output ntuple file")
35 parser.add_argument(
"--globalDAQ", action=
"store_true", default=
False,
36 help=
"Force to assume global DAQ data.")
37 parser.add_argument(
"--pocketDAQ", action=
"store_true", default=
False,
38 help=
"Force to assume global DAQ data.")
39 parser.add_argument(
"--skipPlot", action=
"store_true", default=
False,
40 help=
"Skip making summary plot.")
41 parser.add_argument(
"--interim", action=
"store_true", default=
False,
42 help=
"process data taken with interimFE FW")
43 args = parser.parse_args()
45 if args.inputFile ==
"NoInputFile":
46 print(
"Create a flat ntuple file from sroot data file(s) taken with interimFE firmware and plots for quick data quality check.")
48 print(
"basf2 makeTOPDigitNtuple.py (input_filename.sroot) [--arg --outputFile output_ntuple.root]")
49 print(
" [--arg --calChannel asicCh]")
50 print(
" [--arg --lookbackWindows windows]")
51 print(
" [--arg --heightThreshold threshold]")
52 print(
" [--arg --noOfflineFE] [--arg --saveWaveform]")
53 print(
" [--arg --globalDAQ] [--arg --pocketDAQ]")
54 print(
" [--arg --skipPlot] [--arg --interim]")
55 print(
"*Switching of local/global run and output file name is automatically given as folows if it is not specified:")
56 print(
" runXXXXXX_slotYY_ntuple.root (local run with PocketDAQ)")
57 print(
" or top.XXXXX.YYYYYY_ntuple.root (global run with global DAQ)")
58 print(
"*Deafult asic channel number with calibration signals is 0 (can be changed with \"--calChannel\" option.)")
59 print(
"*Deafult the number of lookback windows is 0, with which timing correction is not applied.")
60 print(
" (rawTime is corrected so that it is measured with respect to the start of search windows when lookbackWindows>0.)")
61 print(
"*Option \"--noOfflineFE\" : disable offline FE from waveform data.")
62 print(
" Calculation of reference timing is based on hit in calibration channel.")
63 print(
"* \"--saveWaveform\" : save waveform data in the output ntuple file")
64 print(
"* \"--globalDAQ\" : force to assume global DAQ data as an input file")
65 print(
"* \"--pocketDAQ\" : force to assume pocketDAQ data as an input file")
66 print(
"* \"--skipPlot\" : only processing sroot data file, do not create summary plot")
67 print(
"* \"--interim\" : process data taken with interimFE FW")
70 inputFile = args.inputFile
72 isOfflineFEDisabled = args.noOfflineFE
73 isGlobalDAQForced = args.globalDAQ
74 isPocketDAQForced = args.pocketDAQ
75 calCh = args.calChannel
76 lookbackWindows = args.lookbackWindows
77 heightThreshold = args.heightThreshold
78 isInterimFE = args.interim
79 if calCh < 0
or calCh > 7:
80 print(
"ERROR : invalid calibration asic channel :" + str(calCh))
81 print(
" (should be [0-7])")
84 if re.search(
r"run[0-9]+_slot[0-1][0-9]", inputFile):
85 outputRoot = re.search(
r"run[0-9]+_slot[0-1][0-9]", inputFile).group() +
"_ntuple.root"
86 elif re.search(
r"(top|cosmic|cdc|ecl|klm|test|debug|beam|physics)\.[0-9]+\.[0-9]+", inputFile):
88 outputRoot = re.search(
89 r"(top|cosmic|cdc|ecl|klm|test|debug|beam|physics)\.[0-9]+\.[0-9]+",
90 inputFile).group() +
"_ntuple.root"
92 outputRoot = inputFile +
"_ntuple.root"
94 if args.outputFile !=
"NoOutputFile":
95 outputRoot = args.outputFile
97 if isGlobalDAQForced
and (
not isPocketDAQForced):
99 elif (
not isGlobalDAQForced)
and isPocketDAQForced:
101 elif isGlobalDAQForced
and isPocketDAQForced:
102 print(
"ERROR : both of --GlobalDAQ or --PocketDAQ can not be given.")
105 print(inputFile +
" --> " + outputRoot)
106 print(
"Is global DAQ? : " + str(isGlobalDAQ))
107 print(
"OfflineFE : " + str(
not isOfflineFEDisabled))
108 print(
"Save waveform? : " + str(args.saveWaveform))
109 print(
"Cal. asic ch : " + str(calCh))
110 print(
"# of lookback windows : " + str(lookbackWindows))
112 print(
"start process...")
115 use_central_database(
'data_reprocessing_proc8')
120 roinput = register_module(
'SeqRootInput')
121 roinput.param(
'inputFileName', inputFile)
122 main.add_module(roinput)
125 histoman = register_module(
'HistoManager')
126 histoman.param(
'histoFileName', outputRoot)
127 main.add_module(histoman)
131 converter = register_module(
'Convert2RawDet')
132 main.add_module(converter)
135 main.add_module(
'TOPGeometryParInitializer')
138 unpack = register_module(
'TOPUnpacker')
140 unpack.param(
'swapBytes',
True)
141 unpack.param(
'dataFormat', 0x0301)
142 main.add_module(unpack)
145 if not isOfflineFEDisabled:
146 featureExtractor = register_module(
'TOPWaveformFeatureExtractor')
147 featureExtractor.param(
'threshold', heightThreshold)
148 featureExtractor.param(
'hysteresis', TMath.CeilNint(heightThreshold * 0.4 - 0.00001))
149 main.add_module(featureExtractor)
152 converter = register_module(
'TOPRawDigitConverter')
153 converter.param(
'useSampleTimeCalibration',
False)
154 converter.param(
'useChannelT0Calibration',
False)
155 converter.param(
'useModuleT0Calibration',
False)
156 converter.param(
'useCommonT0Calibration',
False)
157 converter.param(
'lookBackWindows', lookbackWindows)
158 converter.param(
'storageDepth', 508)
159 converter.param(
'calibrationChannel', calCh)
161 converter.param(
'calpulseHeightMin', 300)
162 converter.param(
'calpulseHeightMax', 900)
163 converter.param(
'calpulseWidthMin', 1.2)
164 converter.param(
'calpulseWidthMax', 2.8)
165 main.add_module(converter)
167 xtalk = register_module(
'TOPXTalkChargeShareSetter')
168 main.add_module(xtalk)
170 ntuple = register_module(
'TOPInterimFENtuple')
171 ntuple.param(
'saveWaveform', (args.saveWaveform))
173 ntuple.param(
'useDoublePulse', (
not isOfflineFEDisabled))
174 ntuple.param(
'calibrationChannel', calCh)
177 ntuple.param(
'minHeightFirstCalPulse', 300)
178 ntuple.param(
'minHeightSecondCalPulse', 300)
179 ntuple.param(
'nominalDeltaT', 21.5)
180 ntuple.param(
'nominalDeltaTRange', 2)
181 ntuple.param(
'globalRefSlotNum', 1)
182 ntuple.param(
'globalRefAsicNum', 0)
183 ntuple.param(
'timePerWin', 23.581939)
184 main.add_module(ntuple)
187 progress = register_module(
'Progress')
188 main.add_module(progress)
196 if isInterimFE
and not args.skipPlot:
197 plotInterimFEDataNtupleSummary(outputRoot, 2, isOfflineFEDisabled)