Skip to content

Commit 4cec0f0

Browse files
Building segment_steps, and some basic get fns
1 parent 85aaaa5 commit 4cec0f0

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

flatgfa/src/flatgfa.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,3 +550,95 @@ pub type FixedGFAStore<'a> = GFAStore<'a, FixedFamily>;
550550
/// `FlatGFA`. It exposes an API for building up a GFA data structure, so it is
551551
/// useful for creating new ones from scratch.
552552
pub type HeapGFAStore = GFAStore<'static, HeapFamily>;
553+
554+
555+
pub struct StepRef {
556+
path: Id<Path>,
557+
offset: u32
558+
}
559+
560+
pub struct StepsBySegIndex {
561+
steps: Vec<StepRef>,
562+
segment_steps: Vec<Span<StepRef>>
563+
}
564+
565+
566+
impl StepsBySegIndex {
567+
568+
pub fn new(fgfa: &FlatGFA) -> Self{
569+
570+
571+
/// helper to extract the segment index from the stepref
572+
fn segment_of_step(fgfa: &FlatGFA, step: &StepRef) -> usize {
573+
let path = &fgfa.paths[step.path];
574+
let step_span = path.steps;
575+
let step_slice = &fgfa.steps[step_span];
576+
step_slice[step.offset as usize].segment().index()
577+
}
578+
579+
// will be our `steps` vector that contains all steprefs
580+
let mut all_steps = Vec::new();
581+
582+
// build the vector of all the steprefs, by iterating over each path, so we can construct using a path id and offset
583+
for (path_id, path) in fgfa.paths.items() {
584+
for (offset, _) in fgfa.get_path_steps(path).enumerate() {
585+
all_steps.push(StepRef {
586+
path: path_id,
587+
offset: offset as u32,
588+
});
589+
}
590+
}
591+
592+
// organize by the index of the segment in the segment pool
593+
all_steps.sort_by_key(|a| {
594+
segment_of_step(fgfa, a)
595+
});
596+
597+
// the working segment's index
598+
let mut seg_ind: usize = segment_of_step(fgfa, &all_steps[0]);
599+
600+
// the working start of the span of StepRefs
601+
let mut span_start: usize = 0;
602+
603+
// the vector of spans of step refs that will act as our index
604+
let mut segment_steps: Vec<Span<StepRef>> = Vec::new();
605+
606+
607+
608+
for (i, step_ref) in all_steps.iter().enumerate() {
609+
let curr_seg_ind: usize = segment_of_step(fgfa, step_ref);
610+
611+
// if we have moved onto a new segment add to the segment_steps vec
612+
if curr_seg_ind > seg_ind {
613+
// create and push the new span of step refs for this segment
614+
// it will be left inclusive right exclusive
615+
let new_seg: Span<StepRef> = Span::new(Id::new(span_start), Id::new(i));
616+
segment_steps.push(new_seg);
617+
618+
// update the working seg_ind and range_start variables to reflect the new segment/range
619+
seg_ind = curr_seg_ind;
620+
span_start = i;
621+
}
622+
623+
}
624+
625+
626+
Self {
627+
steps: all_steps,
628+
segment_steps: segment_steps
629+
}
630+
}
631+
632+
633+
/// Returns a slice of StepRefs that cross over the given segment
634+
pub fn get_steps_slice(&self, segment: Id<Segment>) -> &[StepRef] {
635+
let range: Range<usize> = Range::from(&self.segment_steps[segment.index()]);
636+
&(self.steps[range])
637+
}
638+
639+
/// Returns the number of steps that cross over this segment
640+
pub fn get_num_steps(&self, segment: Id<Segment>) -> usize {
641+
self.segment_steps[segment.index()].len()
642+
}
643+
644+
}

0 commit comments

Comments
 (0)