Skip to content

Support separate odgi depth -b for arbitrary interval depth - #266

Merged
sampsyo merged 7 commits into
mainfrom
interval-depth
May 17, 2026
Merged

sampsyo merged 7 commits into
mainfrom
interval-depth

Conversation

@sampsyo

@sampsyo sampsyo commented May 17, 2026

Copy link
Copy Markdown
Collaborator

In #259, we added an end-to-end fgfa window-depth command that both calculates evenly-sized windows and then computes their average depth. The original script we're working from does this in two commands, though, so I was interested in implementing them separately too. What we needed was a drop-in replacement for odgi depth -b something.bed, which I have now added.

I refactored the stuff in window_depth a bit so that we could share almost all of the implementation across the "fixed-function" window version and the arbitrary-interval version.

I then added odgi depth -b to flash. Following the benchmarks in #259, we can now compare odgi and fgfa against a slightly adapted shell script. Here's that three-way comparison:

$ hyperfine -w1 -r3 \
    'sh odgi_wdepth.sh > odgi_result.bed' \
    'fgfa -i chr8.flatgfa window-depth "chm13#chr8" 5000 > fgfa_result.bed' \
    'flash flash_wdepth.sh > flash_result.bed'

Benchmark 1: sh odgi_wdepth.sh > odgi_result.bed
  Time (mean ± σ):     15.203 s ±  0.358 s    [User: 13.980 s, System: 3.043 s]
  Range (min … max):   14.810 s … 15.509 s    3 runs

Benchmark 2: fgfa -i chr8.flatgfa window-depth "chm13#chr8" 5000 > fgfa_result.bed
  Time (mean ± σ):     989.9 ms ±   3.6 ms    [User: 849.1 ms, System: 138.1 ms]
  Range (min … max):   987.3 ms … 994.1 ms    3 runs

Benchmark 3: flash flash_wdepth.sh > flash_result.bed
  Time (mean ± σ):      1.322 s ±  0.003 s    [User: 1.083 s, System: 0.234 s]
  Range (min … max):    1.318 s …  1.324 s    3 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Summary
  fgfa -i chr8.flatgfa window-depth "chm13#chr8" 5000 > fgfa_result.bed ran
    1.34 ± 0.01 times faster than flash flash_wdepth.sh > flash_result.bed
   15.36 ± 0.37 times faster than sh odgi_wdepth.sh > odgi_result.bed

As expected, flash pays some overhead w/r/t the all-in-one fgfa invocation in order to write that BED file and then parse it back, but it's not too much (1.34x ain't bad). The goal is to mostly eliminate this through optimizations.


As a reminder, here's the script for odgi:

odgi depth -i chr8.pan.og -r chm13#chr8 | \
    bedtools makewindows -b /dev/stdin -w 5000 > chm13.chr8.w5kbps.bed
odgi depth -i chr8.pan.og -b chm13.chr8.w5kbps.bed --threads 2 | \
    bedtools sort

Here's the flash script:

odgi depth -i chr8.flatgfa -r "chm13#chr8" | bedtools makewindows -b /dev/stdin -w 5000 > chm13.chr8.w5kbps.bed
odgi depth -i chr8.flatgfa -b chm13.chr8.w5kbps.bed --threads 2

Some notes on the shell syntax:

  • I'm doing this without optimizations now, hence the hard-coded FlatGFA input file. With -O, you could use the .og input file and not pay for it.
  • Our shell syntax parser sadly doesn't support escaped newlines (Skip escaped newlines raphamorim/flash#13).
  • --threads 2 doesn't do anything; it's silently ignored.
  • We're skipping bedtools sort, which is a little unfair.

sampsyo added 7 commits May 16, 2026 12:03
Just trying to implement *half* of the window-depth computation.
Starting with an initial implementation that involves a lot of code
duplication, and hoping to clean it up next.
We now have one struct to represent the result of both `window_depth`
and the more general `interval_depth`, and they use the `Emit` trait to
share the printing logic between them.
As part of the quest to further unify the "windowed" and "arbitrary
depth" paths, this makes the former use a FlatBED data structure instead
of a plain `Vec<(usize, usize>)`. Now the data interchange format is
identical between the two.

This comes with some overhead (we now have to needlessly keep track of a
"name" field for the windows), but some quick measurement suggests it's
not a big deal. I ran this experiment:

    hyperfine 'fgfa -i chr8.flatgfa window-depth "chm13#chr8" 5000 > /dev/null'

With these results:

old: 953.9 ms ±  11.7 ms
new: 940.0 ms ±   9.6 ms

So I'm calling that "no change" (solidly within the margin of error).
Now `window_depth` and `bed_depth` can be very short because they only
differ by a little bit.
We will need this for `odgi depth -b`, so let's finally cross that
bridge.
It just feels better!
@sampsyo
sampsyo merged commit 86fd036 into main May 17, 2026
@sampsyo
sampsyo deleted the interval-depth branch May 17, 2026 20:01

This branch was previously deployed

1 inactive deployment
github-pages — 86fd0367 Deployed May 17, 2026 by sampsyo via deploy #312
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.

1 participant