Belle II Software development
klm_time_constants.py
1
8
9'''
10Validation of KLM time constants calibration.
11'''
12
13
14import basf2
15from prompt import ValidationSettings
16import ROOT
17from ROOT.Belle2 import KLMCalibrationChecker
18import sys
19import subprocess
20import math
21from ROOT import TH2F, TCanvas, TFile, gStyle
22import os
23import json
24
25
26settings = ValidationSettings(name='KLM time constants',
27 description=__doc__,
28 download_files=['stdout'],
29 expert_config={
30 "chunk_size": 100
31 })
32
33
34def run_validation(job_path, input_data_path, requested_iov, expert_config):
35 '''
36 Run the validation.
37 Note:
38 - job_path will be replaced with path/to/calibration_results
39 - input_data_path will be replaced with path/to/data_path used for calibration, e.g. /group/belle2/dataprod/Data/PromptSkim/
40 '''
41
42 # Grab the expert configurations.
43 expert_config = json.loads(expert_config)
44 chunk_size = expert_config['chunk_size']
45
46 # Ignore the ROOT command line options.
47 ROOT.PyConfig.IgnoreCommandLineOptions = True # noqa
48 # Run ROOT in batch mode.
49 ROOT.gROOT.SetBatch(True)
50 # Set the Belle II style.
51 ROOT.gROOT.SetStyle("BELLE2")
52 # And unset the stat box.
53 ROOT.gStyle.SetOptStat(0)
54
55 # Path to the database.txt file.
56 database_file = os.path.join(f'{job_path}', 'KLMTime', 'outputdb', 'database.txt')
57
58 # Check the list of runs from the file database.txt.
59 exp_run_dict = {}
60 previous_exp = -666
61 with open(database_file) as f:
62 for line in f:
63 fields = line.split(' ')
64 if (fields[0] == 'dbstore/KLMTimeConstants'):
65 iov = fields[2].split(',')
66 exp = int(iov[0])
67 run = int(iov[1])
68 if (exp != previous_exp):
69 exp_run_dict[exp] = [run]
70 previous_exp = exp
71 else:
72 exp_run_dict[exp].append(run)
73
74 # Tweak the IoV range if the first run is 0.
75 # This is needed for display purposes.
76 for exp, run_list in exp_run_dict.items():
77 run_list.sort()
78 if len(run_list) > 1:
79 if run_list[0] == 0 and run_list[1] > 5:
80 run_list[0] = run_list[1] - 5
81
82 # Run the KLMCalibrationChecker class.
83 for exp, run_list in exp_run_dict.items():
84 for run in run_list:
85 checker = KLMCalibrationChecker()
86 checker.setExperimentRun(exp, run)
87 checker.setTestingPayload(database_file)
88 basf2.B2INFO(f'Creating time constants results tree for experiment {exp}, run {run}.')
89 checker.setTimeConstantsResultsFile(f'time_constants_exp{exp}_run{run}.root')
90 checker.checkTimeConstants()
91
92 # Run the validation.
93 for exp, run_list in exp_run_dict.items():
94 # For each experiment, merge the files in chunks of some runs.
95 chunks = math.ceil(len(run_list) / chunk_size)
96 for chunk in range(chunks):
97 file_name = f'time_constants_exp{exp}_chunk{chunk}.root'
98 run_files = [
99 f'time_constants_exp{exp}_run{run}.root' for run in run_list[chunk * chunk_size:(chunk + 1) * chunk_size]]
100 subprocess.run(['hadd', '-f', file_name] + run_files, check=True)
101 input_file = ROOT.TFile(f'{file_name}')
102 gStyle.SetOptStat(1111111)
103 gStyle.SetOptFit(1111)
104
105 barrel_RPCPhi = TH2F("barrel_RPCPhi",
106 "time constants for Barrel RPC phi readout", 100, 30000, 65000, 100, 0.004, 0.015)
107 barrel_RPCZ = TH2F("barrel_RPCZ",
108 "time constants for Barrel RPC Z readout", 100, 30000, 65000, 100, 0.0, 0.0025)
109 barrel_scintillator = TH2F("barrel_scintillator",
110 "time constants for Barrel scintillator", 100, 30000, 65000, 100, 0.075, 0.09)
111 endcap_scintillator = TH2F("endcap_scintillator",
112 "time constants for endcap scintillator", 100, 0, 16000, 100, 0.069, 0.075)
113
114 tree = input_file.Get("constants")
115 assert isinstance(tree, ROOT.TTree) == 1
116 myC = TCanvas("myC")
117
118 tree.Draw("delayRPCPhi:channelNumber>>barrel_RPCPhi", "subdetector==1 & layer>=3", "colz")
119 barrel_RPCPhi.GetXaxis().SetTitle("Channel number")
120 barrel_RPCPhi.GetYaxis().SetTitle("Time Delay constants")
121 myC.Print("barrel_RPCPhi.png")
122
123 tree.Draw("delayRPCZ:channelNumber>>barrel_RPCZ", "subdetector==1 & layer>=3", "colz")
124 barrel_RPCZ.GetXaxis().SetTitle("Channel number")
125 barrel_RPCZ.GetYaxis().SetTitle("Time Delay constants")
126 myC.Print("barrel_RPCZ.png")
127
128 tree.Draw("delayBKLM:channelNumber>>barrel_scintillator", "subdetector==1 & layer<3", "colz")
129 barrel_scintillator.GetXaxis().SetTitle("Channel number")
130 barrel_scintillator.GetYaxis().SetTitle("Time Delay constants")
131 myC.Print("barrel_scintillator.png")
132
133 tree.Draw("delayEKLM:channelNumber>>endcap_scintillator", "subdetector==2", "colz")
134 endcap_scintillator.GetXaxis().SetTitle("Channel number")
135 endcap_scintillator.GetYaxis().SetTitle("Time Delay constants")
136 myC.Print("endcap_scintillator.png")
137
138 fout = TFile("KLMTimeConstants.root", "recreate")
139 barrel_RPCPhi.Write()
140 barrel_scintillator.Write()
141 endcap_scintillator.Write()
142 input_file.Close()
143 fout.Close()
144
145 # Let's delete the files for single IoVs.
146 for run_file in run_files:
147 try:
148 os.remove(run_file)
149 except OSError as e:
150 basf2.B2ERROR(f'The file {run_file} can not be removed: {e.strerror}')
151
152
153if __name__ == "__main__":
154 run_validation(*sys.argv[1:])