1 | // =============================================================== // |
---|
2 | // // |
---|
3 | // File : SEC_helix.cxx // |
---|
4 | // Purpose : helix related things // |
---|
5 | // // |
---|
6 | // Coded by Ralf Westram (coder@reallysoft.de) in August 2007 // |
---|
7 | // Institute of Microbiology (Technical University Munich) // |
---|
8 | // http://www.arb-home.de/ // |
---|
9 | // // |
---|
10 | // =============================================================== // |
---|
11 | |
---|
12 | #include "SEC_root.hxx" |
---|
13 | #include "SEC_helix.hxx" |
---|
14 | #include <arbdbt.h> |
---|
15 | #include <arb_strbuf.h> |
---|
16 | |
---|
17 | using namespace std; |
---|
18 | |
---|
19 | const size_t *SEC_root::getHelixPositions(const char *helixNr) const { |
---|
20 | sec_assert(helixNr); |
---|
21 | const BI_helix *helix = get_helixDef(); |
---|
22 | long start1 = helix->first_position(helixNr); |
---|
23 | |
---|
24 | if (start1 == -1) return NULp; |
---|
25 | |
---|
26 | size_t start2 = helix->last_position(helixNr); |
---|
27 | static size_t pos[4]; |
---|
28 | |
---|
29 | if (size_t(start1)<start2) { |
---|
30 | pos[0] = size_t(start1); |
---|
31 | pos[1] = start2; |
---|
32 | } |
---|
33 | else { |
---|
34 | pos[0] = start2; |
---|
35 | pos[1] = size_t(start1); |
---|
36 | } |
---|
37 | |
---|
38 | pos[2] = helix->opposite_position(pos[1]); |
---|
39 | pos[3] = helix->opposite_position(pos[0]); |
---|
40 | |
---|
41 | return pos; |
---|
42 | } |
---|
43 | |
---|
44 | // ------------------------------------------- |
---|
45 | // current way to save folded helices: |
---|
46 | // |
---|
47 | // save a list of helix-numbers (with sign) separated by ';' |
---|
48 | // strand start-positions are saved as 'num' |
---|
49 | // segment start-positions are saved as '!num' |
---|
50 | |
---|
51 | char *SEC_xstring_to_foldedHelixList(const char *x_string, size_t xlength, const BI_helix *helix, GB_ERROR& error) { |
---|
52 | GBS_strstruct out(1000); |
---|
53 | bool next_is_start = true; |
---|
54 | |
---|
55 | sec_assert(!error); |
---|
56 | error = NULp; |
---|
57 | |
---|
58 | for (size_t pos = 0; pos<xlength && !error; ++pos) { |
---|
59 | if (x_string[pos] == 'x') { |
---|
60 | const char *helixNr = helix->helixNr(pos); |
---|
61 | |
---|
62 | if (next_is_start) { |
---|
63 | sec_assert(helix->is_pairpos(pos)); |
---|
64 | out.cat(helixNr); |
---|
65 | } |
---|
66 | else { |
---|
67 | bool is_end_and_start = helix->is_pairpos(pos); |
---|
68 | |
---|
69 | if (!helix->is_pairpos(pos-1)) { |
---|
70 | // hackaround: xstring got out of sync (e.g. by insert/delete columns) |
---|
71 | error = GBS_global_string("xstring out of sync at position %zu (approximately)\nRefold helices around position!", pos); |
---|
72 | } |
---|
73 | else { |
---|
74 | out.nprintf(20, "!%s", helix->helixNr(pos-1)); |
---|
75 | |
---|
76 | if (is_end_and_start) { |
---|
77 | out.put(';'); |
---|
78 | out.cat(helixNr); |
---|
79 | next_is_start = !next_is_start; |
---|
80 | } |
---|
81 | } |
---|
82 | } |
---|
83 | next_is_start = !next_is_start; |
---|
84 | out.put(';'); |
---|
85 | } |
---|
86 | } |
---|
87 | |
---|
88 | return error ? NULp : out.release(); |
---|
89 | } |
---|
90 | |
---|
91 | char *SEC_foldedHelixList_to_xstring(const char *foldedHelices, size_t xlength, const BI_helix *helix, GB_ERROR& error) { |
---|
92 | // example of foldedHelices: '-5;!-5;-8;!-8;-9;!-9;9;!9;8;!8;5;!5;-18;!-18;18;!18;-19a;!-19a;19a;!19a;-21;!-21;-24;!-24;24;!24;21;!21;-27;!-27;27;!27;-31;!-31;-43;!-43;43;!43;-46;!-46;46;!46;31;!31;-50;!-50;50;!50;' |
---|
93 | char *xstring = ARB_alloc<char>(xlength+1); |
---|
94 | memset(xstring, '.', xlength); |
---|
95 | xstring[xlength] = 0; |
---|
96 | |
---|
97 | sec_assert(!error); |
---|
98 | error = NULp; |
---|
99 | |
---|
100 | while (!error) { |
---|
101 | const char *semi = strchr(foldedHelices, ';'); |
---|
102 | if (!semi) break; |
---|
103 | |
---|
104 | char *taggedHelixNr = ARB_strpartdup(foldedHelices, semi-1); |
---|
105 | const char *helixNr = NULp; |
---|
106 | long xpos = -1; |
---|
107 | |
---|
108 | if (taggedHelixNr[0] == '!') { // position behind end of helix |
---|
109 | helixNr = taggedHelixNr+1; |
---|
110 | xpos = helix->last_position(helixNr); |
---|
111 | if (xpos >= 0) ++xpos; |
---|
112 | } |
---|
113 | else { // position at start of helix |
---|
114 | helixNr = taggedHelixNr; |
---|
115 | xpos = helix->first_position(helixNr); |
---|
116 | } |
---|
117 | |
---|
118 | if (xpos == -1) { |
---|
119 | error = GBS_global_string("Can't find helix '%s'", helixNr); |
---|
120 | } |
---|
121 | else { |
---|
122 | sec_assert(xpos >= 0 && size_t(xpos) < xlength); |
---|
123 | xstring[xpos] = 'x'; |
---|
124 | } |
---|
125 | |
---|
126 | free(taggedHelixNr); |
---|
127 | |
---|
128 | foldedHelices = semi+1; |
---|
129 | } |
---|
130 | |
---|
131 | return xstring; |
---|
132 | } |
---|
133 | |
---|
134 | // ------------------------------------------------------------------------- |
---|
135 | // xstring was made helix-relative, when saved to old version file |
---|
136 | |
---|
137 | |
---|
138 | char *old_decode_xstring_rel_helix(GB_CSTR rel_helix, size_t xlength, const BI_helix *helix, int *no_of_helices_ptr) { |
---|
139 | const char *start_helix_nr = NULp; |
---|
140 | int no_of_helices = 0; |
---|
141 | int start_helix = 0; |
---|
142 | int end_helix = -1; |
---|
143 | int rel_pos = 0; |
---|
144 | size_t lastpos = helix->size()-1; |
---|
145 | |
---|
146 | char *x_buffer = ARB_alloc<char>(xlength+1); |
---|
147 | memset(x_buffer, '.', xlength); |
---|
148 | x_buffer[xlength] = 0; |
---|
149 | |
---|
150 | for (size_t pos=0; ; pos++) { |
---|
151 | const char *helix_nr = NULp; // [required due to goto below] |
---|
152 | |
---|
153 | if (helix->is_pairpos(pos)) { |
---|
154 | helix_nr = helix->helixNr(pos); |
---|
155 | |
---|
156 | if (helix_nr==start_helix_nr) { // same helix as last |
---|
157 | end_helix = pos; |
---|
158 | } |
---|
159 | else { // new helix nr |
---|
160 | if (start_helix_nr) { // not first helix -> write last to xstring |
---|
161 | insert_helix : |
---|
162 | helix_nr = helix->helixNr(pos); // re-init (needed in case of goto insert_helix) |
---|
163 | char flag = rel_helix[rel_pos++]; |
---|
164 | |
---|
165 | no_of_helices++; |
---|
166 | if (flag=='1') { |
---|
167 | sec_assert(end_helix!=-1); |
---|
168 | sec_assert(size_t(start_helix)<xlength); |
---|
169 | sec_assert(size_t(end_helix+1)<xlength); |
---|
170 | |
---|
171 | x_buffer[start_helix] = 'x'; |
---|
172 | x_buffer[end_helix+1] = 'x'; |
---|
173 | } |
---|
174 | else if (flag!='0') { |
---|
175 | if (flag==0) break; // eos |
---|
176 | |
---|
177 | sec_assert(0); // illegal character |
---|
178 | |
---|
179 | break; |
---|
180 | } |
---|
181 | if (pos==lastpos) { |
---|
182 | break; |
---|
183 | } |
---|
184 | } |
---|
185 | start_helix = pos; |
---|
186 | end_helix = pos; |
---|
187 | start_helix_nr = helix_nr; |
---|
188 | } |
---|
189 | } |
---|
190 | if (pos==lastpos) { |
---|
191 | if (start_helix_nr) { |
---|
192 | goto insert_helix; |
---|
193 | } |
---|
194 | } |
---|
195 | } |
---|
196 | |
---|
197 | *no_of_helices_ptr = no_of_helices; |
---|
198 | return x_buffer; |
---|
199 | } |
---|