source: tags/cvs_2_svn/ARB_GDE/GDE_event.cxx

Last change on this file was 5197, checked in by westram, 16 years ago
  • use enum values instead of hardcoded ones
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.7 KB
Line 
1#include <unistd.h>
2#include <netdb.h>
3#include <sys/time.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9//#include <xview/xview.h>
10//#include <xview/panel.h>
11#include <arbdb.h>
12#include <arbdbt.h>
13// #include <malloc.h>
14#include <aw_root.hxx>
15#include <aw_device.hxx>
16#include <aw_window.hxx>
17#include <awt.hxx>
18#include <awt_tree.hxx>
19#include <awt_sel_boxes.hxx>
20#include <gde.hxx>
21#include "GDE_menu.h"
22#include "GDE_def.h"
23#include "GDE_extglob.h"
24#include "GDE_awars.h"
25
26#include <string>
27#include <set>
28
29using namespace std;
30
31#define DEFAULT_COLOR 8
32extern AW_CL agde_filtercd;
33
34/*
35  ReplaceArgs():
36  Replace all command line arguements with the appropriate values
37  stored for the chosen menu item.
38
39  Copyright (c) 1989-1990, University of Illinois board of trustees.  All
40  rights reserved.  Written by Steven Smith at the Center for Prokaryote Genome
41  Analysis.  Design and implementation guidance by Dr. Gary Olsen and Dr.
42  Carl Woese.
43
44  Copyright (c) 1990,1991,1992 Steven Smith at the Harvard Genome Laboratory.
45  All rights reserved.
46
47*/
48
49
50static char *ReplaceArgs(AW_root *awr,char *Action,AWwindowinfo *AWinfo,int number)
51{
52    /*
53     *  The basic idea is to replace all of the symbols in the method
54     *  string with the values picked in the dialog box.  The method
55     *  is the general command line structure.  All arguements have three
56     *  parts, a label, a method, and a value.  The method never changes, and
57     *  is used to represent '-flag's for a given function.  Values are the
58     *  associated arguements that some flags require.  All symbols that
59     *  require argvalue replacement should have a '$' infront of the symbol
60     *  name in the itemmethod definition.  All symbols without the '$' will
61     *  be replaced by their argmethod.  There is currently no way to do a label
62     *  replacement, as the label is considered to be for use in the dialog
63     *  box only.  An example command line replacement would be:
64     *
65     *       itemmethod=>        "lpr arg1 $arg1 $arg2"
66     *
67     *       arglabel arg1=>     "To printer?"
68     *       argmethod arg1=>    "-P"
69     *       argvalue arg1=>     "lw"
70     *
71     *       arglabel arg2=>     "File name?"
72     *       argvalue arg2=>     "foobar"
73     *       argmethod arg2=>    ""
74     *
75     *   final command line:
76     *
77     *       lpr -P lw foobar
78     *
79     *   At this point, the chooser dialog type only supports the arglabel and
80     *   argmethod field.  So if an argument is of type chooser, and
81     *   its symbol is "this", then "$this" has no real meaning in the
82     *   itemmethod definition.  Its format in the .GDEmenu file is slighty
83     *   different as well.  A choice from a chooser field looks like:
84     *
85     *       argchoice:Argument_label:Argument_method
86     *
87     *
88     */
89    const char *symbol=0;
90    char *method=0;
91    char *textvalue=0;
92    char *temp;
93    int i,newlen,type;
94    symbol = AWinfo->gmenuitem->arg[number].symbol;
95    //method = AWinfo->gmenuitem->arg[number]->method;
96    //textvalue = AWinfo->gmenuitem->arg[number]->textvalue;
97    type = AWinfo->gmenuitem->arg[number].type;
98    if( (type == SLIDER) )
99    {
100        char *awarname = GDE_makeawarname(AWinfo,number);
101        textvalue      = (char*)malloc(GBUFSIZ);
102        char *awalue   = awr->awar(awarname)->read_as_string();
103        sprintf(textvalue,"%s",awalue);
104        free(awalue);
105    }
106    else if((type == CHOOSER) ||
107            (type == CHOICE_TREE) ||
108            (type == CHOICE_SAI) ||
109            (type == CHOICE_MENU) ||
110            (type == CHOICE_LIST) ||
111            (type == CHOICE_WEIGHTS) ||
112            (type == TEXTFIELD))
113    {
114        char *awarname=GDE_makeawarname(AWinfo,number);
115        method=awr->awar(awarname)->read_string();
116        textvalue=awr->awar(awarname)->read_string();
117    }
118
119    if(textvalue == NULL)   textvalue=(char *)calloc(1,sizeof(char));
120    if(method == NULL)      method=(char *)calloc(1,sizeof(char));
121    if(symbol == NULL)      symbol="";
122
123    set<string>warned_about;
124    int conversion_warning        = 0;
125    int j                         = 0;
126
127    for(; (i=Find2(Action+j,symbol)) != -1;)
128    {
129        i += j;
130        ++j;
131        if(i>0 && Action[i-1] == '$' )
132        {
133            newlen = strlen(Action)-strlen(symbol)
134                +strlen(textvalue);
135            temp = (char *)calloc(newlen,1);
136            if (temp == NULL)
137                Error("ReplaceArgs():Error in calloc");
138            strncat(temp,Action,i-1);
139            strncat(temp,textvalue,strlen(textvalue));
140            strcat( temp,&(Action[i+strlen(symbol)]) );
141            free(Action);
142            Action = temp;
143        }
144        else
145        {
146            if (warned_about.find(symbol) == warned_about.end()) {
147                fprintf(stderr,
148                        "old arb version converted '%s' to '%s' (now only '$%s' is converted)\n",
149                        symbol, textvalue, symbol);
150                conversion_warning++;
151                warned_about.insert(symbol);
152            }
153            //             newlen = strlen(Action)-strlen(symbol)
154            //                 +strlen(method)+1;
155            //             temp   = (char *)calloc(newlen,1);
156            //             if (temp == NULL)
157            //                 Error("ReplaceArgs():Error in calloc");
158            //             strncat(temp,Action,i);
159            //             strncat(temp,method,strlen(method));
160            //             strcat( temp,&(Action[i+strlen(symbol)]) );
161            //             free(Action);
162            //             Action = temp;
163        }
164    }
165
166    if (conversion_warning) {
167        fprintf(stderr,
168                "Conversion warnings occurred in Action:\n'%s'\n",
169                Action);
170    }
171
172    free(textvalue);
173    free(method);
174    return(Action);
175}
176
177
178
179static long LMAX(long a,long b)
180{
181    if(a>b) return a;
182    return b;
183}
184
185static void GDE_free(void **p)
186{
187    if(*p!=0)
188    {
189        //delete *p;
190        free(*p);
191        *p=0;
192    }
193}
194
195/*void GDE_freemask(GMask *mask)
196  {
197  if(mask==0) return;
198  GDE_free((void**)&mask->name);
199  for(long i=0;i<mask->listlen;i++)
200  {
201  NumList numl=mask->list[i];
202  GDE_free((void**)&numl.valu);
203  }
204  GDE_free((void**)&mask->list);
205  }*/
206
207static char *ReplaceFile(char *Action,GfileFormat file)
208{
209    char *symbol,*method,*temp;
210    int i,newlen;
211    symbol = file.symbol;
212    method = file.name;
213
214    for(; (i=Find2(Action,symbol)) != -1;)
215    {
216        newlen = strlen(Action)-strlen(symbol) + strlen(method)+1;
217        temp = (char *)calloc(newlen,1);
218        if (temp == NULL)
219            Error("ReplaceFile():Error in calloc");
220        strncat(temp,Action,i);
221        strncat(temp,method,strlen(method));
222        strcat( temp,&(Action[i+strlen(symbol)]) );
223        free(Action);
224        Action = temp;
225    }
226    return(Action);
227}
228
229static char *ReplaceString(char *Action,const char *old,const char *news)
230{
231    const char *symbol;
232    const char *method;
233    char *temp;
234    int i,newlen;
235
236    symbol = old;
237    method = news;
238
239    for(; (i=Find2(Action,symbol)) != -1;)
240    {
241        newlen = strlen(Action)-strlen(symbol) + strlen(method)+1;
242        temp = (char *)calloc(newlen,1);
243        if (temp == NULL)
244            Error("ReplaceFile():Error in calloc");
245        strncat(temp,Action,i);
246        strncat(temp,method,strlen(method));
247        strcat( temp,&(Action[i+strlen(symbol)]) );
248        free(Action);
249        Action = temp;
250    }
251    return(Action);
252}
253
254
255static void GDE_freesequ(NA_Sequence *sequ)
256{
257    if(sequ==0) return;
258    GDE_free((void**)&sequ->comments);
259    /* GDE_free((void**)&sequ->col_lut);    OLIVER STRUNK       */
260    GDE_free((void**)&sequ->cmask);
261    /*GDE_freemask(sequ->mask);*/
262    GDE_free((void**)&sequ->baggage);
263    GDE_free((void**)&sequ->sequence);
264    /*if(sequ->groupf)
265      {
266      GDE_freesequ(sequ->groupf);
267      GDE_free((void**)&sequ->groupf);
268      }*/
269}
270
271static void GDE_freeali(NA_Alignment *dataset)
272{
273    if(dataset==0) return;
274    GDE_free((void**)&dataset->id);
275    GDE_free((void**)&dataset->description);
276    GDE_free((void**)&dataset->authority);
277    GDE_free((void**)&dataset->cmask);
278    GDE_free((void**)&dataset->selection_mask);
279    GDE_free((void**)&dataset->alignment_name);
280
281    /* maybe not correct:
282       GMask *mask=dataset->mask;
283       GDE_freemask(dataset->mask);
284       GDE_free((void**)&dataset->mask);*/
285
286    unsigned long i;
287    // **maybe not correct:
288    //NA_Sequence **group=dataset->group;
289    //for(long i=0;i<dataset->numgroups;i++)
290    //  GDE_freesequ(dataset->group[i]);
291    //GDE_free((void**)&dataset->group);
292    // **correction: this was not correct
293
294    for(i=0;i<dataset->numelements;i++)
295        GDE_freesequ(&(dataset->element[i]));
296}
297
298static void GDE_export(NA_Alignment *dataset,char *align,long oldnumelements)
299{
300    GB_begin_transaction(GLOBAL_gb_main);
301    long maxalignlen=GBT_get_alignment_len(GLOBAL_gb_main,align);
302    long isdefaultalign=0;
303    int load_all = 0;
304    if(maxalignlen<=0)
305    {
306        align=GBT_get_default_alignment(GLOBAL_gb_main);
307        isdefaultalign=1;
308    }
309
310    maxalignlen=GBT_get_alignment_len(GLOBAL_gb_main,align);
311    long lotyp=0;
312    {
313        GB_alignment_type at = GBT_get_alignment_type(GLOBAL_gb_main, align);
314
315        switch (at)
316        {
317            case GB_AT_DNA: lotyp = DNA; break;
318            case GB_AT_RNA: lotyp = RNA; break;
319            case GB_AT_AA:  lotyp = PROTEIN; break;
320            case GB_AT_UNKNOWN: lotyp = DNA; break;
321        }
322    }
323
324    GB_ERROR error = 0;
325    unsigned long i;
326    for(i=oldnumelements;!error && i<dataset->numelements;i++)
327    {
328        NA_Sequence *sequ=&(dataset->element[i]);
329        int seqtyp,issame=0;
330        seqtyp=sequ->elementtype;
331        if( (seqtyp==lotyp)||((seqtyp==DNA)&&(lotyp==RNA))||((seqtyp==RNA)&&(lotyp==DNA)) ){
332            issame=1;
333        }else{
334            aw_message(GBS_global_string("Warning: sequence type of species '%s' changed",sequ->short_name));
335        }
336
337        if(sequ->tmatrix) {
338            for(long j=0;j<sequ->seqlen;j++) {
339                sequ->sequence[j] = (char)sequ->tmatrix[sequ->sequence[j]];
340            }
341        }
342
343        char *savename   = GBS_string_2_key(sequ->short_name);
344        sequ->gb_species = 0;
345       
346        if (!issame)            /* save as extended */
347        {
348
349            GBDATA *gb_extended =   GBT_create_SAI(GLOBAL_gb_main,savename);
350            sequ->gb_species=gb_extended;
351            GBDATA *gb_data = GBT_add_data(gb_extended, align,"data", GB_STRING);
352            error = GBT_write_sequence(gb_data,align,maxalignlen,(char *)sequ->sequence);
353        }
354        else /* save as sequence */
355        {
356            GBDATA *gb_species_data = GB_search(GLOBAL_gb_main,"species_data",GB_CREATE_CONTAINER);
357            GBDATA *gb_species;
358            gb_species = GBT_find_species_rel_species_data(gb_species_data, savename);
359            GB_push_my_security(GLOBAL_gb_main);
360
361            if (gb_species) {   /* new element that already exists !!!!*/
362                int select_mode;
363                const char *msg = GBS_global_string(
364                                                    "You are (re-)importing a species '%s'.\n"
365                                                    "That species already exists in your database!\n"
366                                                    "\n"
367                                                    "Possible actions:\n"
368                                                    "\n"
369                                                    "       - delete and overwrite the existing species\n"
370                                                    "       - skip - don't change the species\n"
371                                                    "       - reimport only the sequence of the existing species\n"
372                                                    "       - reimport all sequences (don't ask again)\n"
373                                                    "\n"
374                                                    "Note: After aligning it's recommended to choose 'reimport all'.",
375                                                    savename);
376                if (!load_all) {
377                    select_mode = aw_message(msg,
378                                             "delete existing," // 0
379                                             "skip," // 1
380                                             "reimport sequence," // 2
381                                             "reimport all" // 3
382                                             );
383
384                    if (select_mode == 3) { // load all sequences
385                        load_all = 1;
386                    }
387                }
388
389                if (load_all) {
390                    select_mode = 2; // reimport sequence
391                }
392
393                gde_assert(select_mode >= 0 && select_mode <= 2);
394
395                switch(select_mode) {
396                    case 1:     // skip
397                        gb_species = 0;
398                        continue; // continue with next species
399
400                    case 0:     // delete existing species
401                        GB_delete(gb_species);
402                        // fall-through!
403                    case 2:     // reimport sequence
404                        gb_species = GBT_create_species_rel_species_data(gb_species_data, savename);
405                        break;
406                }
407            }
408            else {
409                gb_species = GBT_create_species_rel_species_data(gb_species_data, savename);
410            }
411            if (!gb_species) continue;
412            sequ->gb_species = gb_species;
413
414            GBDATA *gb_old_data = GBT_read_sequence(gb_species, align);
415            GBDATA *gb_data     = GBT_add_data(gb_species, align,"data", GB_STRING);
416
417            if (gb_old_data) { // we already have data -> compare checksums
418                const char *old_seq      = GB_read_char_pntr(gb_old_data);
419                long        old_checksum = GBS_checksum(old_seq, 1, "-.");
420                long        new_checksum = GBS_checksum((char*)sequ->sequence, 1, "-.");
421
422                if (old_checksum != new_checksum) {
423                    aw_message(GBS_global_string("Warning: Sequence checksum for '%s' differs", savename));
424                }
425            }
426
427            error = GBT_write_sequence(gb_data,align,maxalignlen,(char *)sequ->sequence);
428            GB_pop_my_security(GLOBAL_gb_main);
429
430        }
431        free(savename);
432    }
433
434    /* colormasks */
435    for(i=0;!error && i<dataset->numelements;i++)
436    {
437        NA_Sequence *sequ=&(dataset->element[i]);
438        if(sequ->cmask)
439        {
440            GBDATA *gb_color;
441            maxalignlen=LMAX(maxalignlen,sequ->seqlen);
442            char *resstring=(char *)calloc((unsigned int)maxalignlen+1,sizeof(char));
443
444            char *dummy=resstring;
445            for(long j=0;j<maxalignlen-sequ->seqlen;j++)
446                *resstring++=DEFAULT_COLOR;
447
448            for(long k=0;k<sequ->seqlen;k++)
449                *resstring++=(char)sequ->cmask[i];
450            *resstring='\0';
451
452            GBDATA *gb_ali=GB_search(sequ->gb_species,
453                                     align,GB_CREATE_CONTAINER);
454            gb_color=GB_search(gb_ali,"colmask",GB_BYTES);
455            error = GB_write_bytes(gb_color,dummy,maxalignlen);
456            delete dummy;
457
458        }
459    }
460    if(!error && dataset->cmask)
461    {
462        GBDATA *gb_color;
463        maxalignlen=LMAX(maxalignlen,dataset->cmask_len);
464        char *resstring=(char *)calloc((unsigned int)maxalignlen+1,sizeof(char));
465
466        char *dummy=resstring;
467        long k;
468        for(k=0;k<maxalignlen-dataset->cmask_len;k++)
469            *resstring++=DEFAULT_COLOR;
470
471        for(k=0;k<dataset->cmask_len;k++)
472            *resstring++=(char)dataset->cmask[k];
473        *resstring='\0';
474
475
476        GBDATA *gb_extended =   GBT_create_SAI(GLOBAL_gb_main,"COLMASK");
477        gb_color = GBT_add_data(gb_extended, align,"colmask", GB_BYTES);
478        error = GB_write_bytes(gb_color,dummy,maxalignlen);
479
480        delete dummy;
481    }
482    if (error) {
483        GB_abort_transaction(GLOBAL_gb_main);
484        aw_message(error);
485    }else{
486        GB_commit_transaction(GLOBAL_gb_main);
487    }
488    if(isdefaultalign) delete align;
489}
490
491void GDE_startaction_cb(AW_window *aw,AWwindowinfo *AWinfo,AW_CL cd)
492{
493    long oldnumelements=0;
494    AWUSE(cd);
495    AW_root *aw_root=aw->get_root();
496
497    GapCompression  compress          = static_cast<GapCompression>(aw_root->awar(AWAR_GDE_COMPRESSION)->read_int());
498    AP_filter      *filter2           = awt_get_filter(aw_root,agde_filtercd);
499    char           *filter_name       = 0; /* aw_root->awar(AWAR_GDE_FILTER_NAME)->read_string() */
500    char           *alignment_name    = strdup("ali_unknown");
501    bool            marked            = (aw_root->awar(AWAR_GDE_SPECIES)->read_int() != 0);
502    long            cutoff_stop_codon = aw_root->awar(AWAR_GDE_CUTOFF_STOPCODON)->read_int();
503
504    GmenuItem *current_item;
505    current_item=AWinfo->gmenuitem;
506
507    aw_openstatus(current_item->label);
508    aw_status((double)0);
509
510    int i,j,k,flag,select_mode =0;
511    static int fileindx = 0;
512    char *Action,buffer[GBUFSIZ];
513    i=0;k=0;
514    if (current_item->numinputs>0) {
515        DataSet->gb_main = GLOBAL_gb_main;
516        GB_begin_transaction(DataSet->gb_main);
517        delete DataSet->alignment_name;
518        DataSet->alignment_name = GBT_get_default_alignment(DataSet->gb_main);
519        free(alignment_name);
520        alignment_name = strdup(DataSet->alignment_name);
521
522        aw_status("reading database");
523        int stop;
524        if (gde_cgss.get_sequences) {
525            stop = ReadArbdb2(DataSet, filter2, compress, cutoff_stop_codon);
526        }
527        else {
528            stop = ReadArbdb(DataSet, marked, filter2, compress, cutoff_stop_codon);
529        }
530        GB_commit_transaction(DataSet->gb_main);
531
532        if(stop) goto startaction_end;
533
534        if (DataSet->numelements==0) {
535            aw_message("no sequences selected");
536            goto startaction_end;
537        }
538    }
539
540    flag = AW_FALSE;
541    for(j=0;j<current_item->numinputs;j++) {
542        if(current_item->input[j].format != STATUS_FILE) {
543            flag = AW_TRUE;
544        }
545    }
546    if(flag && DataSet) select_mode = ALL; //TestSelection();
547
548    //chdir(current_dir);
549    for(j=0;j<current_item->numinputs;j++) {
550        sprintf(buffer,"/tmp/gde%d_%d",(int)getpid(),fileindx++);
551        current_item->input[j].name = String(buffer);
552        switch(current_item->input[j].format) {
553            case COLORMASK:     WriteCMask(DataSet,buffer,select_mode, current_item->input[j].maskable); break;
554            case GENBANK:       WriteGen(DataSet,buffer,select_mode, current_item->input[j].maskable); break;
555            case NA_FLAT:       WriteNA_Flat(DataSet,buffer,select_mode, current_item->input[j].maskable); break;
556            case STATUS_FILE:   WriteStatus(DataSet,buffer,select_mode); break;
557            case GDE:           WriteGDE(DataSet,buffer,select_mode, current_item->input[j].maskable); break;
558            default: break;
559        }
560    }
561
562    for(j=0;j<current_item->numoutputs;j++)
563    {
564        sprintf(buffer,"/tmp/gde%d_%d",(int)getpid(),fileindx++);
565        current_item->output[j].name = String(buffer);
566    }
567
568    /*
569     *  Create the command line for external the function call
570     */
571    Action = (char*)strdup(current_item->method);
572    if(Action == NULL) Error("DO(): Error in duplicating method string");
573
574    while (1) {
575        char *oldAction = strdup(Action);
576
577        for(j=0;j<current_item->numargs;j++) Action = ReplaceArgs(aw_root,Action,AWinfo,j);
578        bool changed = strcmp(oldAction, Action) != 0;
579        free(oldAction);
580
581        if (!changed) break;
582    }
583
584    for(j=0;j<current_item->numinputs;j++) Action = ReplaceFile(Action,current_item->input[j]);
585    for(j=0;j<current_item->numoutputs;j++) Action = ReplaceFile(Action,current_item->output[j]);
586
587    filter_name = AWT_get_combined_filter_name(aw_root, "gde");
588    Action = ReplaceString(Action,"$FILTER",filter_name);
589
590    /*
591     *  call and go...
592     */
593
594    aw_status("calling external program");
595    printf("Action: %s\n",Action);
596    system(Action);
597    free(Action);
598
599    oldnumelements=DataSet->numelements;
600
601    BlockInput = AW_FALSE;
602
603    for(j=0;j<current_item->numoutputs;j++)
604    {
605        if(current_item->output[j].overwrite)
606        {
607            if(current_item->output[j].format == GDE)
608                OVERWRITE = AW_TRUE;
609            else
610                Warning("Overwrite mode only available for GDE format");
611        }
612        switch(current_item->output[j].format)
613        {
614            /*
615             *     The LoadData routine must be reworked so that
616             *     OpenFileName uses it, and so I can remove the
617             *     major kluge in OpenFileName().
618             */
619            case GENBANK:
620            case NA_FLAT:
621            case GDE:
622                /*ARB-change:*/
623                /*OpenFileName(current_item->output[j].name,NULL);*/
624                LoadData(current_item->output[j].name);
625                break;
626            case COLORMASK:
627                ReadCMask(current_item->output[j].name);
628                break;
629            case STATUS_FILE:
630                ReadStatus(current_item->output[j].name);
631                break;
632            default:
633                break;
634        }
635        OVERWRITE = AW_FALSE;
636    }
637    for(j=0;j<current_item->numoutputs;j++)
638    {
639        if(!current_item->output[j].save)
640        {
641            unlink(current_item->output[j].name);
642        }
643    }
644
645    for(j=0;j<current_item->numinputs;j++)
646    {
647        if(!current_item->input[j].save)
648        {
649            unlink(current_item->input[j].name);
650        }
651    }
652
653    aw_closestatus();
654    GDE_export(DataSet,alignment_name,oldnumelements);
655
656 startaction_end:
657    aw_closestatus();
658    free(alignment_name);
659    delete filter2;
660    free(filter_name);
661
662    GDE_freeali(DataSet);
663    free(DataSet);
664    DataSet=0;
665    DataSet = (NA_Alignment *) Calloc(1,sizeof(NA_Alignment));
666    DataSet->rel_offset = 0;
667
668    //     aw->hide();
669}
670
Note: See TracBrowser for help on using the repository browser.