11"""Small module containing helper functions to set the metadata on objects
12created for the validation correctly """
15from typing
import Optional, Union, List, Tuple
20from ROOT
import Belle2
23ROOT.gInterpreter.Declare(
"#include <framework/utilities/MakeROOTCompatible.h>")
29def file_description_set(
30 rootfile: Union[ROOT.TFile, str, pathlib.PurePath], description: str
33 Add file description validation metadata to a ROOT file.
36 rootfile (ROOT.TFile, str or pathlib.PurePath): Name of the root file
37 to open
or an already open TFile instance
38 description (str): Common description/information of/about all plots
39 in this ROOT file (will be displayed above the plots)
45 if not isinstance(rootfile, ROOT.TFile):
46 if isinstance(rootfile, pathlib.PurePath):
47 rootfile = str(rootfile)
48 rootfile = ROOT.TFile(rootfile,
"UPDATE")
50 if not rootfile.IsOpen()
or not rootfile.IsWritable():
52 f
"ROOT file {rootfile.GetName()} is not open for writing"
57 directory_guard = ROOT.TDirectory.TContext(rootfile)
58 desc = ROOT.TNamed(
"Description", description)
64def validation_metadata_set(
70 xlabel: Optional[str] =
None,
71 ylabel: Optional[str] =
None,
75 Set the validation metadata for a given object by setting the necessary
76 values. This function can be used on any object supported by the
77 Validation (histograms, profiles, ntuples)
80 obj: Instance of the object which should get the metadata
81 title (str): Title to use
for the object
82 contact (str): Contact person, usually
in the form
"Name <email>"
83 description (str): Text description what can be seen
in the plot
84 check (str): Text description what to look
for in the validation
for
85 shifters to easily see
if the distribution looks ok
86 xlabel (str): If given
try to set this
as the label
for the x axis
87 ylabel (str): If given
try to set this
as the label
for the y axis
88 metaoptions (str): Metaoptions (additional options to influence the
89 comparison between revisions, styling of the plot, etc.)
93 Different ways to specify LaTeX
for different arguments:
94 see `create_validation_histograms`
99 obj.SetAlias(
"Contact", contact)
100 obj.SetAlias(
"Description", description)
101 obj.SetAlias(
"Check", check)
102 obj.SetAlias(
"MetaOptions", metaoptions)
103 except AttributeError:
107 function_list = obj.GetListOfFunctions()
108 function_list.Add(ROOT.TNamed(
"Contact", contact))
109 function_list.Add(ROOT.TNamed(
"Description", description))
110 function_list.Add(ROOT.TNamed(
"Check", check))
111 function_list.Add(ROOT.TNamed(
"MetaOptions", metaoptions))
112 except AttributeError:
116 if xlabel
is not None:
118 obj.GetXaxis().SetTitle(xlabel)
119 except AttributeError:
122 if ylabel
is not None:
124 obj.GetYaxis().SetTitle(ylabel)
125 except AttributeError:
130def validation_metadata_update(
131 rootfile: Union[str, ROOT.TFile, pathlib.PurePath], name: str, *args, **argk
134 This is a convenience helper
for `validation_metadata_set`
in case the
135 objects have already been saved
in a ROOT file before: It will open the
136 file (
or use an existing TFile), extract the object, add the metadata
and
137 save the new version to the file
140 rootfile (str, ROOT.TFile
or pathlib.PurePath): Name of the root file
141 to open
or an already open TFile instance
142 name (str): Name of the object
in the file
143 title (str): Title to use
for the object
144 contact (str): Contact person, usually
in the form
"Name <email>"
145 description (str): Text description what can be seen
in the plot
146 check (str): Text description what to look
for in the validation
for
147 shifters to easily see
if the distribution looks ok
148 xlabel (str): If given
try to set this
as the label
for the x axis
149 ylabel (str): If given
try to set this
as the label
for the y axis
150 metaoptions (str): Metaoptions (additional options to influence the
151 comparison between revisions, styling of the plot, etc.)
155 Different ways to specify LaTeX
for different arguments:
156 see `create_validation_histograms`
160 if not isinstance(rootfile, ROOT.TFile):
161 if isinstance(rootfile, pathlib.PurePath):
162 rootfile = str(rootfile)
163 rootfile = ROOT.TFile(rootfile,
"UPDATE")
165 if not rootfile.IsOpen()
or not rootfile.IsWritable():
167 f
"ROOT file {rootfile.GetName()} is not open for writing"
169 obj = rootfile.Get(name)
172 subdir = rootfile.GetDirectory(args[0])
174 obj = subdir.Get(name)
177 validation_metadata_set(obj, *(args[1:]), **argk)
178 subdir.WriteObject(obj, name,
"Overwrite")
181 f
"Cannot find object named {name} in {rootfile.GetName()}"
184 validation_metadata_set(obj, *args, **argk)
188 directory_guard = ROOT.TDirectory.TContext(rootfile)
189 obj.Write(
"", ROOT.TObject.kOverwrite)
194class ValidationMetadataSetter(basf2.Module):
196 Simple module to set the valdiation metadata for a given list of objects
197 automatically at the end of event processing
199 Just add this module **before** any
200 VariablesToNtuple/VariablesToHistogram modules
and it will set the
201 correct validation metadata at the end of processing
204 The module needs to be before the modules creating the objects
205 as terminate() functions are executed
in reverse order
from last to
206 first module. If this module
is after the creation modules the metadata
207 might
not be set correctly
212 variables: List[Tuple[str]],
213 rootfile: Union[str, pathlib.PurePath],
217 Initialize ValidationMetadataSetter
220 variables (list(tuple(str))): List of objects to set the metadata
221 for. Each entry should be the name of an object followed by the
222 metadata values which will be forwarded to
223 `validation_metadata_set`:
224 ``(name, title, contact, description, check, xlabel, ylabel,
226 where ``xlabel``, ``ylabel``
and ``metaoptions`` are optional
227 rootfile (str
or pathlib.PurePath): The name of the ROOT file where
228 the objects can be found
229 description (str): Common description/information of/about all plots
230 in this ROOT file (will be displayed above the plots)
234 self._variables = variables
235 if isinstance(rootfile, pathlib.PurePath):
236 rootfile = str(rootfile)
238 self._rootfile: str = rootfile
241 self._description = description
244 self._tfile: ROOT.TFile =
None
246 def initialize(self):
247 """Make sure we keep the file open"""
253 """And update the metadata at the end"""
254 for name, *metadata
in self._variables:
256 validation_metadata_update(self._tfile, name, *metadata)
257 if self._description:
258 file_description_set(self._tfile, self._description)
266def create_validation_histograms(
268 rootfile: Union[str, pathlib.PurePath],
270 variables_1d: Optional[List[Tuple]] =
None,
271 variables_2d: Optional[List[Tuple]] =
None,
275 Create histograms for all the variables
and also label them to be useful
276 in validation plots
in one go. This
is similar to the
277 `modularAnalysis.variablesToHistogram` function but also sets the
278 metadata correctly to be used by the validation
281 path (basf2.Path): Path where to put the modules
282 rootfile (str
or pathlib.PurePath): Name of the output root file
283 particlelist (str): Name of the particle list, can be empty
for event
285 variables_1d: List of 1D histogram definitions of the form
286 ``var, bins, min, max, title, contact, description, check_for
287 [, xlabel [, ylabel [, metaoptions]]]``
288 variables_2d: List of 2D histogram definitions of the form
289 ``var1, bins1, min1, max1, var2, bins2, min2, max2, title, contact,
290 description, check_for [, xlabel [, ylabel [, metaoptions]]]``
291 description: Common description/information of/about all plots
in this
292 ROOT file (will be displayed above the plots)
296 Sadly, there are two different ways to specify latex formulas.
298 1. The ROOT-style using ``
299 ``
"Einstein-Pythagoras a^{2} + b^{2} = #frac{E}{m}"``
301 This style should be used
for histogram title
and labels, that
is the
302 ``title``, ``xlabel``
and ``ylabel`` arguments
304 2. The normal Latex style (
with escaped backslashes
or raw
306 ``
"Einstein-Pythagoras $a^2 + b^2 = \\\\frac{E}{m}$"``.
308 This style should be used
for all other fields like ``description``,
311 You can use the normal Latex style also
for histogram title
and descriptions
312 but the PDF version of the plots will still be buggy
and not show all
315 if isinstance(rootfile, pathlib.PurePath):
316 rootfile = str(rootfile)
320 if variables_1d
is not None:
321 for var, nbins, vmin, vmax, *data
in variables_1d:
322 histograms_1d.append((var, nbins, vmin, vmax))
323 metadata.append([var] + data)
325 if variables_2d
is not None:
326 for row
in variables_2d:
329 histograms_2d.append(row[:8])
330 metadata.append([var1 + var2] + list(row[8:]))
333 ValidationMetadataSetter(metadata, rootfile, description=description)
336 "VariablesToHistogram",
337 particleList=particlelist,
338 variables=histograms_1d,
339 variables_2d=histograms_2d,
static std::string makeROOTCompatible(std::string str)
Remove special characters that ROOT dislikes in branch names, e.g.
static RootFileCreationManager & getInstance()
Interface for the FileManager.