Fix sCMOS scalar calibration memory access bug#51
Merged
Conversation
f90a696 to
2801600
Compare
Allow sCMOS cameras to use scalar calibration values for modern uniform sensors like Orca Fusion AND fix pre-existing bug preventing non-square sCMOS images from being processed. Issue #37 - Scalar Calibration: When CameraType='SCMOS' with scalar gain/offset/readnoise and empty CalibrationFilePath, sCMOS CUDA kernels expect 2D variance images to index into, not scalars. Pre-existing Bug - Non-Square sCMOS Images: The gauss_sCMOS() function had incorrect dimension handling after permutation, causing failures with non-square sCMOS data (e.g., 429×244 gattaquant beads). Bug was hidden with square images (256×256) where transpose doesn't change dimensions. EMCCD worked fine (different code path). Root cause: gauss_sCMOS used out-of-place pattern but referenced original Stack dimensions after permuting working arrays, unlike gaussInPlace which updates Stack reference and uses current dimensions. Changes: - FindROI.m constructor (lines 86-104): For sCMOS with scalar calibration, expand scalars to 2D variance image matching Data dimensions. - FindROI.gauss_sCMOS (lines 326-377): Refactored to match gaussInPlace pattern - use working copy and reference current dimensions after permutation, not original Stack dimensions. This fixes non-square bug and improves code consistency. - SingleMoleculeFitting.m: Update documentation to clarify sCMOS supports both pixel-wise arrays and scalars (auto-expanded). Why different filtering algorithms? - EMCCD: Uniform noise → fast recursive Gaussian (Young & van Vliet 1995) - sCMOS: Pixel-varying noise → variance-weighted convolution (Huang 2013) This algorithmic difference is necessary. Dimension handling should be consistent - now it is. Testing verified: - Non-square sCMOS + 2D arrays: ✓ (was broken, now fixed) - Non-square sCMOS + scalars: ✓ (Issue #37) - Square sCMOS: ✓ (backward compatible) - DataToPhotons: ✓ (scalars handled correctly) Fixes #37 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2801600 to
3e63002
Compare
MahsaHabibi
approved these changes
Nov 5, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #37 - Allows sCMOS cameras to use scalar calibration values for modern uniform sensors (like Hamamatsu Orca Fusion) AND fixes a pre-existing bug that prevented non-square sCMOS images from being processed.
Problems Fixed
Bug #1: sCMOS Scalar Calibration (Issue #37)
When using sCMOS cameras with:
CameraGain,CameraOffset, andCameraReadNoisevaluesCalibrationFilePathThe code could fail because downstream sCMOS processing (FindROI, GaussMLE) expects 2D variance images, not scalars.
Modern sCMOS cameras like the Orca Fusion have sufficiently low pixel-to-pixel variation that scalar calibration is acceptable, but the code didn't support this use case.
Bug #2: Non-Square sCMOS Images (Newly Discovered) 🔍
The
gauss_sCMOS()function had a pre-existing dimension bug that caused failures with non-square sCMOS images (e.g., 429×244 gattaquant beads data).Root cause: After permuting the data for the second Gaussian filter pass, the output array was allocated with the wrong dimensions:
Result: Dimension mismatch when assigning results back.
Why it was hidden: Square images (256×256) work fine because transpose doesn't change dimensions. Only fails with non-square data.
Discovered when: User tested Issue #37 fix with real 429×244 gattaquant beads sCMOS data.
Solution
For Scalar Calibration
1. In
convertToPhotons.m(lines 70-90):2. In
FindROI.mconstructor (lines 91-103):Varim)For Non-Square Images
3. In
FindROI.gauss_sCMOS()(line 366):[size(Stack,2), size(Stack,1), size(Stack,3)]size(Stack)which has wrong dimensions after permutation4. In
FindROI.gauss_sCMOS()(line 368):size(Stack,2)as MajorSize parameter (after permutation)size(Stack,1)which was incorrectChanges
Modified Files
+smi_core/@DataToPhotons/convertToPhotons.m(+22 lines)RawDatadimensions+smi_core/@FindROI/FindROI.m(+23/-2 lines)+smi_core/@SingleMoleculeFitting/SingleMoleculeFitting.m(+3/-6 lines)+smi_core/@DataToPhotons/unitTest.m(+20 lines)Testing
Unit Tests
Real-World Validation
Test Coverage
Impact
Issue #37: Enables Modern sCMOS Workflow
Non-Square Bug: Fixes Real Data Analysis
Users with non-square sCMOS sensors (e.g., cropped ROIs, non-square chips) can now analyze data that previously failed with dimension mismatch errors.
Backward Compatibility
✓ Existing pixel-wise calibration files continue to work
✓ EMCCD scalar calibration unchanged
✓ Square sCMOS images work as before
✓ No API changes required
Design Rationale
Why expand in two places?
convertToPhotons(): For photon conversion calculationsFindROIconstructor: For sCMOS variance image used by CUDA kernelsWhy fix dimensions in gauss_sCMOS?
permute([2 1 3]), dimensions swap: 429×244 → 244×429🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com