Small reusable helpers for HEP analysis code generated with large language models.
python -m pip install hep-llm-helpersThe xAOD helper module is imported as:
from hep_llm_helpers.xaod_hints import make_a_tool, make_tool_accessormake_a_tool adds the C++ tool initialization metadata to a func_adl query and
returns a ToolInfo handle. Pass that handle to make_tool_accessor to expose a
tool operation as a Python function that can be used inside a query. The accessor's
source_code is C++ and must assign its result to the variable named result.
Here is a complete ATLAS PHYSLITE b-tagging example. It configures the
BTaggingSelectionTool at the FixedCutBEff_77 operating point and returns both a
tag decision and a tag weight:
from func_adl_servicex_xaodr25 import FuncADLQueryPHYSLITE
from func_adl_servicex_xaodr25.xAOD.jet_v1 import Jet_v1
from hep_llm_helpers.xaod_hints import make_a_tool, make_tool_accessor
base_query = FuncADLQueryPHYSLITE()
# The tool name must be unique if a query uses more than one tool instance.
query_with_tool, tag_tool = make_a_tool(
base_query,
tool_name="btag_tool",
tool_type="BTaggingSelectionTool",
include_files=["xAODBTaggingEfficiency/BTaggingSelectionTool.h"],
link_libraries=["xAODBTaggingEfficiencyLib"],
init_lines=[
'ANA_CHECK(asg::setProperty({tool_name}, "OperatingPoint", "FixedCutBEff_77"));',
"ANA_CHECK({tool_name}->initialize());",
],
)
jet_is_tagged = make_tool_accessor(
tag_tool,
function_name="jet_is_tagged",
source_code=[
"result = static_cast<bool>({tool_name}->accept(*jet));",
],
arguments=[("jet", Jet_v1)],
return_type_cpp="bool",
return_type_python="bool",
)
tag_weight = make_tool_accessor(
tag_tool,
function_name="tag_weight",
source_code=[
"ANA_CHECK({tool_name}->getTaggerWeight(*jet, result, false));",
],
arguments=[("jet", Jet_v1)],
return_type_cpp="double",
return_type_python="float",
)
# Continue building the query from query_with_tool, not base_query, so the
# injected tool metadata is retained during ServiceX translation.
query = query_with_tool.Select(
lambda event: {
"jet_is_tagged": event.Jets().Select(lambda jet: jet_is_tagged(jet)),
"tag_weight": event.Jets().Select(lambda jet: tag_weight(jet)),
}
)The same pattern applies to other xAOD tools: initialize the tool once with
make_a_tool, create one or more accessors from its ToolInfo, and call those
accessors only in the query derived from the returned query object. Use a different
tool_name for each independently configured tool instance.
This project uses Hatch:
hatch run test:run
hatch buildThe local Hatch environments derive a development version from Git automatically. A release build derives the package version from the GitHub release tag.
Create a draft GitHub release with a tag such as v0.1.0, then publish the release.
The release.yml workflow builds the distributions and publishes them to PyPI using
GitHub OIDC trusted publishing. The repository must have a protected pypi environment
and a matching PyPI trusted publisher configuration before the first release.