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