Belle II Software  release-08-01-10
arich.py
1 
8 
9 '''
10 Validation of ARICH channel masking calibration.
11 '''
12 
13 
14 import basf2
15 from prompt import ValidationSettings
16 import ROOT
17 from ROOT.Belle2 import ARICHCalibrationChecker
18 import sys
19 import subprocess
20 import math
21 import json
22 
23 
24 settings = ValidationSettings(name='ARICH channel masks',
25  description=__doc__,
26  download_files=['stdout'],
27  expert_config={"chunk_size": 100})
28 
29 
30 def 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 
139 if __name__ == "__main__":
140  run_validation(*sys.argv[1:])