Skip to content

feat: genomeGenerate VCF genome transform (--genomeTransformType Diploid) - #117

Closed
BenjaminDEMAILLE wants to merge 4 commits into
scverse:mainfrom
BenjaminDEMAILLE:bd/genome-transform-diploid
Closed

feat: genomeGenerate VCF genome transform (--genomeTransformType Diploid)#117
BenjaminDEMAILLE wants to merge 4 commits into
scverse:mainfrom
BenjaminDEMAILLE:bd/genome-transform-diploid

Conversation

@BenjaminDEMAILLE

Copy link
Copy Markdown
Contributor

Summary

Test plan

  • cargo build / test / clippy -D warnings / fmt --check all green

BenjaminDEMAILLE and others added 4 commits July 23, 2026 20:00
CI's clippy advanced to 1.97 (new lints fail the `-D warnings` gate) and rustsec
flagged several advisories in the dependency tree. Both block all PRs.

Clippy:
- src/index/suffix_array.rs: assert!(x == 0) -> assert_eq! (manual_assert_eq)
- src/io/sam.rs, tests/alignment_features.rs: byte-slice literals -> byte
  strings, e.g. [b'S', b'M'] -> *b"SM" (byte_char_slices)
- src/quant/transcriptome.rs: if-let/else-return-None -> `?` (question_mark)

Security audit (Cargo.lock only, no manifest change):
- memmap2 0.9.10 -> 0.9.11 (RUSTSEC-2026-0186, out-of-bounds pointer offset)
- crossbeam-epoch 0.9.18 -> 0.9.20 (RUSTSEC-2026-0204, invalid pointer deref)
- anyhow 1.0.102 -> 1.0.104 (RUSTSEC-2026-0190, unsound downcast_mut)

No behavioural change. Unblocks CI for open and future PRs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add LICENSES/STAR_RS_LICENSE (STAR-rs MIT notice, Copyright (c) 2026 Benjamin
Demaille) and note it in LICENSES/README.md, for attribution of modules ported
from STAR-rs. STAR-rs is dual MIT-OR-Apache; ported code is taken under its MIT
option, compatible with this repo's MIT license.

Add docs-old/dev/porting-from-star-rs.md documenting the STAR-rs to
rustar-aligner type/module mapping, the licensing and cellranger reference-only
caveat, the determinism decision (adopt STAR-rs's thread-invariant, no-rand
model), and how to validate ports against native STAR via the existing test/
harness with DIVERGENCES.md as the acceptance spec.

This is the base of a series of themed, dependency-stacked PRs bringing the
STAR-rs feature surface (WASP, clipping, signal tracks, genome transforms,
STARlong, STARsolo, ...) into rustar-aligner.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…oid)

Port STAR-rs's genomeGenerate-time genome transform from STAR-rs
`crates/star-index/src/transform.rs` (itself a port of STAR's
`Genome_transformGenome.cpp`): substitute a VCF's alleles into the reference
genome before the suffix array is built, so reads carrying the alternate
allele map with fewer mismatches.

Scoped to Haploid only (Diploid — duplicating the genome into `_h1`/`_h2`
haplotypes — is a follow-up), and to genomeGenerate only: with the only
supported `--genomeTransformOutput` (`None`, STAR's own default), the aligner
reports transformed-genome coordinates directly, so align-time back-transform
isn't needed and isn't implemented. `Parameters::validate` loudly rejects
Diploid, an unknown transform type, a missing VCF, or combining a transform
with a GTF (STAR itself doesn't support that combination either).

- src/genome/transform.rs: parse_vcf_haploid (first ALT allele per record, no
  genotype filtering, STAR's overlap filter), transform_one_chromosome
  (per-chromosome allele substitution in chromosome-local coordinates; indels
  shift length and split the block map), transform_chromosomes (globalizes
  blocks using compute_chr_starts run once over original lengths and once over
  transformed lengths), blocks_to_tsv (transformGenomeBlocks.tsv, STAR's
  reverse-conversion format).
- src/genome/mod.rs: extract compute_chr_starts (STAR's bin-padding formula)
  out of Genome::from_fasta as a shared helper; hook the transform in
  from_fasta right after FASTA parsing (indel-resized chromosomes flow
  unchanged through the existing padding/RC-buffer logic below); add
  Genome::transform_blocks, written to transformGenomeBlocks.tsv by
  write_index_files when present.
- src/lib.rs: genome_generate() also writes the untransformed index to
  `<genomeDir>/OriginalGenome/` (STAR's own layout) by re-running
  generate_streaming with the transform disabled and the output directory
  redirected.
- src/params/mod.rs: --genomeTransformType (None/Haploid), --genomeTransformVCF.

Adding the `transform_blocks` field to `Genome` required threading `None`
through ~28 existing test-only struct literals across align/chimeric/io/
junction/quant/signal (mechanical, no behavior change).

Verified end-to-end on a tiny fixture beyond the unit tests: genomeGenerate
with --genomeTransformType Haploid produces a transformed Genome file with the
VCF allele substituted at the right offset, an untouched OriginalGenome/, and
a transformGenomeBlocks.tsv with the correct identity block; the three
validation rejections (missing VCF, Diploid, unknown type) all fire correctly.

Gate green: cargo build --all-targets, clippy -D warnings, fmt, 478 tests (4
new transform unit tests). Byte-level validation against native STAR via the
test/ harness is a separate step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…oid)

Genotype-aware transform ported from STAR-rs: parse_vcf_diploid reads the
sample GT field per haplotype, transform_genome_diploid runs the Haploid
substitution once per haplotype and concatenates chr_h1/chr_h2 with new_start
offset by hap0's padded genome length. Rejects Diploid at validate() time no
longer; both Haploid and Diploid now share the same genomeGenerate path,
writing one OriginalGenome/ for both haplotypes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Psy-Fer Psy-Fer mentioned this pull request Jul 25, 2026
@Psy-Fer Psy-Fer closed this Jul 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants