This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This project is managed with uv.
uv sync # install core dependencies into .venv
uv sync --all-extras # also install optional torch/dnn dependencies
source .venv/bin/activate # or prefix every command with `uv run`The unified CLI entry point is wcpy (also aliased as wirecell):
wcpy --help
wcpy help all # show every namespace and its commands
wcpy help wirecell.util # show just the util namespace (dot or slash notation)Run tests with the system pytest (the venv pytest is currently broken due to a missing iniconfig dependency):
pytest test/ # top-level test suite
pytest wirecell/util/test/test_tdm.py # single test file
pytest wirecell/util/test/test_tdm.py::test_tree_empty # single testBuild a wheel:
uv buildThe wirecell/ directory is both the Python package root and the git repo root (non-standard src-less layout declared in pyproject.toml).
Each functional area lives in a sub-package:
| Sub-package | Domain |
|---|---|
util |
General I/O, LMN resampling, wire geometry, TDM, frame helpers, plotting |
resp |
Field/electronics response ingestion, resampling, Garfield file parsing |
sigproc |
Signal processing, noise models, ForWaRD simulation |
gen |
Deposition and frame simulation (tracks, noise spectra) |
img |
Cluster graph loading and conversion to VTK/Bee formats |
raygrid |
Ray-grid tiling and wire-plane coordinate tools |
dfp |
Data-flow programming graph construction (NetworkX + GraphViz) |
pgraph |
WCT config → GraphViz dot visualization |
bee |
Bee visualization server file helpers |
docs |
index.md generation, staleness checking, LLM prompt emission |
dnn / pytorch |
PyTorch DNN training (optional; requires torch extra) |
Every sub-package exposes a Click command group via __main__.py:
from wirecell.util.cli import context, log
@context("myns") # registers the group as "wcpy myns"
def cli(ctx):
"""Docstring becomes the namespace help text."""
pass
@cli.command("my-cmd")
def cmd_my_cmd():
"""Per-command help text."""
log.info("use log, not print()")wirecell/__main__.py imports each sub-package's cli object and attaches it to the root group. Adding a new namespace means adding it to the subs string there.
The @context decorator automatically adds -l/--log-output and -L/--log-level options to every group. Use the module-level log from wirecell.util.cli for all output (not print()).
CLI path arguments in wcpy docs and wcpy help accept both slash notation (wirecell/util) and dot notation (wirecell.util).
units.py— WCT system of units (base unit: millimeter). Always usefrom wirecell import unitsand express physical quantities as e.g.3.0 * units.cm. Theunitify()function inutil.functionsevaluates unit strings like"3*cm".jsio.py— unified JSON/Jsonnet loader; respectsWIRECELL_PATHenv var and-JCLI option for search paths. Usejsio.load(fname, paths)rather than rawjson.load.ario.py— dict-like read-only access to.npz,.zip,.tararchives with lazy loading.ario.load(path)is the entry point.tdm.py— WCT Tensor Data Model:Treeclass models HDF5-style nested tensors;tdm.load(ario_file)returns a list ofTreeobjects.cli.py— shared Click decorators:context,jsonnet_loader,frame_input,image_output.lmn.py— LMN rational resampling;lmn.interpolate(signal, new_period)is the main entry point.frames.py—Framedataclass wrapping (samples, channels, tickinfo) arrays from WCT.npzframe files.
WCT data flows through several file types:
.npzframes: arrays namedframe_<tag>_<index>,channels_<tag>_<index>,tickinfo_<tag>_<index>.json/.jsonnet: detector configuration and geometry files; resolved viaWIRECELL_PATH- TDM archives (
.npz,.tar,.zip): keys followtensorset_<id>/tensor_<id>_<idx>_metadata/tensor_<id>_<idx>_arraypattern detectors.jsonnetregistry (found viaWIRECELL_PATH): maps canonical detector names to their file paths
Each sub-package directory contains an index.md with YAML frontmatter tracking source-hash and children-hash. Use wcpy docs to manage these:
wcpy docs check all # check staleness
wcpy docs prompt wirecell/util # emit LLM prompt for one module
wcpy docs prompt --monolith # emit combined prompt for all stale modules
wcpy docs prompt --script # emit shell script using $WCPY_LLM
wcpy docs apply < llm_output.md # write FILE blocks from LLM response
wcpy docs show wirecell.util # display a module's index.md