Skip to content

Commit

Permalink
testing report.
Browse files Browse the repository at this point in the history
  • Loading branch information
brentp committed Dec 6, 2023
1 parent 994bcf4 commit 1a4455b
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 53 deletions.
203 changes: 150 additions & 53 deletions src/intersections.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::ops::ControlFlow;

use crate::intersection::Intersections;
use crate::position::Position;
#[allow(unused_imports)]
Expand All @@ -13,6 +15,8 @@ pub enum IntersectionOutput {
Part,
/// Report the whole interval of A that overlaps B
Whole,
/// Report Unique As even if multiple Bs overlap
Unique,
}

bitflags! {
Expand All @@ -23,7 +27,7 @@ bitflags! {
// https://bedtools.readthedocs.io/en/latest/content/tools/intersect.html#usage-and-option-summary

/// Default without extra requirements.
const Empty = 0b00000000;
const Default = 0b00000000;

/// Return A(B) if it does *not* overlap B(A). Bedtools -v
const Not = 0b00000001;
Expand All @@ -38,7 +42,7 @@ bitflags! {

impl Default for IntersectionMode {
fn default() -> Self {
Self::Empty
Self::Default
}
}

Expand Down Expand Up @@ -86,12 +90,6 @@ impl Intersections {
let mut results = Vec::new();
let base = self.base_interval.clone();
// iterate over the intersections and check the requirements
match a_output {
IntersectionOutput::None => {}
IntersectionOutput::Part => {}
IntersectionOutput::Whole => {}
}
// TODO: get pieces here?
let bases: u64 = self
.overlapping
.iter()
Expand Down Expand Up @@ -120,7 +118,7 @@ impl Intersections {

//let mut pieces = vec![];
// TODO: here we add just the a pieces. Need to check how to add the b pieces.
self.overlapping.iter().for_each(|o| {
for o in self.overlapping.iter() {
match a_output {
IntersectionOutput::Part => {
let mut piece: Position = base.as_ref().dup();
Expand All @@ -130,9 +128,13 @@ impl Intersections {
results.push((Some(piece.dup()), None))
}
IntersectionOutput::Whole => results.push((Some(base.as_ref().dup()), None)),
IntersectionOutput::Unique => {
results.push((Some(base.as_ref().dup()), None));
break;
}
IntersectionOutput::None => {}
}
});
}

results
}
Expand All @@ -141,66 +143,161 @@ impl Intersections {
#[cfg(test)]
mod tests {
use super::*;
use crate::intersection::Intersection;
use crate::intersection::{self, Intersection};
use crate::interval::Interval;
use std::sync::Arc;

#[test]
fn test_simple() {
fn make_intersections(a: Interval, bs: Vec<Interval>) -> Intersections {
let base = Position::Interval(a);
let overlapping = bs
.into_iter()
.enumerate()
.map(|(i, b)| Intersection {
interval: Arc::new(Position::Interval(b.dup())),
id: i as u32,
})
.collect();
Intersections {
base_interval: Arc::new(base),
overlapping,
}
}

fn make_example() -> Intersections {
// make a single Intersections
let base = Interval {
chrom: String::from("chr1"),
start: 1,
stop: 10,
fields: Default::default(),
};
let other = Interval {
let o1 = Interval {
chrom: String::from("chr1"),
start: 3,
stop: 6,
fields: Default::default(),
};
let p = Position::Interval(base);
let oi1 = Intersection {
interval: Arc::new(Position::Interval(other)),
id: 0,
};
let oi2 = Intersection {
interval: Arc::new(Position::Interval(Interval {
chrom: String::from("chr1"),
start: 8,
stop: 12,
fields: Default::default(),
})),
id: 1,
};
let intersections = Intersections {
base_interval: Arc::new(p),
overlapping: vec![oi1, oi2],
let o2 = Interval {
chrom: String::from("chr1"),
start: 8,
stop: 12,
fields: Default::default(),
};
make_intersections(base, vec![o1, o2])
}

intersections
.overlapping
.iter()
.map(|o| o.interval.clone())
.for_each(|i| {
let overlap = i.stop().min(intersections.base_interval.stop())
- i.start().max(intersections.base_interval.start());
println!("overlap: {:?}", overlap);
println!("i: {:?}", i);
});

// clip a.start, end
let interval = intersections.base_interval.clone();
eprintln!("overlapping: {:?}", intersections.overlapping);
let mut pieces = vec![];
intersections.overlapping.iter().for_each(|o| {
let mut piece: Position = interval.as_ref().dup();
piece.set_start(o.interval.start().max(piece.start()));
piece.set_stop(o.interval.stop().min(piece.stop()));
pieces.push(piece)
});
eprintln!("pieces: {:?}", pieces);
#[test]
fn test_simple_unique() {
let intersections = make_example();
// a: 1-10
// b: 3-6, 8-12
let r = intersections.intersections(
IntersectionMode::Default,
IntersectionMode::Not,
IntersectionOutput::Unique,
IntersectionOutput::None,
OverlapAmount::Bases(5),
OverlapAmount::Bases(1),
);
assert_eq!(r.len(), 1);
assert_eq!(
r[0],
(
Some(Position::Interval(Interval {
chrom: String::from("chr1"),
start: 1,
stop: 10,
fields: Default::default(),
})),
None,
),
);
}
#[test]
fn test_simple_unique_insufficient_bases() {
let intersections = make_example();
// a: 1-10
// b: 3-6, 8-12
let r = intersections.intersections(
IntersectionMode::Default,
IntersectionMode::Not,
IntersectionOutput::Unique,
IntersectionOutput::None,
// note we require 6 bases of overlap but only have 5
OverlapAmount::Bases(6),
OverlapAmount::Bases(1),
);
assert_eq!(r.len(), 0);
}

#[test]
fn test_simple_whole() {
let intersections = make_example();
// a: 1-10
// b: 3-6, 8-12
let r = intersections.intersections(
IntersectionMode::Default,
IntersectionMode::Not,
IntersectionOutput::Whole,
IntersectionOutput::None,
OverlapAmount::Bases(1),
OverlapAmount::Bases(1),
);
assert_eq!(r.len(), 2);
for v in r {
assert_eq!(
v,
(
Some(Position::Interval(Interval {
chrom: String::from("chr1"),
start: 1,
stop: 10,
fields: Default::default(),
})),
None,
),
);
}
}

#[test]
fn test_simple_parts() {
let intersections = make_example();
// a: 1-10
// b: 3-6, 8-12
let r = intersections.intersections(
IntersectionMode::Default,
IntersectionMode::Not,
IntersectionOutput::Part,
IntersectionOutput::None,
OverlapAmount::Bases(1),
OverlapAmount::Bases(1),
);
assert_eq!(r.len(), 2);
assert_eq!(
r[0],
(
Some(Position::Interval(Interval {
chrom: String::from("chr1"),
start: 3,
stop: 6,
fields: Default::default(),
})),
None,
),
);
assert_eq!(
r[1],
(
Some(Position::Interval(Interval {
chrom: String::from("chr1"),
start: 8,
stop: 10,
fields: Default::default(),
})),
None,
),
);
}

#[test]
Expand Down
8 changes: 8 additions & 0 deletions src/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ pub enum Position {
Other(Box<dyn Positioned>),
}

impl PartialEq for Position {
fn eq(&self, other: &Self) -> bool {
return self.chrom() == other.chrom()
&& self.start() == other.start()
&& self.stop() == other.stop();
}
}

impl Position {
#[inline]
pub fn chrom(&self) -> &str {
Expand Down

0 comments on commit 1a4455b

Please sign in to comment.