Commit Graph
211 Commits
Author SHA1 Message Date
kferjaoui d2c5318312 Add notebook for hz data
Build on RHEL8 / build (push) Successful in 3m33s
Build on RHEL9 / build (push) Successful in 3m40s
Run tests using data on local RHEL8 / build (push) Successful in 4m11s
2026-09-02 10:25:23 +02:00
kferjaoui a9ee1fc074 deck: identify Test3 as the CPU/CPU divergence channel
Build on RHEL8 / build (push) Successful in 3m19s
Build on RHEL9 / build (push) Successful in 3m38s
Run tests using data on local RHEL8 / build (push) Successful in 4m16s
Slide 30 reported an 8/11 cluster mismatch between ClusterFinder and
ClusterFinderFrozen without naming its cause. Two experiments now do.
Instrumented: 974 divergent pixels partition onto the three decisions with
no remainder -- Test1 619 flips / 0 clusters, Test3 347 / 11, local-max gate
8 / 8. Ablated: the 11 go to exactly zero. Corrects a claim the data refuted
-- Test1 initiates independently, ~7x slower, and never creates a cluster.

AARE_BRANCH_TRACE defaults to 0 and folds away at compile time, so the CPU
baseline the deck quotes is unaffected. AARE_TEST3_ENABLED defaults to 1.

New annex A7 (2 slides): part 1 restores the third test slide 4 omits and
derives c3 from variance addition; part 2 carries the measurement.

fig_test3 painted a completed branch map with a "scan is here" cursor over
it -- now the finished frame, arrows meaning raster order, shadow given its
own fill so a photon stops looking 3x4 wide, frozen in red so amber keeps
one meaning. fig_overlap_9x9: row spacing now clears the tag, not the lane.

New docs/deck/QA.md: the code and algorithm questions this raised, with
where each is settled. Also retired 3 figures placed on no slide; annex
count in report and README was stale (6/53, now 7/55).
2026-08-26 17:14:31 +02:00
kferjaoui 9665df975c docs: detail opt2, op3 and opt5->opt6 explanaitons 2026-08-26 14:38:23 +02:00
kferjaoui 4c0a093e9f docs: Performance study
Build on RHEL8 / build (push) Successful in 3m18s
Build on RHEL9 / build (push) Successful in 4m3s
Run tests using data on local RHEL8 / build (push) Successful in 4m10s
2026-08-21 10:04:08 +02:00
kferjaoui 7177f00fc7 Benchmarking of CUDA cluster finder 2026-08-11 13:13:56 +02:00
kferjaoui ce256dd30f Save changes 2026-08-06 14:01:23 +02:00
kferjaoui 3504d96336 ClusterFinderFrozen: CPU finder for CUDA correctness study
- Diagnostic twin of ClusterFinder: identical decisions, but the pedestal is
  frozen per frame (snapshot at frame start, updates deferred to frame end),
  matching the CUDA kernel's update model.
- Isolates pedestal-update timing as the sole remaining CPU/GPU mismatch.
- Adds class + bindings + factory, validation notebook, and helper utilities.
2026-08-03 11:59:27 +02:00
kferjaoui a42d71cf42 Graph-based CUDA ClusterFinder (ClusterFinderCUDAGraph)
- CUDA Graph variant of ClusterFinderCUDA: one pre-recorded graph per stream
  (memset + H2D + kernel + D2H), with per-frame src/dst pointers swapped via
  cudaGraphExecMemcpyNodeSetParams to cut per-frame launch overhead.
- Exposed through the _aare_cuda bindings and a ClusterFinderCUDAGraph factory.
2026-08-03 11:53:51 +02:00
kferjaoui 1bf317f42a CUDA: double-precision device path, local-max fix, pedestal introspection
- DEVICE_PED_TYPE for device pedestal/variance (shipped double/double to match
    the double CPU ClusterFinder).
- Local-max suppression in Test 1/Test 3: non-peak pixels no longer store or
    update, mirroring ClusterFinder's `value < max -> continue`.
- device_pedestal()/device_noise() accessors (+ bindings) for the in-kernel
    decision-time pedestal.
2026-08-03 11:39:02 +02:00
kferjaoui 156667efde Merge 'origin/main' into feature/cuda_clusterfinder 2026-07-21 15:21:49 +02:00
4aadb6f7f0 refactor: hide Minuit2 from aare's public API (#331)
Build on RHEL9 / build (push) Successful in 3m13s
Build on RHEL8 / build (push) Successful in 3m52s
Run tests using data on local RHEL8 / build (push) Successful in 3m56s
Build on local RHEL8 / build (push) Successful in 2m45s
- Move Chi2.hpp from include/aare/ to src/ (private)
- Pimpl on FitModel<Model>: MnUserParameters/MnStrategy behind opaque
src/FitModelImpl.hpp, no Minuit2 includes in public headers
- Move fit_pixel/fit_3d bodies to Fit.cpp with explicit instantiations
for all 8 models; drop FCN template param from public API
- CMake: aare::Minuit2 wrapped in $<BUILD_INTERFACE:...> (hidden from
exported targets, same pattern as lmfit), MINUIT2_INSTALL OFF, Chi2.hpp
removed from PUBLICHEADERS
- Update python bindings and benchmark callsites accordingly

---------

Co-authored-by: Erik Fröjdh <erik.frojdh@psi.ch>
Co-authored-by: Alice <alice.mazzoleni@psi.ch>
2026-07-02 16:04:22 +02:00
mazzol_a b4686e6b85 added moench05 defs (#333)
Build on RHEL9 / build (push) Successful in 2m37s
Build on RHEL8 / build (push) Successful in 3m16s
Run tests using data on local RHEL8 / build (push) Successful in 3m56s
Build on local RHEL8 / build (push) Successful in 2m42s
- add moench05 chip/chiptestboard defs
2026-06-26 17:43:06 +02:00
Erik Fröjdh b4b28fc9e0 len() and pedestal subtraction (#328)
Build on RHEL9 / build (push) Successful in 2m57s
Build on RHEL8 / build (push) Successful in 3m28s
Run tests using data on local RHEL8 / build (push) Successful in 4m0s
Build on local RHEL8 / build (push) Successful in 2m44s
Collection of small improvements in usability: 

- NDView works for large arrays
- Direct subtraction of Pedestal from np.array
- len() support for python bindings of files
2026-06-15 11:38:06 +02:00
mazzol_aandErik Fröjdh ee7503082d Dev/matterhorn decoder (#324)
Build on RHEL9 / build (push) Successful in 2m49s
Build on RHEL8 / build (push) Successful in 3m35s
Run tests using data on local RHEL8 / build (push) Successful in 4m1s
Build on local RHEL8 / build (push) Successful in 3m9s
- reshape image directly in decoder such that first dimension is num
counters
- take into account chip artefact in decoder.

---------

Co-authored-by: Erik Fröjdh <erik.frojdh@psi.ch>
2026-06-11 15:04:20 +02:00
Erik Fröjdh b78ea64ea7 Conditional use of Minuit2 (#320)
Build on RHEL9 / build (push) Successful in 2m31s
Build on RHEL8 / build (push) Successful in 3m9s
Run tests using data on local RHEL8 / build (push) Successful in 3m56s
Build on local RHEL8 / build (push) Successful in 2m44s
If AARE_FETCH_MINUIT is set to OFF we first look for a standalone
Minuit2 and if that is not found we try to find Minuit2 as a part of
ROOT.

In both cases we make an alias to allow for simpler use of the target
later.

It still doesn't solve the issue that we install Minuit to when we fetch
it but that can be addressed in a separate PR.

closes #316
2026-06-10 08:30:03 +02:00
Erik FröjdhandLars Erik Fröjd f670ba77a2 PixelHistogram (#317)
Build on RHEL9 / build (push) Successful in 2m31s
Build on RHEL8 / build (push) Successful in 3m6s
Run tests using data on local RHEL8 / build (push) Successful in 3m55s
Build on local RHEL8 / build (push) Successful in 2m42s
Multi threaded filling of per pixel histograms for example for detector calibration

1. PixelHistogram - Generic variant expects already pedestal subtracted
data
2. PedestalTrackingHistogram - Terrible name, useful class. Keeps it's
own pedestal and does conversion and pedestal tracking in the worker
threads.

---------

Co-authored-by: Lars Erik Fröjd <froejdh_e@pc-jungfrau-02.psi.ch>
2026-06-09 09:08:48 +02:00
maliakal_d 8e69b498e5 Fix version (#319)
Build on RHEL9 / build (push) Successful in 2m34s
Build on RHEL8 / build (push) Successful in 3m2s
Run tests using data on local RHEL8 / build (push) Successful in 3m45s
Build on local RHEL8 / build (push) Successful in 2m38s
- install VERSION file and copy to build
- fix lookup for VERSION file in case of error
- update documentation for installing python bindings
2026-06-03 12:10:58 +02:00
kferjaoui 5922c73c07 feat(ClusterFinderCUDA): async submit_batch/collect API
Build on RHEL8 / build (push) Successful in 3m16s
Build on RHEL9 / build (push) Successful in 3m26s
Run tests using data on local RHEL8 / build (push) Successful in 9m42s
- Eliminate the ~200–300 µs inter-batch idle gap by allowing two batches
to be in-flight simultaneously:
  - submit_batch() enqueues H2D+kernel+D2H without blocking
  - collect() syncs via cudaEventSynchronize (not
  cudaStreamSynchronize) so a queued second batch runs uninterrupted.

- Two ping-pong output slots (NUM_SLOTS=2) with per-slot pinned buffers
and cudaEventDisableTiming sync events.
- find_clusters_batched() keeps its direct implementation.

* Measured: 0.026 -> 0.022 ms/frame (~18%).
2026-05-28 16:23:37 +02:00
lunin_landmazzol_a 282debcc94 Add __version__ variable for python library (#308)
Build on RHEL9 / build (push) Successful in 2m23s
Build on RHEL8 / build (push) Successful in 3m5s
Run tests using data on local RHEL8 / build (push) Successful in 3m56s
Build on local RHEL8 / build (push) Successful in 2m38s
[PEP 396](https://peps.python.org/pep-0396/)

---------

Co-authored-by: AliceMazzoleni99 <alice.mazzoleni@psi.ch>
2026-05-27 14:38:35 +02:00
kferjaoui 4c66802980 perf(ClusterFinderCUDA): FP32 device pedestal and bulk memcpy drain
Build on RHEL8 / build (push) Successful in 3m0s
Build on RHEL9 / build (push) Successful in 3m41s
Run tests using data on local RHEL8 / build (push) Successful in 3m47s
- Device pedestal arrays (mean/sum/sum2) are now float instead of
  double: halves global-memory bandwidth for pedestal reads/writes and
  eliminates FP64 arithmetic in the kernel (3.3x kernel speedup,
  15µs -> 4.6µs).

- Replace the per-cluster push_back loop in the D2H drain with a
  single resize()+memcpy().
2026-05-21 14:12:02 +02:00
Khalil Ferjaoui 52b5cf6b9f Feature/gauss+plateau (#312)
Build on RHEL9 / build (push) Successful in 2m27s
Build on RHEL8 / build (push) Successful in 3m1s
Run tests using data on local RHEL8 / build (push) Successful in 3m54s
Build on local RHEL8 / build (push) Successful in 2m36s
Adds three Minuit2-backed spectrum models to the Python-exposed fitting
API:

- `GaussianErfcPlateau`
- `GaussianChargeSharing`
- `GaussianChargeSharingKb`

Closes #297
2026-05-21 08:33:02 +02:00
kferjaoui 6a12e3de24 Refactor ClusterFinderCUDA
Build on RHEL9 / build (push) Successful in 3m22s
Build on RHEL8 / build (push) Successful in 3m28s
Run tests using data on local RHEL8 / build (push) Successful in 3m37s
Rework the multi-stream pipeline to eliminate per-frame sync barriers and
fix the D2H staging architecture.

Sync reduction:
- Replace one cudaStreamSynchronize per frame with one per stream per batch,
  cutting synchronisation calls from O(n_frames x n_streams) to O(n_streams)
- Introduce a unified per-frame D2H output layout [uint32_t count | clusters[max]]
  stored in a single class-level lazy-allocated pinned pool (h_output_pinned),
  replacing the per-stream separate cluster/count device buffers
- Move CUDA event pool from per-stream fixed-size to per-frame-slot lazy-allocated,
  enabling correct kernel timing across any batch size

Pinned H2D without CPU-side copy:
- Add register_input_buffer(ptr, bytes) / unregister_input_buffer() wrapping
  cudaHostRegister so callers can pin their existing batch buffer once; all
  find_clusters_batched() slices then transfer at DMA speed (~22 GB/s) instead
  of ~15 GB/s for pageable, with no extra memcpy or WC-memory penalty

Result (RTX 4090, 400x400 uint16, 3x3 clusters, batch=2000, 5 streams):
  Before: ~34 µs/frame  ->  After: ~28 µs/frame  (−18 %)
2026-05-18 16:30:13 +02:00
Xiangyu Xieandxie_x1 de74f12640 Dev var cluster finder (#310)
Build on RHEL9 / build (push) Successful in 2m30s
Build on RHEL8 / build (push) Successful in 3m36s
Run tests using data on local RHEL8 / build (push) Successful in 3m51s
Build on local RHEL8 / build (push) Successful in 2m36s
Add options for var cluster_finder_X:
1. number of neighbors (for better segmentation of clusters)
2. option to empty the surrounding pixels

---------

Co-authored-by: xiangyu.xie <xiangyu.xie@psi.ch>
2026-05-18 16:16:09 +02:00
kferjaoui 41d5184e1b Fix ClusterVector move semantics 2026-05-06 11:30:59 +02:00
kferjaoui 88e0e8d678 Optimize CUDA cluster finder transfers and kernel hot path
Build on RHEL8 / build (push) Successful in 2m51s
Build on RHEL9 / build (push) Successful in 3m15s
Run tests using data on local RHEL8 / build (push) Successful in 3m47s
- Use per-stream pinned host staging buffers for truly async CUDA transfers.
- Avoid reserving full device capacity per result frame.
- Reduce kernel work by delaying cluster payload construction.
- Use squared comparisons and removing per-pixel sqrtf() ops.
2026-04-30 18:23:31 +02:00
kferjaoui 34e69a8065 Add per-frame kernel timing via CUDA events
Build on RHEL8 / build (push) Successful in 3m13s
Build on RHEL9 / build (push) Successful in 3m37s
Run tests using data on local RHEL8 / build (push) Successful in 3m51s
2026-04-28 13:09:25 +02:00
kferjaoui ac96d1f688 Implement mixed precision: f32 stencil, f64 pedestal
Build on RHEL8 / build (push) Successful in 2m53s
Build on RHEL9 / build (push) Successful in 3m15s
Run tests using data on local RHEL8 / build (push) Successful in 3m47s
- Stencil arithmetic and shared memory use float (COMPUTE_TYPE alias).
- Pedestal accumulation stays double to preserve variance accuracy.

Notes:
- On RTX 4090, FP32 throughput is ~64× higher than FP64, so moving
  stencil math to float improves performance.
- Using float also avoids shared memory bank conflicts: stride-18 maps
  to distinct banks for 32-bit values, but caused conflicts with 64-bit.
2026-04-27 14:56:40 +02:00
kferjaoui 40f08fad92 Apply cmake-format to build files
Build on RHEL8 / build (push) Successful in 2m52s
Build on RHEL9 / build (push) Successful in 3m13s
Run tests using data on local RHEL8 / build (push) Successful in 3m49s
2026-04-27 11:53:56 +02:00
kferjaoui fddef977af Exclude notebooks from JSON check 2026-04-27 11:53:15 +02:00
kferjaoui a086cbb897 Format CUDA cluster finder files
Build on RHEL8 / build (push) Successful in 3m13s
Build on RHEL9 / build (push) Successful in 3m34s
Run tests using data on local RHEL8 / build (push) Successful in 3m48s
2026-04-27 11:27:47 +02:00
mazzol_a 2736d975c5 Dev/enable custom etas (#305)
Build on local RHEL8 / build (push) Successful in 2m32s
Build on RHEL9 / build (push) Successful in 2m29s
Build on RHEL8 / build (push) Successful in 2m52s
Run tests using data on local RHEL8 / build (push) Successful in 3m49s
- Allowing the users more flexibility to play around with custom eta
functions without touching the c++ code

- passing vector of eta values to ``transform_eta_values`` 

```
from aare import Interpolator, ClusterVector, Etai, Cluster
import numpy as np 

def custom_eta(cluster_pixel_coordinate_x, cluster_pixel_coordinate_y, cluster_data):
    # dummy custom eta function that just returns the sum of the cluster data
    eta = Etai()
    eta.x = 0.1 # dummy x value
    eta.y = 0.1 # dummy y value
    eta.sum = np.sum(cluster_data) # sum of the cluster data as the "energy
    return eta

# Create a dummy eta distribution and bins
eta_distribution = np.zeros((10, 10, 1)) # dummy eta distribution
etax_bins = np.linspace(0, 1.0, 11)
etay_bins = np.linspace(0, 1.0, 11)
e_bins = np.array([0., 10.]) # dummy energy bins

# Create the interpolator
interpolator = Interpolator(eta_distribution, etax_bins, etay_bins, e_bins)

# Create a dummy cluster vector
cluster_vector = ClusterVector()
cluster_vector.push_back(Cluster(10, 5, np.ones(shape=9, dtype = np.int32)))
cluster_vector.push_back(Cluster(20, 10, np.ones(shape=9, dtype = np.int32)))

# Create dummy etas for the clusters
cluster_array = np.array(cluster_vector)
etas = np.array([custom_eta(cluster["x"], cluster["y"], cluster["data"]) for cluster in cluster_array])

# transform eta values to uniform coordinates 
uniform_coordinates = interpolator.transform_eta_values(etas)

# Interpolate to get the photon coordinates e.g. apply interpolation logic 
photon_coordinates_x = cluster_array["x"] + uniform_coordinates["x"] # add to pixel coordinate 
photon_coordinates_y = cluster_array["y"] + uniform_coordinates["y"] # add to pixel coordinate 

```
advantage: full control over interpolation logic, 
downside: inefficient quite some loops in python
- passing pre computed eta values to interpolate function 
```
Interpolator.interpolate(cluster_vector, etas) 
```
downside: less flexibility in interpolation logic. 
downside: People might misuse it instead of using interpolate directly
with a pre compiled eta function implemented in c++
2026-04-24 14:01:13 +02:00
kferjaoui 133cedf755 pybind: make Cluster and ClusterVector bindings module-local
Build on RHEL8 / build (push) Successful in 2m52s
Build on RHEL9 / build (push) Successful in 3m15s
Run tests using data on local RHEL8 / build (push) Successful in 3m47s
- After upgrading to pybind11 3, duplicate registration of cluster-related
  types across `_aare` and `_aare_cuda` started failing.
- Mark the `Cluster` and `ClusterVector` bindings as `py::module_local()` so
each extension owns its local registration.

Note: cluster objects from CPU and CUDA bindings are now distinct Python types.
2026-04-23 14:03:47 +02:00
Khalil Ferjaoui 7c91ce99c2 Merge branch 'main' into feature/cuda_clusterfinder
Build on RHEL8 / build (push) Successful in 3m15s
Build on RHEL9 / build (push) Successful in 3m39s
Run tests using data on local RHEL8 / build (push) Successful in 3m51s
2026-04-23 13:52:52 +02:00
kferjaoui e894bdac9b Add Python bindings for CUDA cluster finder
Build on RHEL8 / build (push) Successful in 2m50s
Build on RHEL9 / build (push) Successful in 2m57s
Run tests using data on local RHEL8 / build (push) Successful in 3m38s
- Add bind_ClusterFinderCUDA.hpp with pybind11 bindings for
  ClusterFinderCUDA
- Build CUDA bindings as separate _aare_cuda.so to avoid
  segfaults from mixing nvcc and gcc compiled code in the
  same shared object
- Re-export CUDA classes onto _aare in __init__.py so user
  code uses `from aare import ClusterFinderCUDA` regardless
  of which .so hosts the class
- Factory in ClusterFinder.py selects backend; RuntimeError
  if GPU requested on CPU-only build
- Update python/CMakeLists.txt: _aare_cuda module gated
  behind AARE_CUDA and AARE_PYTHON_BINDINGS
- Add validation notebook: ~20x speedup vs sequential ClusterFinder
2026-04-23 11:43:40 +02:00
mazzol_aandErik Fröjdh 6ff664f812 allow passing mask to clustervector (#304)
Build on RHEL9 / build (push) Successful in 2m24s
Build on RHEL8 / build (push) Successful in 2m54s
Run tests using data on local RHEL8 / build (push) Successful in 3m52s
Build on local RHEL8 / build (push) Successful in 2m34s
- passing mask to ClusterVector 
- creates a copy of the ClusterVector

Co-authored-by: Erik Fröjdh <erik.frojdh@psi.ch>
2026-04-17 17:13:02 +02:00
Erik Fröjdh 4875c31513 bumped pybind version, cmake fixes (#300)
Build on RHEL9 / build (push) Successful in 2m25s
Build on RHEL8 / build (push) Successful in 2m57s
Run tests using data on local RHEL8 / build (push) Successful in 3m37s
Build on local RHEL8 / build (push) Successful in 2m33s
- Bumped pybind11 version
- Bumped libfmt version
- Patch  Minuit to avoid messing around with CMake policy
2026-04-17 15:50:49 +02:00
lunin_l 8f8173feb6 CI/CD: Integrate pre-commit hooks and GitHub Actions workflow (#303)
Build on RHEL8 / build (push) Successful in 2m48s
Build on RHEL9 / build (push) Successful in 3m8s
Run tests using data on local RHEL8 / build (push) Successful in 3m34s
Build on local RHEL8 / build (push) Successful in 2m24s
To improve codebase quality and reduce human error, this PR introduces
the pre-commit framework. This ensures that all code adheres to project
standards before it is even committed, maintaining a consistent style
and catching common mistakes early.

Key Changes:

- Code Formatting: Automated C++ formatting using clang-format (based on
the project's .clang-format file).
- Syntax Validation: Basic checks for file integrity and syntax.
- Spell Check: Automated scanning for typos in source code and comments.
- CMake Formatting: Standardization of CMakeLists.txt and .cmake
configuration files.
- GitHub Workflow: Added a CI action that validates every Pull Request
against the pre-commit configuration to ensure compliance.

The configuration includes a [ci] block to handle automated fixes within
the PR. Currently, this is disabled. If we want the CI to automatically
commit formatting fixes back to the PR branch, this can be toggled to
true in .pre-commit-config.yaml.

```yaml
ci:
  autofix_commit_msg: [pre-commit] auto fixes from pre-commit hooks
  autofix_prs: false
  autoupdate_schedule: monthly
```

The last large commit with the fit functions, for example, was not
formatted according to the clang-format rules. This PR would allow to
avoid similar mistakes in the future.

Python fomat with `ruff` for tests and sanitiser for `.ipynb` notebooks
can be added as well.
2026-04-14 11:52:23 +02:00
Erik FröjdhandKhalil Ferjaoui a25f5d2344 Access to parameter names and fast erf approx (#298)
Build on RHEL8 / build (push) Successful in 2m44s
Build on RHEL9 / build (push) Successful in 3m3s
Run tests using data on local RHEL8 / build (push) Successful in 3m39s
Build on local RHEL8 / build (push) Successful in 2m23s
- Set parameter starting values, limits or fix through name as well as
index
- Updated parameter names for the scurve
- Fast approximation to erf function (~10% speedup of fitting)

---------

Co-authored-by: Khalil Ferjaoui <khalilferjaoui@yahoo.fr>
2026-04-02 13:33:37 +02:00
Khalil FerjaouiandErik Fröjdh a6afa45b3b Feature/minuit2 wrapper (#279)
Build on RHEL8 / build (push) Successful in 3m6s
Build on RHEL9 / build (push) Successful in 3m20s
Run tests using data on local RHEL8 / build (push) Successful in 3m36s
Build on local RHEL8 / build (push) Successful in 2m21s
## Unified Minuit2 fitting framework with FitModel API

### Models (`Models.hpp`)
Consolidate all model structs (Gaussian, RisingScurve, FallingScurve)
into a
single header. Each model provides: `eval`, `eval_and_grad`, `is_valid`,
`estimate_par`, `compute_steps`, and `param_info` metadata. No Minuit2
dependency.

### Chi2 functors (`Chi2.hpp`)
Generic `Chi2Model1DGrad` (analytic gradient) templated on the model
struct.
Replaces the separate Chi2Gaussian, Chi2GaussianGradient,
Chi2Scurves, and Chi2ScurvesGradient headers.

### FitModel (`FitModel.hpp`)
Configuration object wrapping `MnUserParameters`, strategy, tolerance,
and
user-override tracking. User constraints (fixed parameters, start
values, limits)
always take precedence over automatic data-driven estimates.

### Fit functions (`Fit.hpp`)
- `fit_pixel<Model, FCN>(model, x, y, y_err)` -> single-pixel,
self-contained
- `fit_pixel<Model, FCN>(model, upar_local, x, y, y_err)` -> pre-cloned
upar for hot loops
- `fit_3d<Model, FCN>(model, x, y, y_err, ..., n_threads)` ->
row-parallel over pixel grid

### Python bindings
- `Pol1`, `Pol2`, `Gaussian`, `RisingScurve`, `FallingScurve` model
classes with
  `FixParameter`, `SetParLimits`, `SetParameter`, and properties for
  `max_calls`, `tolerance`, `compute_errors`
- Single `fit(model, x, y, y_err, n_threads)` dispatch replacing the old
`fit_gaus_minuit`, `fit_gaus_minuit_grad`, `fit_scurve_minuit_grad`,
etc.

### Benchmarks
- Updated `fit_benchmark.cpp` (Google Benchmark) to use the new FitModel
API
- Jupyter notebooks for 1D and 3D S-curve fitting (lmfit vs Minuit2
analytic)
- ~1.8x speedup over lmfit, near-linear thread scaling up to physical
core count

---------

Co-authored-by: Erik Fröjdh <erik.frojdh@psi.ch>
2026-03-30 09:12:23 +02:00
mazzol_a 05e6e69c66 added getter and setter for nSigma (#293)
Build on RHEL9 / build (push) Successful in 2m46s
Build on RHEL8 / build (push) Successful in 2m51s
Run tests using data on local RHEL8 / build (push) Successful in 3m15s
Build on local RHEL8 / build (push) Successful in 1m57s
2026-03-26 14:52:32 +01:00
Erik Fröjdhandmazzol_a 81acab6091 bumped version number edited RELEASE.md (#288)
Build on RHEL8 / build (push) Successful in 2m26s
Build on RHEL9 / build (push) Successful in 2m53s
Run tests using data on local RHEL8 / build (push) Successful in 3m17s
Build on local RHEL8 / build (push) Successful in 1m58s
Co-authored-by: Alice <alice.mazzoleni@psi.ch>
2026-03-17 17:22:36 +01:00
mazzol_aandErik Fröjdh d9ff73e8b2 added matterhorn transformation tests (#284)
- added matterhorn transformation tests

---------

Co-authored-by: Erik Fröjdh <erik.frojdh@psi.ch>
2026-03-17 16:54:06 +01:00
mazzol_a 2a3c121574 Fix/test (#278)
Build on RHEL8 / build (push) Successful in 2m29s
Build on RHEL9 / build (push) Successful in 2m40s
Build on local RHEL9 / build (push) Successful in 1m9s
Run tests using data on local RHEL8 / build (push) Has been cancelled
Build on local RHEL8 / build (push) Has been cancelled
2026-02-26 14:23:45 +01:00
mazzol_a 2139e5843c Dev/stuff from pyctbgui (#273)
Build on RHEL8 / build (push) Successful in 2m23s
Build on RHEL9 / build (push) Successful in 2m35s
Run tests using data on local RHEL8 / build (push) Failing after 3m19s
Matterhorn10 Transform 
some other Transformations from pyctbGUI 
added method get_reading_mode for easier error handling in decoders 


## TODO: 

- proper error handling for all other decoders 
- proper documentation for all other decoders 
- refactoring all other decoders to store hard coded values in a Struct
ChipSpecification
2026-02-19 16:12:44 +01:00
mazzol_a 5dbc746462 clang-format
Build on RHEL8 / build (push) Successful in 2m30s
Build on RHEL9 / build (push) Successful in 2m34s
Run tests using data on local RHEL8 / build (push) Failing after 3m10s
2026-02-19 15:35:19 +01:00
218f31ce60 Dev/multiple rois in aare (#263)
Build on RHEL8 / build (push) Successful in 2m23s
Build on RHEL9 / build (push) Successful in 2m32s
Run tests using data on local RHEL8 / build (push) Failing after 3m14s
Reading multiple ROI's for aare 

- read_frame, read_n etc throws for multiple ROIs
- new functions read_ROIs, read_n_ROIs 
-  read_roi_into (used for python bindings - to not copy) 

all these functions use get_frame or get_frame_into where one passes the
roi_index
## Refactoring:
- each roi keeps track of its subfiles that one has to open e.g.
subfiles can be opened several times
- refactored class DetectorGeometry - keep track of the updated module
geometries in new class ROIGeometry.
- ModuleGeometry updates based on ROI

## ROIGeometry: 
- stores number of modules overlapping with ROI and its indices
- size of ROI 

Note: only tested size of the resulting frames not the actual values

---------

Co-authored-by: Erik Fröjdh <erik.frojdh@psi.ch>
Co-authored-by: Erik Fröjdh <erik.frojdh@gmail.com>
2026-02-18 10:57:56 +01:00
mazzol_aandErik Fröjdh b77a576f72 Dev/automate tests using data (#267)
Build on RHEL8 / build (push) Successful in 2m13s
Build on RHEL9 / build (push) Successful in 2m37s
Run tests using data on local RHEL8 / build (push) Successful in 3m12s
- automatically run python tests 
- automatically run test using data files on local runner from gitea
- fixed some of the workflows

---------

Co-authored-by: Erik Fröjdh <erik.frojdh@psi.ch>
2026-01-20 17:20:48 +01:00
siebsiandErik Fröjdh 31f3a60cd3 added correct decoder for ADC-SAR-05-06-07-08 ASIC (#266)
Adding function to correctly decode the ADC-SAR-05-06-07-08 Chip. 

Co-authored-by: Erik Fröjdh <erik.frojdh@psi.ch>
2026-01-20 16:38:06 +01:00
Erik Fröjdh 7f3123d68f Added parsing of exptime and period from master files (#256)
Build on RHEL9 / build (push) Successful in 3m26s
Build on RHEL8 / build (push) Successful in 3m33s
- New aare:to_string/string_to similar to what we have in
slsDetectorPackage
- Added members period and exptime to RawMasterFile
- Parsing exposure time and period for json and raw master file formats
- Parsing of RawMasterFile from string stream to enable test without
files

Comments:

- to_string is at the moment not a public header. Can make it later if
needed. This gives us full freedom with the API
- FileConfig should probably be deprecated need to look into it.
Meanwhile removed python bindings and string conv
2025-12-18 17:04:12 +01:00
mazzol_a fb95e518b4 Dev/interpolation documentation (#255)
Build on RHEL8 / build (push) Successful in 3m5s
Build on RHEL9 / build (push) Successful in 3m21s
- added transform_eta_values for easier debugging more control for the
user
- updated Documentation
2025-12-16 13:06:28 +01:00