1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use crate::Design;
use std::io::Write;
impl<StrandLabel, DomainLabel> Design<StrandLabel, DomainLabel> {
pub fn to_cadnano<W: Write>(&self, w: W) -> Result<(), failure::Error> {
let mut vstrands = Vec::new();
let mut max_x = 0;
let mut min_x = 0;
let mut max_y = 0;
for s in self.strands.iter() {
for dom in s.domains.iter() {
if dom.helix < 0 {
continue;
}
max_x = max_x.max(dom.start).max(dom.end - 1);
min_x = min_x.min(dom.start).min(dom.end - 1);
max_y = max_y.max(dom.helix as usize);
}
}
max_x -= min_x;
let max_x = ((1 + max_x / 32) * 32) as usize;
let mut odd_num = 1;
let mut even_num = 0;
let mut helices = Vec::new();
for (i, _h) in self.helices.iter().enumerate().take(max_y + 1) {
let num;
if i % 2 == 0 {
num = odd_num;
odd_num += 2;
} else {
num = even_num;
even_num += 2;
};
helices.push(num);
vstrands.push(cadnano_format::VStrand {
col: 1,
loop_: vec![0; max_x],
num: num as isize,
row: (max_y - i) as isize,
scaf: vec![(-1, -1, -1, -1); max_x],
scaf_loop: vec![0; max_x],
skip: vec![0; max_x],
stap: vec![(-1, -1, -1, -1); max_x],
stap_loop: vec![0; max_x],
stap_colors: vec![],
})
}
for s in self.strands.iter() {
let mut prev: Option<(usize, usize)> = None;
for (ndom, dom) in s.domains.iter().enumerate() {
let x_range = if dom.end < dom.start {
(dom.end + 1)..(dom.start + 1)
} else {
dom.start..dom.end
};
for x_ in x_range {
let is_scaf = (dom.helix % 2 == 0) ^ (dom.end < dom.start);
let x = (x_ - min_x) as usize;
let mut result: (isize, isize, isize, isize) = (-1, -1, -1, -1);
if let Some((ref prev_helix, ref prev_x)) = prev {
result.0 = helices[*prev_helix] as isize;
result.1 = *prev_x as isize;
}
if x_ < dom.end - 1 {
result.2 = dom.helix as isize;
result.3 = (x + 1) as isize;
} else if ndom + 1 < s.domains.len() {
result.2 = s.domains[ndom + 1].helix as isize;
result.3 = s.domains[ndom + 1].start - min_x;
}
prev = Some((dom.helix as usize, x));
std::mem::swap(&mut result.0, &mut result.2);
std::mem::swap(&mut result.1, &mut result.3);
if is_scaf {
vstrands[dom.helix as usize].scaf[x] = result;
} else {
vstrands[dom.helix as usize].stap[x] = result;
}
}
}
}
for st in self.strands.iter() {
if !st.domains.is_empty() {
let ref dom = st.domains[0];
let is_scaf = (dom.helix % 2 == 0) ^ (dom.end <= dom.start);
if !is_scaf {
let color = st.color.unwrap_or_else(|| st.default_color());
vstrands[dom.helix as usize]
.stap_colors
.push((dom.start - min_x, color as isize));
}
}
}
let nano = cadnano_format::Cadnano {
name: "name".to_string(),
vstrands,
};
Ok(serde_json::to_writer(w, &nano).unwrap())
}
}