source: tags/arb_5.0/MERGE/MG_species.cxx

Last change on this file was 6100, checked in by westram, 15 years ago
  • fix warning "format not a string literal and no format arguments"
    • GB_export_error → GB_export_error/GB_export_errorf
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 50.1 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <arbdb.h>
5#include <arbdbt.h>
6#include <aw_root.hxx>
7#include <aw_device.hxx>
8#include <aw_window.hxx>
9#include <aw_awars.hxx>
10#include <AW_rename.hxx>
11#include <awt.hxx>
12#include <awt_item_sel_list.hxx>
13#include <awt_sel_boxes.hxx>
14#include <db_scanner.hxx>
15#include "merge.hxx"
16#include <inline.h>
17#include <GEN.hxx>
18
19
20#define AWAR1 "tmp/merge1/"
21#define AWAR2 "tmp/merge2/"
22#define AWAR_SPECIES1 AWAR1"name"
23#define AWAR_SPECIES2 AWAR2"name"
24
25#define AWAR_SPECIES1_DEST AWAR1"dest"
26#define AWAR_SPECIES2_DEST AWAR2"dest"
27#define AWAR_FIELD1 AWAR1"field"
28#define AWAR_FIELD2 AWAR2"field"
29
30#define AWAR_TAG1 AWAR1"tag"
31#define AWAR_TAG2 AWAR2"tag"
32
33#define AWAR_TAG_DEL1 AWAR1"tagdel"
34
35#define AWAR_APPEND AWAR2"append"
36
37static AW_CL ad_global_scannerid1 = 0;
38static AW_CL ad_global_scannerid2 = 0;
39
40const char *MG_left_AWAR_SPECIES_NAME() { return AWAR_SPECIES1; }
41const char *MG_right_AWAR_SPECIES_NAME() { return AWAR_SPECIES2; }
42
43MG_remap::MG_remap(){
44    in_length = 0;
45    out_length = 0;
46    remap_tab = 0;
47    soft_remap_tab = 0;
48    compiled = 0;
49}
50
51MG_remap::~MG_remap(){
52    delete [] remap_tab;
53    delete [] soft_remap_tab;
54}
55
56GB_ERROR MG_remap::set(const char *in_reference, const char *out_reference){
57    if (compiled){
58        GB_internal_error("Cannot set remap structure after being compiled");
59        return 0;
60    }
61
62    if (!remap_tab){
63        in_length = strlen(in_reference);
64        out_length = strlen(out_reference);
65        remap_tab = new int[in_length];
66        int i;
67        for (i=0;i<in_length;i++){
68            remap_tab[i] = -1;
69        }
70    }else{
71        int inl = strlen (in_reference);
72        if (inl > in_length){
73            int *new_remap = new int[inl];
74            int i;
75            for (i=0;i<in_length;i++){
76                new_remap[i] = remap_tab[i];
77            }
78            for (;i<inl;i++){
79                new_remap[i] = -1;
80            }
81        }
82        in_length = inl;
83    }
84    {
85        int nol = strlen(out_reference);
86        if (nol> out_length){
87            out_length = nol;
88        }
89    }
90    int *nremap_tab = new int[in_length];
91    {
92        for (int i = 0;i< in_length;i++){
93            nremap_tab[i] = -1;
94        }
95    }
96    {               // write new map to undefined positions
97        const char *spacers = "-. n";
98        int ipos = 0;
99        int opos = 0;
100        while (ipos < in_length && opos < out_length){
101            while (strchr(spacers,in_reference[ipos])){
102                ipos++; // search next in base
103                if (ipos >= in_length ) goto end_of_new_map;
104            }
105            while (strchr(spacers,out_reference[opos])){
106                opos++; // search next in base
107                if (opos >= out_length) goto end_of_new_map;
108            }
109            nremap_tab[ipos] = opos;
110            ipos++;
111            opos++; // jump to next base
112        }
113    end_of_new_map:;
114    }
115    {               // check forward consistency of new map
116        int ipos = 0;
117        int opos = 0;
118        for (ipos=0;ipos < in_length;ipos++){
119            if (remap_tab[ipos] > opos){
120                opos = remap_tab[ipos];
121            }
122            if (nremap_tab[ipos] >=0 && nremap_tab[ipos] < opos){ // consistency error
123                nremap_tab[ipos] = -1; // sorry, not useable
124            }
125        }
126    }
127    {               // check backward consistency of new map
128        int ipos;
129        int opos = out_length-1;
130        for (ipos = in_length-1;ipos>=0;ipos--){
131            if (remap_tab[ipos] >=0 && remap_tab[ipos] < opos){
132                opos = remap_tab[ipos];
133            }
134            if (nremap_tab[ipos] > opos){
135                nremap_tab[ipos] = -1;
136            }
137        }
138    }
139    {               // merge maps
140        for (int pos=0;pos<in_length;pos++){
141            if (remap_tab[pos] == -1){
142                if (nremap_tab[pos] >=0){
143                    remap_tab[pos] = nremap_tab[pos];
144                }
145            }
146        }
147    }
148    delete nremap_tab;
149    return NULL;
150}
151
152GB_ERROR MG_remap::compile(){
153    if (compiled){
154        return 0;
155    }
156    compiled = 1;
157    int in_pos;
158    soft_remap_tab = new int[in_length];
159
160    int last_mapped_position_source = 0;
161    int last_mapped_position_dest = 0;
162    for (in_pos=0;in_pos<in_length;in_pos++){
163        soft_remap_tab[in_pos] = -1;
164    }
165
166    for (in_pos=0;in_pos<in_length;in_pos++){
167        int new_dest;
168
169        if ((new_dest = remap_tab[in_pos]) <0){
170            continue;
171        }
172        {   // fill areas between
173            int source;
174            int dest;
175            int dsource = in_pos - last_mapped_position_source;
176            int ddest = new_dest - last_mapped_position_dest;
177
178            for (source = last_mapped_position_source, dest = last_mapped_position_dest;
179                 source <= last_mapped_position_source + (dsource>1) &&
180                     dest <= last_mapped_position_dest + (ddest>1);
181                 source++,dest++){
182                soft_remap_tab[source] = dest;
183            }
184            for (source = in_pos, dest = new_dest;
185                 source > last_mapped_position_source + (dsource>1) &&
186                     dest > last_mapped_position_dest + (ddest>1);
187                 source--,dest--){
188                soft_remap_tab[source] = dest;
189            }
190        }
191        last_mapped_position_source = in_pos;
192        last_mapped_position_dest = new_dest;
193    }
194    return 0;
195}
196
197char *MG_remap::remap(const char *sequence){
198    const char *gap_chars = "- .";
199    int slen = strlen(sequence);
200    int len = slen;
201    GBS_strstruct *outs = GBS_stropen(slen- in_length + out_length + 100);
202
203    if (in_length < len) {
204        len = in_length;
205    }
206    int lastposset = 0;     // last position written
207    int lastposread = 0;    // last position that is read and written
208    int skippedgaps = 0;    // number of gaps not written
209    int skippedchar = '.';  // last gap character not written
210
211    GB_BOOL within_sequence = GB_FALSE;
212    int i;
213    for (i=0;i<len;i++){
214        int c = sequence[i];
215        if (c == '.' || c == '-'){ // dont write gaps, maybe we have to compress the alignment
216            skippedchar = c;
217            skippedgaps ++;
218            continue;
219        }
220        lastposread = i;
221        int new_pos = this->remap_tab[i];
222        if (new_pos<0){     // no remap, try soft remap
223            new_pos = soft_remap_tab[i];
224        }
225        if (new_pos >=0){   // if found a map than force map
226            while (lastposset < new_pos){ // insert gaps
227                if (within_sequence){
228                    GBS_chrcat(outs,'-');
229                }else{
230                    GBS_chrcat(outs,'.');
231                }
232                lastposset ++;
233            }
234        }else{          // insert not written gaps
235            while(skippedgaps>0){
236                GBS_chrcat(outs,skippedchar);
237                lastposset ++;
238                skippedgaps--;
239            }
240        }
241        skippedgaps = 0;
242        if (c != '.') {
243            within_sequence = GB_TRUE;
244        }else{
245            within_sequence = GB_FALSE;
246        }
247        GBS_chrcat(outs,c);
248        lastposset++;
249    }
250    for (i = lastposread+1;i < slen;i++){   // fill overlength rest of sequence
251        int c = sequence[i];
252        if (strchr(gap_chars,c)) continue; // dont fill with gaps
253        GBS_chrcat(outs,c);
254    }
255    return GBS_strclose(outs);
256}
257
258void MG_create_species_awars(AW_root *aw_root, AW_default aw_def)
259{
260    aw_root->awar_string( AWAR_SPECIES1, "" ,   aw_def);
261    aw_root->awar_string( AWAR_SPECIES2, "" ,   aw_def);
262    aw_root->awar_string( AWAR_SPECIES1_DEST, "" ,  aw_def);
263    aw_root->awar_string( AWAR_SPECIES2_DEST, "" ,  aw_def);
264    aw_root->awar_string( AWAR_FIELD1, "" , aw_def);
265    aw_root->awar_int( AWAR_APPEND );
266}
267
268
269void AD_map_species1(AW_root *aw_root)
270{
271    GB_push_transaction(GLOBAL_gb_merge);
272    char   *source     = aw_root->awar(AWAR_SPECIES1)->read_string();
273    GBDATA *gb_species = GBT_find_species(GLOBAL_gb_merge,source);
274
275    if (gb_species) awt_map_arbdb_scanner(ad_global_scannerid1,gb_species,0, CHANGE_KEY_PATH);
276    GB_pop_transaction(GLOBAL_gb_merge);
277    delete source;
278}
279
280void AD_map_species2(AW_root *aw_root)
281{
282    char *source = aw_root->awar(AWAR_SPECIES2)->read_string();
283    GB_push_transaction(GLOBAL_gb_dest);
284    GBDATA *gb_species = GBT_find_species(GLOBAL_gb_dest,source);
285    if (gb_species) {
286        awt_map_arbdb_scanner(ad_global_scannerid2,gb_species,0, CHANGE_KEY_PATH);
287    }
288    GB_pop_transaction(GLOBAL_gb_dest);
289    delete source;
290}
291
292static GB_ERROR MG_transfer_fields_info(char *fieldname = NULL) {
293    GBDATA   *gb_key_data = GB_search(GLOBAL_gb_merge, CHANGE_KEY_PATH, GB_CREATE_CONTAINER);
294    GB_ERROR  error       = 0;
295
296    if (!gb_key_data) error = GB_await_error();
297    else {
298        if (!GB_search(GLOBAL_gb_dest, CHANGE_KEY_PATH, GB_CREATE_CONTAINER)) error = GB_await_error();
299        else {
300            for (GBDATA *gb_key = GB_entry(gb_key_data,CHANGEKEY);
301                 gb_key && !error;
302                 gb_key = GB_nextEntry(gb_key))
303            {
304                GBDATA *gb_key_name = GB_entry(gb_key, CHANGEKEY_NAME);
305                if (gb_key_name) {
306                    GBDATA *gb_key_type = GB_entry(gb_key, CHANGEKEY_TYPE);
307                    if (gb_key_type) {
308                        char *name = GB_read_string(gb_key_name);
309
310                        if (!fieldname || strcmp(fieldname,name) == 0) {
311                            error = GBT_add_new_changekey(GLOBAL_gb_dest,name,(int)GB_read_int(gb_key_type));
312                        }
313                        free(name);
314                    }
315                }
316            }
317        }
318    }
319    return error;
320}
321
322MG_remap *MG_create_remap(GBDATA *gb_left, GBDATA *gb_right, const char *reference_species_names, const char *alignment_name){
323    char *tok;
324    MG_remap *rem = new MG_remap();
325    char *ref_list = strdup(reference_species_names);
326    for (tok = strtok(ref_list," \n,;");tok;tok = strtok(NULL," \n,;")){
327        bool    is_SAI           = strncmp(tok, "SAI:", 4) == 0;
328        GBDATA *gb_species_left  = 0;
329        GBDATA *gb_species_right = 0;
330
331        if (is_SAI) {
332            gb_species_left  = GBT_find_SAI(gb_left, tok+4);
333            gb_species_right = GBT_find_SAI(gb_right, tok+4);
334        }
335        else {
336            gb_species_left  = GBT_find_species(gb_left,tok);
337            gb_species_right = GBT_find_species(gb_right,tok);
338        }
339
340        if (!gb_species_left || !gb_species_right) {
341            aw_message(GBS_global_string("Warning: Couldn't find %s'%s' in %s DB.\nPlease read ADAPT ALIGNMENT section in help file!",
342                                         is_SAI ? "" : "species ",
343                                         tok,
344                                         gb_species_left ? "right" : "left"));
345            continue;
346        }
347
348        // look for sequence/SAI "data"
349        GBDATA *gb_seq_left  = GBT_read_sequence(gb_species_left,alignment_name);
350        if (!gb_seq_left) continue;
351        GBDATA *gb_seq_right = GBT_read_sequence(gb_species_right,alignment_name);
352        if (!gb_seq_right) continue;
353
354        GB_TYPES type_left  = GB_read_type(gb_seq_left);
355        GB_TYPES type_right = GB_read_type(gb_seq_right);
356
357        if (type_left != type_right) {
358            aw_message(GBS_global_string("Warning: data type of '%s' differs in both databases", tok));
359            continue;
360        }
361
362        if (type_right == GB_STRING) {
363            rem->set(GB_read_char_pntr(gb_seq_left), GB_read_char_pntr(gb_seq_right));
364        }
365        else {
366            char *sleft  = GB_read_as_string(gb_seq_left);
367            char *sright = GB_read_as_string(gb_seq_right);
368            rem->set(sleft,sright);
369            free(sleft);
370            free(sright);
371        }
372    }
373    rem->compile();
374    delete ref_list;
375    return rem;
376}
377
378MG_remaps::MG_remaps(GBDATA *gb_left,GBDATA *gb_right,AW_root *awr){
379    memset((char *)this,0,sizeof(*this));
380    int ref_enable = awr->awar(AWAR_REMAP_ENABLE)->read_int();
381    if (!ref_enable) return;
382
383    char *reference_species_names = awr->awar(AWAR_REMAP_SPECIES_LIST)->read_string();
384    this->alignment_names = GBT_get_alignment_names(gb_left);
385    for (n_remaps = 0;alignment_names[n_remaps];n_remaps++) ;
386    this->remaps = (MG_remap **)GB_calloc(sizeof(MG_remap *),n_remaps);
387    int i;
388    for (i=0;i<n_remaps;i++){
389        this->remaps[i] = MG_create_remap(gb_left,gb_right,reference_species_names,alignment_names[i]);
390    }
391    delete reference_species_names;
392}
393
394MG_remaps::~MG_remaps(){
395    int i;
396    for (i=0;i<n_remaps;i++){
397        delete remaps[i];
398        delete alignment_names[i];
399    }
400    delete alignment_names;
401    delete remaps;
402}
403
404GB_ERROR MG_transfer_sequence(MG_remap *remap, GBDATA *source_species, GBDATA *destination_species,const char *alignment_name) {
405    // align sequence after copy
406    GB_ERROR error = 0;
407
408    if (remap) {                                    // shall remap?
409        GBDATA *gb_seq_left  = GBT_read_sequence(source_species,      alignment_name);
410        GBDATA *gb_seq_right = GBT_read_sequence(destination_species, alignment_name);
411
412        if (gb_seq_left && gb_seq_right) {          // if one DB hasn't sequence -> sequence was not copied
413            char *ls = GB_read_string(gb_seq_left);
414            char *rs = GB_read_string(gb_seq_right);
415
416            if (strcmp(ls, rs) == 0) {              // if sequences are not identical -> sequence was not copied
417                free(rs);
418                rs = remap->remap(ls);
419
420                if (!rs) error = GB_await_error();
421                else {
422                    long old_check = GBS_checksum(ls, 0, ".- ");
423                    long new_check = GBS_checksum(rs, 0, ".- ");
424
425                    if (old_check == new_check) error = GB_write_string(gb_seq_right, rs);
426                    else error                        = GB_export_error("Error in aligning sequences (checksum changed)");
427                }
428            }
429            free(rs);
430            free(ls);
431        }
432    }
433    return error;
434}
435
436GB_ERROR MG_transfer_sequence(MG_remaps *remaps, GBDATA *source_species, GBDATA *destination_species){
437    int i;
438    GB_ERROR error = 0;
439    if (!remaps->remaps) return NULL; // not remapped
440    for (i=0;i<remaps->n_remaps;i++){
441        error = MG_transfer_sequence(remaps->remaps[i],source_species,destination_species,remaps->alignment_names[i]);
442        if (error) break;
443    }
444    return error;
445}
446
447
448static GB_ERROR MG_transfer_one_species(AW_root *aw_root, MG_remaps& remap, 
449                                        GBDATA *gb_species_data1, GBDATA *gb_species_data2,
450                                        bool is_genome_db1, bool is_genome_db2, 
451                                        GBDATA  *gb_species1, const char *name1,
452                                        GB_HASH *source_organism_hash, GB_HASH *dest_species_hash,
453                                        GB_HASH *error_suppressor)
454{
455    // copies one species from source to destination DB
456    //
457    // either 'gb_species1' or 'name1' (and 'gb_species_data1') has to be given
458    // 'source_organism_hash' may be NULL, otherwise it's used to search for source organisms (when merging from genome DB)
459    // 'dest_species_hash' may be NULL, otherwise created species is stored there
460
461    GB_ERROR error = 0;
462    if (gb_species1) {
463        name1 = GBT_read_name(gb_species1);
464    }
465    else {
466        mg_assert(name1);
467        gb_species1 = GBT_find_species_rel_species_data(gb_species_data1, name1);
468        if (!gb_species1) {
469            error = GBS_global_string("Could not find species '%s'", name1);
470        }
471    }
472
473    bool transfer_fields = false;
474    if (is_genome_db1) {
475        if (is_genome_db2) { // genome -> genome
476            if (GEN_is_pseudo_gene_species(gb_species1)) {
477                const char *origin        = GEN_origin_organism(gb_species1);
478                GBDATA     *dest_organism = dest_species_hash
479                    ? (GBDATA*)GBS_read_hash(dest_species_hash, origin)
480                    : GEN_find_organism(GLOBAL_gb_dest, origin);
481
482                if (dest_organism) transfer_fields = true;
483                else {
484                    error = GBS_global_string("Destination DB does not contain '%s's origin-organism '%s'",
485                                              name1, origin);
486                }
487            }
488            // else: merge organism ok
489        }
490        else { // genome -> non-genome
491            if (GEN_is_pseudo_gene_species(gb_species1)) transfer_fields = true;
492            else {
493                error = GBS_global_string("You can't merge organisms (%s) into a non-genome DB.\n"
494                                          "Only pseudo-species are possible", name1);
495            }
496        }
497    }
498    else {
499        if (is_genome_db2) { // non-genome -> genome
500            error = GBS_global_string("You can't merge non-genome species (%s) into a genome DB", name1);
501        }
502        // else: non-genome -> non-genome ok
503    }
504
505    GBDATA *gb_species2 = 0;
506    if (!error) {
507        gb_species2 = dest_species_hash
508            ? (GBDATA*)GBS_read_hash(dest_species_hash, name1)
509            : GBT_find_species_rel_species_data(gb_species_data2, name1);
510       
511        if (gb_species2) error = GB_delete(gb_species2);
512    }
513    if (!error) {
514        gb_species2 = GB_create_container(gb_species_data2, "species");
515        if (!gb_species2) error = GB_await_error();
516    }
517    if (!error) error = GB_copy(gb_species2, gb_species1);
518    if (!error && transfer_fields) {
519        mg_assert(is_genome_db1);
520        error = MG_export_fields(aw_root, gb_species1, gb_species2, error_suppressor, source_organism_hash);
521    }
522    if (!error) GB_write_flag(gb_species2, 1);
523    if (!error) error = MG_transfer_sequence(&remap, gb_species1, gb_species2);
524    if (!error && dest_species_hash) GBS_write_hash(dest_species_hash, name1, (long)gb_species2);
525
526    return error;
527}
528
529
530
531void MG_transfer_selected_species(AW_window *aww) {
532    if (MG_check_alignment(aww,1)) return;
533
534    AW_root  *aw_root = aww->get_root();
535    char     *source  = aw_root->awar(AWAR_SPECIES1)->read_string();
536    GB_ERROR  error   = NULL;
537
538    if (!source || !source[0]) {
539        error = "Please select a species in the left list";
540    }
541    else {
542        aw_openstatus("Transferring selected species");
543
544        error             = GB_begin_transaction(GLOBAL_gb_merge);
545        if (!error) error = GB_begin_transaction(GLOBAL_gb_dest);
546
547        if (!error) {
548            MG_remaps rm(GLOBAL_gb_merge,GLOBAL_gb_dest,aw_root);
549
550            GBDATA *gb_species_data1 = GB_search(GLOBAL_gb_merge,"species_data",GB_CREATE_CONTAINER);
551            GBDATA *gb_species_data2 = GB_search(GLOBAL_gb_dest,"species_data",GB_CREATE_CONTAINER);
552
553            bool is_genome_db1 = GEN_is_genome_db(GLOBAL_gb_merge, -1);
554            bool is_genome_db2 = GEN_is_genome_db(GLOBAL_gb_dest, -1);
555
556            error = MG_transfer_one_species(aw_root, rm,
557                                            gb_species_data1, gb_species_data2,
558                                            is_genome_db1, is_genome_db2,
559                                            NULL, source,
560                                            NULL, NULL,
561                                            NULL);
562        }
563
564        if (!error) error = MG_transfer_fields_info();
565
566        error = GB_end_transaction(GLOBAL_gb_merge, error);
567        error = GB_end_transaction(GLOBAL_gb_dest, error);
568
569        aw_closestatus();
570    }
571
572    if (error) aw_message(error);
573}
574
575#undef IS_QUERIED
576#define IS_QUERIED(gb_species) (1 & GB_read_usr_private(gb_species))
577
578void MG_transfer_species_list(AW_window *aww) {
579    if (MG_check_alignment(aww,1)) return;
580
581    GB_ERROR error = NULL;
582    aw_openstatus("Transferring species");
583    GB_begin_transaction(GLOBAL_gb_merge);
584    GB_begin_transaction(GLOBAL_gb_dest);
585
586    bool is_genome_db1 = GEN_is_genome_db(GLOBAL_gb_merge, -1);
587    bool is_genome_db2 = GEN_is_genome_db(GLOBAL_gb_dest, -1);
588
589    GB_HASH *error_suppressor     = GBS_create_hash(50, GB_IGNORE_CASE);
590    GB_HASH *dest_species_hash    = GBT_create_species_hash(GLOBAL_gb_dest);
591    GB_HASH *source_organism_hash = is_genome_db1 ? GBT_create_organism_hash(GLOBAL_gb_merge) : 0;
592
593    MG_remaps rm(GLOBAL_gb_merge,GLOBAL_gb_dest,aww->get_root());
594
595    GBDATA *gb_species1;
596    int     queried = 0;
597    int     count   = 0;
598
599    for (gb_species1 = GBT_first_species(GLOBAL_gb_merge); gb_species1; gb_species1 = GBT_next_species(gb_species1)) {
600        if (IS_QUERIED(gb_species1)) queried++;
601    }
602
603    for (gb_species1 = GBT_first_species(GLOBAL_gb_merge); gb_species1; gb_species1 = GBT_next_species(gb_species1)) {
604        if (IS_QUERIED(gb_species1)) {
605            GBDATA *gb_species_data2 = GB_search(GLOBAL_gb_dest,"species_data",GB_CREATE_CONTAINER);
606
607            error = MG_transfer_one_species(aww->get_root(), rm,
608                                            NULL, gb_species_data2,
609                                            is_genome_db1, is_genome_db2,
610                                            gb_species1, NULL,
611                                            source_organism_hash, dest_species_hash,
612                                            error_suppressor);
613            aw_status(++count/double(queried));
614        }
615    }
616
617    GBS_free_hash(dest_species_hash);
618    if (source_organism_hash) GBS_free_hash(source_organism_hash);
619    GBS_free_hash(error_suppressor);
620
621    if (!error) error = MG_transfer_fields_info();
622
623    error = GB_end_transaction(GLOBAL_gb_merge, error);
624    GB_end_transaction_show_error(GLOBAL_gb_dest, error, aw_message);
625
626    aw_closestatus();
627}
628
629void MG_transfer_fields_cb(AW_window *aww){
630    if (MG_check_alignment(aww,1)) {
631        return;
632    }
633   
634    char     *field  = aww->get_root()->awar(AWAR_FIELD1)->read_string();
635    long      append = aww->get_root()->awar(AWAR_APPEND)->read_int();
636    GB_ERROR  error  = 0;
637
638    if (field[0] == 0) {
639        error = "Please select a field you want to transfer";
640    }
641    else if (strcmp(field,"name") == 0) {
642        error = "Transferring the 'name' field is forbidden";
643    }
644    else {
645        aw_openstatus("Transferring fields");
646        GB_begin_transaction(GLOBAL_gb_merge);
647        GB_begin_transaction(GLOBAL_gb_dest);
648
649        GBDATA    *gb_dest_species_data  = GB_search(GLOBAL_gb_dest,"species_data",GB_CREATE_CONTAINER);
650        GB_BOOL    transfer_of_alignment = GBS_string_matches(field,"ali_*/data",GB_MIND_CASE);
651        MG_remaps  rm(GLOBAL_gb_merge,GLOBAL_gb_dest,aww->get_root());
652       
653        for (GBDATA *gb_species1 = GBT_first_species(GLOBAL_gb_merge);
654             gb_species1 && !error;
655             gb_species1 = GBT_next_species(gb_species1))
656        {
657            if (IS_QUERIED(gb_species1)) {
658                const char *name1       = GBT_read_name(gb_species1);
659                GBDATA     *gb_species2 = GB_find_string(gb_dest_species_data,"name", name1, GB_IGNORE_CASE, down_2_level);
660
661                if (!gb_species2) {
662                    gb_species2             = GB_create_container(gb_dest_species_data,"species");
663                    if (!gb_species2) error = GB_await_error();
664                    else error              = GBT_write_string(gb_species2, "name", name1);
665                }
666                else {
667                    gb_species2 = GB_get_father(gb_species2);
668                }
669
670                if (!error) {
671                    GBDATA *gb_field1 = GB_search(gb_species1,field,GB_FIND);
672                    GBDATA *gb_field2 = GB_search(gb_species2,field,GB_FIND);
673                    int     type1;
674                    int     type2;
675                    bool    use_copy   = true;
676
677                    if (gb_field2 && gb_field1){
678                        type1 = GB_read_type(gb_field1);
679                        type2 = GB_read_type(gb_field2);
680                        if ((type1==type2) && (GB_DB != type1)) {
681                            if (append && type1 == GB_STRING) {
682                                char *s1 = GB_read_string(gb_field1);
683                                char *s2 = GB_read_string(gb_field2);
684
685                                if (!s1 || !s2) error = GB_await_error();
686                                else {
687                                    if (!GBS_find_string(s2,s1,0)) {
688                                        error             = GB_write_string(gb_field2, GBS_global_string("%s %s", s2, s1));
689                                        if (!error) error = GB_write_flag(gb_species2,1);
690                                    }
691                                }
692
693                                free(s1);
694                                free(s2);
695                            }
696                            else { // not GB_STRING
697                                error             = GB_copy(gb_field2,gb_field1);
698                                if (!error) error = GB_write_flag(gb_species2, 1);
699                                if (transfer_of_alignment && !error){
700                                    error = MG_transfer_sequence(&rm,gb_species1,gb_species2);
701                                }
702                            }
703                            use_copy = false;
704                        }
705                    }
706
707                    if (use_copy) {
708                        if (gb_field2) {
709                            if (gb_field1 && !append) error = GB_delete(gb_field2);
710                        }
711                        if (gb_field1 && !error) {
712                            type1                 = GB_read_type(gb_field1);
713                            gb_field2             = GB_search(gb_species2,field,type1);
714                            if (!gb_field2) error = GB_await_error();
715                            else error            = GB_copy(gb_field2,gb_field1);
716                        }
717                    }
718                }
719            }
720        }
721
722        if (!error) error = MG_transfer_fields_info(field);
723
724        error = GB_end_transaction(GLOBAL_gb_merge, error);
725        error = GB_end_transaction(GLOBAL_gb_dest, error);
726        aw_closestatus();
727    }
728
729    if (error) aw_message(error);
730    free(field);
731}
732
733AW_window *MG_transfer_fields(AW_root *aw_root)
734{
735    GB_transaction dummy(GLOBAL_gb_merge);
736    //  awt_selection_list_rescan(gb_merge,AWT_NDS_FILTER);
737
738    AW_window_simple *aws = new AW_window_simple;
739    aws->init( aw_root, "MERGE_TRANSFER_FIELD", "TRANSFER FIELD");
740    aws->load_xfig("merge/mg_transfield.fig");
741    aws->button_length(13);
742
743    aws->callback( AW_POPDOWN);
744    aws->at("close");
745    aws->create_button("CLOSE","CLOSE","C");
746
747    aws->at("go");
748    aws->callback(MG_transfer_fields_cb);
749    aws->create_button("GO","GO");
750
751    aws->at("help");
752    aws->callback(AW_POPUP_HELP,(AW_CL)"mg_spec_sel_field.hlp");
753    aws->create_button("HELP","HELP");
754
755    aws->at("append");
756    aws->create_toggle(AWAR_APPEND);
757
758    awt_create_selection_list_on_scandb(GLOBAL_gb_merge,
759                                        (AW_window*)aws,AWAR_FIELD1,
760                                        AWT_NDS_FILTER,
761                                        "scandb","rescandb", &AWT_species_selector, 20, 10);
762
763    return (AW_window*)aws;
764}
765
766void MG_move_field_cb(AW_window *aww){
767    if (MG_check_alignment(aww,1)) {
768        return;
769    }
770
771    AW_root  *aw_root = aww->get_root();
772    char     *field   = aww->get_root()->awar(AWAR_FIELD1)->read_string();
773    GB_ERROR  error   = 0;
774
775    if (field[0] == 0) {
776        error = "Please select a field to transfer";
777    }
778    else if (strcmp(field,"name") == 0) {
779        error = "You are not allowed to transfer the 'name' field";
780    }
781    else {
782        aw_openstatus("Cross Move field");
783        error             = GB_begin_transaction(GLOBAL_gb_merge);
784        if (!error) error = GB_begin_transaction(GLOBAL_gb_dest);
785
786        if (!error) {
787            GBDATA *gb_species1;
788            GBDATA *gb_species2;
789            {
790                char *source = aw_root->awar(AWAR_SPECIES1)->read_string();
791                char *dest   = aw_root->awar(AWAR_SPECIES2)->read_string();
792
793                gb_species1 = GBT_find_species(GLOBAL_gb_merge, source);
794                gb_species2 = GBT_find_species(GLOBAL_gb_dest, dest);
795
796                free(dest);
797                free(source);
798            }
799
800            if (!gb_species1) error = "Please select a species in left hitlist";
801            if (!gb_species2) error = "Please select a species in right hitlist";
802
803            if (!error) {
804                GBDATA *gb_field1 = GB_search(gb_species1, field, GB_FIND);
805                if (!gb_field1) error = GBS_global_string("Species 1 has no field '%s'",field);
806
807                if (!error) {
808                    int     type1     = GB_read_type(gb_field1);
809                    GBDATA *gb_field2 = GB_search(gb_species2, field, GB_FIND);
810
811                    if (gb_field2) {
812                        int type2 = GB_read_type(gb_field2);
813
814                        if ((type1==type2) && (GB_DB != type1)) {
815                            error = GB_copy(gb_field2,gb_field1);
816                        }
817                        else { // remove dest. if type mismatch or container
818                            error     = GB_delete(gb_field2);
819                            gb_field2 = 0; // trigger copy
820                        }
821                    }
822
823                    if (!error && !gb_field2) { // destination missing or removed
824                        gb_field2             = GB_search(gb_species2,field,type1);
825                        if (!gb_field2) error = GB_await_error();
826                        else error            = GB_copy(gb_field2,gb_field1);
827                    }
828                }
829                if (!error) error = GB_write_flag(gb_species2,1);
830            }
831        }
832        if (!error) error = MG_transfer_fields_info(field);
833
834        error = GB_end_transaction(GLOBAL_gb_merge, error);
835        error = GB_end_transaction(GLOBAL_gb_dest, error);
836
837        aw_closestatus();
838    }
839
840    if (error) aw_message(error);
841   
842    free(field);
843}
844
845AW_window *create_mg_move_fields(AW_root *aw_root)
846{
847    GB_transaction dummy(GLOBAL_gb_merge);
848
849    AW_window_simple *aws = new AW_window_simple;
850    aws->init( aw_root, "MERGE_CROSS_MOVE_FIELD", "CROSS MOVE FIELD");
851    aws->load_xfig("merge/mg_movefield.fig");
852    aws->button_length(13);
853
854    aws->callback( AW_POPDOWN);
855    aws->at("close");
856    aws->create_button("CLOSE","CLOSE","C");
857
858    aws->at("go");
859    aws->callback(MG_move_field_cb);
860    aws->create_button("GO","GO");
861
862    aws->at("help");
863    aws->callback(AW_POPUP_HELP,(AW_CL)"movefield.hlp");
864    aws->create_button("HELP","HELP");
865
866
867    awt_create_selection_list_on_scandb(GLOBAL_gb_merge,
868                                        (AW_window*)aws,AWAR_FIELD1,
869                                        AWT_NDS_FILTER,
870                                        "scandb","rescandb", &AWT_species_selector, 20, 10);
871
872    return (AW_window*)aws;
873}
874
875void MG_merge_tagged_field_cb(AW_window *aww) {
876    GB_transaction ta_merge(GLOBAL_gb_merge);
877    GB_ERROR       error = GB_begin_transaction(GLOBAL_gb_dest);
878
879    if (!error) {
880        AW_root *awr      = aww->get_root();
881        char    *f1       = awr->awar(AWAR_FIELD1)->read_string();
882        char    *f2       = awr->awar(AWAR_FIELD2)->read_string();
883        char    *tag1     = awr->awar(AWAR_TAG1)->read_string();
884        char    *tag2     = awr->awar(AWAR_TAG2)->read_string();
885        char    *tag_del1 = awr->awar(AWAR_TAG_DEL1)->read_string();
886
887        GBDATA *gb_dest_species_data     = GB_search(GLOBAL_gb_dest, "species_data", GB_CREATE_CONTAINER);
888        if (!gb_dest_species_data) error = GB_await_error();
889        else {
890            for (GBDATA * gb_species1 = GBT_first_species(GLOBAL_gb_merge);
891                 gb_species1 && !error;
892                 gb_species1 = GBT_next_species(gb_species1))
893            {
894                if (IS_QUERIED(gb_species1)) {
895                    char *name       = GBT_read_string(gb_species1, "name");
896                    if (!name) error = GB_await_error();
897                    else {
898                        GBDATA *gb_species2     = GBT_find_or_create_species_rel_species_data(gb_dest_species_data, name);
899                        if (!gb_species2) error = GB_await_error();
900                        else {
901                            char *s1              = GBT_readOrCreate_string(gb_species1, f1, "");
902                            char *s2              = GBT_readOrCreate_string(gb_species2, f2, "");
903                            if (!s1 || !s2) error = GB_await_error();
904                            else {
905                                char *sum       = GBS_merge_tagged_strings(s1, tag1, tag_del1, s2, tag2, tag_del1);
906                                if (!sum) error = GB_await_error();
907                                else  error     = GBT_write_string(gb_species2, f2, sum);
908                                free(sum);
909                            }
910                            free(s2);
911                            free(s1);
912                        }
913                    }
914                    free(name);
915                }
916            }
917        }
918
919        free(tag_del1);
920        free(tag2);
921        free(tag1);
922        free(f2);
923        free(f1);
924    }
925    GB_end_transaction_show_error(GLOBAL_gb_dest, error, aw_message);
926}
927
928AW_window *create_mg_merge_tagged_fields(AW_root *aw_root)
929{
930    static AW_window_simple *aws = 0;
931    if (aws) return aws;
932
933    GB_transaction dummy(GLOBAL_gb_merge);
934
935    aw_root->awar_string( AWAR_FIELD1,"full_name");
936    aw_root->awar_string( AWAR_FIELD2,"full_name");
937
938    aw_root->awar_string( AWAR_TAG1,"S");
939    aw_root->awar_string( AWAR_TAG2,"D");
940
941    aw_root->awar_string( AWAR_TAG_DEL1,"S*");
942
943    aws = new AW_window_simple;
944    aws->init( aw_root, "MERGE_TAGGED_FIELDS", "MERGE TAGGED FIELDS");
945    aws->load_xfig("merge/mg_mergetaggedfield.fig");
946    aws->button_length(13);
947
948    aws->callback( AW_POPDOWN);
949    aws->at("close");
950    aws->create_button("CLOSE","CLOSE","C");
951
952    aws->at("go");
953    aws->callback(MG_merge_tagged_field_cb);
954    aws->create_button("GO","GO");
955
956    aws->at("help");
957    aws->callback(AW_POPUP_HELP,(AW_CL)"mergetaggedfield.hlp");
958    aws->create_button("HELP","HELP");
959
960    aws->at("tag1");    aws->create_input_field(AWAR_TAG1,5);
961    aws->at("tag2");    aws->create_input_field(AWAR_TAG2,5);
962
963    aws->at("del1");    aws->create_input_field(AWAR_TAG_DEL1,5);
964
965    awt_create_selection_list_on_scandb(GLOBAL_gb_merge, (AW_window*)aws,AWAR_FIELD1,AWT_NDS_FILTER,"fields1",0, &AWT_species_selector, 20, 10);
966    awt_create_selection_list_on_scandb(GLOBAL_gb_dest, (AW_window*)aws,AWAR_FIELD2,AWT_NDS_FILTER,"fields2",0, &AWT_species_selector, 20, 10);
967
968    return (AW_window*)aws;
969}
970
971GB_ERROR MG_equal_alignments(bool autoselect_equal_alignment_name) {
972    /** First big job:  Make the alignment names equal */
973    char **   M_alignment_names = GBT_get_alignment_names(GLOBAL_gb_merge);
974    char **   D_alignment_names = GBT_get_alignment_names(GLOBAL_gb_dest);
975    GB_ERROR  error             = 0;
976    char     *dest              = 0;
977
978    if (M_alignment_names[0] == 0) {
979        error =  GB_export_error("No source sequences found");
980    }
981    else {
982        char *type = GBT_get_alignment_type_string(GLOBAL_gb_merge,M_alignment_names[0]);
983        int   s;
984        int   d;
985
986        for (s=0,d=0;D_alignment_names[s];s++){
987            char *type2 = GBT_get_alignment_type_string(GLOBAL_gb_dest,D_alignment_names[s]);
988            if (strcmp(type, type2) == 0) {
989                D_alignment_names[d] = D_alignment_names[s];
990                if (d != s) D_alignment_names[s] = 0;
991                ++d;
992            }
993            else freeset(D_alignment_names[s], 0);
994            free(type2);
995        }
996
997        GBS_strstruct *str;
998        char          *b;
999        int            aliid;
1000
1001        switch (d) {
1002            case 0:
1003                error = GB_export_errorf("Cannot find a target alignment with a type of '%s'\n"
1004                                         "You should create one first or select a different alignment type\n"
1005                                         "during sequence import",type);
1006                break;
1007            case 1:
1008                dest = D_alignment_names[0];
1009                break;
1010
1011            default:
1012                int i;
1013
1014                if (autoselect_equal_alignment_name) {
1015                    for (i = 0; i<d; ++i) {
1016                        if (ARB_stricmp(M_alignment_names[0], D_alignment_names[i]) == 0) {
1017                            dest = D_alignment_names[i];
1018                            break;
1019                        }
1020                    }
1021                }
1022
1023                if (!dest) {
1024                    str = GBS_stropen(100);
1025
1026                    for (i=0;i<d;i++){
1027                        GBS_strcat(str,D_alignment_names[i]);
1028                        GBS_chrcat(str,',');
1029                    }
1030                    GBS_strcat(str,"ABORT");
1031
1032                    b = GBS_strclose(str);
1033                    aliid = aw_question("There are more than one possible alignment targets\n"
1034                                        "Choose one destination alignment or ABORT",b);
1035                    free(b);
1036                    if (aliid >= d) {
1037                        error = "Operation Aborted";
1038                        break;
1039                    }
1040                    dest = D_alignment_names[aliid];
1041                }
1042                break;
1043        }
1044        if (!error && dest && strcmp(M_alignment_names[0], dest) != 0) {
1045            error = GBT_rename_alignment(GLOBAL_gb_merge,M_alignment_names[0], dest, 1, 1);
1046            if (error) {
1047                error = GBS_global_string("Failed to rename alignment '%s' to '%s' (Reason: %s)",
1048                                          M_alignment_names[0], dest, error);
1049            }
1050            else {
1051                GBT_add_new_changekey(GLOBAL_gb_merge, GBS_global_string("%s/data",dest),GB_STRING);
1052            }
1053        }
1054        free(type);
1055    }
1056    GBT_free_names(M_alignment_names);
1057    GBT_free_names(D_alignment_names);
1058
1059    return error;
1060}
1061
1062/** Merge the sequences of two databases */
1063GB_ERROR MG_simple_merge(AW_root *awr) {
1064    static char *m_name         = 0;
1065    GB_ERROR     error          = 0;
1066    GBDATA      *M_species_data = 0;
1067    GBDATA      *D_species_data = 0;
1068    int          overwriteall   = 0;
1069    int          autorenameall  = 0;
1070    GB_HASH     *D_species_hash = 0;
1071
1072    GB_push_my_security(GLOBAL_gb_merge);
1073    GB_push_my_security(GLOBAL_gb_dest);
1074    GB_begin_transaction(GLOBAL_gb_merge);
1075    GB_begin_transaction(GLOBAL_gb_dest);
1076
1077    error = MG_equal_alignments(true);
1078    if (error) goto end;
1079
1080    M_species_data = GB_search(GLOBAL_gb_merge,"species_data",GB_CREATE_CONTAINER);
1081    D_species_data = GB_search(GLOBAL_gb_dest,"species_data",GB_CREATE_CONTAINER);
1082
1083    GBDATA *M_species;
1084    GBDATA *D_species;
1085    freeset(m_name, 0);
1086
1087    {
1088        long M_species_count = GB_number_of_subentries(M_species_data);
1089        long D_species_count = GB_number_of_subentries(D_species_data);
1090
1091        // create hash containing all species from gb_dest,
1092        // but sized to hold all species from both DBs:
1093        D_species_hash = GBT_create_species_hash_sized(GLOBAL_gb_dest, M_species_count+D_species_count);
1094    }
1095
1096    for (M_species = GB_entry(M_species_data,"species"); M_species; M_species = GB_nextEntry(M_species)) {
1097        GBDATA *M_name       = GB_search(M_species,"name",GB_STRING);
1098        free(m_name); m_name = GB_read_string(M_name);
1099
1100        int count = 1;
1101
1102    new_try:
1103
1104        count++;
1105       
1106        D_species = (GBDATA*)GBS_read_hash(D_species_hash, m_name);
1107        if (D_species){
1108            if (overwriteall) {
1109                error = GB_delete(D_species);
1110            }
1111            else if (autorenameall) {
1112                GB_ERROR  dummy;
1113                char     *newname = AWTC_create_numbered_suffix(D_species_hash, m_name, dummy);
1114
1115                mg_assert(newname);
1116                freeset(m_name, newname);
1117            }
1118            else {
1119                switch (aw_question(GBS_global_string("Warning:  There is a name conflict for species '%s'\n"
1120                                                      "  You may:\n"
1121                                                      "  - Overwrite existing species\n"
1122                                                      "  - Overwrite all species with name conflicts\n"
1123                                                      "  - Not import species\n"
1124                                                      "  - Rename imported species\n"
1125                                                      "  - Automatically rename species (append .NUM)\n"
1126                                                      "  - Abort everything", m_name),
1127                                    "overwrite, overwrite all, don't import, rename, auto-rename, abort")){
1128                    case 1:
1129                        overwriteall = 1;
1130                    case 0:
1131                        GB_delete(D_species);
1132                        break;
1133                       
1134                    case 2:
1135                        continue;
1136
1137                    case 3: {
1138                        GB_ERROR  warning;          // duplicated species warning (does not apply here)
1139                        char     *autoname = AWTC_create_numbered_suffix(D_species_hash, m_name, warning);
1140
1141                        if (!autoname) autoname = strdup(m_name);
1142                        freeset(m_name, aw_input("Rename species", "Enter new name of species", autoname));
1143                        free(autoname);
1144                        goto new_try;
1145                    }
1146                    case 4:
1147                        autorenameall = 1;
1148                        goto new_try;
1149                       
1150                    case 5:
1151                        error = "Operation aborted";
1152                        goto end;
1153                }
1154            }
1155        }
1156
1157        if (!error) {
1158            D_species             = GB_create_container(D_species_data,"species");
1159            if (!D_species) error = GB_await_error();
1160            else {
1161                error             = GB_copy_with_protection(D_species, M_species, GB_TRUE);
1162                if (!error) error = GB_write_flag(D_species,1); // mark species
1163                if (!error) error = GB_write_usr_private(D_species,255); // put in hitlist
1164                if (!error) error = GBT_write_string(D_species, "name", m_name);
1165            }
1166
1167            GBS_write_hash(D_species_hash, m_name, (long)D_species);
1168        }
1169
1170        if (error) break;
1171    }
1172
1173 end:
1174
1175    if (D_species_hash) GBS_free_hash(D_species_hash);
1176
1177    if (!error) error = MG_transfer_fields_info();
1178    if (!error) awr->awar(AWAR_SPECIES_NAME)->write_string(m_name);
1179   
1180    error = GB_end_transaction(GLOBAL_gb_merge, error);
1181    GB_end_transaction_show_error(GLOBAL_gb_dest, error, aw_message);
1182
1183    GB_pop_my_security(GLOBAL_gb_merge);
1184    GB_pop_my_security(GLOBAL_gb_dest);
1185   
1186    return error;
1187}
1188
1189//  ---------------------------
1190//      MG_species_selector
1191//  ---------------------------
1192
1193static void mg_select_species1(GBDATA* , AW_root *aw_root, const char *item_name) {
1194    aw_root->awar(AWAR_SPECIES1)->write_string(item_name);
1195}
1196static void mg_select_species2(GBDATA* , AW_root *aw_root, const char *item_name) {
1197    aw_root->awar(AWAR_SPECIES2)->write_string(item_name);
1198}
1199
1200static GBDATA *mg_get_first_species_data1(GBDATA *, AW_root *, AWT_QUERY_RANGE) {
1201    return GBT_get_species_data(GLOBAL_gb_merge);
1202}
1203static GBDATA *mg_get_first_species_data2(GBDATA *, AW_root *, AWT_QUERY_RANGE) {
1204    return GBT_get_species_data(GLOBAL_gb_dest);
1205}
1206
1207static GBDATA *mg_get_selected_species1(GBDATA */*gb_main*/, AW_root *aw_root) {
1208    GB_transaction dummy(GLOBAL_gb_merge);
1209    char   *species_name            = aw_root->awar(AWAR_SPECIES1)->read_string();
1210    GBDATA *gb_species              = 0;
1211    if (species_name[0]) gb_species = GBT_find_species(GLOBAL_gb_merge, species_name);
1212    free(species_name);
1213    return gb_species;
1214}
1215static GBDATA *mg_get_selected_species2(GBDATA */*gb_main*/, AW_root *aw_root) {
1216    GB_transaction dummy(GLOBAL_gb_dest);
1217    char   *species_name            = aw_root->awar(AWAR_SPECIES2)->read_string();
1218    GBDATA *gb_species              = 0;
1219    if (species_name[0]) gb_species = GBT_find_species(GLOBAL_gb_dest, species_name);
1220    free(species_name);
1221    return gb_species;
1222}
1223
1224static struct ad_item_selector MG_species_selector[2];
1225
1226static void mg_initialize_species_selectors() {
1227    static int initialized = 0;
1228    if (!initialized) {
1229        MG_species_selector[0] = AWT_species_selector;
1230        MG_species_selector[1] = AWT_species_selector;
1231
1232        for (int s = 0; s <= 1; ++s) {
1233            ad_item_selector& sel = MG_species_selector[s];
1234
1235            sel.update_item_awars        = s ? mg_select_species2 : mg_select_species1;
1236            sel.get_first_item_container = s ? mg_get_first_species_data2 : mg_get_first_species_data1;
1237            sel.get_selected_item = s ? mg_get_selected_species2 : mg_get_selected_species1;
1238        }
1239
1240        initialized = 1;
1241    }
1242}
1243
1244AW_window *MG_merge_species_cb(AW_root *awr){
1245    static AW_window_simple_menu *aws = 0;
1246    if (aws) return (AW_window *)aws;
1247
1248    awr->awar_string(AWAR_REMAP_SPECIES_LIST, "ecoli",GLOBAL_gb_dest);
1249    awr->awar_int(AWAR_REMAP_ENABLE, 0, GLOBAL_gb_dest);
1250
1251    aws = new AW_window_simple_menu;
1252    aws->init( awr, "MERGE_TRANSFER_SPECIES", "TRANSFER SPECIES");
1253    aws->load_xfig("merge/species.fig");
1254
1255    aws->at("close");aws->callback((AW_CB0)AW_POPDOWN);
1256    aws->create_button("CLOSE","CLOSE","C");
1257
1258    aws->at("help");
1259    aws->callback(AW_POPUP_HELP,(AW_CL)"mg_species.hlp");
1260    aws->create_button("HELP","HELP","H");
1261
1262    awt_query_struct awtqs;
1263    aws->create_menu("DB_I_Expert","D");
1264
1265    awtqs.gb_main                = GLOBAL_gb_merge;
1266    awtqs.gb_ref                 = GLOBAL_gb_dest;
1267    awtqs.expect_hit_in_ref_list = false;
1268    awtqs.species_name           = AWAR_SPECIES1;
1269    awtqs.tree_name              = 0;               // no selected tree here -> can't use tree related ACI commands without specifying a tree
1270    awtqs.select_bit             = 1;
1271    awtqs.ere_pos_fig            = "ere1";
1272    awtqs.by_pos_fig             = "by1";
1273    awtqs.qbox_pos_fig           = "qbox1";
1274    awtqs.rescan_pos_fig         = "rescan1";
1275    awtqs.key_pos_fig            = 0;
1276    awtqs.query_pos_fig          = "content1";
1277    awtqs.result_pos_fig         = "result1";
1278    awtqs.count_pos_fig          = "count1";
1279    awtqs.do_query_pos_fig       = "doquery1";
1280    awtqs.config_pos_fig         = "doconfig1";
1281    awtqs.do_mark_pos_fig        = 0;
1282    awtqs.do_unmark_pos_fig      = 0;
1283    awtqs.do_delete_pos_fig      = "dodelete1";
1284    awtqs.do_set_pos_fig         = "doset1";
1285    awtqs.do_refresh_pos_fig     = "dorefresh1";
1286    awtqs.open_parser_pos_fig    = "openparser1";
1287    awtqs.use_menu               = 1;
1288
1289    mg_initialize_species_selectors();
1290    awtqs.selector = &(MG_species_selector[0]);
1291
1292    awt_create_query_box(aws, &awtqs, "db1");
1293
1294    AW_CL scannerid      = awt_create_arbdb_scanner(GLOBAL_gb_merge, aws, "box1",0,0,0,AWT_SCANNER,0,0,AWT_NDS_FILTER, awtqs.selector);
1295    ad_global_scannerid1 = scannerid;
1296    aws->get_root()->awar(AWAR_SPECIES1)->add_callback(AD_map_species1);
1297
1298    aws->create_menu("DB_II_Expert","B");
1299
1300    awtqs.gb_main                = GLOBAL_gb_dest;
1301    awtqs.gb_ref                 = GLOBAL_gb_merge;
1302    awtqs.expect_hit_in_ref_list = true;
1303    awtqs.species_name           = AWAR_SPECIES2;
1304    awtqs.select_bit             = 1;
1305    awtqs.ere_pos_fig            = "ere2";
1306    awtqs.by_pos_fig             = "by2";
1307    awtqs.qbox_pos_fig           = "qbox2";
1308    awtqs.rescan_pos_fig         = "rescan2";
1309    awtqs.key_pos_fig            = 0;
1310    awtqs.query_pos_fig          = "content2";
1311    awtqs.result_pos_fig         = "result2";
1312    awtqs.count_pos_fig          = "count2";
1313    awtqs.do_query_pos_fig       = "doquery2";
1314    awtqs.config_pos_fig         = "doconfig2";
1315    awtqs.do_mark_pos_fig        = 0;
1316    awtqs.do_unmark_pos_fig      = 0;
1317    awtqs.do_delete_pos_fig      = "dodelete2";
1318    awtqs.do_set_pos_fig         = "doset2";
1319    awtqs.do_refresh_pos_fig     = "dorefresh2";
1320    awtqs.open_parser_pos_fig    = "openparser2";
1321
1322    awtqs.selector = &(MG_species_selector[1]);
1323
1324    awt_create_query_box(aws, &awtqs, "db2");
1325
1326    scannerid            = awt_create_arbdb_scanner(GLOBAL_gb_dest, aws, "box2",0,0,0,AWT_SCANNER,0,0,AWT_NDS_FILTER, awtqs.selector);
1327    ad_global_scannerid2 = scannerid;
1328    aws->get_root()->awar(AWAR_SPECIES2)->add_callback(AD_map_species2);
1329
1330    // big transfer buttons:
1331    aws->button_length(13);
1332    {
1333        aws->shadow_width(3);
1334
1335        aws->at("transsspec");
1336        aws->callback(MG_transfer_selected_species);
1337        aws->create_button("TRANSFER_SELECTED_DELETE_DUPLICATED",
1338                           "TRANSFER\nSELECTED\nSPECIES\n\nDELETE\nDUPLICATE\nIN DB II","T");
1339
1340        aws->at("translspec");
1341        aws->callback(MG_transfer_species_list);
1342        aws->create_button("TRANSFER_LISTED_DELETE_DUPLI",
1343                           "TRANSFER\nLISTED\nSPECIES\n\nDELETE\nDUPLICATES\nIN DB II","T");
1344
1345        aws->at("transfield");
1346        aws->callback(AW_POPUP,(AW_CL)MG_transfer_fields,0);
1347        aws->create_button("TRANSFER_FIELD_OF_LISTED_DELETE_DUPLI",
1348                           "TRANSFER\nFIELD\nOF LISTED\nSPECIES\n\nDELETE\nDUPLICATES\nIN DB II","T");
1349
1350        aws->shadow_width(1);
1351    }
1352
1353    // adapt alignments
1354    aws->button_length(7);
1355    aws->at("adapt");
1356    aws->create_toggle(AWAR_REMAP_ENABLE);
1357
1358    aws->at("reference");
1359    aws->create_text_field(AWAR_REMAP_SPECIES_LIST);
1360
1361    aws->at("pres_sel");
1362    aws->callback((AW_CB1)AW_POPUP,(AW_CL)MG_select_preserves_cb);
1363    aws->create_button("SELECT", "SELECT", "S");
1364
1365    // top icon
1366    aws->button_length(0);
1367    aws->at("icon");
1368    aws->callback(AW_POPUP_HELP,(AW_CL)"mg_species.hlp");
1369    aws->create_button("HELP_MERGE", "#merge/icon.bitmap");
1370
1371    aws->create_menu("DB1->DB2","-");
1372    aws->insert_menu_topic( "compare_field_of_listed",  "Compare a field of listed species ...","C","checkfield.hlp",   AWM_ALL, AW_POPUP,(AW_CL)create_mg_check_fields,0);
1373    aws->insert_menu_topic( "move_field_of_selected",   "Move one field of selected left species to same field of selected right species","M",
1374                            "movefield.hlp", AWM_ALL, AW_POPUP,(AW_CL)create_mg_move_fields,0);
1375    aws->insert_menu_topic( "merge_field_of_listed_to_new_field", "Merge field of listed species of DB1 with different fields of same species of DB2 ","D",
1376                            "mergetaggedfield.hlp", AWM_ALL, AW_POPUP,(AW_CL)create_mg_merge_tagged_fields,0);
1377
1378    aws->insert_separator();
1379    aws->insert_menu_topic("def_gene_species_field_xfer", "Define field transfer for gene-species", "g", "gene_species_field_transfer.hlp",
1380                           AWM_ALL, AW_POPUP, (AW_CL)MG_gene_species_create_field_transfer_def_window, 0);
1381
1382    return (AW_window *)aws;
1383}
Note: See TracBrowser for help on using the repository browser.