Changelog
All notable changes to zsasa. See GitHub Releases for full details.
Unreleased
v0.6.0 — 2026-05-21
Added
- ztraj-backed trajectory formats:
zsasa trajnow supports TRR and AMBER NetCDF alongside XTC and DCD, with coordinates normalized to Å before SASA calculation. (#378)
Changed
- Trajectory reader backend: use
ztrajfor trajectory readers and dependency notices. (#377) - Python trajectory guidance: recommend
pyztrajfor direct Python trajectory-file I/O while keepingzsasa.xtcandzsasa.dcdas compatibility APIs. (#379)
Fixed
- Batch JSONL and FFI concurrency coverage: add regression coverage for batch JSONL output and concurrent FFI calls. (#376)
v0.5.0 — 2026-05-20
Added
- BinaryCIF input support: calc and batch now accept
.bcif,.bcif.gz, and.bcif.zstfiles by decoding_atom_sitedirectly in Zig. Inline CCD extraction from BinaryCIF remains out of scope for this release. (#372) - Adaptive batch bitmask SR: add experimental
zsasa batch --adaptive-srmode with coarse/fine point controls for two-stage bitmask Shrake-Rupley runs. (#371)
Changed
- Workflow batch execution: reuse parsed/classified structures across eligible workflow jobs so named chain analyses such as chain A, chain B, and complex AB avoid repeated parsing while preserving output schemas and compatibility fallbacks. (#374)
- Website documentation: restructure the documentation site around task-oriented guides, CLI references, Python APIs, and integrations. (#370)
Fixed
- BinaryCIF CCD classification: use inline CCD components from BinaryCIF inputs when available. (#373)
v0.4.0 — 2026-05-19
Added
- Workflow files: add TOML workflow support via
zsasa calc --workflowandzsasa batch --workflow;batch --manifestremains a compatibility alias. (#366)
Changed
- Breaking: custom classifier configs are TOML-only; legacy FreeSASA-style custom classifier files are no longer supported. (#366)
- Breaking/API: the public
batch_manifestmodule was removed and replaced byworkflow_manifest. (#366) - Repository automation: add agent instructions and ignore local planning docs. (#367)
Fixed
- CI: ignore gitignore-only changes in automation checks. (#368)
v0.3.2 — 2026-05-17
Added
- Batch JSONL residue maps: add opt-in
--residue-map/residue_map = trueoutput with compact columnar residue identifiers, atom ranges, and residue SASA for large-scale JSONL workflows. (#364)
v0.3.1 — 2026-05-17
Added
- Batch TOML manifests: add the original named multi-job workflow file support for chain A, chain B, and AB complex SASA; includes batch
--chain/--auth-chainsupport, per-job JSONL and per-file output layout, and CLI/docs coverage. (#361)
v0.3.0 — 2026-05-17
Added
- Zstandard decompression for structure inputs:
.json.zst,.pdb.zst,.cif.zst,.mmcif.zst,.ent.zst,.sdf.zst, and.mol.zstare now detected and transparently decompressed via nativestd.compress.zstd. (#357)
Changed
- CLI progress bars now use Zig's standard progress API for
batchandtraj, reducing custom rendering logic while preserving progress reporting. (#358) - Project branding documentation: add the project logo to README and refresh logo SVG assets. (#355, #356)
v0.2.11 — 2026-04-26
Fixed
- Build & Publish workflow: Bump remaining Zig 0.15.2 → 0.16.0 pins missed by PR1 (#345). The
Dockerfileand thecibuildwheelbefore-allinpython/pyproject.tomlwere both pulling the old toolchain and rejecting 0.16-only API; the result is that wheels and the Docker image have not been published since v0.2.8. Also updatesinstall.sh,python/hatch_build.py,python/zsasa/_ffi.pyerror messages,CONTRIBUTING.md, the website docs, and the bug-report ISSUE template. (#353) - Windows wheel test:
examples/1ubq.cifwas failing withStreamTooLongbecause the WindowsmmapFilepath used.limited64(stat.size)and Windows occasionally reports a byte count divergent from the buffered reader. Switch to.unlimited—mmapFile's callers already trust the input path. (#353) - aarch64 wheel build:
cibuildwheel's short aliasmanylinux_2_28resolved to the retired quay.io tag2026.03.01-1. Pin bothmanylinux-x86_64-imageandmanylinux-aarch64-imageto an explicit current tag (2026.04.25-0). (#353) flake.nixderivation version: Catch up to0.2.11(was stale at0.2.4until v0.2.10).
v0.2.10 — 2026-04-26
Changed
- Gzip decompression: C-zlib → native
std.compress.flate. Reverts the workaround introduced in #320 now that the upstream panic (ziglang/zig#25035) is fixed in Zig 0.16. Public API (readGzip,readGzipLimited,DEFAULT_MAX_SIZE,GzipError) and the 4 GB decompression-bomb cap unchanged; callers untouched. (#351)
Added
- Explicit gzip CRC32 + ISIZE trailer verification in
gzip.zig.std.compress.flateparses the gzip trailer fields but does not compare them against the decompressed bytes; without this check a corrupt.cif.gzcould silently decompress to wrong bytes. Adds a regression test (readGzip rejects gzip with corrupted CRC). (#351)
Removed
zlibdependency — removed frombuild.zig.zon,build.zig(b.dependency,linkLibrary,b.addTranslateC), andsrc/c/zlib_wrapper.h. The shared library no longer links zlib. (#351)
v0.2.9 — 2026-04-26
Changed
- Zig 0.16.0 migration: minimum Zig version bumped to 0.16.0. Toolchain (build.zig.zon, flake.nix, CI workflows, README badge) updated. (#345)
std.fs.*→std.Io.*: ~48 file I/O sites migrated to the newstd.Iointerface. "Juicy Main" pattern: a singlestd.Io.Threadedconstructed inmain()is threaded through subcommand handlers;c_api.zigconstructs per-FFI-callIo.Threadedfor batch entries (correct concurrency) and uses the global single-threaded variant for single-call entries. C ABI is preserved. (#345)std.heap.GeneralPurposeAllocator→std.heap.DebugAllocator,std.time.Timer→std.Io.Timestamp,std.Thread.Mutex→std.Io.Mutex(withlockUncancelable),std.Thread.sleep→std.Io.sleep. (#345)std.Io.Writer.Allocating/Writer.fixed/Reader.fixedreplaceArrayList(u8).writer()/fixedBufferStream. (#345)mem.indexOf*→mem.find*rename across 18 sites; Managed → Unmanaged HashMaps across 11 files (StringHashMapUnmanaged.empty+ op-time allocator);std.mem.trimStart/trimEndreplace deprecatedtrimLeft/trimRight;std.posix.PROTpacked-struct syntax. (#345)@cImport(@cInclude("zlib.h"))moved tob.addTranslateCinbuild.zig(usessrc/c/zlib_wrapper.hbecause dep lazy paths cannot serve asroot_source_file). (#345)@Vectorannotation for@sqrtcoercion insimd.zig(8 sites — array → vector);@bitCast(@Vector(N, bool))→@bitCast(@as(@Vector(N, u1), @intFromBool(...)))for cross-platform vector-mask packing (Linux x86_64 fix). (#345)@floor/@ceil/@round/@truncaudit: simplify@as(usize, @intFromFloat(@ceil(x)))→@as(usize, @ceil(x))where 0.16 supports direct int return. (#345)std.testing.Smithfor fuzz tests inmmcif_parser,pdb_parser,cif_tokenizer. (#345)zxdrfilev0.1.1 → v0.4.0 (Zig 0.16 compatible release, 2026-04-26).XtcReader.opensignature gainedio_handleparameter; both call sites updated. (#345)
Fixed
Io.Writer.Allocatingerrdefer leak injson_writer.zig:sasaResultToCsvandsasaResultToRichCsvnow properly clean up the buffer on write errors. (#345)mmap_reader.zigWindows path: restoredsizecap (.limited64(size)) lost during migration; added TOCTOU assertion. (#345)JsonlStreamWriter.writeResultnow records write failures viahasError()for downstream propagation;mutex.lock(io) catch unreachablereplaced withlockUncancelable(io). (#345)
v0.2.8 — 2026-04-13
Added
- SDF/MOL file support: New SDF parser supporting V2000 and V3000 formats. Calculate SASA for small molecules directly from SDF files (
zsasa calc molecule.sdf) (#338) --sdfoption: Provide bond topology for CCD-unregistered compounds (e.g., Boltz-predicted ligands) via--sdf=ligand.sdf. Available incalc,batch, andtrajsubcommands (#338)--moloption: Select a specific molecule from multi-molecule SDF by name or 1-based index (--mol=wateror--mol=2) (#339)- Batch SDF expansion: Multi-molecule SDF files in batch mode are expanded into individual items, each molecule calculated independently (#339)
Changed
- ProtOr is now an alias for CCD:
--classifier=protoruses the same CCD bond-topology classifier. Default classifier for Python bindings changed from NACCESS to CCD (#335, #337) - Trajectory classifier default:
trajsubcommand defaults to NACCESS for MD trajectories (#337)
Fixed
- SDF per-molecule SASA: Multi-molecule SDF files now calculate each molecule independently instead of combining them into one structure (#339)
- Python classifier tests: Updated expected values for CCD default (ALA:O = 1.42 Å) (#338)
- Memory safety: Fixed StoredComponent leaks on ComponentDict insertion failure, toAtomInput over-allocation with >26 molecules (#338, #339)
Documentation
- CCD classifier documentation rewritten with accurate architecture details (#334, #336)
v0.2.7 — 2026-04-12
Added
- CCD classifier (
--classifier=ccd): New classifier that derives ProtOr-compatible radii from CCD (Chemical Component Dictionary) bond topology, enabling accurate radius assignment for any chemical component — not just standard amino acids (#326, #327) - External CCD dictionary (
--ccd=<path>): Load external CCD dictionary for non-standard residues. Supports both CIF text (.cif,.cif.gz) and binary ZSDC format (#328) compile-dictsubcommand: Convert CCD dictionary from CIF text to compact binary ZSDC format for faster loading (zsasa compile-dict components.cif.gz -o components.zsdc) (#328)- Python:
ClassifierType.CCDadded to Python bindings (#330)
Changed
- CCD classifier auto-includes HETATM: When using
--classifier=ccd, HETATM records are included automatically without needing--include-hetatm(#329) - Python: Split monolithic
core.pyinto focused modules (_ffi.py,sasa.py,classifier.py,rsa.py,batch.py). Public API unchanged (#332)
v0.2.6 — 2026-03-22
Fixed
- Docker build: use PIC-enabled zlib for shared library to fix
R_X86_64_32relocation errors in Docker builds (#323) - CI: vendor zlib from source (allyourcodebase/zlib) instead of linking system library, fixing builds on Windows and manylinux containers (#322)
Changed
- Publish workflow: decouple job dependencies to prevent cascading failures — PyPI, GitHub Release, Docker, and package managers now run independently. Added
workflow_dispatchwith selective job re-runs (#324)
v0.2.5 — 2026-03-22
Fixed
- Gzip decompression for mmCIF/PDB files:
.cif.gz,.pdb.gz,.mmcif.gz,.ent.gzfiles are now transparently decompressed. Previously only.json.gzwas supported, and mmCIF/PDB parsers passed raw gzip data to the tokenizer, causingNoAtomSiteLooperrors (#319)
Changed
- Switch from Zig native flate to C zlib: gzip decompression now uses C zlib (
gzopen/gzread/gzclose) instead of Zig 0.15'sstd.compress.flate, which panics on certain valid gzip files (e.g. PDB entry 2OXD). This addslibzas a build dependency. See ziglang/zig#25035. Will revert to native flate when the upstream bug is fixed (#320) - Decompression bomb protection:
readGzipenforces a 4 GB max decompressed size limit to prevent memory exhaustion from malicious.gzfiles
v0.2.4 — 2026-03-11
Added
- CLI installer:
install.shscript for one-line CLI installation — builds from source with Zig or downloads pre-built binary from GitHub Releases (#307) - CLI release binaries: pre-built CLI binaries for linux-x86_64, linux-aarch64, macos-x86_64, macos-aarch64, windows-x86_64 attached to GitHub Releases (#307)
- Nix flake:
nix run github:N283T/zsasaornix profile install github:N283T/zsasafor Nix-based installation (#311)
Changed
- XTC reader: replaced local
src/xtc.zigwith external zxdrfile package dependency (#309) - CI: update cibuildwheel v2.22 to v3.4.0, remove obsolete skip selectors (#305, #306)
v0.2.3 — 2026-03-10
Fixed
- Windows build: fall back to heap allocation on Windows where POSIX mmap is unavailable (#301)
- Windows build: replace
std.mem.zeroeswithundefinedforJsonlStreamWriterplaceholder — zeroes fails on non-nullable pointers on Windows (#301) - Third-party license compliance: add BSD-2-Clause notice for libxdrfile (via chemfiles/xdrfile) in
src/xtc.zigand createTHIRD_PARTY_NOTICES.md(#300) - Correct Lahuta author name (Besian I. Sejdiu) in docs and README (#299)
Changed
- Remove legacy
docs/directory — all documentation migrated to website (#298) - Add acknowledgments section to README and comparison page (#297)
v0.2.2 — 2026-03-10
Added
- Bitmask variants for Python MD wrappers:
use_bitmaskoption for MDTraj, MDAnalysis, XTC, and DCD integrations (#275) - JSONL streaming batch output:
--format=jsonlfor memory-efficient batch results (#227, #235) - Documentation site overhaul:
- Comparison page vs FreeSASA, RustSASA, and Lahuta with source code references (#292)
- Landing page with hero section and feature cards (#291)
- Python autodoc generation with pdoc (#290)
- Split CLI reference into Commands, Input, and Output pages (#289)
- Benchmarks overview page and changelog (#294)
- Rewrote all benchmark pages with new results (#280, #282, #283, #284)
Performance
- mmap file reading: replaced
readToEndAllocwith memory-mapped I/O for structure files (#229) - Flat buffer NeighborList: replaced dynamic
ArrayListwith pre-allocated flat buffers (#230) - Trajectory parallel workers: aligned with batch allocator pattern for lower overhead (#231)
- 64KB write buffer for JSONL output (#228)
Fixed
- Corrected Lahuta metadata (URL, language) and RustSASA precision (f64 → f32) in benchmark docs (#293)
- Various PDB generation fixes: chain name shortening, serial number wrapping, CRYST1 Z value handling (#251, #252, #253)
v0.2.1 — 2026-02-25
Changed
- Relaxed bitmask
n_pointsconstraint from fixed 64/128/256 to any value 1..1024, with internal storage expanded from[4]u64to[16]u64(#210) - Updated Python bindings, C API, CLI help text, and documentation to reflect new n_points range (#210)
Added
--use-bitmaskand--n-pointsflags to benchmark scripts for bitmask LUT benchmarking (#208)
v0.2.0 — 2026-02-25
Added
- Bitmask-optimized Shrake-Rupley algorithm (
--use-bitmask): precomputed occlusion bitmask LUT with O(1) octahedral encoding for direction lookup, replacing per-point neighbor testing (#197) - SIMD 4-neighbor batching for bitmask SR: processes 4 neighbors simultaneously with
@Vector(4, T), branchless octahedral encoding via@select, and combined mask accumulation (#198) - Batch-mode
--use-bitmasksupport: shared LUT across all files in batch processing, avoiding redundant ~20ms LUT construction per file (#198) - Trajectory-mode
--use-bitmasksupport: build LUT once, reuse across all frames in both sequential and batch-parallel paths - Python bindings
use_bitmaskparameter: addeduse_bitmask=Trueoption tocalculate_sasa()andcalculate_sasa_batch(), with pass-through to MDTraj, MDAnalysis, XTC, and DCD integrations - C API bitmask exports:
zsasa_calc_sr_bitmask,zsasa_calc_sr_batch_bitmask,zsasa_calc_sr_batch_bitmask_f32for FFI access to bitmask LUT optimization
Changed
- BREAKING: CLI now requires subcommands:
zsasa calc,zsasa batch,zsasa traj - BREAKING: Removed
--parallelismoption (calcuses atom-level,batchuses file-level parallelism) - Trajectory mode:
--include-hydrogensis now the default (hydrogen atoms included). Use--no-hydrogensto exclude. MD trajectories typically include all atoms. - CI: removed Windows from PR checks (linux + macOS only); Windows builds remain in release workflow (#199)
Removed
- Pipeline parallelism mode (
--parallelism=pipeline) - Atom-level batch parallelism (
--parallelism=atom)
Performance
- E.coli proteome batch (f32, 10 threads, 128 points): 4.92s → 2.57s with bitmask SR (1.9x speedup, within 12% of lahuta reference)
v0.1.3 — 2026-02-25
Added
- Directory batch processing C API:
zsasa_batch_dir_*functions for processing all structure files in a directory (#191) - Python bindings for directory batch processing:
process_directory()function andBatchDirResultdataclass wrapping the C API (#193)- Process all supported structure files in a directory from Python
- Support for SR/LR algorithms, all classifiers, threading, output directory
- Per-file results: filename, atom count, total SASA, status
- Error mapping:
ValueError,FileNotFoundError,MemoryError,RuntimeError
- Docusaurus documentation site with GitHub Pages deployment (#186)
Changed
- Slimmed down README, added uv install instructions (#190)
- CI: skip workflow for website-only changes (#189)
Fixed
- json_writer performance regression: Reverted from unbuffered streaming writes to in-memory string building + single writeAll, fixing ~8x slowdown in batch processing caused by millions of write syscalls (#157 regression, #194)
- Updated benchmark docs for new dataset (#188)
- Fixed absolute paths for benchmark images (#187)
Removed
- Streaming output (
--stream,--stream-format,--stream-output): Removed StreamWriter module and CLI options to reduce code complexity (#194)
v0.1.2 — 2026-02-22
Added
- JSON streaming output for batch processing (
--stream): stream results as NDJSON or JSON array as each file completes (#157) - Stream format selection (
--stream-format): choose betweenndjson(default) andjsonarray format (#157) - Stream output destination (
--stream-output): write stream to file instead of stdout (#157) - Writer-based streaming JSON output for per-file results, reducing memory usage (#157)
- Zig package manager (zon) distribution: zsasa can now be used as a library dependency via
zig fetch(#160) - Public library API in
root.zig:shrake_rupley,lee_richards,types,pdb_parser,mmcif_parser,json_parser,classifier,analysis - Fuzz tests for CIF tokenizer, PDB parser, and mmCIF parser using Zig's built-in
std.testing.fuzz()(#161) - TOML format support for custom classifier configs (
--config=file.toml): human-friendly alternative to the legacy classifier text syntax with auto-detection by file extension (#158) - DCD trajectory reader (native Zig): read NAMD/CHARMM DCD binary trajectories without external dependencies (#154)
- Zig DCD reader (
src/dcd.zig) with endianness auto-detection and CHARMM extension support - C API:
zsasa_dcd_open,zsasa_dcd_close,zsasa_dcd_read_frame,zsasa_dcd_get_natoms - Python DCD reader (
zsasa.dcd):DcdReaderclass andcompute_sasa_trajectory()function - CLI:
zsasa trajnow supports.dcdfiles with auto-detection by file extension
- Zig DCD reader (
- Zig library API reference documentation (
docs/zig-api/): types, algorithms, parsers, classifier, analysis (#156) - Python pdoc auto-generated API documentation (
scripts/generate-python-docs.sh) (#156) - Documentation site with MkDocs Material and GitHub Pages deployment (#184)
zig build docsstep for interactive Zig autodoc generation (#184)
Changed
build.zig: Removed boilerplate template comments (176 → 63 lines)build.zig.zon: Synced version withbuild.zig- Homepage and Documentation URLs now point to GitHub Pages (#184)
Fixed
simd.zig: Fixedstd.math.atan2comptime_float errors with explicit@as(f64, ...)castssimd.zig: CorrectedfastAtan2test tolerance for negative quadrant inputs (0.005 → 0.07)root.zig: Re-enabledshrake_rupleyandlee_richardsin test block (previously excluded due to transitive simd test failure)
v0.1.1 — 2026-02-22
Added
CODE_OF_CONDUCT.md(Contributor Covenant v2.1)CITATION.cff(CFF 1.2.0 format for academic citation)- GitHub issue templates (bug report, feature request) in YAML form
- Pull request template
speedup_by_threads.pngplot generation inanalyze.py large(thread scaling for 50k+ atoms)- CI status, license, Zig, and Python badges to READMEs
- Pre-built wheel distribution via cibuildwheel (Linux x86_64/aarch64, macOS x86_64/arm64, Windows x86_64)
- Windows support: Zig build, tests, CLI, Python bindings
- PyPI publish workflow (
.github/workflows/publish.yml) with OIDC trusted publishing python -m ziglangfallback inhatch_build.pyfor Zig discovery
Changed
python/pyproject.toml: Updated author name, added Documentation/Issues/Changelog URLs
Fixed
- README: Corrected MD trajectory benchmark data (6sup_A_analysis: 4.3x speedup, verified against actual data)
- README: Fixed broken documentation link (
docs/python.md→docs/python-api/) - README: Fixed broken image reference for thread scaling plot
v0.1.0 — 2026-01-31
Added
-
PDB file format support
- Fixed-width PDB parser (
src/pdb_parser.zig) - Auto-detection of
.pdband.entfiles - MODEL/ENDMDL, alternate location, chain filtering
- Element inference from atom names
- Fixed-width PDB parser (
-
mmCIF parser (internal)
- Native mmCIF parser (
src/mmcif_parser.zig) - No external dependencies (replaces gemmi for CLI)
- Native mmCIF parser (
-
Gzip support
- Transparent decompression for
.json.gzand.cif.gz - Streaming decompression with zlib
- Transparent decompression for
-
Batch processing (directory input)
- Process entire directories:
zsasa ./input_dir/ ./output_dir/ - File-level parallelism with work stealing
- Per-thread arena allocators for memory efficiency
- Progress bar with file count
--parallelismoption for concurrent file processing- Duplicate coordinate detection and warning
- Process entire directories:
-
f32 precision option (
--precision=f32)- Single-precision mode for reduced memory usage
- Comptime generics for zero-cost abstraction
- ~Same speed, slightly lower accuracy
-
AVX-512 auto-optimization
- 16-wide SIMD on supported CPUs
- Automatic detection and fallback (16 → 8 → 4 → scalar)
-
Benchmark infrastructure
benchmarks/scripts/run.py- Unified benchmark runnerbenchmarks/scripts/analyze.py- Results analysis and plottingbenchmarks/scripts/sample.py- Stratified sampling for large datasetsbenchmarks/scripts/build_index.py- Dataset indexing- Full PDB dataset benchmark (238,124 structures)
- Batch benchmark: Zig +7% faster than RustSASA
-
Example files (
examples/)- Sample PDB and mmCIF files for quick testing
- README with usage examples
-
8-wide SIMD optimization for Shrake-Rupley algorithm
@Vector(8, f64)for processing 8 atoms in parallel- Tiered processing: 8-wide → 4-wide → scalar for remaining atoms
- ~16% speedup on large structures (4V6X: 237k atoms)
-
Fast trigonometry for Lee-Richards algorithm
- Polynomial approximations for
acosandatan2 - ~37% speedup on large structures (4V6X: 1021ms → 743ms)
- Accuracy within 0.3% of reference (well within 2% tolerance)
- Polynomial approximations for
-
Area difference column in benchmark output
- Shows percentage difference between Zig and FreeSASA C results
-
Analysis options (CLI)
--per-residue- Per-residue SASA aggregation--rsa- Relative Solvent Accessibility calculation--polar- Polar/nonpolar SASA classification
-
Python bindings (
python/zsasa)- C ABI shared library (
libzsasa.dylib/.so/.dll) - NumPy-based Python API with ctypes bindings
- Both SR and LR algorithms supported
calculate_sasa(coords, radii, algorithm="sr"|"lr", ...)function- RSA functions:
calculate_rsa(),calculate_rsa_batch(),get_max_sasa() - Per-residue aggregation:
aggregate_by_residue(),ResidueResultclass - 161 unit tests with pytest
- C ABI shared library (
-
Python integrations (optional dependencies)
- Gemmi integration for mmCIF/PDB file loading
- BioPython integration for structure file support
- Biotite integration for structure analysis workflows
- MDTraj integration (
zsasa.mdtraj) - drop-in replacement formdtraj.shrake_rupley() - MDAnalysis integration (
zsasa.mdanalysis) -SASAAnalysisclass compatible withAnalysisBase
-
XTC trajectory reader (native Zig)
- Zig port of GROMACS libxdrfile (BSD-2-Clause)
- Python XTC reader (
zsasa.xtc) - no MDTraj/MDAnalysis dependency required
-
Trajectory subcommand (
zsasa traj)zsasa traj trajectory.xtc topology.pdb- CLI trajectory mode- Frame-level batch parallelism with work-stealing
--stride=N,--start=N,--end=Nframe filtering--batch-size=Nfor controlling parallel batch size- Default f32 precision for speed in trajectory mode
-
Hydrogen and HETATM filtering
--include-hydrogens- Include H/D atoms (default: excluded)--include-hetatm- Include HETATM records (default: excluded)- Applied to both PDB and mmCIF parsers
-
SASA validation infrastructure
benchmarks/scripts/validation.py- Accuracy validation vs FreeSASA Cbenchmarks/scripts/validation_md.py- MD trajectory validation across implementations- Lee-Richards validation with E. coli proteome (R²=1.0)
-
MD trajectory benchmarks
benchmarks/scripts/bench_md.py- Hyperfine-based MD benchmarkbenchmarks/scripts/analyze_md.py- MD analysis and plots- E. coli proteome batch benchmark
-
Timing breakdown (
--timingflag)- Reports detailed timing for each phase: parsing, classification, SASA calculation, output
- Enables fair performance comparison by measuring SASA-only time
-
Benchmark dataset (6 structures from tiny to xlarge)
- 1CRN (327 atoms), 1UBQ (602), 1A0Q (3,183), 3HHB (4,384), 1AON (58,674), 4V6X (237,685)
benchmarks/inputs_protor/- Pre-generated inputs with ProtOr radiiscripts/data/generate_protor.py- Generate inputs with ProtOr radiiscripts/benchmark.py- Unified benchmark comparing Zig vs FreeSASA
-
Lee-Richards algorithm (
--algorithm=lr)- Slice-based method with exact arc integration
--n-slices=Noption (default: 20)- Multi-threading and SIMD support
- 1.1x-1.7x faster than FreeSASA C
-
Atom classifier module with CLI integration
classifier.zig- Core data structures, element-based radius guessing, ClassifierType enumclassifier_naccess.zig- NACCESS-compatible built-in classifierclassifier_protor.zig- ProtOr classifier (hybridization-based, Tsai et al. 1999)classifier_oons.zig- OONS classifier (older FreeSASA default)- O(1) compile-time hash lookup using
StaticStringMap - Support for 20 standard amino acids + SEC/MSE/PYL/ASX/GLX
- Support for RNA/DNA nucleotides (A, C, G, I, T, U, DA, DC, DG, DI, DT, DU)
- ANY fallback for backbone atoms (NACCESS/OONS)
- Element-based radius guessing from atom names
--classifier=naccess|protor|oons- Use built-in classifier--config=FILE- Use custom classifier config file
-
Extended input format with optional
residueandatom_namefields
Changed
- Updated benchmark: Now compares against FreeSASA C (native binary) instead of Python
- SR: 1.2x-2.3x faster than FreeSASA C
- LR: 1.1x-1.7x faster than FreeSASA C
- Scripts reorganization
- Created
scripts/data/subdirectory for data preparation scripts - Renamed:
benchmark_all.py→benchmark.py,validate_accuracy.py→validate.py - Moved data scripts to
scripts/data/with shorter names
- Created
- Project renamed:
freesasa-zig→zsasa(repository, binary, Python package) - Default ProtOr classifier for PDB/mmCIF input (no
--classifierflag needed) - Internal: Refactored
AtomInput.rfrom[]const f64to[]f64to properly support classifier mutations - Internal:
FixedString5for mmCIF 5-charactercomp_id(modified residue support) - Added LICENSE (MIT) and CONTRIBUTING.md
- Enabled GitHub Actions CI/CD (format, build, test, Python)
v0.0.5 — 2025-01-23
Added
-
Extended CLI options
--probe-radius=R- Configure probe radius (default: 1.4 Å)--n-points=N- Configure test points per atom (default: 100)--quiet/-q- Suppress progress output--help/-h- Show help message--version/-V- Show version
-
Output format options
--format=json- Pretty-printed JSON (default)--format=compact- Single-line JSON--format=csv- CSV format with header
-
Input validation
--validate- Validate input without calculation- Array length consistency check
- Coordinate finiteness check (NaN/Inf detection)
- Radius range validation (positive, ≤ 100 Å)
- Detailed error messages with atom index and value
v0.0.4 — 2025-01-22
Added
- Multi-threading support with configurable thread count
--threads=NCLI option (auto-detect by default)- Generic thread pool implementation with work-stealing
Changed
- Default execution mode is now multi-threaded
- 6.4x faster than FreeSASA (Python) on 3,183 atoms
v0.0.3 — 2025-01-21
Added
- SIMD optimization using
@Vector(4, f64)for batch distance calculations - 4.5x faster than FreeSASA (Python) single-threaded
v0.0.2 — 2025-01-20
Added
- Neighbor list optimization for O(N) neighbor lookup
- Spatial hashing with configurable cell size
- 3.9x faster than FreeSASA (Python) single-threaded
Changed
- Reduced algorithmic complexity from O(N²) to O(N)
v0.0.1 — 2025-01-19
Added
- Initial Shrake-Rupley algorithm implementation
- Golden Section Spiral test point generation
- JSON input/output format
- Basic CLI with input/output file arguments
- Python scripts for structure conversion and benchmarking
cif_to_input_json.py- Convert mmCIF/PDB to input JSONcalc_reference_sasa.py- Generate reference SASAbenchmark.py- Performance benchmarking