101 """Run the tool on events and return output columns as an ak.Array.
106 An ak.Array with fields matching the tool's input column names
107 (after any rename_containers mapping).
109 Optional systematic variation name (e.g. "MUON_EFF_RECO_SYS__1up").
110 If provided, applied before running the tool and reset to nominal
116 Record array with one field per output column, each a
117 variable-length list over the per-particle values.
119 if systematic
is not None:
123 num_events = int(ak.num(events, axis=0))
126 effective = resolve_optional_columns(self.
_classified, events)
129 buffer_dict = extract_buffers(events, effective)
132 allocate_outputs(effective, buffer_dict)
135 for container_name, info
in effective.items():
137 self.
_handle[container_name] = np.asarray(buffer_dict[container_name])
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])
145 for col
in info[
"inputs"]:
146 self.
_handle[col.name] = np.asarray(buffer_dict[col.name])
149 for col
in info[
"outputs"]:
150 self.
_handle.set_column_void(col.name, buffer_dict[col.name],
False)
154 return reconstruct_output(effective, buffer_dict, num_events)
157 if systematic
is not None: