source: tags/arb-6.0/NTREE/AP_consensus.cxx

Last change on this file was 12267, checked in by westram, 10 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.8 KB
Line 
1/* -----------------------------------------------------------------
2 * Project:                       ARB
3 *
4 * Module:                        consensus [abbrev.:CON]
5 *
6 * Exported Classes:              x
7 *
8 * Global Functions:              x
9 *
10 * Global Variables:              AWARS:
11 *                  AW_STRING, "tmp/con/alignment"     : name of alignment
12 *                  AW_STRING, "tmp/con/which_species" : only marked species ?
13 *                  AW_STRING, "con/group"         : allow Sgrouping ?
14 *                  AW_STRING, "con/countgaps"
15 *                  AW_DOUBLE, "con/fupper"
16 *                  AW_INT, "con/lower"
17 *                  AW_INT, "con/gapbound"  : result is '-' if more than
18 *                                            'gapbound' per cent gaps
19 *                  AW_DOUBLE, "con/fconsidbound" : if frequency of character is
20 *                                     more than 'fconsidbound' per cent, this
21 *                                     character can contribute to groups
22 *                  AW_STRING, "tmp/con/name"   : save with this name
23 *                  AW_STRING, "con/result" : result has one or more lines ?
24 *
25 * Global Structures:             x
26 *
27 * Private Classes:               .
28 *
29 * Private Functions:             .
30 *
31 * Private Variables:             .
32 *
33 * Dependencies:       Needs consens.fig and CON_groups.fig
34 *
35 * Description: This module calculates the consensus of sequences of
36 *              bases or amino acids. The result can be one or more lines
37 *              of characters and it is written to the extended data of
38 *              the alignment.
39 *
40 * Integration Notes: To use this module the main function must have a
41 *                    callback to the function
42 *                    AW_window *AP_open_consensus_window( AW_root *aw_root)
43 *                    and the function void AP_create_consensus_var
44 *                    (AW_root *aw_root, AW_default aw_def) has to be called.
45 *
46 * -----------------------------------------------------------------
47 */
48
49#include "NT_local.h"
50#include <awt_sel_boxes.hxx>
51#include <arb_progress.h>
52#include <aw_root.hxx>
53#include <aw_msg.hxx>
54#include <aw_awar.hxx>
55#include <arbdbt.h>
56#include <arb_strbuf.h>
57
58#define AWAR_MAX_FREQ   "tmp/CON_MAX_FREQ/"
59
60#define AWAR_MAX_FREQ_NO_GAPS AWAR_MAX_FREQ "no_gaps"
61#define AWAR_MAX_FREQ_SAI_NAME AWAR_MAX_FREQ "sai_name"
62
63enum {
64    BAS_GAP,
65    BAS_A,  BAS_C,  BAS_G,  BAS_T, BAS_N,
66
67    MAX_BASES,
68    MAX_AMINOS  = 27,
69    MAX_GROUPS  = 40
70};
71
72/* -----------------------------------------------------------------
73 * Function:                     CON_evaluatestatistic
74 *
75 * Arguments:                    int **statistic,char **groupflags,
76 *                               char *groupnames
77 * Returns:                      char *result
78 *
79 * Description:       This function creates one or more result strings out
80 *                    of table statistic. Memory for result is allocated
81 *                    and later freed in function CON_calculate_cb
82 *
83 * NOTE:              Usage of groupflags and groupnames see function
84 *                    CON_makegrouptable.
85 *
86 * Global Variables referenced:  .
87 *
88 * Global Variables modified:    x
89 *
90 * AWARs referenced:             .
91 *
92 * AWARs modified:               x
93 *
94 * Dependencies:                 Always check that behavior is identical to that
95 *                               of ED4_char_table::build_consensus_string()
96 * -----------------------------------------------------------------
97 */
98static void CON_evaluatestatistic(char   *&result, int **statistic, char **groupflags,
99                           char    *groupnames, int alignlength, double fupper, int lower,
100                           double   fconsidbound, int gapbound, int countgap, int numgroups)
101{
102    int row=0;
103    int j = 0;
104    int groupfr[MAX_GROUPS]; // frequency of group
105    int highestfr, highestgr;
106
107    arb_progress progress("calculating result", alignlength);
108
109    result=(char *)GB_calloc(alignlength+1, 1);
110
111    for (int column=0; column<alignlength; column++) {
112        long numentries = 0;
113        for (row=0; statistic[row]; row++) numentries += statistic[row][column];
114        if (numentries==0) {
115            result[column]='.';
116        }
117        else {
118            if (numentries-statistic[0][column]==0) {
119                result[column]='='; // 100 per cent `-` -> `=`
120            }
121            else {
122                if (!countgap) {
123                    numentries -= statistic[0][column];
124                    statistic[0][column]=0;
125                }
126
127                if ((statistic[0][column]*100/numentries)>gapbound) {
128                    result[column]='-';
129                }
130                else {
131                    for (j=0; j<numgroups; j++) {
132                        groupfr[j]=0;
133                    }
134
135                    row=0;
136                    while (statistic[row]) {
137                        if ((statistic[row][column]*100.0)>=fconsidbound*numentries) {
138                            for (j=numgroups-1; j>=0; j--) {
139                                if (groupflags[j][row]) {
140                                    groupfr[j] += statistic[row][column];
141                                }
142                            }
143                        }
144                        row++;
145                    }
146
147                    highestfr=0;
148                    highestgr=0;
149                    for (j=0; j<numgroups; j++) {
150                        if (groupfr[j] > highestfr) {
151                            highestfr=groupfr[j];
152                            highestgr=j;
153                        }
154                    }
155
156                    if ((highestfr*100.0/numentries)>=fupper) {
157                        result[column]=groupnames[highestgr];
158                    }
159                    else if ((highestfr*100/numentries)>=lower) {
160                        char c=groupnames[highestgr];
161                        if (c>='A' && c<='Z') {
162                            c=c-'A'+'a';
163                        }
164                        result[column]=c;
165                    }
166                    else {
167                        result[column]='.';
168                    }
169                }
170            }
171        }
172        ++progress;
173    }
174}
175
176
177
178/* -----------------------------------------------------------------
179 * Function:                     CON_makegrouptable
180 *
181 * Arguments:                    .
182 *
183 * Returns:                      char **gf [groupflags],char *groupnames
184 *
185 * Description:       Creates table groupflags that is used in function
186 *                    CON_evaluatestatistic. E.g. gf[10][3]=1 means, that
187 *                    all characters c with convtable[c]==3 are members
188 *                    of group 10.
189 *                    Table groupnames is also created.
190 *                    E.g. c=groupnames[5] gives abbrev of 5th group.
191 *
192 * NOTE:                         .
193 *
194 * Global Variables referenced:  .
195 *
196 * Global Variables modified:    x
197 *
198 * AWARs referenced:             .
199 *
200 * AWARs modified:               x
201 *
202 * Dependencies:                 .
203 * -----------------------------------------------------------------
204 */
205static int CON_makegrouptable(char **gf, char *groupnames,
206                       int isamino, int groupallowed)
207{
208    for (int j=0; j<MAX_GROUPS; j++) {
209        gf[j]=(char *)GB_calloc(MAX_GROUPS, 1); }
210
211    if (!isamino)
212    {
213        strcpy(groupnames, "-ACGUMRWSYKVHDBN\0");
214        for (int i=1; i<MAX_BASES; i++) {
215            gf[i][i]=1; }
216        if (groupallowed)
217        {
218            gf[5][BAS_A]=1; gf[5][BAS_C]=1;
219            gf[6][BAS_A]=1; gf[6][BAS_G]=1;
220            gf[7][BAS_A]=1; gf[7][BAS_T]=1;
221            gf[8][BAS_C]=1; gf[8][BAS_G]=1;
222            gf[9][BAS_C]=1; gf[9][BAS_T]=1;
223            gf[10][BAS_G]=1; gf[10][BAS_T]=1;
224            gf[11][BAS_A]=1; gf[11][BAS_C]=1; gf[11][BAS_G]=1;
225            gf[12][BAS_A]=1; gf[12][BAS_C]=1; gf[12][BAS_T]=1;
226            gf[13][BAS_A]=1; gf[13][BAS_G]=1; gf[13][BAS_T]=1;
227            gf[14][BAS_C]=1; gf[14][BAS_G]=1; gf[14][BAS_T]=1;
228            gf[15][BAS_A]=1; gf[15][BAS_C]=1;
229            gf[15][BAS_G]=1; gf[15][BAS_T]=1;
230            return (16);
231        }
232        return (5);
233    }
234    else
235    {
236        strcpy(groupnames, "-ABCDEFGHI*KLMN.PQRST.VWXYZADHIF\0");
237        for (int i=1; i<MAX_AMINOS; i++) {
238            gf[i][i]=1; }
239        if (groupallowed)
240#define SC(x, P) gf[x][P-'A'+1] = 1
241        {
242            SC(27, 'P'); SC(27, 'A'); SC(27, 'G'); SC(27, 'S'); SC(27, 'T');
243            // PAGST
244            SC(28, 'Q'); SC(28, 'N'); SC(28, 'E'); SC(28, 'D'); SC(28, 'B');
245            SC(28, 'Z');   // QNEDBZ
246            SC(29, 'H'); SC(29, 'K'); SC(29, 'R');
247            // HKR
248            SC(30, 'L'); SC(30, 'I'); SC(30, 'V'); SC(30, 'M');
249            // LIVM
250            SC(31, 'F'); SC(31, 'Y'); SC(31, 'W');
251            // FYW
252            return (32);
253        }
254#undef SC
255        return (27);
256    }
257}
258
259
260/* -----------------------------------------------------------------
261 * Function:                     CON_makestatistic
262 *
263 * Arguments:                    int *convtable
264 *
265 * Returns:                      int **statistic
266 *
267 * Description:       This function fills the table statistic, that is used
268 *                    later by function CON_evaluatestatistic. The filling
269 *                    is done depending on table convtable, that is created
270 *                    in function CON_maketables. Memory for statistic is
271 *                    allocated also in function CON_maketables.
272 *
273 *
274 * NOTE:                         .
275 *
276 * Global Variables referenced:  .
277 *
278 * Global Variables modified:    x
279 *
280 * AWARs referenced:             .
281 *
282 * AWARs modified:               x
283 *
284 * Dependencies:                 .
285 * -----------------------------------------------------------------
286 */
287
288
289static long CON_makestatistic(int **statistic, int *convtable, char *align, int onlymarked) {
290    long maxalignlen = GBT_get_alignment_len(GLOBAL.gb_main, align);
291
292    int nrofspecies;
293    if (onlymarked) {
294        nrofspecies = GBT_count_marked_species(GLOBAL.gb_main);
295    }
296    else {
297        nrofspecies = GBT_get_species_count(GLOBAL.gb_main);
298    }
299
300    arb_progress progress(nrofspecies);
301    progress.auto_subtitles("Examining sequence");
302
303    GBDATA *gb_species;
304    if (onlymarked) {
305        gb_species = GBT_first_marked_species(GLOBAL.gb_main);
306    }
307    else {
308        gb_species = GBT_first_species(GLOBAL.gb_main);
309    }
310
311    while (gb_species) {
312        GBDATA *alidata = GBT_read_sequence(gb_species, align);
313        if (alidata) {
314            unsigned char        c;
315            const unsigned char *data = (const unsigned char *)GB_read_char_pntr(alidata);
316
317            int i = 0;
318            while ((c=data[i])) {
319                if ((c=='-') || ((c>='a')&&(c<='z')) || ((c>='A')&&(c<='Z'))
320                    || (c=='*')) {
321                    if (i > maxalignlen) break;
322                    statistic[convtable[c]][i] += 1;
323                }
324                i++;
325            }
326        }
327        if (onlymarked) {
328            gb_species = GBT_next_marked_species(gb_species);
329        }
330        else {
331            gb_species = GBT_next_species(gb_species);
332        }
333        ++progress;
334    }
335    return nrofspecies;
336}
337
338
339/* -----------------------------------------------------------------
340 * Function:          CON_maketables
341 *
342 * Arguments:         long maxalignlen,int isamino
343 *
344 * Returns:           return parameters: int *convtable,int **statistic
345 *
346 * Description:       Creates tables convtable and statistic, that are
347 *                    used by function CON_makestatistic. The memory
348 *                    allocated for both tables is freed in the
349 *                    function CON_calculate_cb.
350 *                    E.g. convtable['c']=k means that the character c
351 *                    is counted in table statistic in row k.
352 *
353 * NOTE:                         .
354 *
355 * Global Variables referenced:  .
356 *
357 * Global Variables modified:    x
358 *
359 * AWARs referenced:             .
360 *
361 * AWARs modified:               x
362 *
363 * Dependencies:                 .
364 * -----------------------------------------------------------------
365 */
366static void CON_maketables(int *convtable, int **statistic, long maxalignlen, int isamino)
367{
368    int i;
369    for (i=0; i<256; i++) { convtable[i]=0; }
370    if (!isamino) {
371        for (i='a'; i <= 'z'; i++) convtable[i] = BAS_N;
372        for (i='A'; i <= 'Z'; i++) convtable[i] = BAS_N;
373
374        convtable['a']=BAS_A;   convtable['A']=BAS_A;
375        convtable['c']=BAS_C;   convtable['C']=BAS_C;
376        convtable['g']=BAS_G;   convtable['G']=BAS_G;
377        convtable['t']=BAS_T;   convtable['T']=BAS_T;
378        convtable['u']=BAS_T;   convtable['U']=BAS_T;
379
380
381        for (i=0; i<MAX_BASES; i++) {
382            statistic[i]=(int*)GB_calloc((unsigned int)maxalignlen, sizeof(int));
383        }
384        statistic[MAX_BASES]=NULL;
385    }
386    else {
387        for (i=0; i<MAX_AMINOS-1; i++)
388        {
389            convtable['a'+i]=i+1;
390            convtable['A'+i]=i+1;
391        }
392        for (i=0; i<MAX_AMINOS; i++) {
393            statistic[i]=(int*)GB_calloc((unsigned int)maxalignlen, sizeof(int));
394        }
395        statistic[MAX_AMINOS]=NULL;
396        convtable['*']=10; // 'J'
397    }
398}
399
400// export results into database
401static GB_ERROR CON_export(char *savename, char *align, int **statistic, char *result, int *convtable, char *groupnames, int onlymarked, long nrofspecies, long maxalignlen, int countgaps, int gapbound, int groupallowed, double fconsidbound, double fupper, int lower, int resultiscomplex) {
402    const char *off = "off";
403    const char *on  = "on";
404
405    char *buffer = (char *)GB_calloc(2000, sizeof(char));
406
407    GBDATA   *gb_extended = GBT_find_or_create_SAI(GLOBAL.gb_main, savename);
408    GBDATA   *gb_data     = GBT_add_data(gb_extended, align, "data", GB_STRING);
409    GB_ERROR  err         = GB_write_string(gb_data, result);           // @@@ result is ignored
410    GBDATA   *gb_options  = GBT_add_data(gb_extended, align, "_TYPE", GB_STRING);
411
412    const char *allvsmarked     = onlymarked ? "marked" : "all";
413    const char *countgapsstring = countgaps ? on : off;
414    const char *simplifystring  = groupallowed ? on : off;
415
416    sprintf(buffer, "CON: [species: %s]  [number: %ld]  [count gaps: %s] "
417            "[threshold for gaps: %d]  [simplify: %s] "
418            "[threshold for character: %f]  [upper: %f]  [lower: %d]",
419            allvsmarked, nrofspecies, countgapsstring,
420            gapbound, simplifystring,
421            fconsidbound, fupper, lower);
422
423    err = GB_write_string(gb_options, buffer);
424
425    GBDATA *gb_names = GB_search(GB_get_father(gb_options), "_SPECIES", GB_FIND);
426    if (gb_names) GB_delete(gb_names); // delete old entry
427
428    if (nrofspecies<20) {
429        GBDATA        *gb_species;
430        GBS_strstruct *strstruct = GBS_stropen(1000);
431
432        if (onlymarked) gb_species = GBT_first_marked_species(GLOBAL.gb_main);
433        else gb_species            = GBT_first_species(GLOBAL.gb_main);
434
435        while (gb_species) {
436            if (GBT_read_sequence(gb_species, align)) {
437                GBDATA     *gb_speciesname = GB_search(gb_species, "name", GB_FIND);
438                const char *name           = GB_read_char_pntr(gb_speciesname);
439
440                GBS_strcat(strstruct, name);
441                GBS_chrcat(strstruct, ' ');
442            }
443            if (onlymarked) gb_species = GBT_next_marked_species(gb_species);
444            else gb_species            = GBT_next_species(gb_species);
445        }
446
447        char *allnames = GBS_strclose(strstruct);
448        err            = GBT_write_string(GB_get_father(gb_options), "_SPECIES", allnames);
449        free(allnames);
450    }
451
452    {
453        char buffer2[256];
454        sprintf(buffer2, "%s/FREQUENCIES", align);
455        GBDATA *gb_graph = GB_search(gb_extended, buffer2, GB_FIND);
456        if (gb_graph) GB_delete(gb_graph);  // delete old entry
457    }
458    // export additional information
459    if (resultiscomplex) {
460        GBDATA *gb_graph = GBT_add_data(gb_extended, align, "FREQUENCIES", GB_DB);
461        char   *charname = (char *)GB_calloc(5, sizeof(char));
462
463        // problem : aminos, especially '*' -> new order
464
465        int *allreadycounted = (int*)GB_calloc((unsigned int)256, sizeof(char));
466        int *neworder        = (int*)GB_calloc((unsigned int)256, sizeof(int));
467        int  numdiffchars    = 1; // first additional row (nr. 0) is max-row
468
469        for (int c=0; c<256; c++) {
470            int k = convtable[c];
471            if (k) {
472                if (!(allreadycounted[k])) {
473                    allreadycounted[k]       = 1;
474                    neworder[numdiffchars++] = k;
475                }
476            }
477        }
478
479        float **additional = (float**)GB_calloc((unsigned int)numdiffchars, sizeof(float*));
480
481        for (int group=0; group<numdiffchars; group++) {
482            additional[group]=(float*)GB_calloc((unsigned int)maxalignlen, sizeof(float));
483        }
484
485        int *absolutrow = (int*)GB_calloc((unsigned int)maxalignlen, sizeof(int));
486
487        for (long col=0; col<maxalignlen; col++) {
488            int group2 = 1;
489            int colsum = 0;
490            while (neworder[group2]) {
491                colsum += statistic[neworder[group2++]][col];
492            }
493            if (countgaps) colsum += statistic[0][col];
494            absolutrow[col] = colsum;
495        }
496
497        for (long col=0; col<maxalignlen; col++) {
498            if (absolutrow[col]) {
499                int   group2  = 1;
500                float highest = 0;
501                int   diffchar;
502
503                while ((diffchar=neworder[group2++])) {
504                    float relative = (float)statistic[diffchar][col] / (float)absolutrow[col];
505                    if (relative>highest) highest = relative;
506                    additional[diffchar][col]     = relative;
507                }
508                additional[0][col]=highest;
509            }
510            else {
511                additional[0][col]=0.0;
512            }
513        }
514
515        GBDATA *gb_relative = GB_search(gb_graph, "MAX", GB_FLOATS);
516        err = GB_write_floats(gb_relative, additional[0], maxalignlen);
517
518        for (int group=1; group<numdiffchars; group++) {
519            char ch = groupnames[neworder[group]];
520            if (ch <'A' || ch>'Z') continue;
521           
522            sprintf(charname, "N%c", ch);
523            gb_relative = GB_search(gb_graph, charname, GB_FLOATS);
524            err = GB_write_floats(gb_relative, additional[group], maxalignlen);
525        }
526
527        free(charname);
528        free(neworder);
529        free(allreadycounted);
530
531        for (int group=0; group<numdiffchars; group++) free(additional[group]);
532        free(additional);
533    }
534    free(buffer);
535    return err;
536}
537
538
539static void CON_cleartables(int **statistic, int isamino) {
540    int i;
541    int no_of_tables = isamino ? MAX_AMINOS : MAX_BASES;
542
543    for (i = 0; i<no_of_tables; ++i) {
544        free(statistic[i]);
545    }
546}
547
548/* -----------------------------------------------------------------
549 * Function:                     void CON_calculate_cb(AW_window *aw )
550 *
551 * Arguments:                    .
552 *
553 * Returns:                      .
554 *
555 * Description:                  main callback
556 *                               This function calculates the consensus.
557 *                               Function CON_makestatistic creates the
558 *                               statistic and function CON_evaluatestatistic
559 *                               evaluates the statistic. Then the result
560 *                               string(s) are written to the extended data of
561 *                               the alignment.
562 * NOTE:                         .
563 *
564 * Global Variables referenced:  .
565 *
566 * Global Variables modified:    x
567 *
568 * AWARs referenced:
569 *                  AW_STRING, "tmp/con/alignment"     : name of alignment
570 *                  AW_STRING, "tmp/con/which_species" : only marked species ?
571 *                  AW_STRING, "con/group"         : allow grouping ?
572 *                  AW_STRING, "con/countgaps"
573 *                  AW_DOUBLE, "con/fupper"
574 *                  AW_INT, "con/lower"
575 *                  AW_INT, "con/gapbound"  : result is '-' if more than
576 *                                            'gapbound' per cent gaps
577 *                  AW_DOUBLE, "con/fconsidbound" : if frequency of character is
578 *                                     more than 'considbound' per cent, this
579 *                                     character can contribute to groups
580 *                  AW_STRING, "tmp/intcon/name"   : save with this name
581 *                  AW_STRING, "con/result" : result has one or more lines ?
582 *
583 * AWARs modified:               x
584 *
585 * Dependencies:                 CON_maketables
586 *                               CON_makestatistic
587 *                               CON_makegrouptable
588 *                               CON_evaluatestatistic
589 * -----------------------------------------------------------------
590 */
591static void CON_calculate_cb(AW_window *aw)
592{
593    AW_root  *awr   = aw->get_root();
594    char     *align = awr->awar("tmp/con/alignment")->read_string();
595    GB_ERROR  error = 0;
596
597    GB_push_transaction(GLOBAL.gb_main);
598
599    long maxalignlen = GBT_get_alignment_len(GLOBAL.gb_main, align);
600    if (maxalignlen <= 0) error = GB_export_errorf("alignment '%s' doesn't exist", align);
601
602    if (!error) {
603        int isamino         = GBT_is_alignment_protein(GLOBAL.gb_main, align);
604        int onlymarked      = 1;
605        int resultiscomplex = 1;
606
607        {
608            char *marked        = awr->awar("tmp/con/which_species")->read_string();
609            char *complexresult = awr->awar("con/result")->read_string();
610
611            if (strcmp("marked", marked)        != 0) onlymarked = 0;
612            if (strcmp("complex", complexresult) != 0) resultiscomplex = 0;
613
614            free(complexresult);
615            free(marked);
616        }
617
618
619        // creating the table for characters and allocating memory for 'statistic'
620        int *statistic[MAX_AMINOS+1];
621        int  convtable[256];
622        CON_maketables(convtable, statistic, maxalignlen, isamino);
623
624        // filling the statistic table
625        arb_progress progress("Calculating consensus");
626
627        long   nrofspecies = CON_makestatistic(statistic, convtable, align, onlymarked);
628        double fupper      = awr->awar("con/fupper")->read_float();
629        int    lower       = (int)awr->awar("con/lower")->read_int();
630
631        if (fupper>100.0)   fupper = 100;
632        if (fupper<0)       fupper = 0;
633        if (lower<0)        lower  = 0;
634
635        if (lower>fupper) {
636            error = "fault: lower greater than upper";
637        }
638        else {
639
640            double fconsidbound                = awr->awar("con/fconsidbound")->read_float();
641            if (fconsidbound>100) fconsidbound = 100;
642            if (fconsidbound<0)   fconsidbound = 0;
643
644            int gapbound               = (int)awr->awar("con/gapbound")->read_int();
645            if (gapbound<0)   gapbound = 0;
646            if (gapbound>100) gapbound = 100;
647
648            int groupallowed, countgap;
649            {
650                char *group     = awr->awar("con/group")->read_string();
651                char *countgaps = awr->awar("con/countgaps")->read_string();
652
653                groupallowed = strcmp("on", group) == 0;
654                countgap     = strcmp("on", countgaps) == 0;
655
656                free(countgaps);
657                free(group);
658            }
659
660            // creating the table for groups
661            char *groupflags[40];
662            char  groupnames[40];
663            int   numgroups = CON_makegrouptable(groupflags, groupnames, isamino, groupallowed);
664
665            // calculate and export the result strings
666            char *result = 0;
667            CON_evaluatestatistic(result, statistic, groupflags, groupnames, (int)maxalignlen, fupper, lower, fconsidbound, gapbound, countgap, numgroups);
668
669            char *savename = awr->awar("tmp/con/name")->read_string();
670
671            error = CON_export(savename, align, statistic, result, convtable, groupnames,
672                               onlymarked, nrofspecies, maxalignlen, countgap, gapbound, groupallowed,
673                               fconsidbound, fupper, lower, resultiscomplex);
674
675            // freeing allocated memory
676            free(savename);
677            free(result);
678            for (int i=0; i<MAX_GROUPS; i++) free(groupflags[i]);
679        }
680
681        CON_cleartables(statistic, isamino);
682    }
683
684    free(align);
685    GB_end_transaction_show_error(GLOBAL.gb_main, error, aw_message);
686}
687
688void AP_create_consensus_var(AW_root *aw_root, AW_default aw_def)
689{
690    GB_transaction ta(GLOBAL.gb_main);
691    {
692        char *defali = GBT_get_default_alignment(GLOBAL.gb_main);
693        aw_root->awar_string("tmp/con/alignment", defali, aw_def);
694        free(defali);
695    }
696    aw_root->awar_string("tmp/con/which_species", "marked", aw_def);
697    aw_root->awar_string("con/group", "off", aw_def);
698    aw_root->awar_string("con/countgaps", "on", aw_def);
699    aw_root->awar_float("con/fupper", 95, aw_def);
700    aw_root->awar_int("con/lower", 70, aw_def);
701    aw_root->awar_int("con/gapbound", 60, aw_def);
702    aw_root->awar_float("con/fconsidbound", 30, aw_def);
703    aw_root->awar_string("tmp/con/name", "CONSENSUS", aw_def);
704    aw_root->awar_string("con/result", "single line", aw_def);
705
706    aw_root->awar_string(AWAR_MAX_FREQ_SAI_NAME, "MAX_FREQUENCY", aw_def);
707    aw_root->awar_int(AWAR_MAX_FREQ_NO_GAPS, 1, aw_def);
708
709}
710
711// Open window to show IUPAC tables
712static AW_window * CON_showgroupswin_cb(AW_root *aw_root)
713{
714    AW_window_simple *aws = new AW_window_simple;
715    aws->init(aw_root, "SHOW_IUPAC", "Show IUPAC");
716    aws->load_xfig("consensus/groups.fig");
717    aws->button_length(7);
718
719    aws->at("ok"); aws->callback((AW_CB0)AW_POPDOWN);
720    aws->create_button("CLOSE", "CLOSE", "O");
721
722    return (AW_window *)aws;
723}
724
725AW_window *AP_create_con_expert_window(AW_root *aw_root) {
726    AW_window_simple *aws = new AW_window_simple;
727    aws->init(aw_root, "BUILD_CONSENSUS", "CONSENSUS OF SEQUENCES");
728    aws->load_xfig("consensus/expert.fig");
729    aws->button_length(6);
730
731    aws->at("cancel"); aws->callback((AW_CB0)AW_POPDOWN);
732    aws->create_button("CLOSE", "CLOSE", "C");
733
734    aws->at("help"); aws->callback(makeHelpCallback("consensus.hlp"));
735    aws->create_button("HELP", "HELP", "H");
736
737    aws->button_length(10);
738    aws->at("showgroups"); aws->callback(AW_POPUP, (AW_CL)CON_showgroupswin_cb, 0);
739    aws->create_button("SHOW_IUPAC", "show\nIUPAC...", "s");
740    aws->button_length(10);
741
742    aws->at("which_species");
743    aws->create_toggle_field("tmp/con/which_species", NULL, "");
744    aws->insert_toggle("all", "1", "all");
745    aws->insert_default_toggle("marked",   "1", "marked");
746    aws->update_toggle_field();
747
748    aws->at("which_alignment");
749    awt_create_selection_list_on_alignments(GLOBAL.gb_main, (AW_window *)aws, "tmp/con/alignment", "*=");
750
751    aws->button_length(15);
752
753    // activation of consensus calculation by button ...
754    aws->at("calculate"); aws->callback((AW_CB0)CON_calculate_cb);
755    aws->create_button("GO", "GO", "G");
756
757    aws->at("group");
758    aws->create_toggle_field("con/group", NULL, "");
759    aws->insert_toggle("on", "1", "on");
760    aws->insert_default_toggle("off", "1", "off");
761    aws->update_toggle_field();
762
763    aws->at("countgaps");
764    aws->create_toggle_field("con/countgaps", NULL, "");
765    aws->insert_toggle("on", "1", "on");
766    aws->insert_default_toggle("off", "1", "off");
767    aws->update_toggle_field();
768
769    aws->at("upper");
770    aws->create_input_field("con/fupper", 4);
771
772    aws->at("lower");
773    aws->create_input_field("con/lower", 4);
774
775    aws->at("considbound");
776    aws->create_input_field("con/fconsidbound", 4);
777
778    aws->at("gapbound");
779    aws->create_input_field("con/gapbound", 4);
780
781    aws->at("name");
782    aws->create_input_field("tmp/con/name", 10);
783
784    aws->at("result");
785    aws->create_toggle_field("con/result", NULL, "");
786    aws->insert_toggle("single line", "1", "single line");
787    aws->insert_default_toggle("complex", "1", "complex");
788    aws->update_toggle_field();
789
790    aws->at("save_box");
791    awt_create_selection_list_on_sai(GLOBAL.gb_main, aws, "tmp/con/name", false);
792
793    return aws;
794}
795
796/* -----------------------------------------------------------------
797 * Function:           CON_calc_max_freq_cb( AW_window *aw)
798 *
799 * Description:       Gets the maximum frequency for each columns.
800 *
801 * NOTE:
802 *
803 * -----------------------------------------------------------------
804 */
805
806static void CON_calc_max_freq_cb(AW_window *aw) {
807    arb_assert(!GB_have_error());
808
809    AW_root  *awr   = aw->get_root();
810    GB_ERROR  error = NULL;
811
812    GB_transaction ta(GLOBAL.gb_main);
813
814    char *align       = GBT_get_default_alignment(GLOBAL.gb_main);
815    long  maxalignlen = GBT_get_alignment_len(GLOBAL.gb_main, align);
816
817    if (maxalignlen<=0) {
818        GB_clear_error();
819        error = "alignment doesn't exist!";
820    }
821    else {
822        int isamino = GBT_is_alignment_protein(GLOBAL.gb_main, align);
823
824        arb_progress progress("Calculating max. frequency");
825
826        int *statistic[MAX_AMINOS+1];
827        int  convtable[256];
828        CON_maketables(convtable, statistic, maxalignlen, isamino);
829
830        const int onlymarked  = 1;
831        long      nrofspecies = CON_makestatistic(statistic, convtable, align, onlymarked);
832
833        int end = isamino ? MAX_AMINOS : MAX_BASES;
834
835        char *result1 = new char[maxalignlen+1];
836        char *result2 = new char[maxalignlen+1];
837
838        result1[maxalignlen] = 0;
839        result2[maxalignlen] = 0;
840
841        long no_gaps = awr->awar(AWAR_MAX_FREQ_NO_GAPS)->read_int();
842
843        for (int pos = 0; pos < maxalignlen; pos++) {
844            int sum = 0;
845            int max = 0;
846
847            for (int i=0; i<end; i++) {
848                if (no_gaps && (i == convtable[(unsigned char)'-'])) continue;
849                sum                              += statistic[i][pos];
850                if (statistic[i][pos] > max) max  = statistic[i][pos];
851            }
852            if (sum == 0) {
853                result1[pos] = '=';
854                result2[pos] = '=';
855            }
856            else {
857                result1[pos] = "01234567890"[(( 10*max)/sum)%11]; // @@@ why %11?
858                result2[pos] = "01234567890"[((100*max)/sum)%10];
859            }
860        }
861
862        const char *savename    = awr->awar(AWAR_MAX_FREQ_SAI_NAME)->read_char_pntr();
863        GBDATA     *gb_extended = GBT_find_or_create_SAI(GLOBAL.gb_main, savename);
864        if (!gb_extended) {
865            error = GB_await_error();
866        }
867        else {
868            GBDATA *gb_data1 = GBT_add_data(gb_extended, align, "data", GB_STRING);
869            GBDATA *gb_data2 = GBT_add_data(gb_extended, align, "dat2", GB_STRING);
870
871            error             = GB_write_string(gb_data1, result1);
872            if (!error) error = GB_write_string(gb_data2, result2);
873
874            GBDATA *gb_options = GBT_add_data(gb_extended, align, "_TYPE", GB_STRING);
875
876            if (!error) {
877                const char *type = GBS_global_string("MFQ: [species: %li] [exclude gaps: %li]", nrofspecies, no_gaps);
878                error            = GB_write_string(gb_options, type);
879            }
880        }
881
882        delete [] result1;
883        delete [] result2;
884        CON_cleartables(statistic, isamino);
885    }
886
887    error = ta.close(error);
888    if (error) aw_message(error);
889
890    free(align);
891
892    arb_assert(!GB_have_error());
893}
894
895AW_window *AP_create_max_freq_window(AW_root *aw_root) {
896    AW_window_simple *aws = new AW_window_simple;
897    aws->init(aw_root, "MAX_FREQUENCY", "MAX FREQUENCY");
898    aws->load_xfig("consensus/max_freq.fig");
899
900    GB_push_transaction(GLOBAL.gb_main);
901
902    aws->button_length(6);
903
904    aws->at("cancel"); aws->callback((AW_CB0)AW_POPDOWN);
905    aws->create_button("CLOSE", "CLOSE", "C");
906
907    aws->at("help"); aws->callback(makeHelpCallback("max_freq.hlp"));
908    aws->create_button("HELP", "HELP", "H");
909
910    // activation of consensus calculation by button ...
911    aws->at("go"); aws->callback((AW_CB0)CON_calc_max_freq_cb);
912    aws->create_button("GO", "GO", "C");
913
914    aws->at("save");
915    aws->create_input_field(AWAR_MAX_FREQ_SAI_NAME, 1);
916
917    aws->at("sai");
918    awt_create_selection_list_on_sai(GLOBAL.gb_main, aws, AWAR_MAX_FREQ_SAI_NAME, false);
919
920    aws->at("gaps");
921    aws->create_toggle(AWAR_MAX_FREQ_NO_GAPS);
922
923    GB_pop_transaction(GLOBAL.gb_main);
924
925    return (AW_window *)aws;
926}
927
Note: See TracBrowser for help on using the repository browser.