source: trunk/SECEDIT/SEC_helix.cxx

Last change on this file was 19393, checked in by westram, 18 months ago
  • reintegrates 'ali' into 'trunk'
    • refactored misused enum
    • support for helix pairs:
      • drop non-standard defs
      • add more user defs
    • change defaults
    • add several predefined configs (esp. for IUPAC ambiguity codes)
  • adds: log:branches/ali@19376:19392
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
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
17using namespace std;
18
19const 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
51char *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
91char *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
138char *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}
Note: See TracBrowser for help on using the repository browser.