Belle II Software development
fom.py
1#!/usr/bin/env python3
2
3
10
11import collections
12import array
13import ROOT
14
15from tracking.root_utils import root_cd, root_save_name
16from tracking.validation.matplotting import get_logger
17
18
19class ValidationFiguresOfMerit(collections.abc.MutableMapping):
20 """Create and write an TNtuple of the validation figures of merit"""
21
23 self,
24 name,
25 description='',
26 check='',
27 contact='',
28 title='',
29 ):
30 """Constructor"""
31
32
33 self.name = root_save_name(name)
34
35 self.description = description
36
37 self.check = check
38
39 self.contact = contact
40
41 self.title = title
42
43
44 self.figures_by_name = collections.OrderedDict()
45
46 def __str__(self):
47 """Informal string output listing the assigned figures of merit."""
48
49 figures_by_name = self.figures_by_name
50 return '\n'.join(f'{key} : {figures_by_name[key]}'
51 for key in
52 figures_by_name.keys())
53
54 def write(self, tdirectory=None):
55 """Writes the figures of merit as a TNtuple.
56
57 Parameters
58 ----------
59 tdirectory : ROOT.TDirectory, optional
60 The directory to which the TNtuple shall be written.
61 Defaults to the current directory.
62 """
63 name = self.name
64
65 if not self.figures_by_name:
66 get_logger().warning(f'Do not create Ntuple for empty ValidationFiguresOfMerit {name}')
67 return
68
69 title = self.title or name
70 contact = self.contact
71
72 description = self.description
73 check = self.check
74
75 figure_names = [root_save_name(key) for key in list(self.figures_by_name.keys())]
76 values = list(self.figures_by_name.values())
77
78 with root_cd(tdirectory) as tdirectory:
79 # Try to find the object first
80 tntuple = tdirectory.Get(name)
81 if tntuple:
82 former_description = tntuple.GetAlias('Description')
83 former_check = tntuple.GetAlias('Check')
84 former_figure_names = []
85 former_values = []
86 tntuple.GetEntry(0)
87 for tleaf in tntuple.GetListOfLeaves():
88 former_figure_names.append(tleaf.GetName())
89 former_values.append(tleaf.GetValue())
90
91 # Append the description and check of this figure of merit to whatever is there
92 description = former_description + ' <br/>\n' + description
93 check = former_check + ' <br/>\n' + check
94
95 figure_names = former_figure_names + figure_names
96 values = former_values + values
97
98 # Need both delete and overwrite to get rid of the former object.
99 tdirectory.Delete(name)
100 write_option = ROOT.TObject.kOverwrite
101
102 else:
103 write_option = 0
104
105 leaf_specification = ':'.join(figure_names)
106 tntuple = ROOT.TNtuple(name, title, leaf_specification)
107
108 array_of_values = array.array('f', values)
109 tntuple.Fill(array_of_values)
110
111 tntuple.SetAlias('Description', description)
112 tntuple.SetAlias('Check', check)
113 tntuple.SetAlias('Contact', contact)
114
115 # Overwrite the former TNtuple if one was there
116 tntuple.Write("", write_option)
117
118 def __setitem__(self, figure_name, value):
119 """Braketed item assignment for figures of merit"""
120
121 self.figures_by_name[figure_name] = value
122
123 def __getitem__(self, figure_name):
124 """Braketed item lookup for figures of merit"""
125
126 return self.figures_by_name[figure_name]
127
128 def __delitem__(self, figure_name):
129 """Braketed item deletion for figures of merit"""
130
131 del self.figures_by_name[figure_name]
132
133 def __iter__(self):
134 """Implements the iter() hook as if it was a dictionary."""
135
136 return iter(self.figures_by_name)
137
138 def __len__(self):
139 """Returns the number of figures of merit assigned. Implements the len() hook."""
140
141 return len(self.figures_by_name)
142
143
145 """Create and write an TNtuple with several validation figures of merit"""
146
147 def __str__(self):
148 """Describe myself"""
149 return 'Not supported.'
150
151 def write(self, tdirectory=None):
152 """Writes the figures of merit as a TNtuple.
153
154 Parameters
155 ----------
156 tdirectory : ROOT.TDirectory, optional
157 The directory to which the TNtuple shall be written.
158 Defaults to the current directory.
159 """
160 name = self.name
161 figure_names = [root_save_name(key) for key in list(self.figures_by_name.keys())]
162 values = list(self.figures_by_name.values())
163
164 leaf_specification = ':'.join(figure_names)
165 title = self.title or ""
166 ntuple = ROOT.TNtuple(name, title, leaf_specification)
167
168 for value in zip(*values):
169 ntuple.Fill(*value)
170
171 ntuple.SetAlias('Description', self.description)
172 ntuple.SetAlias('Check', self.check)
173 ntuple.SetAlias('Contact', self.contact)
174
175 with root_cd(tdirectory):
176 ntuple.Write()
title
cached title for this figure of merit
Definition: fom.py:41
description
cached description for this figure of merit
Definition: fom.py:35
contact
cached contact person for this figure of merit
Definition: fom.py:39
def write(self, tdirectory=None)
Definition: fom.py:54
def __setitem__(self, figure_name, value)
Definition: fom.py:118
def __init__(self, name, description='', check='', contact='', title='')
Definition: fom.py:29
name
cached name for this figure of merit
Definition: fom.py:33
check
cached user-check action for this figure of merit
Definition: fom.py:37
figures_by_name
cached dictionary of figures for this figure of merit
Definition: fom.py:44