Commit Graph
383 Commits
Author SHA1 Message Date
suter_aandClaude Opus 5 618e96fb00 fix musrview ctest failures on macOS: RGB order and path buffers
Build and Deploy Documentation / build-and-deploy (push) Successful in 27s
Three unrelated issues made the musrview_check tests fail on macOS while
passing on Linux.

1. Unspecified argument evaluation order

   TColor::GetColor(rand.Integer(255), rand.Integer(255), rand.Integer(255))

   evaluates its (side-effecting) arguments in an unspecified order: clang
   goes left-to-right, gcc right-to-left, so the same seed yielded RGB on
   one platform and BGR on the other. Visible whenever more runs are
   plotted than the startup xml colour list provides, e.g.
   test-histo-HAL9500.msr with 16 runs against 10 colours.

   The rgb values are now drawn into separate variables first. This keeps
   the clang result and changes gcc to match, hence the regenerated
   reference PNG for musrview-histo-HAL9500 (99.94% of the differing
   pixels were exact R<->B swaps).

   Fixed in PMusrCanvas, PFourierCanvas and both mupp PMuppCanvas copies.

2. Fixed size path buffers

   char fileName[128] plus strncpy(dst, src, sizeof(dst)) truncates *and*
   leaves the buffer unterminated once the path reaches the buffer size.
   musrview then failed on a 132 character msr-path in doc/examples/ViewOpts.
   musrFT and musrt0 were worse: an unbounded strcpy of the startup file
   path into char startup_path_name[128], i.e. a stack buffer overflow.

   All path/filename buffers in the drivers are now std::string:
   musrview, musrFT, musrt0, musrfit, any2many, addRun, dump_header.
   PMusrCanvas::SaveGraphicsAndQuit() takes const Char_t* accordingly.

   Along the way in the same files:
   - msr2msr_replace() wrote a 256 byte line into char temp[128]
   - msr2msr assembled "cp"/"rm" shell commands from paths in a 256 byte
     buffer; replaced by std::filesystem
   - msr2msr and addRun read lines with getline(buf, N), which silently
     abandons the rest of the file on the first over-long line
   - addRun: bound the unbounded sscanf "%s" to "%255s"
   - dropped scratch buffers that only held a string literal, in favour of
     TString::ReplaceAll(const char*, const char*)

3. musrview_check.py left its PNGs behind on failure

   The two early error returns skipped the cleanup, and since generated
   PNGs were identified by "not in the pre-run snapshot", one leftover file
   permanently masked the real output of that test: musrview overwrites the
   stale PNG, so it was there, just filtered out. One failure thus poisoned
   every later run (30 of the 37 observed failures) after a 15 s poll each.

   Cleanup now runs in a finally block on every exit path, and generated
   PNGs are detected by mtime instead, which sees rewritten leftovers while
   staying safe for a sibling test running concurrently under ctest -j.
   Also dropped the MUSRVIEW_PNG_DIR env var and its tmp-dir fallback: it
   is read nowhere in src/, so the fallback was dead code that guaranteed
   the full 15 s poll before every "no PNGs found" failure.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 19:44:50 +02:00
suter_aandClaude Opus 5 0577d5d211 fix dead time correction for Red/Green (period) NeXus IDF V2 data
Build and Deploy Documentation / build-and-deploy (push) Successful in 34s
Since the Red/Green mode handling was added for NeXus HDF5 IDF V2, the
histogram numbers of the routed histograms carry the period offset, i.e.
histoNo = period*10000 + histo. PRunBase::DeadTimeCorrection() was still
addressing the dead time parameter vector with 'histoNo-1', hence for any
period > 0 it read far beyond the end of the vector. The garbage picked up
there scaled the counts, so every invocation of musrfit gave a different
(sometimes nan) result for the affected run blocks.

The dead time parameters are stored contiguously, period-by-period, and
therefore need to be addressed as period*noOfHistosPerPeriod + histo - 1.
Introduce PERIOD_HISTO_OFFSET for the period encoding, keep the number of
histos per period in PRawRunData, and add PRawRunData::GetDeadTimeParam(histoNo)
which does the mapping and guards against out-of-range access.

Cross-checked against the HDF4 IDF V1 twin of the same run, where the two
periods are flattened into histos 1-192: both readers now yield bit-identical
chisq, with and without dead time correction.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 11:10:53 +02:00
suter_a e663d229e6 Merge remote-tracking branch 'origin/refactor-pmsrhandler-cpp17-tokenizer' into root6 2026-07-22 08:03:49 +02:00
suter_a 1f4fa54928 add Red/Green mode handling for NeXus HDF5 IDF V2. See also the musrfit docu.
Build and Deploy Documentation / build-and-deploy (push) Successful in 32s
2026-07-15 07:54:42 +02:00
suter_aandClaude Sonnet 4.6 05d8d51699 guard all any_cast attribute reads in ReadNexusFileIdf1 against bad_any_cast
Build and Deploy Documentation / build-and-deploy (push) Successful in 29s
Uncaught std::bad_any_cast calls terminated the program when an HDF4
attribute's stored type didn't match the expected type (e.g. vector<int>
instead of int, or a non-string units attribute). Wrap all eight attribute
casts with try/catch so type mismatches produce a warning rather than a crash.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-13 08:05:38 +02:00
suter_a 61e7fac90a fix of wrong type: float instead of int, for frames_good.
Build and Deploy Documentation / build-and-deploy (push) Successful in 32s
2026-07-12 16:59:24 +02:00
suter_aandClaude Sonnet 4.6 471b928622 Fix macOS 26 CLING runtime dictionary errors caused by Homebrew/SDK header conflicts
macOS 26 (Darwin 25.5.0) introduced stricter Clang module map rules in
DarwinFoundation1.modulemap: the '_c_standard_library_obsolete' module
now requires the 'found_incompatible_headers__check_search_paths' feature,
which CLING's runtime interpreter does not set. When fftw3.h (from
/opt/homebrew/include) was parsed by CLING via the inlined PStartupHandler
dictionary payload, it triggered this module map error, causing all
PStartupHandler signal/slot connections to fail.

Two fixes:
- PMusr.h: guard '#include "fftw3.h"' with '#ifndef __CLING__'. No fftw
  types appear in PMusr.h class definitions, so CLING does not need it
  for reflection. This is the primary runtime fix.
- CMakeLists.txt (src/classes and all src/external libs): replace
  '-I${FFTW3_INCLUDE}', '-I${Boost_INCLUDE_DIRS}', '-I${GSL_INCLUDE_DIRS}',
  and '-I${ROOT_INCLUDE_DIRS}' with '-isystem' in all root_generate_dictionary
  OPTIONS blocks, and change 'include_directories(${FFTW3_INCLUDE})' to
  'include_directories(SYSTEM ...)'. Internal project paths (MUSRFIT_INC,
  BMW_TOOLS_INC, NONLOCAL_INC, CMAKE_CURRENT_SOURCE_DIR, etc.) keep '-I'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-27 14:06:11 +02:00
suter_aandClaude Opus 4.8 07f9c744b3 PStringUtils::IsInt: accept an optional leading sign
IsInt now recognises (possibly signed) integers such as "-5" or "+42",
making it slightly more permissive than TString::IsDigit(). A lone sign,
a double sign, or a sign following a digit are still rejected. strToNum
test expectations updated accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 14:14:11 +02:00
suter_aandClaude Opus 4.8 bb32426005 PStringUtils::ToDouble: signal conversion errors like ToInt
ToDouble() had the same shortcoming as ToInt(): wrapping strtod() with a
nullptr endptr made a failed conversion indistinguishable from a
legitimate 0.0. Add an optional `bool *ok` out-parameter that reports
success. strtod() (with endptr + errno) is kept instead of
std::from_chars so the accepted input set stays identical to
TString::Atof() (leading whitespace skipped, leading '+' honoured,
trailing characters ignored); ok is set false on a non-numeric string or
an ERANGE overflow. The parameter defaults to nullptr, so existing call
sites keep compiling unchanged.

Convert the IsFloat-guarded ToDouble call sites in PMsrHandler to the
single-parse ToDouble(token, &ok) form (replacing the IsFloat() guard +
separate ToDouble() that parsed every token twice). All downstream
>=0 / <=0 / range checks are preserved, and push_back sites only append
on success so no spurious 0.0 is stored on error. Number-vs-keyword
discriminators (pos.error/boundary "none", rrf_phase/fourier-phase parX)
are restructured so the keyword branch is taken when ok is false.

As a side effect this fixes a latent gap in the GLOBAL rrf_freq handler,
where a non-numeric frequency previously slipped through with a stale
value instead of raising an error.

The IsFloat-guarded ToInt fit-range offsets (fgb/lgb) are intentionally
left untouched, as there the guard type differs from the conversion.

All 85 integration tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 12:08:01 +02:00
suter_aandClaude Opus 4.8 4319b4ad69 PStringUtils::ToInt: signal conversion errors via from_chars
ToInt() previously wrapped strtol() with a nullptr endptr, so a failed
conversion was indistinguishable from a legitimate 0 (matching the old
TString::Atoi() behaviour). Switch the implementation to std::from_chars
and add an optional `bool *ok` out-parameter that reports success: it is
set to false on a non-numeric string or an out-of-range value, true
otherwise. Leading whitespace is skipped and trailing characters are
ignored, preserving the Atoi-like prefix semantics. The parameter
defaults to nullptr, so existing call sites keep compiling unchanged.

Convert the parse-validation call sites in PMsrHandler to the single
-parse ToInt(token, &ok) form, replacing the IsInt() guard + separate
ToInt() (which parsed every token twice). All downstream >0 / >=0 /
range / enum checks are preserved.

Left untouched the call sites where IsInt() acts as a structural
discriminator rather than a numeric validator (write path, xy-data
index-vs-label, fParamInUse usage scans) and the IsFloat-guarded ToInt
offsets, where switching to ToInt(&ok) would change parsing semantics.

All 85 integration tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 11:54:33 +02:00
suter_aandClaude Opus 4.8 b072a481ba PMsrHandler: replace ROOT tokenizer machinery with C++17 PStringUtils
Reduce the ROOT footprint of the MSR parser by removing the pervasive
TString::Tokenize / TObjArray / TObjString / dynamic_cast pattern (28
tokenize sites, 14 TObjArray, 106 TObjString) used to split lines into
tokens, together with the manual `delete tokens` cleanup.

Add a new dependency-free C++17 utility class PStringUtils (Split, IsInt,
IsFloat, ToInt, ToDouble, IsEqualNoCase, ContainsNoCase, BeginsWithNoCase)
that replicates the relevant TString semantics exactly, so it can be reused
elsewhere in the suite. IsInt/IsFloat tolerate surrounding whitespace to
match TString::IsDigit/IsFloat (needed for tokens split on ',' / ';' only).

The public API and the PMusr.h data structures keep TString unchanged; only
the internal tokenizing logic is rewritten. Net -451 lines in
PMsrHandler.cpp. All 85 integration tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 11:15:02 +02:00
suter_a 9aae350c13 move DeadTimeCorrection to PRunBase. Make ADDRUN part in PrepareData more readable. 2026-02-20 18:17:05 +01:00
suter_a 6a41458310 start working on the deadtime correction. 2026-02-08 15:34:22 +01:00
suter_a 3bb004ea2d more work on the NeXus write routines. 2026-02-07 11:31:11 +01:00
suter_a 300c9200df start implementing the NeXus write routines, needed by any2many. 2026-02-07 08:05:42 +01:00
suter_a dfa8852cfe removed debug tag. 2026-02-06 15:14:25 +01:00
suter_a 810306cb2a first full IDF V2 implementation. 2026-02-05 10:59:15 +01:00
suter_a 43cb8b2460 start with the implementation of NeXus IDF V2. 2026-02-04 19:48:38 +01:00
suter_a ceb9673330 read deadtime parameters for IDF V1. 2026-02-04 17:57:48 +01:00
suter_a b262ee33c5 start implementing with the deadtime correction, if present 2026-02-04 13:20:10 +01:00
suter_a 12888be4c9 add deadtime correction related params. 2026-02-04 11:06:56 +01:00
suter_a 867ac4895b switched to HDF4/HDF5 template loading in order to simplify the code. 2026-02-04 09:26:49 +01:00
suter_a f66c832d56 updated the copyright info. 2026-01-25 07:45:44 +01:00
suter_a 4adf66cb26 replace 'nil' by 'leer' since 'nil' leads to conflict with macOS. 2025-12-30 14:34:26 +01:00
suter_a 418ca6b0a1 add missing header file PFunctionsAst.h 2025-12-30 13:56:50 +01:00
suter_a 73aff4ec69 modernize musrfit function handling using spirit x3 instead of spirit classic now. 2025-12-30 13:31:18 +01:00
suter_a 0db498284f improve the doxygen docu of PUserFcn.* and PUserFcnBase.*
Build and Deploy Documentation / build-and-deploy (push) Successful in 18s
2025-11-23 17:58:07 +01:00
suter_a d8ae606a55 improve the doxygen docu of PTheory.* 2025-11-23 17:47:46 +01:00
suter_a e940ad09b4 improve the doxygen docu of PStartupHandler.* 2025-11-23 17:35:31 +01:00
suter_a 633f63b104 improve the doxygen docu of PRunSingleHistoRRF.* 2025-11-23 17:25:45 +01:00
suter_a fa1d496cf5 improve the doxygen docu of PRunSingleHisto.*
Build and Deploy Documentation / build-and-deploy (push) Successful in 19s
2025-11-15 21:31:09 +01:00
suter_a 310713da0e improve the doxygen docu of PRunNonMusr.* 2025-11-15 08:42:21 +01:00
suter_a 3e545f1d50 improve the doxygen docu of PRunMuMinus.* 2025-11-15 08:35:24 +01:00
suter_a 278fd47e52 improve the doxygen docu of PRunListCollection.* 2025-11-15 08:27:51 +01:00
suter_a 26b87e0659 improve the doxygen docu of PRunDataHandler.h 2025-11-15 08:16:15 +01:00
suter_a 38decd8b58 improve the doxygen docu of PRunBase.* 2025-11-15 08:02:11 +01:00
suter_a a05b4fe867 improve the doxygen docu of PRunAsymmetryRRF.* 2025-11-15 07:54:12 +01:00
suter_a 7b82b2c2c8 improve the doxygen docu of PRunAsymmetry.*. 2025-11-15 07:43:49 +01:00
suter_a 4d5ad0a00c improve doxygen documentation of PRunAsymmetryBNMR.*
Build and Deploy Documentation / build-and-deploy (push) Successful in 17s
2025-11-14 10:21:07 +01:00
suter_a c5d5038b4d improve doxygen documentation of PRgeHandler.* 2025-11-14 10:05:36 +01:00
suter_a be8161bac1 improve doxygen documentation of PPrepFourier.* 2025-11-14 09:57:18 +01:00
suter_a cdd248d116 improve doxygen documentation of PMusrT0.* 2025-11-14 09:48:35 +01:00
suter_a 26d55bc048 improve doxygen documentation of PMusrCanvas.* 2025-11-14 09:36:18 +01:00
suter_a 218e2125e3 improve doxygen documentation of PMsrHandler.* 2025-11-14 09:22:24 +01:00
suter_a 5f1b4fa5f5 improve doxygen documentation of PMsr2Data.* 2025-11-14 09:11:28 +01:00
suter_a a40c431396 improve doxygen documentation of PMsgBox.* 2025-11-14 07:57:06 +01:00
suter_a 40a797c0da improve doxygen documentation of PFunction.* and PFunctionGrammar.h
Build and Deploy Documentation / build-and-deploy (push) Successful in 18s
2025-11-14 07:50:50 +01:00
suter_a f8a2d646dc improve the doxygen docu.
Build and Deploy Documentation / build-and-deploy (push) Successful in 19s
2025-11-13 08:36:42 +01:00
suter_a 25024aae6b improve the doxygen docu with the help of Claude AI.
Build and Deploy Documentation / build-and-deploy (push) Successful in 17s
2025-11-12 20:32:20 +01:00
suter_a 9363bafec4 make sure that the comment content is not confused with end of comment. 2025-11-12 08:06:38 +01:00