GuidesAlgorithms

Algorithms

zsasa provides two SASA calculation algorithms.

Recommendation#

Use Shrake-Rupley (SR) for most use cases. It is the default algorithm and the faster one. At the default settings the totals of the two algorithms differ by less than 1% on the bundled examples, and they converge to the same value as --n-points and --n-slices grow (see Accuracy).

Use Lee-Richards (LR) when you need to compare results with other LR implementations, or when you want areas without sampling noise: LR computes the exposed arc of every slice analytically, so the slice thickness is its only approximation.

Comparison#

Property Shrake-Rupley (SR) Lee-Richards (LR)
Method Test point sampling Slice/arc integration
Speed Fast ~5x slower
Default Yes (--algorithm=sr) No (--algorithm=lr)
Precision control --n-points (default: 100) --n-slices (default: 20)
Recommended for General use Comparison with LR implementations

Performance (1A0Q, 3,183 atoms, 4 threads)#

Algorithm Time vs FreeSASA C
SR (100 points) 2.6ms 1.7x faster
LR (20 slices) 9.9ms 1.6x faster

The LR row was measured with the approximate arc angles that were the default up to zsasa 0.9.1 (now --lr-trig=fast). With the exact default, the LR calculation takes about 1.3 times as long.

Accuracy#

Both algorithms converge to the same area. Totals in Ų for two of the bundled examples (--classifier=naccess, f64):

Setting examples/1ubq.pdb (602 atoms) examples/3hhb.cif.gz (4,384 atoms)
SR, 100 points (default) 4,823.29 25,484.51
SR, 1,000 points 4,780.03 25,453.82
SR, 10,000 points 4,782.19 25,442.39
LR, 20 slices (default) 4,782.16 25,436.14
LR, 200 slices 4,783.22 25,442.13
LR, 1,000 slices 4,783.34 25,442.93

At the defaults, SR is within 0.9% and LR within 0.03% of the converged value on these two structures. The SR total scatters around that value as the number of test points changes (the sampling noise shrinks with more points and with more atoms). The LR total is within 0.01% of it from 50 slices on.

Lee-Richards arc angles#

For every slice of an atom, LR needs two angles per neighbor: the half-width of the arc the neighbor covers (an acos) and its direction (an atan2).

Mode Angles Use
--lr-trig=exact (default) acos and atan2 for every neighbor All new work
--lr-trig=fast Polynomial approximations (up to 0.064 rad, or 3.7°, off) for most neighbors Reproducing results of zsasa 0.9.1 and earlier

Up to zsasa 0.9.1 the approximations were always used. They overestimate the exposed area by an amount that does not shrink with --n-slices, and they make the area of an atom depend on the order of the atoms in the input:

Structure (--algorithm=lr, default options) exact (Ų) fast (Ų) Difference Largest per-atom difference (Ų)
examples/1ubq.pdb 4,804.06 4,812.47 +0.18% 0.88
examples/1crn.pdb 2,999.33 3,005.06 +0.19% 0.97
examples/3hhb.cif.gz 25,515.99 25,583.13 +0.26% 1.31

In exact mode the per-atom areas agree with an independent reference implementation to rounding error (below 1e-12 Ų) and do not depend on the atom order. The exact calculation takes about 1.3 times as long as the fast one.

The mode is a command-line and workflow option (lr_trig under [calculation]). The Python and C APIs always use exact trigonometry.

Usage#

bash
# Shrake-Rupley (default)
zsasa calc structure.cif output.json

# Lee-Richards
zsasa calc --algorithm=lr structure.cif output.json

# Lee-Richards with the approximate arc angles of zsasa 0.9.1 and earlier
zsasa calc --algorithm=lr --lr-trig=fast structure.cif output.json

# SR with more test points (higher precision)
zsasa calc --n-points=200 structure.cif output.json

Precision vs Speed#

Shrake-Rupley: --n-points#

Points Precision Relative Time
50 Low 0.5x
100 Medium (default) 1.0x
200 High 2.0x
1000 Very high 10.0x

Lee-Richards: --n-slices#

Slices Precision Relative Time
10 Low 0.5x
20 Medium (default) 1.0x
50 High 2.5x
100 Very high 5.0x

Bitmask LUT Optimization#

The Shrake-Rupley algorithm supports an optional bitmask lookup table (LUT) optimization that significantly improves performance, especially for large structures and MD trajectories. This approach is inspired by Lahuta, which demonstrated the effectiveness of bitmask-based neighbor occlusion for SASA calculations.

How It Works#

In standard SR, each neighbor's occlusion of test points is computed individually by distance checks. The bitmask LUT approach replaces this with precomputed bitmask patterns:

  1. Precompute: For each possible neighbor geometry (distance, relative orientation), a bitmask encodes which test points on the sphere are occluded
  2. Lookup: During calculation, the appropriate bitmask is fetched from the LUT based on neighbor position
  3. Combine: Neighbor occlusion masks are combined using bitwise OR — a single CPU instruction processes all test points simultaneously

This converts the inner loop from per-point floating-point comparisons to bulk bitwise operations, yielding ~2x speedup on large systems.

Performance#

Bitmask mode provides the largest benefit on large structures and long trajectories:

Use Case Speedup vs Standard Details
Single file (100k+ atoms) ~1.1–1.2x Single-file benchmarks
Batch proteome processing ~1.5–3x Batch benchmarks
MD trajectory (33k atoms, 1k frames) ~2.5x MD benchmarks

Memory usage is minimal — the LUT adds only ~2 MB overhead for CLI mode.

Accuracy#

Bitmask introduces a small systematic offset due to the LUT discretization:

Metric Standard SR Bitmask
R² vs FreeSASA 1.000000 0.9997
Mean error < 0.001% ~0.7%
Max error < 0.02% ~2.5%

The offset is constant regardless of n_points (unlike standard SR where error decreases with more points). However, for MD trajectory analysis, the frame-to-frame changes (ΔR²) are nearly identical between standard and bitmask (> 0.99 at 500+ points) — the systematic offset cancels out in differences.

For detailed accuracy analysis, see SASA Validation.

Experimental Bias Correction#

Bitmask mode also provides an opt-in experimental correction for workflows where the mean total-SASA offset matters:

bash
zsasa traj --use-bitmask --bitmask-correction trajectory.xtc topology.pdb

The correction adjusts each atom's bitmask exposed fraction with a boundary-weighted term:

text
f_corrected = f + coeff × f × (1 - f)

This leaves fully buried (f = 0) and fully exposed (f = 1) atoms unchanged, while lifting partially exposed atoms where LUT direction/angle quantization most often over-occludes surface points. The default coefficient is conservative (0.020) and can be overridden with --bitmask-correction-coeff=V. Treat this as an experimental bias-mitigation mode, not as a replacement for exact SR when maximum numerical agreement is required.

Trajectory LUT Reuse Modes#

Trajectory bitmask mode reuses one prebuilt LUT by default for maximum throughput:

bash
zsasa traj --use-bitmask --bitmask-lut-mode=single trajectory.xtc topology.pdb

For experiments that need to separate LUT reuse from bitmask quantization, trajectory mode also supports:

  • single — default; build one LUT and reuse it for all frames.
  • per-frame — rebuild the bitmask LUT for each processed frame. This is slower and mainly useful as a validation/control mode.
  • cycle — prebuild a small deterministic set of rotated test-point LUT variants and cycle frames through them. This keeps LUT reuse while decorrelating the fixed test-point quantization pattern across adjacent frames.
bash
zsasa traj --use-bitmask --bitmask-lut-mode=cycle trajectory.xtc topology.pdb

cycle changes bitmask approximation details and should be treated as an experimental accuracy mode. Use exact SR when maximum numerical agreement is required.

Constraints#

  • SR algorithm only — not available for Lee-Richards
  • Supported n_points: 1–1024
  • Correction mode: requires bitmask SR and is disabled by default
  • Trajectory LUT modes: single is the default; per-frame and cycle require --use-bitmask
  • Lahuta uses n_points=128 fixed; zsasa supports any value in range

When to Use#

Mode Best For
Standard (default) Maximum accuracy, small structures, single calculations
Bitmask MD trajectories, batch processing, large structures, memory-constrained environments

Usage#

bash
# Bitmask with 128 test points (recommended)
zsasa calc --use-bitmask --n-points=128 structure.cif output.json

# Trajectory with bitmask
zsasa traj --use-bitmask --n-points=128 trajectory.xtc topology.pdb

# Trajectory with experimental bitmask bias correction
zsasa traj --use-bitmask --bitmask-correction trajectory.xtc topology.pdb

# Trajectory with rotated LUT cycling
zsasa traj --use-bitmask --bitmask-lut-mode=cycle trajectory.xtc topology.pdb

# Batch with bitmask
zsasa batch --use-bitmask --n-points=128 input_dir/ output_dir/

References#

  • Shrake, A.; Rupley, J. A. Environment and Exposure to Solvent of Protein Atoms. J. Mol. Biol. 1973, 79(2), 351-371.
  • Lee, B.; Richards, F. M. The Interpretation of Protein Structures: Estimation of Static Accessibility. J. Mol. Biol. 1971, 55(3), 379-400.
  • Lahuta — Bitmask LUT approach for SASA neighbor occlusion.
Edit this page