source: branches/alilink/SL/AW_HELIX/AW_helix.cxx

Last change on this file was 18126, checked in by westram, 5 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1// ==================================================================== //
2//                                                                      //
3//   File      : AW_helix.cxx                                           //
4//   Purpose   : Wrapper for BI_helix + AW-specific functions           //
5//                                                                      //
6//                                                                      //
7// Coded by Ralf Westram (coder@reallysoft.de) in December 2004         //
8// Copyright Department of Microbiology (Technical University Munich)   //
9//                                                                      //
10// Visit our web site at: http://www.arb-home.de/                       //
11//                                                                      //
12// ==================================================================== //
13
14#include "AW_helix.hxx"
15#include <aw_root.hxx>
16#include <aw_window.hxx>
17#include <aw_awar.hxx>
18#include <aw_device.hxx>
19#include <arbdbt.h>
20#include <cctype>
21#include <awt_config_manager.hxx>
22
23#define HELIX_AWAR_ENABLE          "Helix/enable"
24#define HELIX_AWAR_SYMBOL_TEMPLATE "Helix/symbols/%s"
25#define HELIX_AWAR_PAIR_TEMPLATE   "Helix/pairs/%s"
26
27struct helix_pair_def {
28    const char *awar;
29    BI_PAIR_TYPE pair_type;
30};
31
32static helix_pair_def helix_awars[] = {
33    { "Strong_Pair",      HELIX_STRONG_PAIR },
34    { "Normal_Pair",      HELIX_PAIR },
35    { "Weak_Pair",        HELIX_WEAK_PAIR },
36    { "No_Pair",          HELIX_NO_PAIR },
37    { "User_Pair",        HELIX_USER0 },
38    { "User_Pair2",       HELIX_USER1 },
39    { "User_Pair3",       HELIX_USER2 },
40    { "User_Pair4",       HELIX_USER3 },
41    { "Default",          HELIX_DEFAULT },
42    { "Non_Standard_aA",  HELIX_NON_STANDARD0 },
43    { "Non_Standard1",    HELIX_NON_STANDARD1 },
44    { "Non_Standard2",    HELIX_NON_STANDARD2 },
45    { "Non_Standard3",    HELIX_NON_STANDARD3 },
46    { "Non_Standard4",    HELIX_NON_STANDARD4 },
47    { "Non_Standard5",    HELIX_NON_STANDARD5 },
48    { "Non_Standard6",    HELIX_NON_STANDARD6 },
49    { "Non_Standard7",    HELIX_NON_STANDARD7 },
50    { "Non_Standard8",    HELIX_NON_STANDARD8 },
51    { "Non_Standard9",    HELIX_NON_STANDARD9 },
52    { "Not_Non_Standard", HELIX_NO_MATCH },
53    { NULp,               HELIX_NONE },
54};
55
56inline const char *helix_symbol_awar(int idx) { return GBS_global_string(HELIX_AWAR_SYMBOL_TEMPLATE, helix_awars[idx].awar); }
57inline const char *helix_pair_awar  (int idx) { return GBS_global_string(HELIX_AWAR_PAIR_TEMPLATE,   helix_awars[idx].awar); }
58
59AW_helix::AW_helix(AW_root * aw_root)
60    : enabled(0)
61{
62    for (int j=0; helix_awars[j].awar; j++) {
63        int i = helix_awars[j].pair_type;
64        aw_root->awar_string(helix_pair_awar(j),   pairs[i])    ->add_target_var(&pairs[i]);
65        aw_root->awar_string(helix_symbol_awar(j), char_bind[i])->add_target_var(&char_bind[i]);
66    }
67    aw_root->awar_int(HELIX_AWAR_ENABLE, 1)->add_target_var(&enabled);
68}
69
70char AW_helix::get_symbol(char left, char right, BI_PAIR_TYPE pair_type) {
71    left  = toupper(left);
72    right = toupper(right);
73
74    int erg;
75    if (pair_type < HELIX_NON_STANDARD0) {
76        erg = *char_bind[HELIX_DEFAULT];
77        for (int i = HELIX_STRONG_PAIR; i< HELIX_NON_STANDARD0; i++) {
78            if (is_pairtype(left, right, (BI_PAIR_TYPE)i)) {
79                erg = *char_bind[i];
80                break;
81            }
82        }
83    }
84    else {
85        erg = *char_bind[HELIX_NO_MATCH];
86        if (is_pairtype(left, right, pair_type)) erg = *char_bind[pair_type];
87    }
88    if (!erg) erg = ' ';
89    return erg;
90}
91
92char *AW_helix::seq_2_helix(char *sequence, char undefsymbol) {
93    size_t size2 = strlen(sequence);
94    bi_assert(size2<=size()); // if this fails there is a sequence longer than the alignment
95    char *helix = ARB_calloc<char>(size()+1);
96    size_t i, j;
97    for (i=0; i<size2; i++) {
98        BI_PAIR_TYPE pairType = pairtype(i);
99
100        if (pairType == HELIX_NONE) {
101            helix[i] = undefsymbol;
102        }
103        else {
104            j        = opposite_position(i);
105            char sym = get_symbol(sequence[i], sequence[j], pairType);
106            helix[i] = sym == ' ' ? undefsymbol : sym;
107        }
108    }
109    return helix;
110}
111
112static void helix_pairs_changed_cb(AW_window *aww, int changed_idx, const WindowCallback *refreshCallback) {
113    static bool recursion = false;
114
115    if (!recursion) {
116        AW_root *aw_root   = aww->get_root();
117        AW_awar *awar_pair = aw_root->awar(helix_pair_awar(changed_idx));
118        char    *pairdef   = awar_pair->read_string();
119
120        {
121            LocallyModify<bool> flag(recursion, true);
122            for (int i = 0; ; i += 3) {
123                char left  = toupper(pairdef[i]); if (!left) break;
124                char right = toupper(pairdef[i+1]); if (!right) break;
125
126                pairdef[i]   = left;
127                pairdef[i+1] = right;
128
129                for (int j = 0; helix_awars[j].awar; j++) {
130                    if (j != changed_idx) {
131                        AW_awar *awar_pair2 = aw_root->awar(helix_pair_awar(j));
132                        char    *pd2        = awar_pair2->read_string();
133                        int      dst        = 0;
134                        bool     modified   = false;
135
136                        for (int k = 0; ; k += 3) {
137                            char l = toupper(pd2[k]); if (!l) break;
138                            char r = toupper(pd2[k+1]); if (!r) break;
139
140                            if ((left == l && right == r) || (left == r && right == l)) {
141                                // remove duplicated pair
142                                modified = true;
143                            }
144                            else {
145                                pd2[dst]   = l;
146                                pd2[dst+1] = r;
147
148                                dst += 3;
149                            }
150                            if (!pd2[k+2]) break;
151                        }
152
153                        if (modified) {
154                            pd2[dst-1] = 0;
155                            awar_pair2->write_string(pd2);
156                        }
157
158                        free(pd2);
159                    }
160                }
161
162                if (!pairdef[i+2]) break;
163            }
164            awar_pair->write_string(pairdef); // write back uppercase version
165        }
166        (*refreshCallback)(aww);
167
168        free(pairdef);
169    }
170}
171
172static void setup_helix_config(AWT_config_definition& cdef) {
173    cdef.add(HELIX_AWAR_ENABLE, "enable");
174
175    for (int j=0; helix_awars[j].awar; j++) {
176        int i = helix_awars[j].pair_type;
177
178        const char *name = helix_awars[j].awar;
179        if (i != HELIX_DEFAULT && i != HELIX_NO_MATCH) {
180            cdef.add(helix_pair_awar(j), name);
181        }
182        cdef.add(helix_symbol_awar(j), GBS_global_string("%s_symbol", name));
183    }
184}
185
186AW_window *create_helix_props_window(AW_root *awr, const WindowCallback *refreshCallback) {
187    static AW_window_simple *aws = NULp;
188    if (!aws) {
189        aws = new AW_window_simple;
190        aws->init(awr, "HELIX_PROPS", "HELIX_PROPERTIES");
191
192        aws->at(10, 10);
193        aws->auto_space(3, 3);
194
195        aws->callback(AW_POPDOWN);
196        aws->create_button("CLOSE", "CLOSE", "C");
197
198        aws->callback(makeHelpCallback("helixsym.hlp"));
199        aws->create_button("HELP", "HELP", "H");
200
201        AWT_insert_config_manager(aws, AW_ROOT_DEFAULT, "helix", makeConfigSetupCallback(setup_helix_config));
202
203        aws->at_newline();
204
205        const size_t max_awar_len = 18;
206        aws->label_length(max_awar_len);
207
208        aws->label("Show helix?");
209        aws->callback(*refreshCallback); // @@@ used as TOGGLE_CLICK_CB (see #559)
210        aws->create_toggle(HELIX_AWAR_ENABLE);
211
212        aws->at_newline();
213
214        int ex = 0;
215        for (int j = 0; helix_awars[j].awar; j++) {
216            int  i = helix_awars[j].pair_type;
217
218            aw_assert(strlen(helix_awars[j].awar) <= max_awar_len);
219
220            if (i != HELIX_DEFAULT && i != HELIX_NO_MATCH) {
221                aws->label(helix_awars[j].awar);
222                aws->callback(makeWindowCallback(helix_pairs_changed_cb, j, refreshCallback)); // @@@ used as INPUTFIELD_CB (see #559)
223                aws->create_input_field(helix_pair_awar(j), 20);
224
225                if (j == 0) ex = aws->get_at_xposition();
226            }
227            else {
228                aw_assert(j != 0);
229                aws->create_autosize_button(NULp, helix_awars[j].awar);
230                aws->at_x(ex);
231            }
232
233            aws->callback(*refreshCallback); // @@@ used as INPUTFIELD_CB (see #559)
234            aws->create_input_field(helix_symbol_awar(j), 3);
235            aws->at_newline();
236        }
237        aws->window_fit();
238    }
239    return aws;
240}
241
242
Note: See TracBrowser for help on using the repository browser.