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