100 def __call__(self, events, systematic=None):
101 """Run the tool on events and return output columns as an ak.Array.
102
103 Parameters
104 ----------
105 events:
106 An ak.Array with fields matching the tool's input column names
107 (after any rename_containers mapping).
108 systematic:
109 Optional systematic variation name (e.g. "MUON_EFF_RECO_SYS__1up").
110 If provided, applied before running the tool and reset to nominal
111 after execution.
112
113 Returns
114 -------
115 ak.Array
116 Record array with one field per output column, each a
117 variable-length list over the per-particle values.
118 """
119 if systematic is not None:
120 self.apply_systematic_variation(systematic)
121
122 try:
123 num_events = int(ak.num(events, axis=0))
124
125
126 effective = resolve_optional_columns(self._classified, events)
127
128
129 buffer_dict = extract_buffers(events, effective)
130
131
132 allocate_outputs(effective, buffer_dict)
133
134
135 for container_name, info in effective.items():
136
137 self._handle[container_name] = np.asarray(buffer_dict[container_name])
138
139
140 for nested_name in info["nested_offsets"]:
141 if nested_name in buffer_dict:
142 self._handle[nested_name] = np.asarray(buffer_dict[nested_name])
143
144
145 for col in info["inputs"]:
146 self._handle[col.name] = np.asarray(buffer_dict[col.name])
147
148
149 for col in info["outputs"]:
150 self._handle.set_column_void(col.name, buffer_dict[col.name], False)
151
152 self._handle.call()
153
154 return reconstruct_output(effective, buffer_dict, num_events)
155 finally:
156
157 if systematic is not None:
158 self.apply_systematic_variation("")