diff --git a/README.md b/README.md index e228042..b80a9ae 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ Fast fuzzy search over biological sequences (amino-acid or nucleotide), as a C++ core with a minimal Python binding. Build an immutable index once, then search single queries or massive batches in parallel. + + + + seqtree workflow: inputs, batched processing and outputs. Schematic illustrations. + + ## Install ```fish @@ -31,29 +37,12 @@ p = seqtree.SearchParams(max_subs=2, engine="seqtm") for hit in idx.search("CASSLAPGATNEKLFF", p): print(hit.ref_id, hit.score, hit.n_subs) -# parallel batch (releases the GIL) -results = idx.search_batch(queries, p, threads=0) # 0 = automatic, up to 16 allocated CPUs - -# matrix-weighted budget. Name seqtrie -- engine="auto" always means seqtm. -# gap_open must follow the matrix: 2 * blosum62.scale() == 28, not the default 1. -pm = seqtree.SearchParams(matrix="blosum62", max_penalty=12, engine="seqtrie", gap_open=28) -top = idx.search_top("CASSLAPGATNEKLFF", pm, k=5) - -# alignment on demand -aln = idx.align(0, "CASSLELGATNEKLFF", p) -print(aln.aligned_query, aln.aligned_ref, aln.ops) - -# batch-vs-batch (auto-indexes the larger set) -pairs = seqtree.pairwise_batch(query_set, db_set, p, alphabet="aa") - -# a short query against a long TEXT (a proteome), one index for every query length -tix = seqtree.TextIndex.build(proteome_records, alphabet="aa", k=4) -res = tix.search_batch(peptides, max_subs=2, threads=0) -for hit in res[0]: - print(hit.ref_id, hit.offset, hit.n_subs, hit.mismatches) +# Batch search uses the automatic budget (up to 16 allocated CPUs). +queries = ["CASSLAPGATNEKLFF", "CASSLELGATNEKLFF"] +results = idx.search_batch(queries, p) ``` -That is the whole core loop. Significance, gap blocks, alignment and distances are in +Significance, gap blocks, alignment and distances are in [More examples](#more-examples) below, and the [docs](https://antigenomics.github.io/seqtree/) explain the why. diff --git a/assets/workflow-dark.svg b/assets/workflow-dark.svg new file mode 100644 index 0000000..19e48ae --- /dev/null +++ b/assets/workflow-dark.svg @@ -0,0 +1,70 @@ +From sequence collections to fast batch searchBuild an immutable index once; submit queries together. Illustrations are schematic, not measured results. + +From sequence collections to fast batch search +Build an immutable index once; submit queries together. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reference collection +Amino-acid or nucleotide sequences +Caller-owned IDs and annotations +Immutable native index +Whole-sequence or substring search +Shared read-only reference state +One batch of queries +Hits, alignments and reductions +Automatic allocation-aware parallelism + + +Indexed search +Bounded fuzzy matches and top hits. +TextIndex finds substrings in long records. + +Pairwise operations +Affine alignment and sequence distances. +Gap-block scoring and matrix reductions. + +Composable outputs +Map ref_id back to your reference rows. +Biological interpretation stays downstream. + +C++20 + Python API +Batch APIs · shared resources · automatic CPU budgets + diff --git a/assets/workflow-light.svg b/assets/workflow-light.svg new file mode 100644 index 0000000..9234ba4 --- /dev/null +++ b/assets/workflow-light.svg @@ -0,0 +1,70 @@ +From sequence collections to fast batch searchBuild an immutable index once; submit queries together. Illustrations are schematic, not measured results. + +From sequence collections to fast batch search +Build an immutable index once; submit queries together. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Reference collection +Amino-acid or nucleotide sequences +Caller-owned IDs and annotations +Immutable native index +Whole-sequence or substring search +Shared read-only reference state +One batch of queries +Hits, alignments and reductions +Automatic allocation-aware parallelism + + +Indexed search +Bounded fuzzy matches and top hits. +TextIndex finds substrings in long records. + +Pairwise operations +Affine alignment and sequence distances. +Gap-block scoring and matrix reductions. + +Composable outputs +Map ref_id back to your reference rows. +Biological interpretation stays downstream. + +C++20 + Python API +Batch APIs · shared resources · automatic CPU budgets + diff --git a/assets/workflow.png b/assets/workflow.png new file mode 100644 index 0000000..4128720 Binary files /dev/null and b/assets/workflow.png differ diff --git a/docs/gapblock.rst b/docs/gapblock.rst index 7fcc6db..4f4f645 100644 --- a/docs/gapblock.rst +++ b/docs/gapblock.rst @@ -341,9 +341,9 @@ rows identical in both views. No cross-row combinations are created. from seqtree.gapblock import topk_batch, count_batch queries, refs = ["ACDE", "ACD"], ["ACDE", "ACD", "ACDF"] - hits = topk_batch(queries, refs, k=2, threads=1) + hits = topk_batch(queries, refs, k=2, threads=0) thresholds = [[h.score for h in row] for row in hits] - counts = count_batch(queries, refs, thresholds, threads=1) + counts = count_batch(queries, refs, thresholds, threads=0) Each operation runs as one native batch with the GIL released. Top-k results use O(Q*k) storage and each worker uses O(k + maximum sequence length) scratch. diff --git a/docs/index.rst b/docs/index.rst index c9029b1..41a55a3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,6 +1,16 @@ seqtree ======= +.. image:: ../assets/workflow-light.svg + :alt: seqtree workflow overview: inputs, processing and outputs. + :width: 100% + :class: only-light + +.. image:: ../assets/workflow-dark.svg + :alt: seqtree workflow overview: inputs, processing and outputs. + :width: 100% + :class: only-dark + .. raw:: html
diff --git a/skills/seqtree/SKILL.md b/skills/seqtree/SKILL.md index f2c3daf..598c92c 100644 --- a/skills/seqtree/SKILL.md +++ b/skills/seqtree/SKILL.md @@ -24,9 +24,9 @@ operations, not domain datasets, clustering policy, or biological interpretation Read the installed signatures or the public headers for the version being used. Python-only convenience layers do not imply matching C++ classes. -In a source checkout, consult [API contracts](../../docs/api.rst), -[gap-block operations](../../docs/gapblock.rst), and -[E-value methodology](../../docs/evalue.rst) for advanced reductions and layouts. +In a source checkout, consult [API contracts](https://antigenomics.github.io/seqtree/api.html), +[gap-block operations](https://antigenomics.github.io/seqtree/gapblock.html), and +[E-value methodology](https://antigenomics.github.io/seqtree/evalue.html) for advanced reductions and layouts. ## C++ integration @@ -73,7 +73,7 @@ from seqtree.pairwise import score, align index = seqtree.Index.build(["CAT", "CAR", "WST"], alphabet="aa") params = seqtree.SearchParams(max_subs=1, engine="seqtm") -rows = index.search_batch(["CAT", "CAR"], params, threads=1) +rows = index.search_batch(["CAT", "CAR"], params, threads=0) assert {hit.ref_id for hit in rows[0]} == {0, 1} matrix = seqtree.SubstitutionMatrix.blosum62()