ruranges_core/
complement_single.rs1use rustc_hash::FxHashMap;
2
3use crate::{
4 ruranges_structs::{GroupType, PositionType},
5 sorts,
6};
7
8pub fn sweep_line_complement<G: GroupType, T: PositionType>(
9 chrs: &[G],
10 starts: &[T],
11 ends: &[T],
12 slack: T,
13 chrom_lens: &FxHashMap<G, T>,
14 include_first_interval: bool, ) -> (Vec<G>, Vec<T>, Vec<T>, Vec<u32>) {
16 let mut out_chrs = Vec::with_capacity(chrs.len());
17 let mut out_starts = Vec::with_capacity(chrs.len());
18 let mut out_ends = Vec::with_capacity(chrs.len());
19 let mut out_idxs = Vec::with_capacity(chrs.len());
20
21 if chrs.is_empty() {
23 return (out_chrs, out_starts, out_ends, out_idxs);
24 }
25
26 let events = sorts::build_sorted_events_single_collection(chrs, starts, ends, slack);
28
29 let mut current_chr = events[0].chr;
31 let mut active_count = 0_i64;
32 let mut in_complement = include_first_interval;
34 let mut current_start = T::zero();
36 let mut current_index = 0_u32;
37
38 for e in events {
39 if e.chr != current_chr {
41 if let Some(chlen) = chrom_lens.get(¤t_chr) {
44 if in_complement {
45 out_chrs.push(current_chr);
46 out_starts.push(current_start);
47 out_ends.push(*chlen);
48 out_idxs.push(current_index);
49 }
50 }
51
52 current_chr = e.chr;
54 active_count = 0;
55 in_complement = include_first_interval;
56 current_start = T::zero();
57 current_index = e.idx;
58 }
59
60 if e.is_start {
62 active_count += 1;
64 if active_count == 1 && in_complement && current_start != e.pos {
66 out_chrs.push(current_chr);
68 out_starts.push(current_start);
69 out_ends.push(e.pos);
70 out_idxs.push(current_index);
71
72 in_complement = false;
74 }
75 } else {
76 active_count -= 1;
78 if active_count == 0 {
81 in_complement = true;
82 current_start = e.pos;
83 }
84 }
85 }
86
87 if let Some(chlen) = chrom_lens.get(¤t_chr) {
89 if in_complement {
90 out_chrs.push(current_chr);
91 out_starts.push(current_start);
92 out_ends.push(*chlen);
93 out_idxs.push(current_index);
94 }
95 }
96
97 (out_chrs, out_starts, out_ends, out_idxs)
98}