ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
PhysicsAnalysis
Columnar
ColumnarToolWrapperPython
python
atlascp.py
Go to the documentation of this file.
1
# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2
#
3
# @author Giordon Stark
4
5
# Syntactic sugar for creating CP tools by class name rather than raw
6
# type strings. Module-level __getattr__ dispatches attribute access
7
# to a constructor factory so that, e.g.:
8
#
9
# from ColumnarToolWrapperPython import atlascp
10
# tool = atlascp.MuonEfficiencyScaleFactors('myTool')
11
#
12
# is equivalent to:
13
#
14
# Tool("CP::MuonEfficiencyScaleFactors/myTool")
15
16
import
uuid
17
18
import
awkward
as
ak
19
20
from
ColumnarToolWrapperPython.tool
import
Tool
21
from
ColumnarToolWrapperPython.config
import
load_config, merge_tool_config
22
23
_class_cache = {}
24
25
26
def
_make_tool_class
(tool_type_name):
27
"""Return a named Tool subclass for tool_type_name, creating it if needed.
28
29
Parameters
30
----------
31
tool_type_name:
32
The C++ class name without namespace, e.g. "MuonEfficiencyScaleFactors".
33
34
Returns
35
-------
36
type
37
A subclass of Tool whose ``__name__`` equals ``tool_type_name``.
38
Repeated calls with the same name return the same class object.
39
"""
40
if
tool_type_name
not
in
_class_cache:
41
_class_cache[tool_type_name] =
type
(tool_type_name, (Tool,), {})
42
return
_class_cache[tool_type_name]
43
44
45
def
__getattr__
(name):
46
"""Return a constructor for the named CP tool type.
47
48
Called when code accesses ``atlascp.<ToolTypeName>``. Returns a callable
49
that creates and initializes a ``Tool`` subclass instance.
50
51
Parameters
52
----------
53
name:
54
Tool type name without namespace, e.g. "MuonEfficiencyScaleFactors".
55
56
Returns
57
-------
58
callable
59
A constructor with signature
60
``(instance_name=None, /, *, namespace="CP", properties=None, rename_containers=None)``.
61
``instance_name`` is positional-only and optional; all other arguments are keyword-only.
62
When omitted, an auto-generated unique name is used.
63
"""
64
def
constructor(instance_name=None, /, *, namespace="CP", properties=None, rename_containers=None):
65
if
instance_name
is
None
:
66
instance_name = f
"unique{uuid.uuid4().hex[:12]}"
67
type_and_name = f
"{namespace}::{name}/{instance_name}"
68
cls =
_make_tool_class
(name)
69
instance = cls.__new__(cls)
70
Tool.__init__(instance, type_and_name, properties=properties, rename_containers=rename_containers)
71
return
instance
72
constructor.__name__ = name
73
constructor.__qualname__ = name
74
return
constructor
75
76
77
class
Corrections
:
78
"""Ordered list-like container of configured CP tools.
79
80
Returned by ``atlascp.configure()``. Multiple tools of the same type are
81
supported. Iterating yields ``(tool_type_name, Tool)`` pairs in config
82
file order.
83
84
Use ``corrections[type_name]`` to get a list of all tools of that type.
85
Use ``corrections.apply(events)`` to run all tools and merge outputs.
86
"""
87
88
def
__init__
(self, tools):
89
self.
_tools
= list(tools)
# list of (tool_type_name, Tool)
90
91
def
__getitem__
(self, tool_type_name):
92
"""Return list of tools matching tool_type_name."""
93
matches = [tool
for
name, tool
in
self.
_tools
if
name == tool_type_name]
94
if
not
matches:
95
raise
KeyError(tool_type_name)
96
return
matches
97
98
def
__contains__
(self, tool_type_name):
99
return
any(name == tool_type_name
for
name, _
in
self.
_tools
)
100
101
def
__iter__
(self):
102
return
iter(name
for
name, _
in
self.
_tools
)
103
104
def
items
(self):
105
return
iter(self.
_tools
)
106
107
def
apply
(self, events):
108
"""Run all tools on events and return merged output columns.
109
110
Parameters
111
----------
112
events:
113
An ak.Array with fields matching the configured containers.
114
115
Returns
116
-------
117
ak.Array
118
Record array with all output columns from all tools merged.
119
"""
120
outputs = {}
121
for
_name, tool
in
self.
_tools
:
122
result = tool(events)
123
for
field
in
ak.fields(result):
124
outputs[field] = result[field]
125
return
ak.Array(outputs)
126
127
128
def
configure
(path, *, namespace="CP"):
129
"""Load a TOML config file and return an initialized Corrections object.
130
131
The ``[global]`` section provides default ``rename_containers`` and
132
``properties``. Tool entries are defined as ``[[tool.TypeName]]`` blocks;
133
multiple blocks of the same type create multiple tool instances.
134
135
Parameters
136
----------
137
path:
138
Path to a TOML configuration file (str or Path).
139
namespace:
140
C++ namespace for all tools (default ``"CP"``).
141
142
Returns
143
-------
144
Corrections
145
"""
146
cfg = load_config(path)
147
global_cfg = cfg.get(
"global"
, {})
148
tools = []
149
for
type_name, entries
in
cfg.get(
"tool"
, {}).items():
150
for
entry
in
entries:
151
merged = merge_tool_config(global_cfg, entry)
152
constructor =
__getattr__
(type_name)
153
tool = constructor(
154
namespace=namespace,
155
properties=merged[
"properties"
]
or
None
,
156
rename_containers=merged[
"rename_containers"
]
or
None
,
157
)
158
tools.append((type_name, tool))
159
return
Corrections
(tools)
python.atlascp.Corrections
Definition
atlascp.py:77
python.atlascp.Corrections.apply
apply(self, events)
Definition
atlascp.py:107
python.atlascp.Corrections.items
items(self)
Definition
atlascp.py:104
python.atlascp.Corrections.__init__
__init__(self, tools)
Definition
atlascp.py:88
python.atlascp.Corrections.__getitem__
__getitem__(self, tool_type_name)
Definition
atlascp.py:91
python.atlascp.Corrections.__iter__
__iter__(self)
Definition
atlascp.py:101
python.atlascp.Corrections._tools
_tools
Definition
atlascp.py:89
python.atlascp.Corrections.__contains__
__contains__(self, tool_type_name)
Definition
atlascp.py:98
python.atlascp._make_tool_class
_make_tool_class(tool_type_name)
Definition
atlascp.py:26
python.atlascp.configure
configure(path, *, namespace="CP")
Definition
atlascp.py:128
python.atlascp.__getattr__
__getattr__(name)
Definition
atlascp.py:45
type
Generated on
for ATLAS Offline Software by
1.17.0