diff --git a/docmd/architecture/index_architecture.refs.md b/docmd/architecture/index_architecture.refs.md new file mode 100644 index 0000000..ff9e3c0 --- /dev/null +++ b/docmd/architecture/index_architecture.refs.md @@ -0,0 +1,22 @@ + +# Coverage: architecture/index_architecture.md + +## Code couvert + +- `obilayeredmap/src/layer.rs` — Layer, trait LayerData, modes () / PersistentCompactIntMatrix / PersistentBitMatrix +- `obilayeredmap/src/mphf_layer.rs` — MphfLayer, EvidenceKind (Exact / Approx), LayerEvidence enum +- `obilayeredmap/src/map.rs` — LayeredMap +- `obilayeredmap/src/meta.rs` — LayerMeta, PartitionMeta +- `obikindex/src/meta.rs` — IndexConfig (kmer_size, n_bits, with_counts, evidence, block_bits), IndexMeta +- `obikindex/src/index.rs` — KmerIndex, build_layers +- `obicompactvec/src/` — PersistentCompactIntMatrix, PersistentBitMatrix (DataStore implementations) + +## Notes + +FORT RISQUE DE DÉRIVE. Nombreux changements récents : +- Ajout de `EvidenceKind` (Exact / Approx { b, z }) dans `IndexConfig` et `LayerMeta` +- Ajout de `block_bits` dans `IndexConfig` +- `LayerEvidence` enum dans `mphf_layer.rs` remplace l'ancienne approche monolithique +- Distinction `open()` vs `open_sequential()` dans `UnitigFileReader` +- Commandes `reindex` et `estimate` ajoutées +Vérifier que la hiérarchie à 3 niveaux décrite est toujours exacte et que les nouveaux paramètres sont documentés. diff --git a/docmd/architecture/query.refs.md b/docmd/architecture/query.refs.md new file mode 100644 index 0000000..2dcbc50 --- /dev/null +++ b/docmd/architecture/query.refs.md @@ -0,0 +1,16 @@ + +# Coverage: architecture/query.md + +## Code couvert + +- `obikmer/src/cmd/query.rs` — commande query, format de sortie +- `obikpartitionner/src/query_layer.rs` — routage de la requête à travers les partitions +- `obiread/src/lib.rs` — lecture des séquences d'entrée pour la requête + +## Notes + +RISQUE DE DÉRIVE. Vérifier : +- La commande `unitig` a été modifiée pour utiliser `open_sequential()` — vérifier si query est concerné +- `find_exact` / `find_approx` / `find` générique ont été ajoutés dans `MphfLayer` — le chemin de requête a changé +- Si l'index est approximatif (Approx), la requête peut produire des faux positifs : la doc le mentionne-t-elle ? +- Format de sortie CSV (`obikindex/src/csv.rs` ou équivalent) à vérifier diff --git a/docmd/architecture/sequences/invariant.refs.md b/docmd/architecture/sequences/invariant.refs.md new file mode 100644 index 0000000..52130f3 --- /dev/null +++ b/docmd/architecture/sequences/invariant.refs.md @@ -0,0 +1,12 @@ + +# Coverage: architecture/sequences/invariant.md + +## Code couvert + +- `obikseq/src/sequence.rs` — invariants de représentation des séquences (ACGT, longueur max) +- `obikseq/src/unitig.rs` — type Unitig, contrainte MAX_KMERS_PER_CHUNK (255 kmers par chunk) + +## Notes + +Document court et stable. Vérifier que la limite de 256 nucléotides (ou 255 kmers) par chunk +est toujours la même dans `obiskio::MAX_KMERS_PER_CHUNK`. diff --git a/docmd/implementation/chunkreader.refs.md b/docmd/implementation/chunkreader.refs.md new file mode 100644 index 0000000..99be9cf --- /dev/null +++ b/docmd/implementation/chunkreader.refs.md @@ -0,0 +1,12 @@ + +# Coverage: implementation/chunkreader.md + +## Code couvert + +- `obiread/src/chunk.rs` — SeqChunkIter, détection de frontières FASTA/FASTQ, state machines +- `obikrope/src/lib.rs` — type Rope (Vec), opérations zero-copy + +## Notes + +Document stable (la stratégie de chunking rope ne devrait pas avoir changé). +Vérifier que le split FASTA/FASTQ reste correct si de nouveaux formats ont été ajoutés. diff --git a/docmd/implementation/evidence_elimination.refs.md b/docmd/implementation/evidence_elimination.refs.md new file mode 100644 index 0000000..0fedcb3 --- /dev/null +++ b/docmd/implementation/evidence_elimination.refs.md @@ -0,0 +1,22 @@ + +# Coverage: implementation/evidence_elimination.md + +## Code couvert + +- `obilayeredmap/src/fingerprint.rs` — FingerprintVec, FingerprintVecWriter, stockage b bits/slot, matches() +- `obilayeredmap/src/mphf_layer.rs` — build_approx_evidence(dir, b, z), find_approx() +- `obilayeredmap/src/meta.rs` — EvidenceKind::Approx { b, z }, LayerMeta +- `obikindex/src/reindex.rs` — KmerIndex::reindex(), conversion exact↔approx en place +- `obikmer/src/cmd/reindex.rs` — CLI reindex, options --approx, -z, --evidence-bits, --fp, --block-size +- `obikmer/src/cmd/index.rs` — resolve_approx_params(), options --approx, -z, --evidence-bits, --fp +- `obikmer/src/cmd/estimate.rs` — commande estimate (dry-run des paramètres) + +## Notes + +Ce document était à l'origine une discussion de design (4 approches). L'implémentation +a maintenant convergé vers l'approche fingerprint (Findere-style). +FORT RISQUE DE DÉRIVE — le contenu est probablement un mélange de design et d'implémentation : +- Le modèle FP = 1/2^(b·z) et les règles de résolution (2-of-3 parmi b, z, fp) sont implémentés +- La commande `reindex` permet la conversion a posteriori exact↔approx +- La commande `estimate` fait le dry-run des paramètres +Cette page doit être réécrite pour documenter l'implémentation Findere réelle plutôt que les alternatives abandonnées. diff --git a/docmd/implementation/kmer.refs.md b/docmd/implementation/kmer.refs.md new file mode 100644 index 0000000..747d5e3 --- /dev/null +++ b/docmd/implementation/kmer.refs.md @@ -0,0 +1,13 @@ + +# Coverage: implementation/kmer.md + +## Code couvert + +- `obikseq/src/kmer.rs` — layout mémoire (repr(transparent) u64), encodage/décodage, revcomp, forme canonique +- `obikseq/src/params.rs` — k global (set_k / k()) + +## Notes + +Document d'implémentation stable. L'algorithme de revcomp bit-à-bit est décrit — +vérifier qu'il correspond à `revcomp_raw` dans `obiskio/src/unitig_index.rs` (copie locale) +et à l'implémentation dans `obikseq/src/kmer.rs`. diff --git a/docmd/implementation/merge.refs.md b/docmd/implementation/merge.refs.md new file mode 100644 index 0000000..a9ffa07 --- /dev/null +++ b/docmd/implementation/merge.refs.md @@ -0,0 +1,19 @@ + +# Coverage: implementation/merge.md + +## Code couvert + +- `obikindex/src/merge.rs` — `KmerIndex::merge()`, validation de compatibilité d'évidence, `validate_evidence_compat()` +- `obikpartitionner/src/merge_layer.rs` — `merge_partition()`, construction de la nouvelle layer, paramètre `block_bits` +- `obikpartitionner/src/rebuild_layer.rs` — `rebuild_partition()`, paramètre `block_bits` +- `obilayeredmap/src/layer.rs` — `Layer::append_genome_column()` (PersistentCompactIntMatrix et PersistentBitMatrix) +- `obicompactvec/src/intmatrix.rs` — `append_column` pour PersistentCompactIntMatrix +- `obicompactvec/src/bitmatrix.rs` — `append_column` pour PersistentBitMatrix + +## Notes + +FORT RISQUE DE DÉRIVE. Changements récents : +- Ajout de la validation de compatibilité d'évidence : merge exact+approx → erreur (OKIError::IncompatibleEvidence) +- `merge_partition` reçoit maintenant `block_bits: u8` +- La commande `reindex` a été ajoutée comme outil de conversion exact↔approx avant merge +Vérifier que la doc décrit la politique de merge mixed-evidence et le recours à `reindex`. diff --git a/docmd/implementation/mphf.refs.md b/docmd/implementation/mphf.refs.md new file mode 100644 index 0000000..fd56c80 --- /dev/null +++ b/docmd/implementation/mphf.refs.md @@ -0,0 +1,16 @@ + +# Coverage: implementation/mphf.md + +## Code couvert + +- `obilayeredmap/src/mphf_layer.rs` — type Mphf (PtrHash + CubicEps + CachelineEfVec + Xx64), construction en 2 passes, `build()`, `build_exact_evidence()`, `build_approx_evidence()`, `build_evidence()` +- `obikpartitionner/src/index_layer.rs` — `build_index_layer()` avec passage de `block_bits` + +## Notes + +FORT RISQUE DE DÉRIVE. Changements récents : +- `build_exact_evidence(dir, block_bits)` — `block_bits` maintenant paramétrisé (défaut 0) +- `build_approx_evidence(dir, b, z)` — nouvelle fonction pour l'évidence fingerprint +- `build_evidence(dir, kind, block_bits)` — dispatch selon EvidenceKind +- Construction en 2 phases : pass 1 (Rayon parallèle) + pass 2 (callback `fill_slot`) +Vérifier que la doc décrit correctement les deux nouvelles routes d'évidence et le paramètre `block_bits`. diff --git a/docmd/implementation/obilayeredmap.refs.md b/docmd/implementation/obilayeredmap.refs.md new file mode 100644 index 0000000..5340ab3 --- /dev/null +++ b/docmd/implementation/obilayeredmap.refs.md @@ -0,0 +1,22 @@ + +# Coverage: implementation/obilayeredmap.md + +## Code couvert + +- `obilayeredmap/src/mphf_layer.rs` — MphfLayer, LayerEvidence enum (Exact/Approx), find(), find_exact(), find_approx() +- `obilayeredmap/src/layer.rs` — Layer, trait LayerData, modes () / PersistentCompactIntMatrix / PersistentBitMatrix, build(), build_evidence(), append_genome_column() +- `obilayeredmap/src/map.rs` — LayeredMap, push_layer(), query() +- `obilayeredmap/src/evidence.rs` — Evidence, EvidenceWriter, encodage chunk_id:rank +- `obilayeredmap/src/fingerprint.rs` — FingerprintVec, FingerprintVecWriter, matches() +- `obilayeredmap/src/meta.rs` — LayerMeta, EvidenceKind (Exact / Approx { b, z }) + +## Notes + +FORT RISQUE DE DÉRIVE. C'est le fichier le plus affecté par les changements récents : +- EvidenceKind (Exact / Approx) est désormais un concept de premier plan — toute la sémantique de query en dépend +- `LayerEvidence` enum interne à `MphfLayer` : dispatch transparent find() → find_exact() ou find_approx() +- `fingerprint.rs` : module entièrement nouveau (FingerprintVec + FingerprintVecWriter) +- `build_evidence()` / `build_exact_evidence()` / `build_approx_evidence()` sont nouveaux +- `block_bits` dans les fonctions build : O(1) garanti avec le chemin chaud explicit pour block_bits=0 +- Séparation open() (accès aléatoire, requiert .idx) vs open_sequential() (itération seule) +Pratiquement toute cette page est à réécrire. diff --git a/docmd/implementation/obipipeline.refs.md b/docmd/implementation/obipipeline.refs.md new file mode 100644 index 0000000..82fb2e8 --- /dev/null +++ b/docmd/implementation/obipipeline.refs.md @@ -0,0 +1,13 @@ + +# Coverage: implementation/obipipeline.md + +## Code couvert + +- `obipipeline/src/lib.rs` — WorkerPool, Pipeline, macro make_pipeline! +- `obipipeline/src/scheduler.rs` — Scheduler avec Select biaisé sur les entrées de canaux + +## Notes + +Document stable (librairie générique, peu de risque de dérive). +Vérifier si `obipipeline` est toujours utilisé dans la phase scatter de `obikpartitionner` +ou s'il a été remplacé par Rayon dans certains chemins. diff --git a/docmd/implementation/persistent_bit_vec.refs.md b/docmd/implementation/persistent_bit_vec.refs.md new file mode 100644 index 0000000..67fed55 --- /dev/null +++ b/docmd/implementation/persistent_bit_vec.refs.md @@ -0,0 +1,13 @@ + +# Coverage: implementation/persistent_bit_vec.md + +## Code couvert + +- `obicompactvec/src/bitvec.rs` — PersistentBitVec, opérations mot u64, invariant de padding +- `obicompactvec/src/bitmatrix.rs` — PersistentBitMatrix, wrapper colonne-major, append_column +- `obicompactvec/src/bitmatrix.rs` — PersistentBitMatrixBuilder + +## Notes + +Document d'implémentation stable. Vérifier que `PersistentBitMatrixBuilder` et `append_column` +sont couverts (utilisés dans `Layer::::build_presence` et `append_genome_column`). diff --git a/docmd/implementation/persistent_compact_int_vec.refs.md b/docmd/implementation/persistent_compact_int_vec.refs.md new file mode 100644 index 0000000..c5da1b0 --- /dev/null +++ b/docmd/implementation/persistent_compact_int_vec.refs.md @@ -0,0 +1,14 @@ + +# Coverage: implementation/persistent_compact_int_vec.md + +## Code couvert + +- `obicompactvec/src/builder.rs` — PersistentCompactIntVecBuilder, cycle de vie +- `obicompactvec/src/reader.rs` — PersistentCompactIntVec, accès aléatoire et séquentiel +- `obicompactvec/src/intmatrix.rs` — PersistentCompactIntMatrix, wrapper colonne-major, append_column +- `obicompactvec/src/format.rs` — format de fichier (magic PCIV, header, primary u8, overflow, index) + +## Notes + +Document d'implémentation stable. Vérifier que `append_column` (utilisé dans merge et reindex) +est décrit. Vérifier que `PersistentCompactIntMatrixBuilder` est couvert (utilisé dans `layer.rs`). diff --git a/docmd/implementation/pipeline.refs.md b/docmd/implementation/pipeline.refs.md new file mode 100644 index 0000000..a5656a0 --- /dev/null +++ b/docmd/implementation/pipeline.refs.md @@ -0,0 +1,19 @@ + +# Coverage: implementation/pipeline.md + +## Code couvert + +- `obikpartitionner/src/partition.rs` — estimation des paramètres (phase 0) +- `obiskbuilder/src/iter.rs` — scatter : filtre entropie, extraction superkmers, routage partition (phase 1) +- `obikpartitionner/src/filter.rs` — déduplication bucket-sort (phase 2) +- `obikpartitionner/src/kmer_sort.rs` — tri externe + agrégation de comptages (phase 3) +- `obidebruinj/src/debruijn.rs` — graphe De Bruijn, extraction des unitigs (phase 5) +- `obikpartitionner/src/index_layer.rs` — construction MPHF + évidence (phase 6), paramètre `block_bits` +- `obikindex/src/index.rs` — `build_layers()`, `dereplicate_and_count()` + +## Notes + +RISQUE DE DÉRIVE modéré. Vérifier : +- Phase 6 : la doc mentionne-t-elle le filtre d'abondance (`min_ab`, `max_ab`) ? +- Phase 6 : `block_bits` passé à `build_index_layer` depuis `IndexConfig` +- Phase 6 : dispatch exact/approx selon `EvidenceKind` dans `build_index_layer` diff --git a/docmd/implementation/storage.refs.md b/docmd/implementation/storage.refs.md new file mode 100644 index 0000000..6987401 --- /dev/null +++ b/docmd/implementation/storage.refs.md @@ -0,0 +1,18 @@ + +# Coverage: implementation/storage.md + +## Code couvert + +- `obikindex/src/meta.rs` — IndexMeta, IndexConfig (version, config, genomes) +- `obikindex/src/index.rs` — layout sur disque : partitions/, index.meta +- `obilayeredmap/src/meta.rs` — LayerMeta (evidence kind), PartitionMeta (n_layers) +- `obiskio/src/unitig_index.rs` — fichiers unitigs.bin + unitigs.bin.idx + +## Notes + +FORT RISQUE DE DÉRIVE. Nombreux champs ajoutés : +- `IndexConfig` : champs `evidence` (EvidenceKind) et `block_bits` ajoutés +- Nouveau fichier `fingerprint.bin` pour l'évidence approximative +- `LayerMeta` / `layer_meta.json` introduit pour stocker EvidenceKind par layer +- Structure du répertoire layer : `evidence.bin` vs `fingerprint.bin` selon le mode +Mettre à jour le schéma de layout sur disque en conséquence. diff --git a/docmd/implementation/superkmer.refs.md b/docmd/implementation/superkmer.refs.md new file mode 100644 index 0000000..8aedb67 --- /dev/null +++ b/docmd/implementation/superkmer.refs.md @@ -0,0 +1,13 @@ + +# Coverage: implementation/superkmer.md + +## Code couvert + +- `obikseq/src/superkmer.rs` — layout mémoire SuperKmer (header 32 bits + séquence byte-alignée), encodage ASCII, revcomp, deque minimiseur +- `obiskbuilder/src/lib.rs` — fenêtre glissante monotone pour le maintien du minimiseur + +## Notes + +Document d'implémentation détaillé. Vérifier que le layout header (longueur, orientation, +position minimiseur) n'a pas changé. La doc mentionne un revcomp SIMD — vérifier si c'est +toujours le cas ou si l'implémentation est scalaire. diff --git a/docmd/implementation/unitig_evidence.refs.md b/docmd/implementation/unitig_evidence.refs.md new file mode 100644 index 0000000..d25b200 --- /dev/null +++ b/docmd/implementation/unitig_evidence.refs.md @@ -0,0 +1,18 @@ + +# Coverage: implementation/unitig_evidence.md + +## Code couvert + +- `obiskio/src/unitig_index.rs` — format unitigs.bin + unitigs.bin.idx, UnitigFileWriter, UnitigFileReader, build_unitig_idx(), DEFAULT_BLOCK_BITS=0, chemin chaud block_bits=0 dans chunk_start() +- `obilayeredmap/src/evidence.rs` — encodage Evidence (chunk_id 25 bits | rank 7 bits), EvidenceWriter +- `obidebruinj/src/debruijn.rs` — extraction unitigs, chunking à MAX_KMERS_PER_CHUNK + +## Notes + +FORT RISQUE DE DÉRIVE. Changements récents : +- `DEFAULT_BLOCK_BITS` est passé de 6 à 0 (accès O(1) par défaut) +- `block_bits` est maintenant un paramètre runtime de `build_unitig_idx()` et `UnitigFileWriter` +- `chunk_start()` a un chemin chaud explicite pour block_bits=0 (accès tableau direct, 0 scan) +- `open()` vs `open_sequential()` : distinction nouvelle, importante pour la compréhension du coût +- `iter_unitigs()` ajouté comme alias public de `iter_chunks_sequential()` +Mettre à jour la description du format .idx et le modèle de coût d'accès aléatoire. diff --git a/docmd/index.refs.md b/docmd/index.refs.md new file mode 100644 index 0000000..60e0163 --- /dev/null +++ b/docmd/index.refs.md @@ -0,0 +1,13 @@ + +# Coverage: index.md + +## Code couvert + +- `obikmer/src/main.rs` — point d'entrée CLI, contraintes globales +- `obikmer/src/cli.rs` — structure des arguments communs + +## Notes + +Document de niveau projet (vue d'ensemble, motivations, contraintes fondamentales). +Pas de code Rust spécifique à vérifier au-delà des contraintes générales (k impair, formats d'entrée). +À mettre à jour si de nouvelles sous-commandes ou formats sont ajoutés. diff --git a/docmd/kmers.refs.md b/docmd/kmers.refs.md new file mode 100644 index 0000000..4dbe0a3 --- /dev/null +++ b/docmd/kmers.refs.md @@ -0,0 +1,13 @@ + +# Coverage: kmers.md + +## Code couvert + +- `obikseq/src/kmer.rs` — type Kmer, propriétés, forme canonique +- `obikseq/src/superkmer.rs` — type SuperKmer, longueur attendue +- `obiskbuilder/src/lib.rs` — extraction de superkmers par minimiseur + +## Notes + +Chevauche `theory/encoding.md` (encodage 2 bits) et `theory/minimizer.md` (choix du minimiseur). +Vérifier que la définition de SuperKmer est cohérente avec les invariants actuels de `obikseq`. diff --git a/docmd/theory/encoding.refs.md b/docmd/theory/encoding.refs.md new file mode 100644 index 0000000..125b588 --- /dev/null +++ b/docmd/theory/encoding.refs.md @@ -0,0 +1,11 @@ + +# Coverage: theory/encoding.md + +## Code couvert + +- `obikseq/src/kmer.rs` — encodage 2 bits/base, revcomp, forme canonique + +## Notes + +Document purement théorique. Peu de risque de dérive sauf si l'encodage interne de Kmer change. +Vérifier que la table d'encodage A=00, C=01, G=10, T=11 est toujours celle du code. diff --git a/docmd/theory/entropy.refs.md b/docmd/theory/entropy.refs.md new file mode 100644 index 0000000..79ca55c --- /dev/null +++ b/docmd/theory/entropy.refs.md @@ -0,0 +1,12 @@ + +# Coverage: theory/entropy.md + +## Code couvert + +- `obiskbuilder/src/entropy_table.rs` — filtre Shannon sur les kmers à basse complexité +- `obiskbuilder/src/lib.rs` — application du filtre lors du scatter (phase 1) + +## Notes + +Document théorique stable. Vérifier que les paramètres `theta` et `level_max` dans le CLI +(`obikmer/src/cli.rs` → `CommonArgs`) correspondent bien à ce qui est décrit. diff --git a/docmd/theory/indexing.refs.md b/docmd/theory/indexing.refs.md new file mode 100644 index 0000000..444abff --- /dev/null +++ b/docmd/theory/indexing.refs.md @@ -0,0 +1,12 @@ + +# Coverage: theory/indexing.md + +## Code couvert + +- `obikpartitionner/src/partition.rs` — routage par hash de minimiseur, choix des paramètres +- `obikpartitionner/src/lib.rs` — structure KmerPartition, nombre de partitions + +## Notes + +Vérifier que la doc mentionne bien que le nombre de partitions est une puissance de 2 +(converti par `partitions_to_bits` dans `obikmer/src/cli.rs`). diff --git a/docmd/theory/minimizer.refs.md b/docmd/theory/minimizer.refs.md new file mode 100644 index 0000000..277a89f --- /dev/null +++ b/docmd/theory/minimizer.refs.md @@ -0,0 +1,12 @@ + +# Coverage: theory/minimizer.md + +## Code couvert + +- `obiskbuilder/src/lib.rs` — sélection du minimiseur par hash seedé (splitmix64 finalizer) +- `obikseq/src/superkmer.rs` — forme canonique du minimiseur, fenêtre glissante + +## Notes + +Vérifier que la fonction de hash décrite (splitmix64 finalizer avec graine) correspond +au code actuel. Vérifier aussi que la définition de « minimiseur canonique » est toujours cohérente.