Since musrview is built on the ROOT7 web graphics it needs a fair number of ROOT build options which are not all on by default. Without them musrview either does not compile at all or, worse, compiles and then shows a blank window at run time. The only check so far was for the ROOT::ROOTWebDisplay target. The new cmake/MusrfitCheckROOT7.cmake collects all problems and reports them in one go, together with the ROOT cmake flags needed to fix them: - the ROOT build options root7, webgui and http (ROOT_<option>_FOUND), - the libraries ROOT::ROOTWebDisplay and ROOT::RHTTP, - the headers ROOT/RWebWindow.hxx and ROOT/RWebWindowsManager.hxx, - the API itself, through a compile-only check of the calls musrview and PMusrWebCanvas make. If that fails it is retried in the ROOT::Experimental namespace, which tells the user that the ROOT is older than 6.32 instead of leaving them with a compiler error, - JSROOT: the js directory (overridable with -DMUSRVIEW_JSROOT_DIR=<dir>), the modules musrview.html imports and the '<!--jsroot_importmap-->' support of THttpServer which resolves the 'jsroot/...' specifiers. Not fatal, but warned about and shown in the config summary: - MUSRVIEW_HAS_QT6WEB: without ROOT's qt6web musrview falls back from its embedded window to the standard browser of the system, - MUSRVIEW_HAS_IMAGE_EXPORT: without libASImage 'musrview --png/--gif/--jpg' writes nothing. In that case the musrview_check tests, which compare rendered PNGs, are no longer registered - they could then only fail for a reason that has nothing to do with musrfit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013Ck7v5F7KjinfC2EyE7K3C
10 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 librariesDummyUserFcn— build the example/template user functionqt_based_tools(default ON) — build musredit/musrWiz/musrStep/mupp; auto-detects Qt6 → Qt5 → Qt4 → Qt3qt_version— force a specific Qt major version instead of auto-detecttry_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/) — runsmusrfiton an.msrfile and asserts the final max-log-likelihood/χ² value matches an expected value to 1e-4 (registered intests/maxLH_check/CMakeLists.txt).musrview_check(tests/musrview_check/) — runsmusrview(optionally with-f/-afor Fourier/averaged-Fourier) and compares rendered PNG output against references intests/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/):
PMsrHandlerparses/writes the.msrfit-definition file format (theory block, parameters, run blocks, Fourier/plot options) — the human-editable input driving every fit.PRunDataHandlerloads raw histogram data from the various supported file formats (MusrRoot/HDF5, PSI-BIN, PSI-MDU, ROOT (LEM), MUD (TRIUMF), NeXus, WKM-deprecated).PRunBaseis the abstract base for all fit types; concrete subclasses implement format/analysis-specificPrepareData()/theory-evaluation logic:PRunSingleHisto,PRunAsymmetry,PRunSingleHistoRRF,PRunAsymmetryRRF,PRunAsymmetryBNMR,PRunMuMinus,PRunNonMusr. The run type is selected by thePRUN_*constants inPMusr.h.PRunListCollectionaggregates all runs of a fit for global/simultaneous fitting.PTheoryparses 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/PFunctionAstimplement a small Boost.Spirit-based expression grammar used for user-defined parameter functions (FUNCTIONS block in the msr file).PFitterFcnwraps the χ²/max-log-likelihood objective for ROOT's Minuit2;PFitterdrives the minimization and post-fit error analysis.PMusrViewMode/PMusrViewModel/PMusrWebCanvas(namespacemusrview) are whatmusrviewis built from since the ROOT7 rewrite:PMusrViewModedescribes what is shown as four orthogonal properties: domain (time/Fourier), Fourier component, difference (and whether it is formed before or after the transform, d-f vs f-d) and average. No GUI/ROOT dependency; unit tested intests/viewmode_check/.PMusrViewModelis the GUI-free data layer: it builds the data/theory histograms, their Fourier transforms, the differences and the average, and answersGetCurves(mode)with the histograms that mode makes visible. Plotting and ascii export both go through that one selector, so they cannot disagree.PMusrWebCanvasis the front end.CollectDrawables()returns the objects of the current view with their ROOT draw options; from that, the interactive path serializes a plainTListwithTBufferJSONand pushes it through anROOT::RWebWindowto a JSROOT page (src/musrview_web/musrview.html), which draws them in order and shows title/parameters/theory/run-info as scrollable, individually collapsible HTML panels. Deliberately noTCanvasis built for that path: a TCanvas maps its window in the constructor, which would put an empty ROOT window next to the musrview window (togglinggROOT->SetBatch()at run time crashes inTCanvas::Build(), and ROOT web canvases open their own window). The graphics export (--png, ...) uses the same collector but draws into a realTCanvaswith the classic pad layout, running with ROOT in batch mode, so batch runs need no browser.- The web assets are installed to
<prefix>/share/musrfit/musrview; setMUSRFIT_WEB_DIRto run from the source tree, andMUSRVIEW_DEBUG=1to trace the websocket traffic. - musrview needs a ROOT built with
-Droot7=ON -Dwebgui=ON -Dhttp=ON, plus-Dqt6web=ONfor the embedded window (--embedded, the default).--browseruses the system browser,--browser=serveronly prints the URL. All of that (build options,ROOT::ROOTWebDisplay/ROOT::RHTTP, the ROOT7 headers, theROOT::RWebWindowAPI itself via a compile check, JSROOT and its import map) is verified at config time bycmake/MusrfitCheckROOT7.cmake, which also setsMUSRVIEW_HAS_QT6WEB/MUSRVIEW_HAS_IMAGE_EXPORT(the latter gates themusrview_checktests, since they compare rendered PNGs and thus need ROOT's libASImage).
PFourier/PFourierCanvas/PPrepFourierhandle the Fourier transform and its (still TCanvas based) display, used bymusrview/musrFT.PMsr2Dataimplementsmsr2data'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 runningmusrfit.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 (PMsrHandlerC++17 tokenizer rewrite,PMsrHighlighterrenamed to CERN/ROOT naming scheme — seeChangeLog). - 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.msrfiles consumed by the test suite.