10Validation of KLM time calibration (cable delay and time constants).
15from prompt
import ValidationSettings
17from ROOT.Belle2
import KLMCalibrationChecker
23from ROOT
import TH1F, TH2F, TCanvas, TFile, gStyle
26settings = ValidationSettings(name=
'KLM time',
28 download_files=[
'stdout'],
31 "LowerTimeBoundaryRPC": -800.0,
32 "UpperTimeBoundaryRPC": -600.0,
33 "LowerTimeBoundaryScintillatorsBKLM": -4800.0,
34 "UpperTimeBoundaryScintillatorsBKLM": -4600.0,
35 "LowerTimeBoundaryScintillatorsEKLM": -4850.0,
36 "UpperTimeBoundaryScintillatorsEKLM": -4600.0,
37 "UpperSigmaAxisEventT0": 20.0,
41basf2.conditions.override_globaltags()
44def run_validation(job_path, input_data_path, requested_iov, expert_config):
48 - job_path will be replaced with path/to/calibration_results
49 - input_data_path will be replaced with path/to/data_path used for calibration, e.g. /group/belle2/dataprod/Data/PromptSkim/
53 expert_config = json.loads(expert_config)
55 chunk_size = expert_config[
'chunk_size']
56 LowerTimeBoundaryRPC = expert_config[
'LowerTimeBoundaryRPC']
57 UpperTimeBoundaryRPC = expert_config[
'UpperTimeBoundaryRPC']
58 LowerTimeBoundaryScintillatorsBKLM = expert_config[
'LowerTimeBoundaryScintillatorsBKLM']
59 UpperTimeBoundaryScintillatorsBKLM = expert_config[
'UpperTimeBoundaryScintillatorsBKLM']
60 LowerTimeBoundaryScintillatorsEKLM = expert_config[
'LowerTimeBoundaryScintillatorsEKLM']
61 UpperTimeBoundaryScintillatorsEKLM = expert_config[
'UpperTimeBoundaryScintillatorsEKLM']
62 UpperSigmaAxisEventT0 = expert_config[
'UpperSigmaAxisEventT0']
65 ROOT.PyConfig.IgnoreCommandLineOptions =
True
67 ROOT.gROOT.SetBatch(
True)
69 ROOT.gROOT.SetStyle(
"BELLE2")
71 ROOT.gStyle.SetOptStat(0)
74 database_file = os.path.join(f
'{job_path}',
'KLMTime',
'outputdb',
'database.txt')
77 exp_run_dict_cabledelay = {}
78 exp_run_dict_constants = {}
79 exp_run_dict_resolution = {}
80 previous_exp_cabledelay = -666
81 previous_exp_constants = -666
82 previous_exp_resolution = -666
84 with open(database_file)
as f:
86 fields = line.split(
' ')
87 if fields[0] ==
'dbstore/KLMTimeCableDelay':
88 iov = fields[2].split(
',')
91 if exp != previous_exp_cabledelay:
92 exp_run_dict_cabledelay[exp] = [run]
93 previous_exp_cabledelay = exp
95 exp_run_dict_cabledelay[exp].append(run)
96 elif fields[0] ==
'dbstore/KLMTimeConstants':
97 iov = fields[2].split(
',')
100 if exp != previous_exp_constants:
101 exp_run_dict_constants[exp] = [run]
102 previous_exp_constants = exp
104 exp_run_dict_constants[exp].append(run)
105 elif fields[0] ==
'dbstore/KLMEventT0HitResolution':
106 iov = fields[2].split(
',')
109 if exp != previous_exp_resolution:
110 exp_run_dict_resolution[exp] = [run]
111 previous_exp_resolution = exp
113 exp_run_dict_resolution[exp].append(run)
117 for exp, run_list
in exp_run_dict_cabledelay.items():
119 if len(run_list) > 1:
120 if run_list[0] == 0
and run_list[1] > 5:
121 run_list[0] = run_list[1] - 5
123 for exp, run_list
in exp_run_dict_constants.items():
125 if len(run_list) > 1:
126 if run_list[0] == 0
and run_list[1] > 5:
127 run_list[0] = run_list[1] - 5
129 for exp, run_list
in exp_run_dict_resolution.items():
131 if len(run_list) > 1:
132 if run_list[0] == 0
and run_list[1] > 5:
133 run_list[0] = run_list[1] - 5
136 for exp, run_list
in exp_run_dict_cabledelay.items():
138 checker = KLMCalibrationChecker()
139 checker.setExperimentRun(exp, run)
140 checker.setTestingPayload(database_file)
141 basf2.B2INFO(f
'Creating time cable delay results tree for experiment {exp}, run {run}.')
142 checker.setTimeCableDelayResultsFile(f
'time_cabledelay_exp{exp}_run{run}.root')
143 checker.checkTimeCableDelay()
146 for exp, run_list
in exp_run_dict_constants.items():
148 checker = KLMCalibrationChecker()
149 checker.setExperimentRun(exp, run)
150 checker.setTestingPayload(database_file)
151 basf2.B2INFO(f
'Creating time constants results tree for experiment {exp}, run {run}.')
152 checker.setTimeConstantsResultsFile(f
'time_constants_exp{exp}_run{run}.root')
153 checker.checkTimeConstants()
156 for exp, run_list
in exp_run_dict_resolution.items():
158 checker = KLMCalibrationChecker()
159 checker.setExperimentRun(exp, run)
160 checker.setTestingPayload(database_file)
161 basf2.B2INFO(f
'Creating EventT0 hit resolution results tree for experiment {exp}, run {run}.')
162 checker.setEventT0HitResolutionResultsFile(f
'eventT0HitResolution_exp{exp}_run{run}.root')
163 checker.checkEventT0HitResolution()
166 for exp, run_list
in exp_run_dict_cabledelay.items():
168 chunks = math.ceil(len(run_list) / chunk_size)
170 for chunk
in range(chunks):
171 file_name = f
'time_cabledelay_exp{exp}_chunk{chunk}.root'
173 f
'time_cabledelay_exp{exp}_run{run}.root' for run
in run_list[chunk * chunk_size:(chunk + 1) * chunk_size]]
174 subprocess.run([
'hadd',
'-f', file_name] + run_files, check=
True)
175 chunk_files.append(file_name)
178 for run_file
in run_files:
182 basf2.B2ERROR(f
'The file {run_file} can not be removed: {e.strerror}')
185 final_file_name = f
'time_cabledelay_exp{exp}_all.root'
186 subprocess.run([
'hadd',
'-f', final_file_name] + chunk_files, check=
True)
187 input_file = ROOT.TFile(final_file_name)
189 gStyle.SetOptStat(1111111)
191 barrel_RPC = TH1F(
"barrel_RPC",
"time cable delay for Barrel RPC", 100, LowerTimeBoundaryRPC, UpperTimeBoundaryRPC)
192 barrel_scintillator = TH1F(
"barrel_scintillator",
"time cable delay for Barrel scintillator",
193 100, LowerTimeBoundaryScintillatorsBKLM, UpperTimeBoundaryScintillatorsBKLM)
194 endcap_scintillator = TH1F(
"endcap_scintillator",
"time cable delay for endcap scintillator",
195 100, LowerTimeBoundaryScintillatorsEKLM, UpperTimeBoundaryScintillatorsEKLM)
197 tree = input_file.Get(
"cabledelay")
198 assert isinstance(tree, ROOT.TTree) == 1
199 myC_cd = TCanvas(
"myC_cd")
201 tree.Draw(
"timeDelay>>barrel_RPC",
"subdetector==1 & layer>=3")
202 barrel_RPC.GetXaxis().SetTitle(
"T_{cable} (ns)")
203 barrel_RPC.GetYaxis().SetTitle(
"Entries")
204 myC_cd.Print(
"barrel_RPC.png")
206 tree.Draw(
"timeDelay>>barrel_scintillator",
"subdetector==1 & layer<3")
207 barrel_scintillator.GetXaxis().SetTitle(
"T_{cable} (ns)")
208 barrel_scintillator.GetYaxis().SetTitle(
"Entries")
209 myC_cd.Print(
"barrel_scintillator.png")
211 tree.Draw(
"timeDelay>>endcap_scintillator",
"subdetector==2")
212 endcap_scintillator.GetXaxis().SetTitle(
"T_{cable} (ns)")
213 endcap_scintillator.GetYaxis().SetTitle(
"Entries")
214 myC_cd.Print(
"endcap_scintillator.png")
217 fout = TFile(
"KLMTimeCableDelay.root",
"recreate")
219 barrel_scintillator.Write()
220 endcap_scintillator.Write()
225 for chunk_file
in chunk_files:
227 os.remove(chunk_file)
229 basf2.B2ERROR(f
'The file {chunk_file} can not be removed: {e.strerror}')
232 for exp, run_list
in exp_run_dict_constants.items():
234 chunks = math.ceil(len(run_list) / chunk_size)
236 for chunk
in range(chunks):
237 file_name = f
'time_constants_exp{exp}_chunk{chunk}.root'
239 f
'time_constants_exp{exp}_run{run}.root' for run
in run_list[chunk * chunk_size:(chunk + 1) * chunk_size]]
240 subprocess.run([
'hadd',
'-f', file_name] + run_files, check=
True)
241 chunk_files.append(file_name)
244 for run_file
in run_files:
248 basf2.B2ERROR(f
'The file {run_file} can not be removed: {e.strerror}')
251 final_file_name = f
'time_constants_exp{exp}_all.root'
252 subprocess.run([
'hadd',
'-f', final_file_name] + chunk_files, check=
True)
253 input_file = ROOT.TFile(final_file_name)
254 gStyle.SetOptStat(1111111)
256 barrel_RPCPhi = TH2F(
"barrel_RPCPhi",
257 "time constants for Barrel RPC phi readout", 100, 30000, 65000, 100, 0.004, 0.015)
258 barrel_RPCZ = TH2F(
"barrel_RPCZ",
259 "time constants for Barrel RPC Z readout", 100, 30000, 65000, 100, 0.0, 0.0025)
260 barrel_scintillator_constants = TH2F(
"barrel_scintillator_constants",
261 "time constants for Barrel scintillator", 100, 30000, 65000, 100, 0.075, 0.09)
262 endcap_scintillator_constants = TH2F(
"endcap_scintillator_constants",
263 "time constants for endcap scintillator", 100, 0, 16000, 100, 0.060, 0.075)
265 tree = input_file.Get(
"constants")
266 assert isinstance(tree, ROOT.TTree) == 1
267 myC_const = TCanvas(
"myC_const")
269 tree.Draw(
"delayRPCPhi:channelNumber>>barrel_RPCPhi",
"subdetector==1 & layer>=3",
"colz")
270 barrel_RPCPhi.GetXaxis().SetTitle(
"Channel number")
271 barrel_RPCPhi.GetYaxis().SetTitle(
"Time Delay constants")
272 myC_const.Print(
"barrel_RPCPhi.png")
274 tree.Draw(
"delayRPCZ:channelNumber>>barrel_RPCZ",
"subdetector==1 & layer>=3",
"colz")
275 barrel_RPCZ.GetXaxis().SetTitle(
"Channel number")
276 barrel_RPCZ.GetYaxis().SetTitle(
"Time Delay constants")
277 myC_const.Print(
"barrel_RPCZ.png")
279 tree.Draw(
"delayBKLM:channelNumber>>barrel_scintillator_constants",
"subdetector==1 & layer<3",
"colz")
280 barrel_scintillator_constants.GetXaxis().SetTitle(
"Channel number")
281 barrel_scintillator_constants.GetYaxis().SetTitle(
"Time Delay constants")
282 myC_const.Print(
"barrel_scintillator_constants.png")
284 tree.Draw(
"delayEKLM:channelNumber>>endcap_scintillator_constants",
"subdetector==2",
"colz")
285 endcap_scintillator_constants.GetXaxis().SetTitle(
"Channel number")
286 endcap_scintillator_constants.GetYaxis().SetTitle(
"Time Delay constants")
287 myC_const.Print(
"endcap_scintillator_constants.png")
289 fout = TFile(
"KLMTimeConstants.root",
"recreate")
290 barrel_RPCPhi.Write()
292 barrel_scintillator_constants.Write()
293 endcap_scintillator_constants.Write()
298 for chunk_file
in chunk_files:
300 os.remove(chunk_file)
302 basf2.B2ERROR(f
'The file {chunk_file} can not be removed: {e.strerror}')
307 category_labels = {1:
"EKLM Scint", 2:
"BKLM Scint", 3:
"RPC combined", 4:
"RPC Phi", 5:
"RPC Z"}
308 category_order = [2, 4, 5, 3, 1]
310 for exp, run_list
in exp_run_dict_resolution.items():
312 chunks = math.ceil(len(run_list) / chunk_size)
314 for chunk
in range(chunks):
315 file_name = f
'eventT0HitResolution_exp{exp}_chunk{chunk}.root'
317 f
'eventT0HitResolution_exp{exp}_run{run}.root' for run
in run_list[chunk * chunk_size:(chunk + 1) * chunk_size]]
318 subprocess.run([
'hadd',
'-f', file_name] + run_files, check=
True)
319 chunk_files.append(file_name)
322 for run_file
in run_files:
326 basf2.B2ERROR(f
'The file {run_file} can not be removed: {e.strerror}')
329 final_file_name = f
'eventT0HitResolution_exp{exp}_all.root'
330 subprocess.run([
'hadd',
'-f', final_file_name] + chunk_files, check=
True)
331 input_file = ROOT.TFile(final_file_name)
335 tree = input_file.Get(
"eventT0HitResolution")
336 assert isinstance(tree, ROOT.TTree) == 1
339 nCats = len(category_order)
340 hSigma = TH1F(
"eventT0_sigma_per_category",
341 f
"KLM EventT0 hit resolution (exp {exp});Detector;#sigma_{{t}} (ns)",
344 for iBin, cat
in enumerate(category_order, start=1):
349 if int(entry.category) == cat:
351 sumS2 += entry.sigma * entry.sigma
355 var = max(sumS2 / n - mean * mean, 0.0)
356 stderr = (var ** 0.5) / (n ** 0.5)
if n > 1
else 0.0
360 hSigma.SetBinContent(iBin, mean)
361 hSigma.SetBinError(iBin, stderr)
362 hSigma.GetXaxis().SetBinLabel(iBin, category_labels[cat])
364 hSigma.SetMinimum(0.0)
365 hSigma.SetMaximum(UpperSigmaAxisEventT0)
366 hSigma.SetMarkerStyle(20)
367 hSigma.SetMarkerSize(1.2)
368 hSigma.SetLineWidth(2)
370 myC_evt = TCanvas(
"myC_evt",
"", 800, 600)
372 myC_evt.Print(f
"eventT0HitResolution_exp{exp}.png")
375 fout = TFile(
"KLMEventT0HitResolution.root",
"recreate")
381 for chunk_file
in chunk_files:
383 os.remove(chunk_file)
385 basf2.B2ERROR(f
'The file {chunk_file} can not be removed: {e.strerror}')
388if __name__ ==
"__main__":