seqtree 1.1.1__tar.gz → 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {seqtree-1.1.1 → seqtree-1.3.0}/CHANGELOG.md +27 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/CMakeLists.txt +1 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/PKG-INFO +12 -1
- {seqtree-1.1.1 → seqtree-1.3.0}/README.md +11 -0
- seqtree-1.3.0/RELEASE_AUDIT.md +12 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/include/seqtree/seqtree.hpp +44 -3
- {seqtree-1.1.1 → seqtree-1.3.0}/pyproject.toml +1 -1
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/gapblock.py +38 -6
- {seqtree-1.1.1 → seqtree-1.3.0}/src/_bindings.cpp +124 -8
- seqtree-1.3.0/src/alignment_max.cpp +177 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/count_unit.hpp +31 -9
- {seqtree-1.1.1 → seqtree-1.3.0}/src/engine_seqtm.cpp +2 -2
- {seqtree-1.1.1 → seqtree-1.3.0}/src/engines.hpp +1 -1
- {seqtree-1.1.1 → seqtree-1.3.0}/src/gapblock.cpp +228 -46
- {seqtree-1.1.1 → seqtree-1.3.0}/src/index.cpp +133 -3
- {seqtree-1.1.1 → seqtree-1.3.0}/src/searcher.cpp +5 -1
- {seqtree-1.1.1 → seqtree-1.3.0}/.gitattributes +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/.gitignore +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/LICENSE +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/include/seqtree/kmer_index.hpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/include/seqtree/parallel.hpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/include/seqtree/text_index.hpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/include/seqtree/types.hpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/__init__.py +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/control.py +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/data/control_human_trb_aa.txt.gz +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/distance.py +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/evalue.py +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/layout.py +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/pairwise.py +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/pmhc.py +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/pmhc_evalue.py +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/py.typed +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/seeds.py +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/python/seqtree/text_evalue.py +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/atomic_write.hpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/blosum45.inc +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/blosum62.inc +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/blosum80.inc +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/codec.cpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/distance.cpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/engine_seqtrie.cpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/kmer_index.cpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/pairwise.cpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/pairwise_detail.hpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/pam100.inc +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/pam250.inc +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/positional_matrix.cpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/structural.inc +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/substitution_matrix.cpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/text_index.cpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/trie.cpp +0 -0
- {seqtree-1.1.1 → seqtree-1.3.0}/src/trie.hpp +0 -0
|
@@ -3,6 +3,33 @@
|
|
|
3
3
|
All notable changes to `seqtree`. Dates are release dates. From 1.0.0 the project follows semantic
|
|
4
4
|
versioning: breaking changes need a **major** bump.
|
|
5
5
|
|
|
6
|
+
## [1.3.0] — 2026-10-19
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Bounded complete-query hit consumers for single and coordinated two-index
|
|
11
|
+
searches, with owned numeric buffers, explicit byte budgets and worker cleanup.
|
|
12
|
+
- Optional empty query axes in coordinated search retain original query offsets
|
|
13
|
+
and supported marginal evidence without creating a query for the missing axis.
|
|
14
|
+
|
|
15
|
+
## [1.2.0] — 2026-10-17
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Exact exclusion masks matching hits without shrinking model populations or
|
|
20
|
+
supplied annotation counters, including withheld-label models.
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Fixed query/reference partitions for native group audits.
|
|
25
|
+
- Bounded sparse grouped radius-hit output with deterministic ordering and explicit memory-cap failures.
|
|
26
|
+
- Optional grouped geometry compatible with the supported nanobind 2.5 floor.
|
|
27
|
+
|
|
28
|
+
- Generic float64 global-alignment target maxima with numeric annotation CSR,
|
|
29
|
+
group offsets, explicit matrix symbols and independent candidate edit budgets.
|
|
30
|
+
- Optional aggregate insertion/deletion limits for batched edit histograms;
|
|
31
|
+
omitted and redundant limits preserve the existing count paths.
|
|
32
|
+
|
|
6
33
|
## [1.1.0] — 2026-10-11
|
|
7
34
|
|
|
8
35
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: seqtree
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Fast fuzzy search over biological sequences (C++ core, Python bindings)
|
|
5
5
|
Keywords: sequence-search,fuzzy-matching,CDR3,immunology,bioinformatics,trie
|
|
6
6
|
Author-Email: ISALGO laboratory <mikhail.shugay@gmail.com>
|
|
@@ -289,3 +289,14 @@ This repo follows **git-flow**:
|
|
|
289
289
|
Roadmap (affine gaps, position-specific matrices, succinct memory packing) lives in
|
|
290
290
|
[docs/roadmap.rst](docs/roadmap.rst). Control-set E-values already ship — see the
|
|
291
291
|
[E-value guide](https://antigenomics.github.io/seqtree/evalue.html).
|
|
292
|
+
|
|
293
|
+
### Floating alignment reductions
|
|
294
|
+
|
|
295
|
+
`Index.alignment_max_batch` streams unit-cost search candidates through float64
|
|
296
|
+
global alignment and requested numeric-target maxima without a dense pair table.
|
|
297
|
+
It accepts explicit matrix symbols, small group-offset matrices and annotation CSR,
|
|
298
|
+
with separate alignment-selection and final scoring coefficients.
|
|
299
|
+
`Index.edit_histogram_batch(..., max_indels=...)` additionally supports an aggregate
|
|
300
|
+
insertion/deletion cap; its default preserves previous behavior. See the
|
|
301
|
+
[API reference](https://antigenomics.github.io/seqtree/api.html) for array contracts
|
|
302
|
+
and tie, count, exclusion and unsupported-value semantics.
|
|
@@ -257,3 +257,14 @@ This repo follows **git-flow**:
|
|
|
257
257
|
Roadmap (affine gaps, position-specific matrices, succinct memory packing) lives in
|
|
258
258
|
[docs/roadmap.rst](docs/roadmap.rst). Control-set E-values already ship — see the
|
|
259
259
|
[E-value guide](https://antigenomics.github.io/seqtree/evalue.html).
|
|
260
|
+
|
|
261
|
+
### Floating alignment reductions
|
|
262
|
+
|
|
263
|
+
`Index.alignment_max_batch` streams unit-cost search candidates through float64
|
|
264
|
+
global alignment and requested numeric-target maxima without a dense pair table.
|
|
265
|
+
It accepts explicit matrix symbols, small group-offset matrices and annotation CSR,
|
|
266
|
+
with separate alignment-selection and final scoring coefficients.
|
|
267
|
+
`Index.edit_histogram_batch(..., max_indels=...)` additionally supports an aggregate
|
|
268
|
+
insertion/deletion cap; its default preserves previous behavior. See the
|
|
269
|
+
[API reference](https://antigenomics.github.io/seqtree/api.html) for array contracts
|
|
270
|
+
and tie, count, exclusion and unsupported-value semantics.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Release audit — 17 October 2026
|
|
2
|
+
|
|
3
|
+
The requested generic batch/search APIs are implemented. No new native algorithm is needed for the audited downstream requirements.
|
|
4
|
+
|
|
5
|
+
- Native batch search and edit histograms; aggregate insertion/deletion caps.
|
|
6
|
+
- Float64 global-alignment target reductions, separate candidate/final scoring semantics, fixed populations under exact exclusion.
|
|
7
|
+
- Grouped geometry, fixed audit partitions, bounded deterministic sparse radius hits and optional-geometry compatibility at the supported nanobind floor.
|
|
8
|
+
- Shared CPU allocation checks; one-thread inline execution and explicit over-budget rejection.
|
|
9
|
+
|
|
10
|
+
Verification on `0852ff5`: **379 passed, 1 Linux-only platform skip** across `test_batch_threads.py`, `test_alignment_max.py`, `test_edit_histogram.py`, `test_grouped_optional_geometry.py` and `test_grouped_sparse_hits.py`. An additional 280 checks cover grouped populations, withholding, paired lanes, offsets, score bins and partitions. Native budget was two CPUs; numerical libraries used one thread. The committed `examples/01_gapped_search.py` runs and its per-query cutoff/search output was inspected. Sphinx builds with `-W`.
|
|
11
|
+
|
|
12
|
+
The local `dev` commits `0126e00`, `858056b` and `0852ff5` were three commits ahead of the remote at audit start. They are preserved and included when this audited `dev` is pushed. The changelog now covers these capabilities; public API documentation already describes the alignment reductions. [Issue 18](https://github.com/antigenomics/seqtree/issues/18) tracks integration into the release head and the remaining exact-head cross-platform/wheel gate. Publishing remains the maintainer's action; this audit creates no tag or release. Focused checks do not substitute for complete release CI.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#include "seqtree/types.hpp"
|
|
3
3
|
|
|
4
4
|
#include <cstdint>
|
|
5
|
+
#include <functional>
|
|
5
6
|
#include <memory>
|
|
6
7
|
#include <optional>
|
|
7
8
|
#include <string>
|
|
@@ -13,6 +14,7 @@ namespace seqtree {
|
|
|
13
14
|
|
|
14
15
|
struct Trie; // internal, src/trie.hpp
|
|
15
16
|
struct Scratch; // internal, src/engines.hpp
|
|
17
|
+
struct CountBuffer;
|
|
16
18
|
|
|
17
19
|
// Maps characters to small integer codes (<=32) and back. Case-insensitive on
|
|
18
20
|
// input. Invalid characters encode to kInvalid.
|
|
@@ -105,6 +107,14 @@ private:
|
|
|
105
107
|
std::vector<uint8_t> masked_; // [width]
|
|
106
108
|
};
|
|
107
109
|
|
|
110
|
+
struct AlignmentMaxResult {
|
|
111
|
+
std::vector<double> scores, raw_similarity, normalized_similarity, pfit, informativeness;
|
|
112
|
+
std::vector<uint64_t> counts, modeled_counts, aa_counts, exact_counts, candidate_counts, nw_pairs;
|
|
113
|
+
std::vector<int64_t> best_ref_ids, best_lane_ids;
|
|
114
|
+
std::vector<uint32_t> gap_counts;
|
|
115
|
+
std::vector<uint8_t> query_supported;
|
|
116
|
+
};
|
|
117
|
+
|
|
108
118
|
// Immutable after build. Lock-free for concurrent reads; share one Index across
|
|
109
119
|
// threads, give each thread its own Searcher.
|
|
110
120
|
class Index {
|
|
@@ -126,10 +136,34 @@ public:
|
|
|
126
136
|
std::vector<std::vector<Hit>> search_batch(const std::vector<std::string>& queries,
|
|
127
137
|
const SearchParams&, int threads = 0) const;
|
|
128
138
|
|
|
139
|
+
// One pool, serialized owned primitive blocks; each query is emitted completely.
|
|
140
|
+
// Columns: query index, ref_id, score, n_subs, n_ins, n_dels (all nonnegative).
|
|
141
|
+
void search_batch_consume(const std::vector<std::string>& queries, const SearchParams&,
|
|
142
|
+
const std::function<void(size_t, size_t, CountBuffer&&)>& consume,
|
|
143
|
+
int threads = 0, size_t chunk_size = 32, size_t max_hit_bytes = 64*1024*1024) const;
|
|
144
|
+
|
|
145
|
+
// Coordinate two indexes in one pool; both owned buffers cover the same queries.
|
|
146
|
+
void search_paired_batch_consume(const Index& other,
|
|
147
|
+
const std::vector<std::string>& queries, const std::vector<std::string>& other_queries,
|
|
148
|
+
const SearchParams&,
|
|
149
|
+
const std::function<void(size_t, size_t, CountBuffer&&, CountBuffer&&)>& consume,
|
|
150
|
+
int threads = 0, size_t chunk_size = 32, size_t max_hit_bytes = 64*1024*1024, bool skip_empty = false) const;
|
|
151
|
+
|
|
129
152
|
// Exact edit-count bins 0..max_total_edits; one reusable hit buffer per worker.
|
|
130
153
|
std::vector<std::vector<uint64_t>> edit_histogram_batch(
|
|
131
154
|
const std::vector<std::string>& queries, const SearchParams&,
|
|
132
|
-
int threads = 0, bool exclude_exact = false) const;
|
|
155
|
+
int threads = 0, bool exclude_exact = false, int max_indels = -1) const;
|
|
156
|
+
|
|
157
|
+
// Numeric requested-label maxima; float NW selection is independent of candidate scope.
|
|
158
|
+
AlignmentMaxResult alignment_max_batch(const std::vector<std::string>& queries,
|
|
159
|
+
const SearchParams&, const std::vector<std::vector<double>>& similarity, const std::string& symbols, int max_indels,
|
|
160
|
+
const std::vector<uint32_t>& query_target_offsets, const std::vector<uint32_t>& query_target_ids,
|
|
161
|
+
const std::vector<uint32_t>& reference_target_offsets, const std::vector<uint32_t>& reference_target_ids,
|
|
162
|
+
const std::vector<int32_t>& target_class_ids, const std::vector<uint32_t>& reference_class_offsets,
|
|
163
|
+
const std::vector<int32_t>& reference_class_ids, const std::vector<std::vector<int32_t>>& query_group_ids,
|
|
164
|
+
const std::vector<std::vector<int32_t>>& reference_group_ids, const std::vector<std::vector<std::vector<double>>>& group_offsets,
|
|
165
|
+
const std::vector<uint64_t>& reference_other_counts, const std::vector<uint64_t>& reference_multiplicities,
|
|
166
|
+
const std::vector<double>& coefficients, int threads=0, bool exclude_exact=false) const;
|
|
133
167
|
|
|
134
168
|
// Per-query count of seqtm collisions: how often a reference was re-reached via a
|
|
135
169
|
// different edit path during branch-and-bound (0 for the seqtrie engine / Hamming).
|
|
@@ -155,7 +189,7 @@ public:
|
|
|
155
189
|
~Searcher();
|
|
156
190
|
|
|
157
191
|
std::vector<Hit> search(std::string_view query, const SearchParams&);
|
|
158
|
-
void search_into(std::string_view query, const SearchParams&, std::vector<Hit>& out);
|
|
192
|
+
void search_into(std::string_view query, const SearchParams&, std::vector<Hit>& out, int max_indels = -1);
|
|
159
193
|
bool search_top(std::string_view query, const SearchParams&, Hit& out);
|
|
160
194
|
|
|
161
195
|
// seqtm collisions from the most recent search_into on this Searcher.
|
|
@@ -285,7 +319,9 @@ gapblock_group_audit_batch(const std::vector<std::string>& queries,
|
|
|
285
319
|
const std::vector<std::vector<int32_t>>& group_distances = {},
|
|
286
320
|
const std::vector<std::vector<int32_t>>& query_weights = {},
|
|
287
321
|
const std::vector<std::vector<int32_t>>& reference_weights = {},
|
|
288
|
-
const std::optional<PairedFeatureOffsets>& feature_offsets = std::nullopt
|
|
322
|
+
const std::optional<PairedFeatureOffsets>& feature_offsets = std::nullopt,
|
|
323
|
+
const std::vector<int32_t>& query_partitions = {},
|
|
324
|
+
const std::vector<int32_t>& reference_partitions = {});
|
|
289
325
|
|
|
290
326
|
std::vector<std::vector<Hit>> gapblock_topk_batch(const std::vector<std::string>& queries,
|
|
291
327
|
const std::vector<std::string>& refs, uint32_t k, Alphabet alphabet,
|
|
@@ -371,6 +407,10 @@ struct GroupedGeometry {
|
|
|
371
407
|
int32_t alignment_scale = 1;
|
|
372
408
|
uint32_t trim_left = 0, trim_right = 0;
|
|
373
409
|
int32_t score_quantum = 1;
|
|
410
|
+
bool return_hits = false;
|
|
411
|
+
size_t max_hit_bytes = 64*1024*1024;
|
|
412
|
+
std::optional<std::vector<int32_t>> query_target_ids;
|
|
413
|
+
std::optional<std::vector<int64_t>> query_reference_ids;
|
|
374
414
|
std::vector<std::vector<int32_t>> weights, group_distances, query_weights, reference_weights;
|
|
375
415
|
std::vector<int32_t> query_groups, reference_groups;
|
|
376
416
|
std::optional<PairedFeatureOffsets> features;
|
|
@@ -382,6 +422,7 @@ struct CountBuffer {
|
|
|
382
422
|
struct GroupedCountChunk {
|
|
383
423
|
size_t start = 0, stop = 0;
|
|
384
424
|
CountBuffer counts, sizes, exact_counts;
|
|
425
|
+
CountBuffer hits{{},{0,3}};
|
|
385
426
|
};
|
|
386
427
|
class GroupedCountBatch {
|
|
387
428
|
public:
|
|
@@ -745,24 +745,34 @@ def group_audit_batch(queries, refs, thresholds, matrix=None, gap_open=None, gap
|
|
|
745
745
|
gap_prior=None, alphabet="aa", threads=0, exclude_exact=False,
|
|
746
746
|
position_weights_by_length=None,
|
|
747
747
|
query_group_ids=None, reference_group_ids=None, group_distances=None,
|
|
748
|
-
query_position_weights=None, reference_position_weights=None, feature_offsets=None
|
|
748
|
+
query_position_weights=None, reference_position_weights=None, feature_offsets=None,
|
|
749
|
+
query_partition_ids=None, reference_partition_ids=None):
|
|
749
750
|
"""Stream component-ball count, full-score count and bounded nearest in one batch.
|
|
750
751
|
|
|
751
752
|
Geometry/offset options match ball_batch. Component excludes the nonnegative
|
|
752
753
|
group offset; full score includes it. For each query threshold, return three
|
|
753
754
|
lists: component count, full count and minimum full score among component hits.
|
|
754
755
|
Empty component balls have nearest=-1. Duplicate references count separately;
|
|
755
|
-
full encoded exact puncturing is identical.
|
|
756
|
+
full encoded exact puncturing is identical. Optional nonnegative partition IDs
|
|
757
|
+
restrict each query to references with the same ID. Both arrays are required;
|
|
758
|
+
unmatched partitions return zero counts and nearest=-1. Partition restriction
|
|
759
|
+
precedes scoring and is independent of additive group/feature distances. O(Q) output; no sparse hit objects.
|
|
756
760
|
"""
|
|
757
761
|
q, r = list(queries), list(refs)
|
|
758
762
|
thresholds = [_batch_integer(v, "threshold", -(1 << 31)) for v in thresholds]
|
|
759
763
|
if len(thresholds) != len(q):
|
|
760
764
|
raise ValueError("group audit thresholds must have one value per query")
|
|
765
|
+
if (query_partition_ids is None) != (reference_partition_ids is None):
|
|
766
|
+
raise ValueError("both query and reference partition IDs are required")
|
|
767
|
+
qp = [] if query_partition_ids is None else [_batch_integer(v, "query partition ID") for v in query_partition_ids]
|
|
768
|
+
rp = [] if reference_partition_ids is None else [_batch_integer(v, "reference partition ID") for v in reference_partition_ids]
|
|
769
|
+
if query_partition_ids is not None and (len(qp) != len(q) or len(rp) != len(r)):
|
|
770
|
+
raise ValueError("partition IDs must cover every query and reference")
|
|
761
771
|
go, ge, cube, width, threads = _batch_options((q, r), matrix, gap_open, gap_extend, gap_prior, threads)
|
|
762
772
|
return _gapblock_group_audit_batch(q, r, thresholds, alphabet, matrix, go, ge, cube, width,
|
|
763
773
|
threads, exclude_exact, _position_weights(position_weights_by_length, q, r),
|
|
764
774
|
*_group_options(query_group_ids, reference_group_ids, group_distances, q, r),
|
|
765
|
-
*_sequence_weights(query_position_weights, reference_position_weights, position_weights_by_length, q, r), feature_offsets)
|
|
775
|
+
*_sequence_weights(query_position_weights, reference_position_weights, position_weights_by_length, q, r), feature_offsets, qp, rp)
|
|
766
776
|
|
|
767
777
|
|
|
768
778
|
def ball_batch(queries, refs, thresholds, matrix=None, gap_open=None, gap_extend=1,
|
|
@@ -950,7 +960,8 @@ def _grouped_geometry(q, r, weights, query_groups, reference_groups, distances,
|
|
|
950
960
|
query_groups, reference_groups, distances, q, r)
|
|
951
961
|
geometry.query_weights, geometry.reference_weights = _sequence_weights(
|
|
952
962
|
query_weights, reference_weights, weights, q, r)
|
|
953
|
-
|
|
963
|
+
if features is not None:
|
|
964
|
+
geometry.features = features
|
|
954
965
|
return geometry
|
|
955
966
|
|
|
956
967
|
|
|
@@ -963,9 +974,21 @@ def grouped_count_batch(queries, refs, thresholds, *, reference_target_offsets,
|
|
|
963
974
|
feature_offsets=None, query_withheld_peptide_ids=None,
|
|
964
975
|
reference_peptide_offsets=None, reference_peptide_ids=None, score_quantum=1,
|
|
965
976
|
alignment_mode="gapblock", alignment_scale=1, trim_left=0, trim_right=0,
|
|
966
|
-
additional_feature_offsets=None
|
|
977
|
+
additional_feature_offsets=None, return_hits=False, query_target_ids=None,
|
|
978
|
+
query_reference_ids=None, max_hit_bytes=64*1024*1024):
|
|
967
979
|
"""Yield bounded label curves from one immutable prepared scoring population.
|
|
968
980
|
|
|
981
|
+
``return_hits=True`` instead yields ``chunk.hits[H,3]`` read-only uint32 rows
|
|
982
|
+
(global query index, reference index, raw distance) at thresholds[-1], ordered
|
|
983
|
+
by query then reference; counts/sizes/exact_counts are empty. Requires one
|
|
984
|
+
query_target_ids entry per query and scans only that target's CSR references.
|
|
985
|
+
Optional query_reference_ids keeps reference indices strictly greater than
|
|
986
|
+
each query's supplied index (-1 keeps all). Exact exclusion still compares
|
|
987
|
+
full sequences. Supports the single non-withheld population API only.
|
|
988
|
+
max_hit_bytes bounds actual hit output per chunk (default64MiB); exceeding it
|
|
989
|
+
raises without dropping hits. Row assembly plus final output temporarily uses
|
|
990
|
+
at most roughly three times that cap, excluding inputs and worker DP scratch.
|
|
991
|
+
|
|
969
992
|
``alignment_mode`` defaults to gapblock. Global/local reuse the existing affine
|
|
970
993
|
similarity recurrence and require a raw similarity matrix. For trimmed sequences
|
|
971
994
|
q/r, junction distance is alignment_scale * max(0, sum(diag(q)) + sum(diag(r))
|
|
@@ -997,7 +1020,7 @@ def grouped_count_batch(queries, refs, thresholds, *, reference_target_offsets,
|
|
|
997
1020
|
Each chunk owns read-only uint32 buffers: counts[C,1+2*T+P,K], sizes[C,1+2*T+P],
|
|
998
1021
|
exact_counts[C,T], with start/stop query offsets. numpy.asarray is zero-copy;
|
|
999
1022
|
no NumPy import/dependency is required. Exact counts retain raw multiplicity;
|
|
1000
|
-
exclude_exact
|
|
1023
|
+
exclude_exact masks hit curves by full sequence identity; model population sizes remain fixed.
|
|
1001
1024
|
Optional query_withheld_peptide_ids is one ID/query (-1 means none) and
|
|
1002
1025
|
requires full reference_peptide_offsets/reference_peptide_ids CSR. Each sorted
|
|
1003
1026
|
unique row includes all raw peptide labels, including sparse/unselected IDs in
|
|
@@ -1018,6 +1041,15 @@ def grouped_count_batch(queries, refs, thresholds, *, reference_target_offsets,
|
|
|
1018
1041
|
go, ge, cube, width, threads = _batch_options((q, r), matrix, gap_open, gap_extend, gap_prior, threads)
|
|
1019
1042
|
geometry = _grouped_geometry(q, r, position_weights_by_length, query_group_ids,
|
|
1020
1043
|
reference_group_ids, group_distances, query_position_weights, reference_position_weights, feature_offsets, score_quantum)
|
|
1044
|
+
if return_hits or query_target_ids is not None or query_reference_ids is not None:
|
|
1045
|
+
if not hasattr(geometry, "return_hits"):
|
|
1046
|
+
raise RuntimeError("sparse hits require native return_hits support")
|
|
1047
|
+
geometry.return_hits = bool(return_hits)
|
|
1048
|
+
geometry.max_hit_bytes = _batch_integer(max_hit_bytes, "max_hit_bytes", 12)
|
|
1049
|
+
if query_target_ids is not None:
|
|
1050
|
+
geometry.query_target_ids = [_batch_integer(x, "query target ID", 0) for x in query_target_ids]
|
|
1051
|
+
if query_reference_ids is not None:
|
|
1052
|
+
geometry.query_reference_ids = [_batch_integer(x, "query reference ID", -1) for x in query_reference_ids]
|
|
1021
1053
|
_additional_geometry(geometry, additional_feature_offsets)
|
|
1022
1054
|
_alignment_options(geometry, q, r, alignment_mode, alignment_scale, trim_left, trim_right,
|
|
1023
1055
|
matrix, gap_prior, position_weights_by_length, query_position_weights, reference_position_weights)
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#include <nanobind/stl/vector.h>
|
|
13
13
|
|
|
14
14
|
#include <algorithm>
|
|
15
|
+
#include <exception>
|
|
15
16
|
#include <optional>
|
|
16
17
|
#include <string>
|
|
17
18
|
#include <vector>
|
|
@@ -186,15 +187,62 @@ nb::list py_search_batch(const Index& idx, const std::vector<std::string>& queri
|
|
|
186
187
|
return out;
|
|
187
188
|
}
|
|
188
189
|
|
|
190
|
+
void py_search_batch_consume(const Index& idx, const std::vector<std::string>& queries,
|
|
191
|
+
const PyParams& pp, nb::object consume, int threads, size_t chunk_size, size_t max_hit_bytes) {
|
|
192
|
+
if (!PyCallable_Check(consume.ptr())) throw nb::value_error("consumer must be callable");
|
|
193
|
+
// A callback may mutate the original Python parameters; native workers read
|
|
194
|
+
// only these owned matrix/positional snapshots until the whole pool joins.
|
|
195
|
+
const PyParams owned = pp;
|
|
196
|
+
auto mat = make_matrix(owned, idx.alphabet());
|
|
197
|
+
SearchParams cp = to_cpp(owned, mat ? &*mat : nullptr);
|
|
198
|
+
std::exception_ptr error;
|
|
199
|
+
{
|
|
200
|
+
nb::gil_scoped_release release;
|
|
201
|
+
try {
|
|
202
|
+
idx.search_batch_consume(queries, cp,
|
|
203
|
+
[&](size_t start, size_t stop, CountBuffer&& buffer) {
|
|
204
|
+
nb::gil_scoped_acquire acquire;
|
|
205
|
+
consume(start, stop, nb::cast(std::move(buffer)));
|
|
206
|
+
}, threads, chunk_size, max_hit_bytes);
|
|
207
|
+
} catch (...) { error = std::current_exception(); }
|
|
208
|
+
}
|
|
209
|
+
// Restore the caller's GIL before Python exceptions are restored/destroyed.
|
|
210
|
+
if (error) std::rethrow_exception(error);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
void py_search_paired_batch_consume(const Index& idx, const Index& other,
|
|
214
|
+
const std::vector<std::string>& queries, const std::vector<std::string>& other_queries,
|
|
215
|
+
const PyParams& pp, nb::object consume, int threads, size_t chunk_size, size_t max_hit_bytes, bool skip_empty) {
|
|
216
|
+
if (!PyCallable_Check(consume.ptr())) throw nb::value_error("consumer must be callable");
|
|
217
|
+
// A callback may mutate the original Python parameters; native workers read
|
|
218
|
+
// only these owned matrix/positional snapshots until the whole pool joins.
|
|
219
|
+
const PyParams owned = pp;
|
|
220
|
+
auto mat = make_matrix(owned, idx.alphabet());
|
|
221
|
+
SearchParams cp = to_cpp(owned, mat ? &*mat : nullptr);
|
|
222
|
+
std::exception_ptr error;
|
|
223
|
+
{
|
|
224
|
+
nb::gil_scoped_release release;
|
|
225
|
+
try {
|
|
226
|
+
idx.search_paired_batch_consume(other, queries, other_queries, cp,
|
|
227
|
+
[&](size_t start, size_t stop, CountBuffer&& buffer, CountBuffer&& other_buffer) {
|
|
228
|
+
nb::gil_scoped_acquire acquire;
|
|
229
|
+
consume(start, stop, nb::cast(std::move(buffer)), nb::cast(std::move(other_buffer)));
|
|
230
|
+
}, threads, chunk_size, max_hit_bytes, skip_empty);
|
|
231
|
+
} catch (...) { error = std::current_exception(); }
|
|
232
|
+
}
|
|
233
|
+
// Restore the caller's GIL before Python exceptions are restored/destroyed.
|
|
234
|
+
if (error) std::rethrow_exception(error);
|
|
235
|
+
}
|
|
236
|
+
|
|
189
237
|
std::vector<std::vector<uint64_t>> py_edit_histogram_batch(
|
|
190
238
|
const Index& idx, const std::vector<std::string>& queries,
|
|
191
|
-
const PyParams& pp, int threads, bool exclude_exact) {
|
|
239
|
+
const PyParams& pp, int threads, bool exclude_exact, int max_indels) {
|
|
192
240
|
if (pp.max_total_edits < 1 || pp.max_total_edits > 65535)
|
|
193
241
|
throw nb::value_error("edit histogram requires max_total_edits in [1, 65535]");
|
|
194
242
|
auto mat = make_matrix(pp, idx.alphabet());
|
|
195
243
|
SearchParams cp = to_cpp(pp, mat ? &*mat : nullptr);
|
|
196
244
|
nb::gil_scoped_release release;
|
|
197
|
-
return idx.edit_histogram_batch(queries, cp, threads, exclude_exact);
|
|
245
|
+
return idx.edit_histogram_batch(queries, cp, threads, exclude_exact, max_indels);
|
|
198
246
|
}
|
|
199
247
|
|
|
200
248
|
std::vector<uint64_t> py_collisions_batch(const Index& idx, const std::vector<std::string>& queries,
|
|
@@ -335,6 +383,26 @@ ArrayView view_of(const nb::object& owner, const std::vector<T>& v, char fmt) {
|
|
|
335
383
|
return ArrayView{owner, v.data(), v.size(), sizeof(T), {fmt, 0}};
|
|
336
384
|
}
|
|
337
385
|
|
|
386
|
+
nb::dict alignment_max_arrays(const nb::object& self) {
|
|
387
|
+
const auto& r=nb::cast<const AlignmentMaxResult&>(self); nb::dict d;
|
|
388
|
+
d["scores"]=view_of(self,r.scores,'d');
|
|
389
|
+
d["raw_similarity"]=view_of(self,r.raw_similarity,'d');
|
|
390
|
+
d["normalized_similarity"]=view_of(self,r.normalized_similarity,'d');
|
|
391
|
+
d["pfit"]=view_of(self,r.pfit,'d');
|
|
392
|
+
d["informativeness"]=view_of(self,r.informativeness,'d');
|
|
393
|
+
d["counts"]=view_of(self,r.counts,'Q');
|
|
394
|
+
d["modeled_counts"]=view_of(self,r.modeled_counts,'Q');
|
|
395
|
+
d["aa_counts"]=view_of(self,r.aa_counts,'Q');
|
|
396
|
+
d["exact_counts"]=view_of(self,r.exact_counts,'Q');
|
|
397
|
+
d["candidate_counts"]=view_of(self,r.candidate_counts,'Q');
|
|
398
|
+
d["nw_pairs"]=view_of(self,r.nw_pairs,'Q');
|
|
399
|
+
d["best_ref_ids"]=view_of(self,r.best_ref_ids,'q');
|
|
400
|
+
d["best_lane_ids"]=view_of(self,r.best_lane_ids,'q');
|
|
401
|
+
d["gap_counts"]=view_of(self,r.gap_counts,'I');
|
|
402
|
+
d["query_supported"]=view_of(self,r.query_supported,'B');
|
|
403
|
+
return d;
|
|
404
|
+
}
|
|
405
|
+
|
|
338
406
|
// One hit as a Python object. Built only for the query actually asked for, never for the whole
|
|
339
407
|
// batch -- the flat arrays are what a 445k-query run should read.
|
|
340
408
|
struct PyTextHit {
|
|
@@ -395,6 +463,7 @@ ScoreMatrix py_gapblock_matrix(const std::vector<std::string>& queries,
|
|
|
395
463
|
} // namespace
|
|
396
464
|
|
|
397
465
|
NB_MODULE(_core, m) {
|
|
466
|
+
m.attr("exact_exclusion_hits_only") = true;
|
|
398
467
|
m.doc() = "seqtree: fuzzy biological-sequence search (C++ core)";
|
|
399
468
|
|
|
400
469
|
nb::class_<SubstitutionMatrix>(m, "SubstitutionMatrix",
|
|
@@ -663,6 +732,9 @@ NB_MODULE(_core, m) {
|
|
|
663
732
|
return "Alignment(score=" + std::to_string(a.score) + ", ops='" + a.ops + "')";
|
|
664
733
|
});
|
|
665
734
|
|
|
735
|
+
nb::class_<AlignmentMaxResult>(m,"AlignmentMaxResult")
|
|
736
|
+
.def("arrays",&alignment_max_arrays,"Read-only zero-copy requested-target CSR buffers; views own their result.");
|
|
737
|
+
|
|
666
738
|
nb::class_<Index>(m, "Index",
|
|
667
739
|
"Immutable search index over a set of reference sequences. Build once, "
|
|
668
740
|
"then query concurrently; reference id is the position in ``refs``.")
|
|
@@ -694,13 +766,52 @@ NB_MODULE(_core, m) {
|
|
|
694
766
|
nb::arg("threads") = 0,
|
|
695
767
|
"Search many queries in parallel (releases the GIL). ``threads=0`` uses all "
|
|
696
768
|
"cores. Returns one hit list per query, in input order.")
|
|
769
|
+
.def("search_batch_consume", &py_search_batch_consume,
|
|
770
|
+
nb::arg("queries"), nb::arg("params"), nb::arg("consume"), nb::arg("threads") = 0,
|
|
771
|
+
nb::arg("chunk_size") = 32, nb::arg("max_hit_bytes") = 64*1024*1024,
|
|
772
|
+
"One population/pool, serialized consume(start, stop, owned_buffer) callbacks. "
|
|
773
|
+
"Read-only uint32 rows: query_index, ref_id, score, n_subs, n_ins, n_dels. "
|
|
774
|
+
"Every query is complete; block order may vary across threads. Output bytes per "
|
|
775
|
+
"block never exceed max_hit_bytes; an oversized query raises, never truncates. "
|
|
776
|
+
"Native worker scratch also holds the current block of hits. Consumer-retained "
|
|
777
|
+
"buffers remain owned; callers control their retention. Parameters are snapshotted.")
|
|
778
|
+
.def("search_paired_batch_consume", &py_search_paired_batch_consume,
|
|
779
|
+
nb::arg("other"), nb::arg("queries"), nb::arg("other_queries"),
|
|
780
|
+
nb::arg("params"), nb::arg("consume"), nb::arg("threads") = 0,
|
|
781
|
+
nb::arg("chunk_size") = 32, nb::arg("max_hit_bytes") = 64*1024*1024, nb::arg("skip_empty") = false,
|
|
782
|
+
"One pool with two Searchers; consume(start, stop, owned_buffer, other_owned_buffer). "
|
|
783
|
+
"Both six-column buffers cover the same complete query block. Combined output "
|
|
784
|
+
"bytes are bounded by max_hit_bytes; block order may vary. Same-alphabet indexes "
|
|
785
|
+
"and equal-length query populations required. Parameters are snapshotted. "
|
|
786
|
+
"skip_empty=True emits no hits for empty query axes; other axes remain searched.")
|
|
697
787
|
.def("edit_histogram_batch", &py_edit_histogram_batch,
|
|
698
788
|
nb::arg("queries"), nb::arg("params"), nb::arg("threads") = 0,
|
|
699
|
-
nb::arg("exclude_exact") = false,
|
|
789
|
+
nb::arg("exclude_exact") = false, nb::arg("max_indels") = -1,
|
|
700
790
|
"Exact reference counts by total n_subs+n_ins+n_dels, bins 0..max_total_edits. "
|
|
701
791
|
"Requires explicit positive max_total_edits and uncapped seqtm/auto all-hit search. "
|
|
792
|
+
"max_indels>=0 also caps total insertions+deletions; -1 preserves directional-only caps. "
|
|
702
793
|
"Duplicates count separately; exclude_exact retains bin 0 with count zero. threads<=0 uses the detected available CPU budget. Releases the GIL; "
|
|
703
794
|
"one reusable hit buffer per worker, no all-query hit vectors.")
|
|
795
|
+
.def("alignment_max_batch", [](const Index& idx,const std::vector<std::string>& queries,const PyParams& pp,
|
|
796
|
+
const std::vector<std::vector<double>>& sim,const std::string& symbols,int max_indels,
|
|
797
|
+
const std::vector<uint32_t>& qo,const std::vector<uint32_t>& qt,const std::vector<uint32_t>& ro,
|
|
798
|
+
const std::vector<uint32_t>& rt,const std::vector<int32_t>& tc,const std::vector<uint32_t>& co,
|
|
799
|
+
const std::vector<int32_t>& ci,const std::vector<std::vector<int32_t>>& qg,
|
|
800
|
+
const std::vector<std::vector<int32_t>>& rg,const std::vector<std::vector<std::vector<double>>>& offsets,
|
|
801
|
+
const std::vector<uint64_t>& other,const std::vector<uint64_t>& multiplicities,
|
|
802
|
+
const std::vector<double>& coefficients,int threads,bool exclude_exact) {
|
|
803
|
+
auto mat=make_matrix(pp,idx.alphabet()); auto cp=to_cpp(pp,mat?&*mat:nullptr);
|
|
804
|
+
nb::gil_scoped_release release;
|
|
805
|
+
return idx.alignment_max_batch(queries,cp,sim,symbols,max_indels,qo,qt,ro,rt,tc,co,ci,qg,rg,offsets,other,multiplicities,coefficients,threads,exclude_exact);
|
|
806
|
+
}, nb::arg("queries"),nb::arg("params"),nb::arg("similarity"),nb::arg("similarity_symbols"),nb::arg("max_indels"),nb::kw_only(),
|
|
807
|
+
nb::arg("query_target_offsets"),nb::arg("query_target_ids"),nb::arg("reference_target_offsets"),nb::arg("reference_target_ids"),
|
|
808
|
+
nb::arg("target_class_ids"),nb::arg("reference_class_offsets"),nb::arg("reference_class_ids"),
|
|
809
|
+
nb::arg("query_group_ids"),nb::arg("reference_group_ids"),nb::arg("group_offsets"),nb::arg("reference_other_counts"),
|
|
810
|
+
nb::arg("reference_multiplicities"),nb::arg("coefficients"),nb::arg("threads")=0,nb::arg("exclude_exact")=false,
|
|
811
|
+
"Fused numeric requested-label max of cloglog(offset+c3*(rawNW-maxself)+gapcoef*g)*finite information. "
|
|
812
|
+
"Candidate scope is independent of float64 global NW; selection gap=max(abs(similarity)); "
|
|
813
|
+
"strict ties use M/X/Y for M and X, M/Y/X for Y, terminal M/X/Y. Group ID -1 is unsupported, not imputed. "
|
|
814
|
+
"Target filtering precedes NW. Use bounded query chunks against the same immutable Index. GIL released.")
|
|
704
815
|
.def("align", &py_align, nb::arg("ref_id"), nb::arg("query"), nb::arg("params"),
|
|
705
816
|
"Compute a global alignment between ``query`` and a reference, on demand.")
|
|
706
817
|
.def("collisions_batch", &py_collisions_batch, nb::arg("queries"), nb::arg("params"),
|
|
@@ -839,9 +950,14 @@ NB_MODULE(_core, m) {
|
|
|
839
950
|
nb::class_<GroupedCountChunk>(m,"GroupedCountChunk")
|
|
840
951
|
.def_ro("start",&GroupedCountChunk::start).def_ro("stop",&GroupedCountChunk::stop)
|
|
841
952
|
.def_ro("counts",&GroupedCountChunk::counts).def_ro("sizes",&GroupedCountChunk::sizes)
|
|
842
|
-
.def_ro("exact_counts",&GroupedCountChunk::exact_counts)
|
|
953
|
+
.def_ro("exact_counts",&GroupedCountChunk::exact_counts)
|
|
954
|
+
.def_ro("hits",&GroupedCountChunk::hits);
|
|
843
955
|
nb::class_<GroupedGeometry>(m,"_GroupedGeometry")
|
|
844
956
|
.def(nb::init<>()).def_rw("weights",&GroupedGeometry::weights)
|
|
957
|
+
.def_rw("return_hits",&GroupedGeometry::return_hits)
|
|
958
|
+
.def_rw("max_hit_bytes",&GroupedGeometry::max_hit_bytes)
|
|
959
|
+
.def_rw("query_target_ids",&GroupedGeometry::query_target_ids)
|
|
960
|
+
.def_rw("query_reference_ids",&GroupedGeometry::query_reference_ids)
|
|
845
961
|
.def_rw("additional_features",&GroupedGeometry::additional_features)
|
|
846
962
|
.def_rw("gap_prior",&GroupedGeometry::gap_prior)
|
|
847
963
|
.def_rw("alignment_mode",&GroupedGeometry::alignment_mode)
|
|
@@ -895,7 +1011,7 @@ NB_MODULE(_core, m) {
|
|
|
895
1011
|
nb::arg("reference_target_offsets"),nb::arg("reference_target_ids"),
|
|
896
1012
|
nb::arg("target_peptide_ids"),nb::arg("reference_exclusive_peptide_ids"),
|
|
897
1013
|
nb::arg("query_gene_ids"),nb::arg("reference_gene_ids"),nb::arg("chunk_size"),
|
|
898
|
-
nb::arg("alphabet"),nb::arg("matrix"),nb::arg("gap_open"),nb::arg("gap_extend"),
|
|
1014
|
+
nb::arg("alphabet"),nb::arg("matrix").none(),nb::arg("gap_open"),nb::arg("gap_extend"),
|
|
899
1015
|
nb::arg("prior"),nb::arg("prior_width"),nb::arg("threads"),nb::arg("exclude_exact"),
|
|
900
1016
|
nb::arg("alpha"),nb::arg("beta")=std::nullopt,
|
|
901
1017
|
nb::arg("queries_beta")=std::vector<std::string>{},nb::arg("refs_beta")=std::vector<std::string>{},
|
|
@@ -923,11 +1039,11 @@ NB_MODULE(_core, m) {
|
|
|
923
1039
|
return gapblock_count_mass_batch(queries, refs, thresholds, alph, matrix ? &*matrix : nullptr, go, ge, prior, width, threads, exclude_exact, weights, query_groups, reference_groups, group_distances, query_weights, reference_weights, feature_offsets, shared_thresholds);
|
|
924
1040
|
}, nb::arg("queries"), nb::arg("refs"), nb::arg("thresholds"), nb::arg("alphabet")="aa", nb::arg("matrix")=std::nullopt, nb::arg("gap_open")=1, nb::arg("gap_extend")=1, nb::arg("prior")=std::vector<int32_t>{}, nb::arg("prior_width")=0, nb::arg("threads")=0, nb::arg("exclude_exact")=false, nb::arg("position_weights_by_length")=std::vector<std::vector<int32_t>>{}, nb::arg("query_group_ids")=std::vector<int32_t>{}, nb::arg("reference_group_ids")=std::vector<int32_t>{}, nb::arg("group_distances")=std::vector<std::vector<int32_t>>{}, nb::arg("query_position_weights")=std::vector<std::vector<int32_t>>{}, nb::arg("reference_position_weights")=std::vector<std::vector<int32_t>>{}, nb::arg("feature_offsets")=std::nullopt, nb::arg("shared_thresholds")=false, "Counts and integer linear mass in one bounded traversal, GIL released.");
|
|
925
1041
|
|
|
926
|
-
m.def("gapblock_group_audit_batch", [](const std::vector<std::string>& queries, const std::vector<std::string>& refs, const std::vector<int32_t>& thresholds, const std::string& alphabet, const std::optional<SubstitutionMatrix>& matrix, int32_t go, int32_t ge, const std::vector<int32_t>& prior, uint32_t width, int threads, bool exclude_exact, const std::vector<std::vector<int32_t>>& weights, const std::vector<int32_t>& query_groups, const std::vector<int32_t>& reference_groups, const std::vector<std::vector<int32_t>>& group_distances, const std::vector<std::vector<int32_t>>& query_weights, const std::vector<std::vector<int32_t>>& reference_weights, const std::optional<PairedFeatureOffsets>& feature_offsets) {
|
|
1042
|
+
m.def("gapblock_group_audit_batch", [](const std::vector<std::string>& queries, const std::vector<std::string>& refs, const std::vector<int32_t>& thresholds, const std::string& alphabet, const std::optional<SubstitutionMatrix>& matrix, int32_t go, int32_t ge, const std::vector<int32_t>& prior, uint32_t width, int threads, bool exclude_exact, const std::vector<std::vector<int32_t>>& weights, const std::vector<int32_t>& query_groups, const std::vector<int32_t>& reference_groups, const std::vector<std::vector<int32_t>>& group_distances, const std::vector<std::vector<int32_t>>& query_weights, const std::vector<std::vector<int32_t>>& reference_weights, const std::optional<PairedFeatureOffsets>& feature_offsets, const std::vector<int32_t>& query_partitions, const std::vector<int32_t>& reference_partitions) {
|
|
927
1043
|
const auto alph = parse_alphabet(alphabet);
|
|
928
1044
|
nb::gil_scoped_release release;
|
|
929
|
-
return gapblock_group_audit_batch(queries, refs, thresholds, alph, matrix ? &*matrix : nullptr, go, ge, prior, width, threads, exclude_exact, weights, query_groups, reference_groups, group_distances, query_weights, reference_weights, feature_offsets);
|
|
930
|
-
}, nb::arg("queries"), nb::arg("refs"), nb::arg("thresholds"), nb::arg("alphabet")="aa", nb::arg("matrix")=std::nullopt, nb::arg("gap_open")=1, nb::arg("gap_extend")=1, nb::arg("prior")=std::vector<int32_t>{}, nb::arg("prior_width")=0, nb::arg("threads")=0, nb::arg("exclude_exact")=false, nb::arg("position_weights_by_length")=std::vector<std::vector<int32_t>>{}, nb::arg("query_group_ids")=std::vector<int32_t>{}, nb::arg("reference_group_ids")=std::vector<int32_t>{}, nb::arg("group_distances")=std::vector<std::vector<int32_t>>{}, nb::arg("query_position_weights")=std::vector<std::vector<int32_t>>{}, nb::arg("reference_position_weights")=std::vector<std::vector<int32_t>>{}, nb::arg("feature_offsets")=std::nullopt, "Streaming component/full ball counts and minimum full score within the component ball, GIL released.");
|
|
1045
|
+
return gapblock_group_audit_batch(queries, refs, thresholds, alph, matrix ? &*matrix : nullptr, go, ge, prior, width, threads, exclude_exact, weights, query_groups, reference_groups, group_distances, query_weights, reference_weights, feature_offsets, query_partitions, reference_partitions);
|
|
1046
|
+
}, nb::arg("queries"), nb::arg("refs"), nb::arg("thresholds"), nb::arg("alphabet")="aa", nb::arg("matrix")=std::nullopt, nb::arg("gap_open")=1, nb::arg("gap_extend")=1, nb::arg("prior")=std::vector<int32_t>{}, nb::arg("prior_width")=0, nb::arg("threads")=0, nb::arg("exclude_exact")=false, nb::arg("position_weights_by_length")=std::vector<std::vector<int32_t>>{}, nb::arg("query_group_ids")=std::vector<int32_t>{}, nb::arg("reference_group_ids")=std::vector<int32_t>{}, nb::arg("group_distances")=std::vector<std::vector<int32_t>>{}, nb::arg("query_position_weights")=std::vector<std::vector<int32_t>>{}, nb::arg("reference_position_weights")=std::vector<std::vector<int32_t>>{}, nb::arg("feature_offsets")=std::nullopt, nb::arg("query_partition_ids")=std::vector<int32_t>{}, nb::arg("reference_partition_ids")=std::vector<int32_t>{}, "Streaming component/full ball counts and minimum full score within the component ball, GIL released.");
|
|
931
1047
|
|
|
932
1048
|
m.def("gapblock_ball_batch", [](const std::vector<std::string>& queries, const std::vector<std::string>& refs, const std::vector<int32_t>& thresholds, const std::string& alphabet, const std::optional<SubstitutionMatrix>& matrix, int32_t go, int32_t ge, const std::vector<int32_t>& prior, uint32_t width, int threads, bool exclude_exact, const std::vector<std::vector<int32_t>>& weights, const std::vector<int32_t>& query_groups, const std::vector<int32_t>& reference_groups, const std::vector<std::vector<int32_t>>& group_distances, const std::vector<std::vector<int32_t>>& query_weights, const std::vector<std::vector<int32_t>>& reference_weights, const std::optional<PairedFeatureOffsets>& feature_offsets) {
|
|
933
1049
|
const auto alph = parse_alphabet(alphabet);
|