Skip to content

Commit f1e51c6

Browse files
committed
feature to get necessary branches
1 parent c666e03 commit f1e51c6

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Copyright (c) 2025, IRIS-HEP
2+
# All rights reserved.
3+
#
4+
# Redistribution and use in source and binary forms, with or without
5+
# modification, are permitted provided that the following conditions are met:
6+
#
7+
# * Redistributions of source code must retain the above copyright notice, this
8+
# list of conditions and the following disclaimer.
9+
#
10+
# * Redistributions in binary form must reproduce the above copyright notice,
11+
# this list of conditions and the following disclaimer in the documentation
12+
# and/or other materials provided with the distribution.
13+
#
14+
# * Neither the name of the copyright holder nor the names of its
15+
# contributors may be used to endorse or promote products derived from
16+
# this software without specific prior written permission.
17+
#
18+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
29+
import awkward as ak
30+
from awkward.forms import RecordForm, NumpyForm, ListOffsetForm
31+
32+
33+
def add_keys(original_form):
34+
"""
35+
Add a form_key to the parent Record and to every child ListOffset/content associated to a field.
36+
37+
Parameters:
38+
original_form (ak.forms.Form): Form of the awkward array the typetracer will be built upon.
39+
This should be a RecordForm, which contains fields and contents.
40+
41+
Returns:
42+
RecordForm:
43+
"""
44+
45+
# RecordForm: zip contents + field names, recurse on each child,
46+
# then rebuild with each child's form_key set to its field name
47+
if isinstance(original_form, RecordForm):
48+
new_contents = []
49+
for child, name in zip(original_form.contents, original_form.fields):
50+
child = child.copy(form_key=name)
51+
new_contents.append(child)
52+
return RecordForm(
53+
new_contents,
54+
original_form.fields,
55+
form_key="RecordForm_key", # Give name to parent RecordForm
56+
parameters=original_form.parameters,
57+
)
58+
59+
else:
60+
raise ValueError(
61+
f"Unsupported form type: {type(original_form)}. "
62+
"This function only supports RecordForm."
63+
)
64+
65+
66+
def is_branch_buffer(form_key, attribute, form):
67+
# rename any node that has no form_key
68+
if form_key is None:
69+
return "Not-a-branch"
70+
return f"{form_key}"
71+
72+
73+
def build_typetracer(form):
74+
"""
75+
Build a typetracer from an awkward form, adding keys to the RecordForm and ListOffsetForm.
76+
77+
Parameters:
78+
form (ak.forms.Form): Form of the awkward array the typetracer will be built upon.
79+
80+
Returns:
81+
tracer, report: ak.typetracer.TypeTracer: the typetracer built from the array form.
82+
"""
83+
stamped_form = add_keys(form)
84+
85+
tracer, report = ak.typetracer.TypeTracer(
86+
stamped_form,
87+
buffer_key=is_branch_buffer,
88+
highlevel=True,
89+
behavior=None,
90+
attrs=None,
91+
)
92+
return tracer, report
93+
94+
95+
def necessary_branches(report):
96+
"""
97+
Utility function to get the necessary branches from a typetracer report.
98+
99+
Parameters:
100+
report (ak.typetracer.Report): Report from the typetracer.
101+
102+
Returns:
103+
list: List of necessary branches.
104+
"""
105+
return [
106+
br for br in report.data_touched if br != "Not-a-branch"
107+
] # filter out "Not-a-branch"

0 commit comments

Comments
 (0)