Belle II Software development
arich.py
1
8
9'''
10Validation of ARICH channel masking calibration.
11'''
12
13
14import basf2
15from prompt import ValidationSettings
16import ROOT
17from ROOT.Belle2 import ARICHCalibrationChecker
18import sys
19import subprocess
20import math
21import json
22
23# Avoid looking for the release globaltag
24basf2.conditions.override_globaltags()
25
26
27settings = ValidationSettings(name='ARICH channel masks',
28 description=__doc__,
29 download_files=['stdout'],
30 expert_config={"chunk_size": 100})
31
32
33def run_validation(job_path, input_data_path, requested_iov, expert_config):
34 '''
35 Run the validation.
36 '''
37
38 expert_config = json.loads(expert_config)
39 chunk_size = expert_config["chunk_size"]
40
41 # Ignore the ROOT command line options.
42 ROOT.PyConfig.IgnoreCommandLineOptions = True # noqa
43
44 # Run ROOT in batch mode.
45 ROOT.gROOT.SetBatch(True)
46 # And unset the stat box.
47 ROOT.gStyle.SetOptStat(0)
48
49 # Path to the database.txt file.
50 database_file = f'{job_path}/ARICHChannelMasks/outputdb/database.txt'
51
52 # Check the list of runs from the file database.txt.
53 exp_run_dict = {}
54 previous_exp = -666
55 with open(database_file) as f:
56 for line in f:
57 fields = line.split(' ')
58 if (fields[0] == 'dbstore/ARICHChannelMask'):
59 iov = fields[2].split(',')
60 exp = int(iov[0])
61 run = int(iov[1])
62 if (exp != previous_exp):
63 exp_run_dict[exp] = [run]
64 previous_exp = exp
65 else:
66 exp_run_dict[exp].append(run)
67
68 # Tweak the IoV range if the first run is 0.
69 # This is needed for display purposes.
70 for exp, run_list in exp_run_dict.items():
71 run_list.sort()
72 if len(run_list) > 1:
73 if run_list[0] == 0 and run_list[1] > 5:
74 run_list[0] = run_list[1] - 5
75
76 # Run the ARICHCalibrationChecker class.
77 for exp, run_list in exp_run_dict.items():
78 for run in run_list:
79 checker = ARICHCalibrationChecker()
80 checker.setExperimentRun(exp, run)
81 checker.setTestingPayload(database_file)
82 basf2.B2INFO(f'Creating arich channel mask results tree for experiment {exp}, run {run}.')
83 checker.setChannelMaskResultsFile(f'channel_mask_exp{exp}_run{run}.root')
84 checker.checkChannelMask()
85
86 # Run the validation.
87 for exp, run_list in exp_run_dict.items():
88 # For each experiment, merge the files in chunks of some runs.
89 chunks = math.ceil(len(run_list) / chunk_size)
90 for chunk in range(chunks):
91 file_name = f'channel_mask_exp{exp}_chunk{chunk}.root'
92 run_file_names = [
93 f'channel_mask_exp{exp}_run{run}.root' for run in run_list[chunk * chunk_size:(chunk + 1) * chunk_size]]
94 subprocess.run(['hadd', '-f', file_name] + run_file_names, check=True)
95 input_file = ROOT.TFile(f'{file_name}')
96 output_file = ROOT.TFile(f'histograms_{file_name}', 'recreate')
97 output_file.cd()
98 tree = input_file.Get('arich_masked')
99 assert isinstance(tree, ROOT.TTree) == 1
100 canvas = ROOT.TCanvas(f'canvas_exp{exp}_chunk{chunk}', 'canvas', 800, 500)
101 canvas.cd()
102 graphs = []
103 mg = ROOT.TMultiGraph("mg", "ARICH masked channels")
104 leg = ROOT.TLegend(0.9, 0.5, 0.98, 0.9)
105
106 # draw graphs for each sector
107 for i in range(0, 6):
108 n = tree.Draw(f'frac_masked_sector[{i}]:run', "", "goff")
109 graphs.append(ROOT.TGraph(n, tree.GetV2(), tree.GetV1()))
110 graphs[i].SetMarkerStyle(7)
111 graphs[i].SetMarkerColor(i + 1)
112 graphs[i].SetLineWidth(0)
113 graphs[i].SetTitle(f'sector {i+1}')
114 leg.AddEntry(graphs[i])
115 mg.Add(graphs[i])
116
117 # draw graph for total
118 n = tree.Draw('frac_masked:run', "", "goff")
119 graphs.append(ROOT.TGraph(n, tree.GetV2(), tree.GetV1()))
120 graphs[6].SetMarkerStyle(20)
121 graphs[6].SetMarkerColor(6 + 1)
122 graphs[6].SetLineWidth(0)
123 graphs[6].SetTitle('total')
124 leg.AddEntry(graphs[6])
125 mg.Add(graphs[6])
126
127 mg.Draw("ap")
128 mg.GetXaxis().SetTitle(f'Exp. {exp} -- Run number')
129 mg.GetYaxis().SetTitle('fraction of masked channels')
130 leg.Draw()
131 ROOT.gPad.SetGridx()
132 ROOT.gPad.SetGridy()
133 canvas.Write()
134 canvas.SaveAs(file_name.replace("root", "pdf"))
135
136 input_file.Close()
137 output_file.Close()
138 # delete run files
139 subprocess.run(['rm', '-rf'] + run_file_names, check=True)
140
141
142if __name__ == "__main__":
143 run_validation(*sys.argv[1:])