add CLAUDE.md

This commit is contained in:
2026-07-25 17:16:12 +02:00
parent ead8c4b17a
commit 63c8ae85e3
+148
View File
@@ -0,0 +1,148 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What this is
musrfit is a C++ data analysis package for time-differential μSR (muon spin rotation/relaxation)
and β-NMR data. It provides a fitting engine (`musrfit`), a viewer (`musrview`), Fourier transform
tools, run-management utilities, and a set of Qt-based GUI applications (musredit, musrWiz,
musrStep, mupp). It builds on CERN ROOT (Minuit2 for minimization) and depends on Boost, GSL,
FFTW3, and LibXml2.
## Build
Out-of-source CMake build only (in-source builds are refused). `ROOTSYS` must be set/sourced
before configuring (`. $ROOTSYS/bin/thisroot.sh` or equivalent).
```
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$ROOTSYS
cmake --build . --clean-first
cmake --install . # installs binaries + writes ~/.musrfit XML config
```
An existing `build/` tree from a prior configure already lives at `build/` in this checkout
(git-ignored). Reconfigure with `cmake ..` inside it rather than creating a second build dir.
Key CMake options (`-D<option>=1` to enable):
- `nexus` — NeXus (HDF4/HDF5) file format support (needed for ISIS data)
- `BMWlibs`, `ASlibs`, `BNMRlibs` — optional external theory-function libraries
- `DummyUserFcn` — build the example/template user function
- `qt_based_tools` (default ON) — build musredit/musrWiz/musrStep/mupp; auto-detects Qt6 → Qt5 → Qt4 → Qt3
- `qt_version` — force a specific Qt major version instead of auto-detect
- `try_OpenMP` (default ON) — use OpenMP if available
Requires ROOT >= 6.18, C++17. On macOS see `macos26_build_issues.txt` for two known local
workarounds (AGL framework must be dropped from Qt6 app linking; mupp needs a `mupp-1.1.0 -> mupp`
symlink under `MacOS`).
## Testing
Tests are registered with CTest from the top-level `tests/` directory (separate from the
developer sandbox in `src/tests/`, which is example/scratch code, not part of the test suite).
```
cd build
ctest # run everything
ctest -N # list tests without running
ctest -R test-histo-MusrRoot # run a single test by name (regex match)
ctest -R '^musrview-' # run just the musrview rendering tests
```
Two test families, both driven by Python wrapper scripts against `.msr` files in `doc/examples/`:
- `maxLH_check` (`tests/maxLH_check/`) — runs `musrfit` on an `.msr` file and asserts the final
max-log-likelihood/χ² value matches an expected value to 1e-4 (registered in
`tests/maxLH_check/CMakeLists.txt`).
- `musrview_check` (`tests/musrview_check/`) — runs `musrview` (optionally with `-f`/`-a` for
Fourier/averaged-Fourier) and compares rendered PNG output against references in
`tests/musrview_check/ref/`.
When adding a new example/regression case: drop the `.msr` (and data file) into `doc/examples/`,
then add a corresponding `add_maxLH_test(...)` / `add_musrview_test(...)` line in the relevant
`tests/*/CMakeLists.txt`.
## Documentation
The user documentation for setting it up, as well as for its usage can be find either under
../musrfit-docu (sphinx)
or under
https://lmu.pages.psi.ch/musrfit-docu/
## Architecture
### Core fitting pipeline
The central data model and control flow (all in `src/classes/` with headers in `src/include/`):
- **`PMsrHandler`** parses/writes the `.msr` fit-definition file format (theory block, parameters,
run blocks, Fourier/plot options) — the human-editable input driving every fit.
- **`PRunDataHandler`** loads raw histogram data from the various supported file formats
(MusrRoot/HDF5, PSI-BIN, PSI-MDU, ROOT (LEM), MUD (TRIUMF), NeXus, WKM-deprecated).
- **`PRunBase`** is the abstract base for all fit types; concrete subclasses implement
format/analysis-specific `PrepareData()`/theory-evaluation logic:
`PRunSingleHisto`, `PRunAsymmetry`, `PRunSingleHistoRRF`, `PRunAsymmetryRRF`,
`PRunAsymmetryBNMR`, `PRunMuMinus`, `PRunNonMusr`. The run type is selected by the
`PRUN_*` constants in `PMusr.h`.
- **`PRunListCollection`** aggregates all runs of a fit for global/simultaneous fitting.
- **`PTheory`** parses the algebraic theory expression from the msr file into a tree of built-in
functions (~34 of them) and evaluates it per bin.
- **`PFunction`** / `PFunctionHandler` / `PFunctionGrammar` / `PFunctionAst` implement a small
Boost.Spirit-based expression grammar used for user-defined parameter functions (FUNCTIONS block
in the msr file).
- **`PFitterFcn`** wraps the χ²/max-log-likelihood objective for ROOT's Minuit2; **`PFitter`**
drives the minimization and post-fit error analysis.
- **`PMusrCanvas`** / **`PFourier`** / **`PFourierCanvas`** / **`PPrepFourier`** handle plotting
and Fourier-transform display, used by `musrview`/`musrFT`.
- **`PMsr2Data`** implements `msr2data`'s logic for generating follow-up/global msr files from a
template across a run list.
Executables in `src/*.cpp` are thin drivers over these classes: `musrfit.cpp` (fitter),
`musrview.cpp` (viewer), `musrFT.cpp` (Fourier tool), `musrt0.cpp` (t0 determination),
`msr2data.cpp` / `msr2msr.cpp` (msr file generation/conversion), `addRun.cpp` (run summation),
`any2many.cpp` / `dump_header.cpp` / `write_musrRoot_runHeader.cpp` (format conversion/inspection),
`musrRootValidation.cpp`.
### Extending with user functions (plugins)
Beyond the built-in theory functions, custom physics models are added as `PUserFcnBase` subclasses
compiled into standalone shared libraries and loaded dynamically at runtime via ROOT's plugin
mechanism — no core rebuild needed. See the doc comment in `src/include/PUserFcnBase.h` for the
full header/impl/LinkDef pattern. Existing examples of this pattern live under `src/external/`
(`libFitPofB`, `libGbGLF`, `libLFRelaxation`, `libZFRelaxation`, `libSpinValve`, `libGapIntegrals`,
`libPhotoMeissner`, `libCalcMeanFieldsLEM`, `libCuba`, `LF_GL`, `Nonlocal`, `MagProximity`,
`DepthProfile`, `BMWtools`, `libBNMR`, `DummyUserFcn` as a minimal template). Each has its own
CMake option gate (`ASlibs`, `BMWlibs`, `BNMRlibs`, `DummyUserFcn`) or is built unconditionally.
### Third-party/vendored format support (`src/external/`)
`mud` (TRIUMF MUD format), `MusrRoot` (ROOT/HDF5-based format + its LaTeX definition doc),
`TLemRunHeader` (LEM ROOT files), `MuSR_software/Class_MuSR_PSI` (PSI-BIN/PSI-MDU), `nexus`
(NeXus/HDF4/HDF5, only built when `-Dnexus=1`) are vendored client libraries for reading each
raw data format; `PRunDataHandler` dispatches to the appropriate one based on file
extension/content.
### GUI tools (`src/musredit_qt6/`, with `_qt5`/legacy `musredit`/`musrgui` siblings)
Qt6 is the primary target; CMake auto-falls-back to Qt5 → Qt4 → Qt3 equivalents if Qt6 isn't
found (`qt_based_tools`/`qt_version` options above). Four independent Qt apps:
- `musredit` — msr-file editor/front-end for running `musrfit`.
- `musrWiz` — wizard for constructing new msr files from instrument/function templates
(`func_defs/`, `instrument_defs/`).
- `musrStep` — step-through/interactive fit tool.
- `mupp` — μSR parameter plotter (plots fit results extracted across multiple msr files).
### Runtime configuration
Installed binaries read an XML startup config from `~/.musrfit` (written at `cmake --install`
time), not from the source tree — check that location when debugging why an installed binary
behaves differently from a locally-built one in `build/`.
## Notes
- Version is tracked in `CMakeLists.txt` (`project(musrfit VERSION x.y.z ...)`); the current
branch (`root6`) is mid-refactor targeting ROOT 6-only support (`PMsrHandler` C++17 tokenizer
rewrite, `PMsrHighlighter` renamed to CERN/ROOT naming scheme — see `ChangeLog`).
- Full user documentation lives externally at https://lmu.pages.psi.ch/musrfit-docu/index.html,
not in this repo; `doc/` here holds Doxygen configs (`doc/*.dox`, `doc/*_dox.cfg`) and the
example/regression `.msr` files consumed by the test suite.