Algorithms
zsasa provides two SASA calculation algorithms.
Recommendation
Use Shrake-Rupley (SR) for most use cases. It is the default algorithm, faster, and produces results within 0.05% of Lee-Richards.
Use Lee-Richards (LR) only when you need to compare results with other LR implementations or require arc-based geometric rigor.
Comparison
| Property | Shrake-Rupley (SR) | Lee-Richards (LR) |
|---|---|---|
| Method | Test point sampling | Slice/arc integration |
| Speed | Fast | ~4x 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 |
Accuracy
Both algorithms produce nearly identical results on the same structure:
| Algorithm | SASA (Ų) |
|---|---|
| SR (100 points) | 19,211.19 |
| LR (20 slices) | 19,201.26 |
| Difference | 0.05% |
Usage
- CLI
- Python
# Shrake-Rupley (default)
zsasa calc structure.cif output.json
# Lee-Richards
zsasa calc --algorithm=lr structure.cif output.json
# SR with more test points (higher precision)
zsasa calc --n-points=200 structure.cif output.json
from zsasa import calculate_sasa
# Shrake-Rupley (default)
result = calculate_sasa(coords, radii)
# Lee-Richards
result = calculate_sasa(coords, radii, algorithm="lr")
# SR with more test points
result = calculate_sasa(coords, radii, n_points=200)
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:
- Precompute: For each possible neighbor geometry (distance, relative orientation), a bitmask encodes which test points on the sphere are occluded
- Lookup: During calculation, the appropriate bitmask is fetched from the LUT based on neighbor position
- 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.2x | Single-file benchmarks |
| Batch proteome processing | ~1.5–2x | Batch benchmarks |
| MD trajectory (33k atoms, 1k frames) | ~2.3x | 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:
zsasa traj --use-bitmask --bitmask-correction trajectory.xtc topology.pdb
The correction adjusts each atom's bitmask exposed fraction with a boundary-weighted term:
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:
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.
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:
singleis the default;per-frameandcyclerequire--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
- CLI
- Python
# 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/
from zsasa import calculate_sasa
# Single frame
result = calculate_sasa(coords, radii, n_points=128, use_bitmask=True)
# Experimental correction
result = calculate_sasa(
coords,
radii,
n_points=128,
use_bitmask=True,
bitmask_correction=True,
)
# Batch (trajectory)
from zsasa import calculate_sasa_batch
result = calculate_sasa_batch(coords, radii, n_points=128, use_bitmask=True)
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.