source: tags/cvs_2_svn/NTREE/ad_transpro.cxx

Last change on this file was 5309, checked in by westram, 16 years ago
  • replaced calls to GB_find with new find-functions
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.0 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <ctype.h>
5
6#include <arbdb.h>
7#include <arbdbt.h>
8#include <aw_root.hxx>
9#include <aw_device.hxx>
10#include <aw_awars.hxx>
11#include <aw_window.hxx>
12#include <awt.hxx>
13#include <awt_codon_table.hxx>
14#include <awt_changekey.hxx>
15#include <awt_sel_boxes.hxx>
16#include <awt_pro_a_nucs.hxx>
17#include <awt_translate.hxx>
18
19#ifndef ARB_ASSERT_H
20#include <arb_assert.h>
21#endif
22#define nt_assert(bed) arb_assert(bed)
23
24extern GBDATA *GLOBAL_gb_main;
25
26static GB_ERROR arb_r2a(GBDATA *gbmain, bool use_entries, bool save_entries, int selected_startpos,
27                        bool    translate_all, const char *ali_source, const char *ali_dest)
28{
29    // if use_entries   == true -> use fields 'codon_start' and 'transl_table' for translation
30    //                           (selected_startpos and AWAR_PROTEIN_TYPE are only used if one or both fields are missing)
31    // if use_entries   == false -> always use selected_startpos and AWAR_PROTEIN_TYPE
32    // if translate_all == true -> a selected_startpos > 1 produces a leading 'X' in protein data
33    //                             (otherwise nucleotides in front of the starting pos are simply ignored)
34
35    nt_assert(selected_startpos >= 0 && selected_startpos < 3);
36
37    GBDATA   *gb_source;
38    GBDATA   *gb_dest;
39    GBDATA   *gb_species;
40    GBDATA   *gb_source_data;
41    GBDATA   *gb_dest_data;
42    GB_ERROR  error = 0;
43    char     *data;
44    int       count = 0;
45    int       stops = 0;
46
47    gb_source = GBT_get_alignment(gbmain,ali_source);
48    if (!gb_source) return "Please select a valid source alignment";
49    gb_dest = GBT_get_alignment(gbmain,ali_dest);
50    if (!gb_dest) {
51        const char *msg = GBS_global_string("You have not selected a destination alignment\n"
52                                            "May I create one ('%s_pro') for you?",ali_source);
53        if (aw_message(msg,"CREATE,CANCEL")){
54            return "Cancelled";
55        }
56
57        long slen = GBT_get_alignment_len(gbmain,ali_source);
58        ali_dest  = GBS_global_string_copy("%s_pro",ali_source);
59        gb_dest   = GBT_create_alignment(gbmain,ali_dest,slen/3+1,0,1,"ami");
60
61        {
62            char *fname = GBS_global_string_copy("%s/data",ali_dest);
63            awt_add_new_changekey(gbmain,fname,GB_STRING);
64            free(fname);
65        }
66
67        if (!gb_dest){
68            aw_closestatus();
69            return GB_get_error();
70        }
71    }
72
73    aw_openstatus("Translating");
74
75    int spec_count           = GBT_get_species_count(gbmain);
76    int spec_i               = 0;
77    int spec_no_transl_table = 0;
78    int spec_no_codon_start  = 0;
79
80    bool table_used[AWT_CODON_TABLES];
81    memset(table_used, 0, sizeof(table_used));
82    int  selected_ttable = GBT_read_int(GLOBAL_gb_main,AWAR_PROTEIN_TYPE); // read selected table
83
84    if (use_entries) {
85        for (gb_species = GBT_first_marked_species(gbmain);
86             gb_species && !error;
87             gb_species = GBT_next_marked_species(gb_species) )
88        {
89            int arb_table;
90            error = AWT_findTranslationTable(gb_species, arb_table);
91
92            if (!error) {
93                if (arb_table == -1) arb_table = 0; // no transl_table entry -> default to standard code
94                table_used[arb_table] = true;
95            }
96
97//             GBDATA *gb_transl_table = GB_entry(gb_species, "transl_table");
98//             int     arb_table       = 0; // use 'Standard Code' if no 'transl_table' entry was found
99
100//             if (gb_transl_table) {
101//                 int embl_table = atoi(GB_read_char_pntr(gb_transl_table));
102//                 arb_table  = AWT_embl_transl_table_2_arb_code_nr(embl_table);
103
104//                 if (arb_table == -1) {
105//                     GBDATA *gb_name = GB_entry(gb_species, "name");
106//                     return GB_export_error("Illegal (or unsupported) value for 'transl_table' in '%s'", GB_read_char_pntr(gb_name));
107//                 }
108//             }
109
110//             table_used[arb_table] = true;
111        }
112    }
113    else {
114        table_used[selected_ttable] = true; // and mark it used
115    }
116
117    for (int table = 0; table<AWT_CODON_TABLES && !error; ++table) {
118        if (!table_used[table]) continue;
119
120        GBT_write_int(GLOBAL_gb_main, AWAR_PROTEIN_TYPE, table); // set wanted protein table
121        awt_pro_a_nucs_convert_init(GLOBAL_gb_main); // (re-)initialize codon tables for current translation table
122
123        for (   gb_species = GBT_first_marked_species(gbmain);
124                gb_species && !error;
125                gb_species = GBT_next_marked_species(gb_species) )
126        {
127            bool found_table_entry = false;
128            bool found_start_entry = false;
129            int  startpos          = selected_startpos;
130
131            if (use_entries) {  // if entries are used, test if field 'transl_table' matches current table
132                GBDATA *gb_transl_table = GB_entry(gb_species, "transl_table");
133                int     sp_arb_table    = selected_ttable; // use selected translation table as default (if 'transl_table' field is missing)
134
135                if (gb_transl_table) {
136                    int sp_embl_table = atoi(GB_read_char_pntr(gb_transl_table));
137                    sp_arb_table      = AWT_embl_transl_table_2_arb_code_nr(sp_embl_table);
138                    found_table_entry = true;
139
140                    nt_assert(sp_arb_table != -1); // sp_arb_table must be a valid code (or error should occur above)
141                }
142
143                if (sp_arb_table != table) continue; // species has not current transl_table
144
145                if (!gb_transl_table) {
146                    ++spec_no_transl_table; // count species w/o transl_table entry
147                }
148
149                GBDATA *gb_codon_start = GB_entry(gb_species, "codon_start");
150                int     sp_codon_start = selected_startpos+1; // default codon startpos (if 'codon_start' field is missing)
151
152                if (gb_codon_start) {
153                    sp_codon_start = atoi(GB_read_char_pntr(gb_codon_start));
154                    if (sp_codon_start<1 || sp_codon_start>3) {
155                        GBDATA *gb_name = GB_entry(gb_species, "name");
156                        error = GB_export_error("'%s' has invalid codon_start entry %i (allowed: 1..3)",
157                                                GB_read_char_pntr(gb_name), sp_codon_start);
158                        break;
159                    }
160                    found_start_entry = true;
161                }
162                else {
163                    ++spec_no_codon_start;
164                }
165                startpos = sp_codon_start-1; // internal value is 0..2
166            }
167
168            if (aw_status(double(spec_i++)/double(spec_count))) {
169                error = "Aborted";
170                break;
171            }
172            gb_source = GB_entry(gb_species,ali_source);
173            if (!gb_source) continue;
174            gb_source_data = GB_entry(gb_source,"data");
175            if (!gb_source_data) continue;
176            data = GB_read_string(gb_source_data);
177            if (!data) {
178                GB_print_error(); // cannot read data (ignore species)
179                continue;
180            }
181
182            stops += AWT_pro_a_nucs_convert(data, GB_read_string_count(gb_source_data), startpos, translate_all); // do the translation
183
184            count ++;
185            gb_dest_data = GBT_add_data(gb_species,ali_dest,"data", GB_STRING);
186            if (!gb_dest_data) return GB_get_error();
187            error        = GB_write_string(gb_dest_data,data);
188            free(data);
189
190            if (!error && save_entries) {
191                if (!found_table_entry || !use_entries) {
192                    GBDATA *gb_transl_table = GB_search(gb_species, "transl_table", GB_STRING);
193                    if (!gb_transl_table) {
194                        error = GB_get_error();
195                    }
196                    else {
197                        GB_write_string(gb_transl_table, GBS_global_string("%i", AWT_arb_code_nr_2_embl_transl_table(selected_ttable)));
198                    }
199                }
200                if (!error && (!found_start_entry || !use_entries)) {
201                    GBDATA *gb_start_pos = GB_search(gb_species, "codon_start", GB_STRING);
202                    if (!gb_start_pos) {
203                        error = GB_get_error();
204                    }
205                    else {
206                        GB_write_string(gb_start_pos, GBS_global_string("%i", startpos+1));
207                    }
208                }
209            }
210        }
211    }
212
213    GBT_write_int(GLOBAL_gb_main, AWAR_PROTEIN_TYPE, selected_ttable); // restore old value
214
215    aw_closestatus();
216    if (!error) {
217        if (use_entries) { // use 'transl_table' and 'codon_start' fields ?
218            if (spec_no_transl_table) {
219                aw_message(GBS_global_string("%i taxa had no 'transl_table' field (defaulted to %i)",
220                                             spec_no_transl_table, selected_ttable));
221            }
222            if (spec_no_codon_start) {
223                aw_message(GBS_global_string("%i taxa had no 'codon_start' field (defaulted to %i)",
224                                             spec_no_codon_start, selected_startpos));
225            }
226            if ((spec_no_codon_start+spec_no_transl_table) == 0) { // all entries were present
227                aw_message("codon_start and transl_table entries found for all taxa");
228            }
229            else if (save_entries) {
230                aw_message("The defaults have been written into 'transl_table' and 'codon_start' fields.");
231            }
232        }
233
234        aw_message(GBS_global_string("%i taxa converted\n  %f stops per sequence found",
235                                     count, (double)stops/(double)count));
236    }
237    return error;
238}
239
240#define AWAR_TRANSPRO_PREFIX "transpro/"
241#define AWAR_TRANSPRO_SOURCE AWAR_TRANSPRO_PREFIX "source"
242#define AWAR_TRANSPRO_DEST   AWAR_TRANSPRO_PREFIX "dest"
243#define AWAR_TRANSPRO_POS    AWAR_TRANSPRO_PREFIX "pos"
244#define AWAR_TRANSPRO_MODE   AWAR_TRANSPRO_PREFIX "mode"
245#define AWAR_TRANSPRO_XSTART AWAR_TRANSPRO_PREFIX "xstart"
246#define AWAR_TRANSPRO_WRITE  AWAR_TRANSPRO_PREFIX "write"
247
248void transpro_event(AW_window *aww){
249    AW_root *aw_root = aww->get_root();
250    GB_ERROR error;
251    GB_begin_transaction(GLOBAL_gb_main);
252
253#if defined(DEBUG) && 0
254    test_AWT_get_codons();
255#endif
256    awt_pro_a_nucs_convert_init(GLOBAL_gb_main);
257
258    char *ali_source    = aw_root->awar(AWAR_TRANSPRO_SOURCE)->read_string();
259    char *ali_dest      = aw_root->awar(AWAR_TRANSPRO_DEST)->read_string();
260    char *mode          = aw_root->awar(AWAR_TRANSPRO_MODE)->read_string();
261    int   startpos      = aw_root->awar(AWAR_TRANSPRO_POS)->read_int();
262    bool  save2fields   = aw_root->awar(AWAR_TRANSPRO_WRITE)->read_int();
263    bool  translate_all = aw_root->awar(AWAR_TRANSPRO_XSTART)->read_int();
264
265    error = arb_r2a(GLOBAL_gb_main, strcmp(mode, "fields") == 0, save2fields, startpos, translate_all, ali_source, ali_dest);
266    if (error) {
267        GB_abort_transaction(GLOBAL_gb_main);
268        aw_message(error);
269    }else{
270        GBT_check_data(GLOBAL_gb_main,0);
271        GB_commit_transaction(GLOBAL_gb_main);
272    }
273
274    free(mode);
275    free(ali_dest);
276    free(ali_source);
277}
278
279void nt_trans_cursorpos_changed(AW_root *awr) {
280    int pos = awr->awar(AWAR_CURSOR_POSITION)->read_int()-1;
281    pos = pos %3;
282    awr->awar(AWAR_TRANSPRO_POS)->write_int(pos);
283}
284
285AW_window *NT_create_dna_2_pro_window(AW_root *root) {
286    AWUSE(root);
287    GB_transaction dummy(GLOBAL_gb_main);
288
289    AW_window_simple *aws = new AW_window_simple;
290    aws->init( root, "TRANSLATE_DNA_TO_PRO", "TRANSLATE DNA TO PRO");
291
292    //     aws->auto_off();
293
294    aws->load_xfig("transpro.fig");
295
296    aws->callback( (AW_CB0)AW_POPDOWN);
297    aws->at("close");
298    aws->create_button("CLOSE","CLOSE","C");
299
300    aws->callback( AW_POPUP_HELP,(AW_CL)"translate_dna_2_pro.hlp");
301    aws->at("help");
302    aws->create_button("HELP","HELP","H");
303
304    aws->at("source");
305    awt_create_selection_list_on_ad(GLOBAL_gb_main,(AW_window *)aws, AWAR_TRANSPRO_SOURCE,"dna=:rna=");
306
307    aws->at("dest");
308    awt_create_selection_list_on_ad(GLOBAL_gb_main,(AW_window *)aws, AWAR_TRANSPRO_DEST,"pro=:ami=");
309
310    root->awar_int(AWAR_PROTEIN_TYPE, AWAR_PROTEIN_TYPE_bacterial_code_index, GLOBAL_gb_main);
311    aws->at("table");
312    aws->create_option_menu(AWAR_PROTEIN_TYPE);
313    for (int code_nr=0; code_nr<AWT_CODON_TABLES; code_nr++) {
314        aws->insert_option(AWT_get_codon_code_name(code_nr), "", code_nr);
315    }
316    aws->update_option_menu();
317
318    aws->at("mode");
319    aws->create_toggle_field(AWAR_TRANSPRO_MODE,0,"");
320    aws->insert_toggle( "from fields 'codon_start' and 'transl_table'", "", "fields" );
321    aws->insert_default_toggle( "use settings below (same for all species):", "", "settings" );
322    aws->update_toggle_field();
323
324    aws->at("pos");
325    aws->create_option_menu(AWAR_TRANSPRO_POS,0,"");
326    aws->insert_option( "1", "1", 0 );
327    aws->insert_option( "2", "2", 1 );
328    aws->insert_option( "3", "3", 2 );
329    aws->update_option_menu();
330    aws->get_root()->awar_int(AWAR_CURSOR_POSITION)->add_callback(nt_trans_cursorpos_changed);
331
332    aws->at("write");
333    aws->label("Save settings (to 'codon_start'+'transl_table')");
334    aws->create_toggle(AWAR_TRANSPRO_WRITE);
335
336    aws->at("start");
337    aws->label("Translate all data");
338    aws->create_toggle(AWAR_TRANSPRO_XSTART);
339
340    aws->at("translate");
341    aws->callback(transpro_event);
342    aws->highlight();
343    aws->create_button("TRANSLATE","TRANSLATE","T");
344
345    aws->window_fit();
346
347    return (AW_window *)aws;
348}
349
350// Realign a dna alignment with a given protein source
351
352static int synchronizeCodons(const char *proteins, const char *dna, int minCatchUp, int maxCatchUp, int *foundCatchUp,
353                             const AWT_allowedCode& initially_allowed_code, AWT_allowedCode& allowed_code_left) {
354
355    for (int catchUp=minCatchUp; catchUp<=maxCatchUp; catchUp++) {
356        const char *dna_start = dna+catchUp;
357        AWT_allowedCode allowed_code;
358        allowed_code = initially_allowed_code;
359
360        for (int p=0; ; p++) {
361            char prot = proteins[p];
362
363            if (!prot) { // all proteins were synchronized
364                *foundCatchUp = catchUp;
365                return 1;
366            }
367
368            if (!AWT_is_codon(prot, dna_start, allowed_code, allowed_code_left)) break;
369
370            allowed_code = allowed_code_left; // if synchronized: use left codes as allowed codes!
371            dna_start += 3;
372        }
373    }
374
375    return 0;
376}
377
378#define SYNC_LENGTH 4
379// every X in amino-alignment, it represents 1 to 3 bases in DNA-Alignment
380// SYNC_LENGTH is the # of codons which will be syncronized (ahead!)
381// before deciding "X was realigned correctly"
382
383GB_ERROR arb_transdna(GBDATA *gbmain, char *ali_source, char *ali_dest, long *neededLength)
384{
385    AWT_initialize_codon_tables();
386
387    GBDATA *gb_source = GBT_get_alignment(gbmain,ali_source);           if (!gb_source) return "Please select a valid source alignment";
388    GBDATA *gb_dest = GBT_get_alignment(gbmain,ali_dest);           if (!gb_dest) return "Please select a valid destination alignment";
389
390    long     ali_len            = GBT_get_alignment_len(gbmain,ali_dest);
391    long     max_wanted_ali_len = 0;
392    GB_ERROR error              = 0;
393
394    aw_openstatus("Re-aligner");
395    int no_of_marked_species = GBT_count_marked_species(gbmain);
396    int no_of_realigned_species = 0;
397    int ignore_fail_pos = 0;
398
399    for (GBDATA *gb_species = GBT_first_marked_species(gbmain);
400         !error && gb_species;
401         gb_species = GBT_next_marked_species(gb_species) ) {
402
403        {
404            char stat[200];
405
406            sprintf(stat, "Re-aligning #%i of %i ...", no_of_realigned_species+1, no_of_marked_species);
407            aw_status(stat);
408        }
409
410        gb_source=              GB_entry(gb_species, ali_source); if(!gb_source)     continue;
411        GBDATA *gb_source_data= GB_entry(gb_source,  "data")    ; if(!gb_source_data)continue;
412        gb_dest=                GB_entry(gb_species, ali_dest)  ; if(!gb_dest)       continue;
413        GBDATA *gb_dest_data=   GB_entry(gb_dest,    "data")    ; if(!gb_dest_data)  continue;
414
415        char *source = GB_read_string(gb_source_data);          if (!source) { GB_print_error(); continue; }
416        char *dest = GB_read_string(gb_dest_data);          if (!dest) { GB_print_error(); continue; }
417
418        long source_len = GB_read_string_count(gb_source_data);
419        long dest_len = GB_read_string_count(gb_dest_data);
420
421        // compress destination DNA (=remove align-characters):
422        char *compressed_dest = (char*)malloc(dest_len+1);
423        {
424            char *f = dest;
425            char *t = compressed_dest;
426
427            while (1) {
428                char c = *f++;
429                if (!c) break;
430                if (c!='.' && c!='-') *t++ = c;
431            }
432            *t = 0;
433        }
434
435        int failed = 0;
436        const char *fail_reason = 0;
437
438        long  wanted_ali_len = source_len*3L;
439        char *buffer         = (char*)malloc(ali_len+1);
440        if (ali_len<wanted_ali_len) {
441            failed          = 1;
442            fail_reason     = GBS_global_string("Alignment '%s' is too short (increase its length to %li)", ali_dest, wanted_ali_len);
443            ignore_fail_pos = 1;
444
445            if (wanted_ali_len>max_wanted_ali_len) max_wanted_ali_len = wanted_ali_len;
446        }
447
448        AWT_allowedCode allowed_code; // default = all allowed
449
450        if (!failed) {
451            int arb_transl_table;
452            GB_ERROR local_error = AWT_findTranslationTable(gb_species, arb_transl_table);
453            if (local_error) {
454                failed          = 1;
455                fail_reason     = GBS_global_string("Error while reading 'transl_table' (%s)", local_error);
456                ignore_fail_pos = 1;
457            }
458            else if (arb_transl_table >= 0) {
459                // we found a 'transl_table' entry -> restrict used code to the code stored there
460                allowed_code.forbidAllBut(arb_transl_table);
461            }
462        }
463
464        char *d = compressed_dest;
465        char *s = source;
466
467        if (!failed) {
468            char *p = buffer;
469            int x_count = 0;
470            const char *x_start = 0;
471
472            for (;;) {
473                char c = *s++;
474                if (!c) {
475                    if (x_count) {
476                        int off = -(x_count*3);
477                        while (d[0]) {
478                            p[off++] = *d++;
479                        }
480                    }
481                    break;
482                }
483
484                if (c=='.' || c=='-') {
485                    p[0] = p[1] = p[2] = c;
486                    p += 3;
487                }
488                else if (toupper(c)=='X') { // one X represents 1 to 3 DNAs
489                    x_start = s-1;
490                    x_count = 1;
491                    int gap_count = 0;
492
493                    for (;;) {
494                        char c2 = toupper(s[0]);
495
496                        if (c2=='X') {
497                            x_count++;
498                        }
499                        else {
500                            if (c2!='.' && c2!='-') break;
501                            gap_count++;
502                        }
503                        s++;
504                    }
505
506                    int setgap = (x_count+gap_count)*3;
507                    memset(p, '.', setgap);
508                    p += setgap;
509                }
510                else {
511                    AWT_allowedCode allowed_code_left;
512
513                    if (x_count) { // synchronize
514                        char protein[SYNC_LENGTH+1];
515                        int count;
516                        {
517                            int off;
518
519                            protein[0] = toupper(c);
520                            for (count=1,off=0; count<SYNC_LENGTH; off++) {
521                                char c2 = s[off];
522
523                                if (c2!='.' && c2!='-') {
524                                    c2 = toupper(c2);
525                                    if (c2=='X') break; // can't sync X
526                                    protein[count++] = c2;
527                                }
528                            }
529                        }
530
531                        nt_assert(count>=1);
532                        protein[count] = 0;
533
534                        int catchUp;
535                        if (count<SYNC_LENGTH) {
536                            int sync_possibilities = 0;
537                            int *sync_possible_with_catchup = new int[x_count*3+1];
538                            int maxCatchup = x_count*3;
539
540                            catchUp = x_count-1;
541                            for (;;) {
542                                if (!synchronizeCodons(protein, d, catchUp+1, maxCatchup, &catchUp, allowed_code, allowed_code_left)) {
543                                    break;
544                                }
545                                sync_possible_with_catchup[sync_possibilities++] = catchUp;
546                            }
547
548                            if (sync_possibilities==0) {
549                                delete sync_possible_with_catchup;
550                                failed = 1;
551                                fail_reason = "Can't syncronize after 'X'";
552                                break;
553                            }
554                            if (sync_possibilities>1) {
555                                delete sync_possible_with_catchup;
556                                failed = 1;
557                                fail_reason = "Not enough data behind 'X' (please contact ARB-Support)";
558                                break;
559                            }
560
561                            nt_assert(sync_possibilities==1);
562                            catchUp = sync_possible_with_catchup[0];
563                            delete sync_possible_with_catchup;
564                        }
565                        else if (!synchronizeCodons(protein, d, x_count, x_count*3, &catchUp, allowed_code, allowed_code_left)) {
566                            failed = 1;
567                            fail_reason = "Can't syncronize after 'X'";
568                            break;
569                        }
570
571                        allowed_code = allowed_code_left;
572
573                        // copy 'catchUp' characters (they are the content of the found Xs):
574                        {
575                            const char *after = s-1;
576                            const char *i;
577                            int off = int(after-x_start);
578                            nt_assert(off>=x_count);
579                            off = -(off*3);
580                            int x_rest = x_count;
581
582                            for (i=x_start; i<after; i++) {
583                                switch (i[0]) {
584                                    case 'x':
585                                    case 'X':
586                                        {
587                                            int take_per_X = catchUp/x_rest;
588                                            int o;
589                                            for (o=0; o<3; o++) {
590                                                if (o<take_per_X) {
591                                                    p[off++] = *d++;
592                                                }
593                                                else {
594                                                    p[off++] = '.';
595                                                }
596                                            }
597                                            x_rest--;
598                                            break;
599                                        }
600                                    case '.':
601                                    case '-':
602                                        p[off++] = i[0];
603                                        p[off++] = i[0];
604                                        p[off++] = i[0];
605                                        break;
606                                    default:
607                                        nt_assert(0);
608                                        break;
609                                }
610                            }
611                        }
612                        x_count = 0;
613                    }
614                    else {
615                        const char *why_fail;
616                        if (!AWT_is_codon(c, d, allowed_code, allowed_code_left, &why_fail)) {
617                            failed = 1;
618                            fail_reason = GBS_global_string("Not a codon (%s)", why_fail);
619                            break;
620                        }
621
622                        allowed_code = allowed_code_left;
623                    }
624
625                    // copy one codon:
626                    p[0] = d[0];
627                    p[1] = d[1];
628                    p[2] = d[2];
629
630                    p += 3;
631                    d += 3;
632                }
633            }
634
635            if (!failed) {
636                int len = p-buffer;
637                int rest = ali_len-len;
638
639                memset(p, '.', rest);
640                p += rest;
641                p[0] = 0;
642            }
643        }
644
645        if (failed) {
646            int source_fail_pos = (s-1)-source+1;
647            int dest_fail_pos = 0;
648            {
649                int fail_d_base_count = d-compressed_dest;
650                char *dp = dest;
651
652                for (;;) {
653                    char c = *dp++;
654
655                    if (!c) {
656                        nt_assert(c);
657                        break;
658                    }
659                    if (c!='.' && c!='-') {
660                        if (!fail_d_base_count) {
661                            dest_fail_pos = (dp-1)-dest+1;
662                            break;
663                        }
664                        fail_d_base_count--;
665                    }
666                }
667            }
668
669            {
670                char *name = GBT_read_name(gb_species);
671                if (!name) name = strdup("(unknown species)");
672
673                char *dup_fail_reason = strdup(fail_reason); // otherwise it may be destroyed by GBS_global_string
674                aw_message(GBS_global_string("Automatic re-align failed for '%s'", name));
675
676                if (ignore_fail_pos) {
677                    aw_message(GBS_global_string("Reason: %s", dup_fail_reason));
678                }
679                else {
680                    aw_message(GBS_global_string("Reason: %s at %s:%i / %s:%i", dup_fail_reason, ali_source, source_fail_pos, ali_dest, dest_fail_pos));
681                }
682
683                free(dup_fail_reason);
684                free(name);
685            }
686
687        }
688        else {
689            nt_assert(strlen(buffer) == (unsigned)ali_len);
690           
691            // re-alignment sucessfull
692            error = GB_write_string(gb_dest_data,buffer);
693            if (!error) {
694                GBDATA *gb_codon_start = GB_entry(gb_species, "codon_start");
695                if (gb_codon_start) {
696                    // overwrite existing 'codon_start' entries
697                    error = GB_write_string(gb_codon_start, "1"); // after re-alignment codon_start is always 1
698                }
699            }
700        }
701
702        free(buffer);
703        free(compressed_dest);
704        free(dest);
705        free(source);
706
707        no_of_realigned_species++;
708        GB_status(double(no_of_realigned_species)/double(no_of_marked_species));
709    }
710    aw_closestatus();
711
712    if (max_wanted_ali_len>0) {
713        if (neededLength) *neededLength = max_wanted_ali_len;
714    }
715
716    if (error) {
717        return error;
718    }
719
720    error = GBT_check_data(gbmain,ali_dest);
721
722    return error;
723}
724
725#undef SYNC_LENGTH
726
727
728void transdna_event(AW_window *aww)
729{
730    AW_root  *aw_root      = aww->get_root();
731    GB_ERROR  error;
732    char     *ali_source   = aw_root->awar(AWAR_TRANSPRO_DEST)->read_string();
733    char     *ali_dest     = aw_root->awar(AWAR_TRANSPRO_SOURCE)->read_string();
734    long      neededLength = 0;
735    bool      retrying     = false;
736
737    retry :
738    GB_begin_transaction(GLOBAL_gb_main);
739
740    error = arb_transdna(GLOBAL_gb_main,ali_source,ali_dest, &neededLength);
741    if (error) {
742        GB_abort_transaction(GLOBAL_gb_main);
743        aw_message(error,"OK");
744    }else{
745        // GBT_check_data(GLOBAL_gb_main,ali_dest); // done by arb_transdna()
746        GB_commit_transaction(GLOBAL_gb_main);
747    }
748
749    if (!retrying && neededLength) {
750        if (aw_message(GBS_global_string("Increase length of '%s' to %li?", ali_dest, neededLength), "Yes,No") == 0) {
751            GB_transaction dummy(GLOBAL_gb_main);
752            GBT_set_alignment_len(GLOBAL_gb_main, ali_dest, neededLength); // @@@ has no effect ? ? why ?
753            aw_message(GBS_global_string("Alignment length of '%s' set to %li\nrunning re-aligner again!", ali_dest, neededLength));
754            retrying = true;
755            goto retry;
756        }
757    }
758
759    free(ali_source);
760    free(ali_dest);
761
762}
763
764AW_window *NT_create_realign_dna_window(AW_root *root) {
765    AW_window_simple *aws = new AW_window_simple;
766    aws->init( root, "REALIGN_DNA", "REALIGN DNA");
767
768    aws->load_xfig("transdna.fig");
769
770    aws->callback( (AW_CB0)AW_POPDOWN);
771    aws->at("close");
772    aws->create_button("CLOSE","CLOSE","C");
773
774    aws->callback( AW_POPUP_HELP,(AW_CL)"realign_dna.hlp");
775    aws->at("help");
776    aws->create_button("HELP","HELP","H");
777
778    aws->at("source");
779    awt_create_selection_list_on_ad(GLOBAL_gb_main,(AW_window *)aws, AWAR_TRANSPRO_SOURCE,"dna=:rna=");
780    aws->at("dest");
781    awt_create_selection_list_on_ad(GLOBAL_gb_main,(AW_window *)aws, AWAR_TRANSPRO_DEST,"pro=:ami=");
782
783    aws->at("realign");
784    aws->callback(transdna_event);
785    aws->highlight();
786    aws->create_button("REALIGN","REALIGN","T");
787
788    return (AW_window *)aws;
789}
790
791
792void create_transpro_menus(AW_window *awmm)
793{
794    awmm->insert_menu_topic("dna_2_pro",    "Translate Nucleic to Amino Acid ...","T","translate_dna_2_pro.hlp",        AWM_PRO,    AW_POPUP, (AW_CL)NT_create_dna_2_pro_window, 0 );
795    awmm->insert_menu_topic("realign_dna",  "Realign Nucleic Acid according to Aligned Protein ...","r","realign_dna.hlp",  AWM_PRO,    AW_POPUP, (AW_CL)NT_create_realign_dna_window, 0 );
796}
797
798void NT_create_transpro_variables(AW_root *root,AW_default db1)
799{
800    root->awar_string(AWAR_TRANSPRO_SOURCE, "",         db1);
801    root->awar_string(AWAR_TRANSPRO_DEST,   "",         db1);
802    root->awar_string(AWAR_TRANSPRO_MODE,   "settings", db1);
803    root->awar_int(AWAR_TRANSPRO_POS,    0, db1);
804    root->awar_int(AWAR_TRANSPRO_XSTART, 1, db1);
805    root->awar_int(AWAR_TRANSPRO_WRITE, 0, db1);
806}
Note: See TracBrowser for help on using the repository browser.