Skip to main content

handlegraph/
conversion.rs

1use crate::{
2    handle::{Edge, Handle, NodeId},
3    handlegraph::HandleGraphRef,
4    mutablehandlegraph::*,
5    pathhandlegraph::*,
6};
7
8use gfa::{
9    gfa::{Line, Link, Orientation, Path, Segment, GFA},
10    optfields::OptFields,
11    parser::GFAResult,
12};
13
14pub fn from_gfa<G, T>(gfa: &GFA<usize, T>) -> G
15where
16    G: Default + AdditiveHandleGraph + MutableGraphPaths,
17    T: OptFields,
18{
19    let mut graph: G = Default::default();
20
21    for segment in gfa.segments.iter() {
22        assert!(segment.name > 0);
23        let seq = &segment.sequence;
24        graph.create_handle(seq, segment.name);
25    }
26
27    for link in gfa.links.iter() {
28        let left = Handle::new(link.from_segment, link.from_orient);
29        let right = Handle::new(link.from_segment, link.from_orient);
30        graph.create_edge(Edge(left, right));
31    }
32
33    for path in gfa.paths.iter() {
34        let name = &path.path_name;
35        let path_id = graph.create_path(name, false).unwrap();
36        for (seg, orient) in path.iter() {
37            let handle = Handle::new(seg, orient);
38            graph.path_append_step(path_id, handle);
39        }
40    }
41
42    graph
43}
44
45pub fn fill_gfa_lines<G, I, T>(graph: &mut G, gfa_lines: I) -> GFAResult<()>
46where
47    G: AdditiveHandleGraph + MutableGraphPaths,
48    I: Iterator<Item = GFAResult<Line<usize, T>>>,
49    T: OptFields,
50{
51    for line in gfa_lines {
52        let line = line?;
53        match line {
54            Line::Segment(v) => {
55                let id = NodeId::from(v.name);
56                graph.create_handle(&v.sequence, id);
57            }
58            Line::Link(v) => {
59                let left = Handle::new(v.from_segment, v.from_orient);
60                let right = Handle::new(v.to_segment, v.to_orient);
61                graph.create_edge(Edge(left, right));
62            }
63            Line::Path(v) => {
64                let name = &v.path_name;
65                let path_id = graph.create_path(name, false).unwrap();
66                for (seg, orient) in v.iter() {
67                    let handle = Handle::new(seg, orient);
68                    graph.path_append_step(path_id, handle);
69                }
70            }
71            _ => (),
72        }
73    }
74
75    Ok(())
76}
77
78pub fn to_gfa<G>(graph: &G) -> GFA<usize, ()>
79where
80    G: HandleGraphRef
81        + GraphPaths
82        + IntoPathIds
83        + GraphPathNames
84        + GraphPathsRef,
85    G::PathRef: PathSteps,
86{
87    let mut gfa = GFA::new();
88
89    for handle in graph.handles() {
90        let name = usize::from(handle.id());
91        let sequence: Vec<_> = graph.sequence(handle.forward()).collect();
92
93        let segment = Segment {
94            name,
95            sequence,
96            optional: (),
97        };
98        gfa.segments.push(segment);
99    }
100
101    let orient = |rev: bool| {
102        if rev {
103            Orientation::Backward
104        } else {
105            Orientation::Forward
106        }
107    };
108
109    for edge in graph.edges() {
110        let Edge(left, right) = edge;
111        let from_segment: usize = usize::from(left.id());
112        let from_orient = orient(left.is_reverse());
113        let to_segment: usize = usize::from(right.id());
114        let to_orient = orient(right.is_reverse());
115        let overlap = vec![b'0', b'M'];
116
117        let link = Link {
118            from_segment,
119            from_orient,
120            to_segment,
121            to_orient,
122            overlap,
123            optional: (),
124        };
125
126        gfa.links.push(link);
127    }
128
129    for path_id in graph.path_ids() {
130        let path_name: Vec<_> = graph.get_path_name(path_id).unwrap().collect();
131        let overlaps = Vec::new();
132        let mut segment_names: Vec<Vec<u8>> = Vec::new();
133
134        let path = graph.get_path_ref(path_id).unwrap();
135
136        for step in path.steps() {
137            // for step in graph.steps_iter(path_id) {
138            let handle = step.handle();
139            // let handle = graph.handle_of_step(&step).unwrap();
140            let segment: usize = handle.id().into();
141            let orientation = orient(handle.is_reverse());
142            segment_names.push(segment.to_string().into());
143            segment_names.push(orientation.to_string().into());
144            segment_names.push(",".into());
145        }
146        let segment_names: Vec<u8> =
147            segment_names.into_iter().flatten().collect();
148
149        let path: Path<usize, ()> =
150            Path::new(path_name, segment_names, overlaps, ());
151
152        gfa.paths.push(path);
153    }
154
155    gfa
156}