Skip to content

Single kernel call for volume and intensity#3963

Open
jellybean2004 wants to merge 3 commits into
SD_calc_reformatfrom
SD_remove_hardcode
Open

Single kernel call for volume and intensity#3963
jellybean2004 wants to merge 3 commits into
SD_calc_reformatfrom
SD_remove_hardcode

Conversation

@jellybean2004
Copy link
Copy Markdown
Member

Description

Removes hard-coded/duplicated volume math and ensures intensities/volumes come from the model kernel.

Replaces the previous per-bin DirectModel/analytic volume approach with a kernel-based single call.
Builds the sasmodels kernel (from model info) and calls call_Fq for each bin to retrieve Fsq and volume. Compute intensity per bin as intensity = (scale/volume) * Fsq + background and store per-bin volumes in self._volumes.

Fixes #3418

How Has This Been Tested?

Tested functionality -- same as before.

Review Checklist:

Documentation

  • There is nothing that needs documenting
  • Documentation changes are in this PR
  • There is an issue open for the documentation (link?)

Installers

  • There is a chance this will affect the installers, if so
    • Windows installer (GH artifact) has been tested (installed and worked)
    • MacOSX installer (GH artifact) has been tested (installed and worked)
    • Wheels installer (GH artifact) has been tested (installed and worked)

Licensing

  • The introduced changes comply with SasView license (BSD 3-Clause)

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the size distribution model-matrix generation so that both per-bin intensity and volume are obtained via a single sasmodels kernel call, removing the prior duplicated/hard-coded volume math path.

Changes:

  • Replaces load_model/DirectModel usage with load_model_info + build_model and call_Fq in generate_model_matrix.
  • Computes per-bin intensity from returned kernel outputs and stores per-bin volumes on the class for later use.
Comments suppressed due to low confidence (1)

src/sas/sascalc/size_distribution/SizeDistribution.py:193

  • self._volumes is initialized twice in __init__ (once untyped, then again with a type annotation). This duplication is redundant and can confuse readers/type checkers; remove the earlier self._volumes = None assignment and keep the single typed initialization.
        self.model_matrix: np.ndarray | None = None
        self._volumes = None

        # Advanced parameters for MaxEnt
        self._iterMax: int = 5000
        self._skyBackground: float = 1e-6
        self._weightType: str = "dI"
        self._weightFactor: float = 1.0
        self._weightPercent: float = 1.0
        self._weights: np.ndarray | None = np.array(data.dy)

        self._bin_edges: np.ndarray = np.array([])
        self._binDiff: np.ndarray = np.array([])
        self._volumes: np.ndarray | None = None

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/sas/sascalc/size_distribution/SizeDistribution.py Outdated
Comment thread src/sas/sascalc/size_distribution/SizeDistribution.py Outdated
Comment thread src/sas/sascalc/size_distribution/SizeDistribution.py Outdated
call_pars = p.copy()
_, Fsq, _, volume, volume_ratio = call_Fq(calculator, call_pars)

# Compute intensity using kernel convention: combined_scale = scale / shell_volume
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is duplicating code from within sasmodels.kernel.Kernel.Iq. This isn't avoidable in the current implementation, but we should consider this use case when addressing sasmodels #182.

The idea is to return intermediate and derived values from the calculation back to the caller. The current hack to get $P(Q)$ and $S(Q)$ from P@S is that sasmodels.product sets up a kernel.results() function that returns a dictionary with keys P(Q), S(Q), volume, volume_ratio and radius_effective after calling kernel.Iq(). We could extend this to the base Kernel class in sasmodels. Then using call_kernel instead of call_Fq we can get the volume and volume ratio from calculator.results().

@jellybean2004
Copy link
Copy Markdown
Member Author

Hey @pkienzle! Thanks for your review! I have addressed your comments in my recent commit.

@jellybean2004 jellybean2004 linked an issue May 26, 2026 that may be closed by this pull request
@pkienzle
Copy link
Copy Markdown
Contributor

_volumes is never used. Is this preparation for a future change?

@jellybean2004
Copy link
Copy Markdown
Member Author

_volumes is never used. Is this preparation for a future change?

I somehow managed to miss one commit. The goal in the issue was to replace ellsipse_volume with self._volumes, and I have now done that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix problem of hard coding in Size Distribution

3 participants