ATLAS Offline Software
Loading...
Searching...
No Matches
python.physvalPostProcessingTools Namespace Reference

Classes

class  ConfigManager
class  RebinningOperation
class  EfficiencyComputation
class  ResolutionComputation
class  ROCCurveComputation
class  ProjectionComputation
class  HistogramAddition
class  HistogramAdjustment
class  HistogramBlackList

Functions

 find_histo (root_file, path, should_delete=False)
 — HELPER — ###
 ensure_directory_exists (root_file, path)
 — HELPER — ###
 histogram_paths (directory, prefix="")
 pattern_to_regex (pattern)
 fill_fields (value, fields)
 empty_input (root_file, fragment, fields)
 expand_fragments (fragments, root_file)

Variables

bool crash_on_error = False
 _FIELD = re.compile(r"\{(\w+)\}")
 — HELPER — ###

Function Documentation

◆ empty_input()

empty_input ( root_file,
fragment,
fields )
Return the first of the named fragment inputs that exists but has no entries.

Definition at line 81 of file physvalPostProcessingTools.py.

81def empty_input(root_file, fragment, fields):
82 """Return the first of the named fragment inputs that exists but has no entries."""
83 for field in [fields] if isinstance(fields, str) else fields:
84 histo = root_file.Get(fragment[field])
85 if histo and histo.InheritsFrom(ROOT.TH1.Class()) and not histo.GetEntries():
86 return fragment[field]
87 return None
88

◆ ensure_directory_exists()

ensure_directory_exists ( root_file,
path )

— HELPER — ###

Definition at line 38 of file physvalPostProcessingTools.py.

38def ensure_directory_exists(root_file, path):
39 current = root_file
40 for part in path.strip("/").split("/"):
41 next_dir = current.Get(part)
42 if not next_dir:
43 logging.info(f"Saving directory not exist. Creating directory '{part}' in '{current.GetName()}'")
44 current.mkdir(part)
45 current.cd(part)
46 current = ROOT.gDirectory
47
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179

◆ expand_fragments()

expand_fragments ( fragments,
root_file )
Resolve the for_each patterns of a domain against the histograms in a file.

A fragment without for_each is kept as it is. One with for_each is repeated
once per histogram matching the pattern, with its {field} placeholders filled
in from the match. skip_if_empty names the inputs that a repetition needs to
be non-empty, which is how the selections a sample does not fill are dropped.

Definition at line 89 of file physvalPostProcessingTools.py.

89def expand_fragments(fragments, root_file):
90 """Resolve the for_each patterns of a domain against the histograms in a file.
91
92 A fragment without for_each is kept as it is. One with for_each is repeated
93 once per histogram matching the pattern, with its {field} placeholders filled
94 in from the match. skip_if_empty names the inputs that a repetition needs to
95 be non-empty, which is how the selections a sample does not fill are dropped.
96 """
97 paths = None
98 expanded = []
99 for fragment in fragments:
100 pattern = fragment.get("for_each")
101 if pattern is None:
102 expanded.append(fragment)
103 continue
104 if paths is None:
105 paths = histogram_paths(root_file)
106 matches = [match.groupdict() for match in map(pattern_to_regex(pattern).fullmatch, paths) if match]
107 if not matches:
108 logging.info(f"No histogram matches '{pattern}', nothing to expand")
109 for fields in sorted(matches, key=lambda match: sorted(match.items())):
110 entry = {key: fill_fields(value, fields) for key, value in fragment.items()
111 if key not in ("for_each", "skip_if_empty")}
112 required = fragment.get("skip_if_empty")
113 empty = empty_input(root_file, entry, required) if required else None
114 if empty:
115 logging.info(f"'{empty}' is empty, skipping '{entry['output']}'")
116 continue
117 expanded.append(entry)
118 return expanded
119
STL class.

◆ fill_fields()

fill_fields ( value,
fields )
Substitute the {field} placeholders of one fragment value.

Definition at line 75 of file physvalPostProcessingTools.py.

75def fill_fields(value, fields):
76 """Substitute the {field} placeholders of one fragment value."""
77 if not isinstance(value, str):
78 return value
79 return _FIELD.sub(lambda field: fields[field.group(1)], value)
80

◆ find_histo()

find_histo ( root_file,
path,
should_delete = False )

— HELPER — ###

Definition at line 11 of file physvalPostProcessingTools.py.

11def find_histo(root_file, path, should_delete=False):
12 obj = root_file.Get(path)
13 if not obj:
14 if crash_on_error:
15 raise RuntimeError(f"Object not found at path: {path}")
16 else:
17 logging.warning(f"Object not found at path: {path}")
18 return None
19 if should_delete:
20 # Extract directory and name for deletion
21 path_parts = path.strip("/").split("/")
22 *dirs, name = path_parts
23 current_dir = root_file
24 for d in dirs:
25 current_dir = current_dir.Get(d)
26 if not current_dir:
27 if crash_on_error:
28 raise RuntimeError(f"Directory '{d}' not found in path '{'/'.join(dirs)}' for deletion.")
29 else:
30 logging.warning(f"Directory '{d}' not found in path '{'/'.join(dirs)}' for deletion.")
31 return None
32 # logging.info(f"Deleting '{name}' in '{'/'.join(dirs)}'")
33 current_dir.Delete(f"{name};*")
34 return None
35 return obj
36

◆ histogram_paths()

histogram_paths ( directory,
prefix = "" )
Return the path of every histogram below a directory.

Definition at line 51 of file physvalPostProcessingTools.py.

51def histogram_paths(directory, prefix=""):
52 """Return the path of every histogram below a directory."""
53 paths = []
54 for key in directory.GetListOfKeys():
55 path = f"{prefix}/{key.GetName()}" if prefix else key.GetName()
56 # only the directories are read, so the histograms stay on disk
57 stored = ROOT.TClass.GetClass(key.GetClassName())
58 if stored.InheritsFrom(ROOT.TDirectory.Class()):
59 paths += histogram_paths(key.ReadObj(), path)
60 elif stored.InheritsFrom(ROOT.TH1.Class()):
61 paths.append(path)
62 return paths
63

◆ pattern_to_regex()

pattern_to_regex ( pattern)
Turn a pattern with {field} placeholders into a regex with one group per field.

Definition at line 64 of file physvalPostProcessingTools.py.

64def pattern_to_regex(pattern):
65 """Turn a pattern with {field} placeholders into a regex with one group per field."""
66 regex, seen, pos = "", set(), 0
67 for field in _FIELD.finditer(pattern):
68 name = field.group(1)
69 regex += re.escape(pattern[pos:field.start()])
70 regex += f"(?P={name})" if name in seen else f"(?P<{name}>[^/]+)"
71 seen.add(name)
72 pos = field.end()
73 return re.compile(regex + re.escape(pattern[pos:]))
74
STL class.

Variable Documentation

◆ _FIELD

python.physvalPostProcessingTools._FIELD = re.compile(r"\{(\w+)\}")
protected

— HELPER — ###

Definition at line 49 of file physvalPostProcessingTools.py.

◆ crash_on_error

bool python.physvalPostProcessingTools.crash_on_error = False

Definition at line 8 of file physvalPostProcessingTools.py.