Calculation¶
The Debye sum¶
calculate() sums over all points:
with \(\rho_j\) the SLD of point \(j\) in Å⁻², \(\rho_s\) = sld_solvent × 10⁻⁶
Å⁻², \(V_j\) its volume in ų and \(r_{jk}\) in Å. The factor \(10^8\) turns Å⁻¹
into cm⁻¹, the unit of \(I\).
sld_solvent is in 10⁻⁶ Å⁻², like every sasmodels SLD parameter. SasView's
calculator takes Å⁻² instead; a value that looks like Å⁻² triggers a warning.
The structure's own SLDs stay in Å⁻², as the files store them.
Normalisation¶
\(V_\mathrm{norm}\) is the volume of the points that scatter, those whose SLD differs
from the solvent's. For a particle of pixels or cells in a box of solvent, the
curve at scale=1 then equals sasmodels' form factor at scale=1, so scale
is a volume fraction.
When the solvent exactly matches a population of points, those points stop
counting and the curve jumps by the volume ratio; for contrast-variation
series set set_params(normalisation_volume=...) explicitly ('auto'
restores the default). SasView calls the override total_volume and, when
some points have zero contrast, also multiplies by the ratio of all points'
volume to the scattering volume. This calculator does not.
Size polydispersity¶
set_params(size_pd=0.1) sums blown-up and shrunk copies of the whole
structure, as sasmodels does for radius_pd: size_pd_n size factors (35)
evenly over ±size_pd_nsigma (3) standard deviations, factors at or below 0
dropped, each weighted by the Gaussian's height there. A factor \(f\) stretches
every distance by \(f\) and every amplitude by \(f^3\), so
with \(V\) the volume of the points that scatter and the shares \(n_f\) adding up
to 1, so scale stays a volume fraction. The lattice, histogram and average
kernels evaluate their one distance spectrum at \(f q\) for every size, which costs only the sums over q; 'pairs' repeats the
whole pair sum per size and warns. The automatic histogram bin and the
cell-size warning use the largest factor, 1 + size_pd_nsigma * size_pd.
Deuteration¶
set_params(deuterated=['CTA']) gives the hydrogens of these residue names
the SLD of D at calculate(), as
Structure.deuterated does.
Kernels¶
set_params(kernel=...) picks how D(q) is summed; the profile's method
records it.
kernel |
How | Exact? | Time |
|---|---|---|---|
'lattice' |
FFT autocorrelation of the pixel grid | yes | well under a second for 10⁵ pixels |
'histogram' |
pairs counted by distance, then one sum per q over the occupied distances | to about 1e-4 | about 2 s for 11 000 atoms, N² |
'average' |
⟨A⟩²: each point's distance from the bounding-box centre | only for spherically symmetric structures | linear in N |
'pairs' |
every pair at every q | to the last digit | 2–3 s for 4 000 points, 25 s for 8 000 |
'auto' (the default) is 'lattice' for pixels on a lattice and
'histogram' for everything else.
The histogram bin is 'auto':
\(\min\left(0.01~\text{Å},\ 10^{-3} / (q_\mathrm{max} f_\mathrm{max})\right)\),
with \(f_\mathrm{max}\) the largest size factor (1 without polydispersity),
which keeps the rounding phase error below \(5 \cdot 10^{-4}\) rad; histogram_bin= sets it, and
profile.histogram_bin records it. A cached spectrum with a finer bin is
reused.
'average' reproduces SasView's is_avg=True and suits round aggregates
above about 10⁵ atoms. calculate(progress=...) can report progress or stop
the pair passes of 'histogram' and 'pairs'.
Things to know¶
PDB structures in a solvent are only qualitative
The natural atomic volumes use bulk elemental densities, liquid H₂, N₂
and O₂ for H, N and O. A typical residue gets about 310 ų instead of
about 133 ų, so in D₂O a protein comes out about 8× too intense at
q → 0. There is no hydration shell and no H/D exchange either.
calculate() warns with the actual volume ratio. In vacuum
(sld_solvent=0) the result is right. For atoms, scale is not a
volume fraction.
- Points stand in for cells. Pixels and VTK cells are treated as points,
which degrades as q × cell size approaches 1.
calculate()warns above that, with the cell size taken as the lattice step or the cell diameter divided by √3. - The curve is theory.
profile.to_data1d()returns aData1Dwith no dI and no dQ, withqmin,qmaxand an emptymaskset. A fit of it should state its weighting and resolution explicitly; passto_data1d(dI=...)to attach uncertainties. - Console output. Progress lines go through the
sinccitylogger;sinccity.set_verbosity('quiet')silences them.