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