Skip to content

Commit eb993fb

Browse files
committed
Single call for volume and intensity
1 parent 96a9192 commit eb993fb

1 file changed

Lines changed: 33 additions & 10 deletions

File tree

src/sas/sascalc/size_distribution/SizeDistribution.py

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
from scipy import integrate, optimize, stats
1414

1515
from sasdata.dataloader.data_info import Data1D
16-
from sasmodels.core import load_model
17-
from sasmodels.direct_model import DirectModel
16+
from sasmodels.core import build_model, load_model_info
17+
from sasmodels.direct_model import call_Fq
1818

1919
from sas.sascalc.size_distribution.maxEnt_method import maxEntMethod
2020

@@ -114,6 +114,7 @@ def background_fit(
114114
# Fit only scale
115115
def fit_func(x: npt.ArrayLike, b: float) -> npt.ArrayLike:
116116
return line_func(x, b, power)
117+
117118
init_guess = linearized_data.y[0]
118119

119120
else:
@@ -177,6 +178,7 @@ def __init__(self, data: Data1D):
177178
self._resolution: float | None = None
178179

179180
self.model_matrix: np.ndarray | None = None
181+
self._volumes = None
180182

181183
# Advanced parameters for MaxEnt
182184
self._iterMax: int = 5000
@@ -483,24 +485,45 @@ def generate_model_matrix(self, moddata: Data1D) -> None:
483485
:param moddata: Data1D object that has the data trimmed depending on background
484486
subtraction or powerlaw subtracted from the data. Also self.qMin and self.qMax.
485487
"""
486-
model = load_model(self.model)
487-
488488
pars = {
489489
"sld": self.contrast,
490490
"sld_solvent": 0.0,
491491
"background": 0.0,
492492
"scale": 1.0,
493493
}
494494

495-
kernel = DirectModel(moddata, model)
496-
497495
intensities = []
496+
volumes = []
497+
498+
# Build a single Kernel to compute both intensity and volume per bin
499+
model_info = load_model_info(self.model)
500+
model_obj = build_model(model_info)
501+
calculator = model_obj.make_kernel((moddata.x,))
502+
498503
for bin in self.bins:
499-
pars["radius_equatorial"] = bin
500-
pars["radius_polar"] = bin * self.aspectRatio
501-
intensities.append(kernel(**pars))
504+
p = pars.copy()
505+
p["radius_equatorial"] = bin
506+
p["radius_polar"] = bin * self.aspectRatio
507+
508+
call_pars = p.copy()
509+
_, Fsq, _, volume, volume_ratio = call_Fq(calculator, call_pars)
510+
511+
# Compute intensity using kernel convention: combined_scale = scale / shell_volume
512+
scale_val = p.get("scale", 1.0)
513+
background_val = p.get("background", 0.0)
514+
combined_scale = scale_val / volume
515+
516+
intensity = combined_scale * Fsq + background_val
517+
intensities.append(intensity)
518+
519+
# Volume ratio is 1 for solid particles
520+
if volume_ratio is not None:
521+
volume *= volume_ratio
522+
523+
volumes.append(volume)
502524

503525
self.model_matrix = np.vstack(intensities).T
526+
self._volumes = np.array(volumes)
504527

505528
def calc_volume_weighted_dist(self, binmag: np.ndarray) -> None:
506529
"""
@@ -669,7 +692,7 @@ def calculate_statistics(self, bin_mag: npt.ArrayLike) -> None:
669692
"""
670693
Calculate statistics from the MaxEnt results, including volume fraction cumulative distribution function (CDF),
671694
number distribution, and related statistics such as mean, median, and mode.
672-
695+
673696
:param bin_mag: list of bin magnitudes from the MaxEnt fits
674697
"""
675698
bin_mag = np.asarray(bin_mag)

0 commit comments

Comments
 (0)