handlegraph/
conversion.rs1use 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 let handle = step.handle();
139 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}