Files
musrfit/CLAUDE.md
T
2026-07-25 17:16:12 +02:00

7.8 KiB

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.