The .snipesig format
snipe computes alignment-free QC metrics — coverage, depth, error and mutation rates, contamination, ploidy signals — from a sketch of the sequencing data rather than from an alignment. .snipesig is the native format that stores that sketch: a full-fidelity edgemer signature, including every hash, abundance, and metadata field, so a signature written now reloads with the same contents later. The same input produces the same signature (same checksum).
One format, Parquet-encoded
Section titled “One format, Parquet-encoded”.snipesig is the single signature format snipe writes. Internally it is Parquet-encoded: the edgemer data lives in columnar Parquet, and the whole thing carries a self-describing header. There is no separate .parquet extension — Parquet is the encoding of .snipesig, not a different file type. The extension changed nothing about what a signature is; it changed how the bytes are laid out on disk.
Two pieces make up the file:
- Edgemer columns, stored in compressed (zstd) Parquet row-groups. This is the K1/K2 hash and abundance payload — the edgemers themselves.
- A
snipe_signature_headerblob — the full signature header serialized as JSON and stored in the Parquet footer’s key-value metadata. It carries the ksize parameters, counts, checksums, and the rest of the signature’s identity alongside the columnar data.
Because the header travels with the columns, a .snipesig file is self-describing: everything needed to reconstruct the signature is inside it, including data that plainer formats would drop — for example, a signature sketched with --keep-acgt round-trips with full fidelity.
The K1 checksum
Section titled “The K1 checksum”Every signature carries a k1_checksum in its header — an md5 computed over the signature’s sorted, distinct K1 hash set. The same K1 content produces the same checksum whether the signature is an edgemer signature or a K1-only one, and it is stable across a save/load round-trip.
The checksum is abundance-independent: two signatures with the same K1 hashes but different counts share a checksum, so it answers “are these the same k-mer set?” without regard to depth. snipe info reports it directly:
K1 checksum (md5): 85e65cc582d48cbf2fa1b2b7c9b552c7The checksum is an md5 over the signature’s sorted, distinct K1 hashes.
Writes are always Parquet, always single-signature
Section titled “Writes are always Parquet, always single-signature”There is only one thing snipe writes: a single Parquet-encoded signature per file. JSON writing was removed entirely — there is no environment hatch to force legacy output, and no multi-signature file on the write path. Commands that emit a signature, including downscale and export, produce one signature; they operate on a single signature and reject legacy multi-signature input.
Reading legacy JSON
Section titled “Reading legacy JSON”Before Parquet, .snipesig was a JSON-gzip encoding. snipe still reads those older files — that path is preserved as read-only backward compatibility — but it never writes them.
The loader auto-detects the encoding by the file’s leading magic bytes, so you never pass a flag to say which kind you have:
PAR1→ Parquet-encoded.snipesig(the current format)1f 8b(gzip) or[→ legacy JSON-gzip.snipesig
Both resolve through the same load path, so old and new signatures behave identically once in memory. Only the writer has moved on.
- Edgemers → — what the columns actually store.
- FracMinHash & scale → — how snipe samples the hash space before it ever writes a file.
- QC metrics explained → — the metrics computed from a signature.