source: tags/cvs_2_svn/MERGE/MG_species.cxx

Last change on this file was 5356, checked in by westram, 16 years ago
  • fixed calls to GBS_create_hash
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 50.3 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_changekey.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_transfer_fields_info(char *fieldname = 0);
259
260void MG_create_species_awars(AW_root *aw_root, AW_default aw_def)
261{
262    aw_root->awar_string( AWAR_SPECIES1, "" ,   aw_def);
263    aw_root->awar_string( AWAR_SPECIES2, "" ,   aw_def);
264    aw_root->awar_string( AWAR_SPECIES1_DEST, "" ,  aw_def);
265    aw_root->awar_string( AWAR_SPECIES2_DEST, "" ,  aw_def);
266    aw_root->awar_string( AWAR_FIELD1, "" , aw_def);
267    aw_root->awar_int( AWAR_APPEND );
268}
269
270
271void AD_map_species1(AW_root *aw_root)
272{
273    GB_push_transaction(GLOBAL_gb_merge);
274    char   *source     = aw_root->awar(AWAR_SPECIES1)->read_string();
275    GBDATA *gb_species = GBT_find_species(GLOBAL_gb_merge,source);
276
277    if (gb_species) awt_map_arbdb_scanner(ad_global_scannerid1,gb_species,0, CHANGE_KEY_PATH);
278    GB_pop_transaction(GLOBAL_gb_merge);
279    delete source;
280}
281
282void AD_map_species2(AW_root *aw_root)
283{
284    char *source = aw_root->awar(AWAR_SPECIES2)->read_string();
285    GB_push_transaction(GLOBAL_gb_dest);
286    GBDATA *gb_species = GBT_find_species(GLOBAL_gb_dest,source);
287    if (gb_species) {
288        awt_map_arbdb_scanner(ad_global_scannerid2,gb_species,0, CHANGE_KEY_PATH);
289    }
290    GB_pop_transaction(GLOBAL_gb_dest);
291    delete source;
292}
293
294void MG_transfer_fields_info(char *fieldname)
295{
296    GBDATA *gb_key_data = GB_search(GLOBAL_gb_merge, CHANGE_KEY_PATH, GB_CREATE_CONTAINER);
297
298    GB_search(GLOBAL_gb_dest, CHANGE_KEY_PATH, GB_CREATE_CONTAINER);
299
300    for (GBDATA *gb_key = GB_entry(gb_key_data,CHANGEKEY); gb_key; gb_key = GB_nextEntry(gb_key)) {
301        GBDATA *gb_key_name = GB_entry(gb_key, CHANGEKEY_NAME); if (!gb_key_name) continue;
302        GBDATA *gb_key_type = GB_entry(gb_key, CHANGEKEY_TYPE); if (!gb_key_type) continue;
303        char   *name        = GB_read_string(gb_key_name);
304
305        if (!fieldname || strcmp(fieldname,name) == 0) {
306            awt_add_new_changekey(GLOBAL_gb_dest,name,(int)GB_read_int(gb_key_type));
307        }
308        free(name);
309    }
310}
311
312MG_remap *MG_create_remap(GBDATA *gb_left, GBDATA *gb_right, const char *reference_species_names, const char *alignment_name){
313    char *tok;
314    MG_remap *rem = new MG_remap();
315    char *ref_list = strdup(reference_species_names);
316    for (tok = strtok(ref_list," \n,;");tok;tok = strtok(NULL," \n,;")){
317        bool    is_SAI           = strncmp(tok, "SAI:", 4) == 0;
318        GBDATA *gb_species_left  = 0;
319        GBDATA *gb_species_right = 0;
320
321        if (is_SAI) {
322            gb_species_left  = GBT_find_SAI(gb_left, tok+4);
323            gb_species_right = GBT_find_SAI(gb_right, tok+4);
324        }
325        else {
326            gb_species_left  = GBT_find_species(gb_left,tok);
327            gb_species_right = GBT_find_species(gb_right,tok);
328        }
329
330        if (!gb_species_left || !gb_species_right) {
331            aw_message(GBS_global_string("Warning: Couldn't find %s'%s' in %s DB.\nPlease read ADAPT ALIGNMENT section in help file!",
332                                         is_SAI ? "" : "species ",
333                                         tok,
334                                         gb_species_left ? "right" : "left"));
335            continue;
336        }
337
338        // look for sequence/SAI "data"
339        GBDATA *gb_seq_left  = GBT_read_sequence(gb_species_left,alignment_name);
340        if (!gb_seq_left) continue;
341        GBDATA *gb_seq_right = GBT_read_sequence(gb_species_right,alignment_name);
342        if (!gb_seq_right) continue;
343
344        GB_TYPES type_left  = GB_read_type(gb_seq_left);
345        GB_TYPES type_right = GB_read_type(gb_seq_right);
346
347        if (type_left != type_right) {
348            aw_message(GBS_global_string("Warning: data type of '%s' differs in both databases", tok));
349            continue;
350        }
351
352        if (type_right == GB_STRING) {
353            rem->set(GB_read_char_pntr(gb_seq_left), GB_read_char_pntr(gb_seq_right));
354        }
355        else {
356            char *sleft  = GB_read_as_string(gb_seq_left);
357            char *sright = GB_read_as_string(gb_seq_right);
358            rem->set(sleft,sright);
359            free(sleft);
360            free(sright);
361        }
362    }
363    rem->compile();
364    delete ref_list;
365    return rem;
366}
367
368MG_remaps::MG_remaps(GBDATA *gb_left,GBDATA *gb_right,AW_root *awr){
369    memset((char *)this,0,sizeof(*this));
370    int ref_enable = awr->awar(AWAR_REMAP_ENABLE)->read_int();
371    if (!ref_enable) return;
372
373    char *reference_species_names = awr->awar(AWAR_REMAP_SPECIES_LIST)->read_string();
374    this->alignment_names = GBT_get_alignment_names(gb_left);
375    for (n_remaps = 0;alignment_names[n_remaps];n_remaps++) ;
376    this->remaps = (MG_remap **)GB_calloc(sizeof(MG_remap *),n_remaps);
377    int i;
378    for (i=0;i<n_remaps;i++){
379        this->remaps[i] = MG_create_remap(gb_left,gb_right,reference_species_names,alignment_names[i]);
380    }
381    delete reference_species_names;
382}
383
384MG_remaps::~MG_remaps(){
385    int i;
386    for (i=0;i<n_remaps;i++){
387        delete remaps[i];
388        delete alignment_names[i];
389    }
390    delete alignment_names;
391    delete remaps;
392}
393
394GB_ERROR MG_transfer_sequence(MG_remap *remap, GBDATA *source_species, GBDATA *destination_species,const char *alignment_name){ // align sequence after copy !!!
395    if (!remap) return 0;   // no remap
396    GBDATA *gb_seq_left = GBT_read_sequence(source_species,alignment_name);
397    GBDATA *gb_seq_right = GBT_read_sequence(destination_species,alignment_name);
398    if (!gb_seq_right || !gb_seq_left) return 0; // one has no sequence -> not copied;
399    char *ls = GB_read_string(gb_seq_left);
400    char *rs = GB_read_string(gb_seq_right);
401    if (strcmp(ls,rs)){
402        delete ls;
403        delete rs;
404        return 0;           // sequences differ -> not copied
405    }
406    delete rs;
407    rs = remap->remap(ls);
408    GB_ERROR error = 0;
409    if (rs){
410        long old_check = GBS_checksum(ls,0,".- ");
411        long new_check = GBS_checksum(rs,0,".- ");
412        if (old_check == new_check){
413            error = GB_write_string(gb_seq_right,rs);
414        }else{
415            error = GB_export_error("Error in aligning sequences");
416        }
417    }else{
418        error = GB_get_error();
419    }
420    delete rs;
421    delete ls;
422    return error;
423}
424
425GB_ERROR MG_transfer_sequence(MG_remaps *remaps, GBDATA *source_species, GBDATA *destination_species){
426    int i;
427    GB_ERROR error = 0;
428    if (!remaps->remaps) return NULL; // not remapped
429    for (i=0;i<remaps->n_remaps;i++){
430        error = MG_transfer_sequence(remaps->remaps[i],source_species,destination_species,remaps->alignment_names[i]);
431        if (error) break;
432    }
433    return error;
434}
435
436
437static GB_ERROR MG_transfer_one_species(AW_root *aw_root, MG_remaps& remap, 
438                                        GBDATA *gb_species_data1, GBDATA *gb_species_data2,
439                                        bool is_genome_db1, bool is_genome_db2, 
440                                        GBDATA  *gb_species1, const char *name1,
441                                        GB_HASH *source_organism_hash, GB_HASH *dest_species_hash,
442                                        GB_HASH *error_suppressor)
443{
444    // copies one species from source to destination DB
445    //
446    // either 'gb_species1' or 'name1' (and 'gb_species_data1') has to be given
447    // 'source_organism_hash' may be NULL, otherwise it's used to search for source organisms (when merging from genome DB)
448    // 'dest_species_hash' may be NULL, otherwise created species is stored there
449
450    GB_ERROR error = 0;
451    if (gb_species1) {
452        GBDATA *gb_name1 = GB_entry(gb_species1,"name");
453        gb_assert(gb_name1);
454        name1             = GB_read_char_pntr(gb_name1);
455    }
456    else {
457        mg_assert(name1);
458        gb_species1 = GBT_find_species_rel_species_data(gb_species_data1, name1);
459        if (!gb_species1) {
460            error = GBS_global_string("Could not find species '%s'", name1);
461        }
462    }
463
464    bool transfer_fields = false;
465    if (is_genome_db1) {
466        if (is_genome_db2) { // genome -> genome
467            if (GEN_is_pseudo_gene_species(gb_species1)) {
468                const char *origin        = GEN_origin_organism(gb_species1);
469                GBDATA     *dest_organism = dest_species_hash
470                    ? (GBDATA*)GBS_read_hash(dest_species_hash, origin)
471                    : GEN_find_organism(GLOBAL_gb_dest, origin);
472
473                if (dest_organism) transfer_fields = true;
474                else {
475                    error = GBS_global_string("Destination DB does not contain '%s's origin-organism '%s'",
476                                              name1, origin);
477                }
478            }
479            // else: merge organism ok
480        }
481        else { // genome -> non-genome
482            if (GEN_is_pseudo_gene_species(gb_species1)) transfer_fields = true;
483            else {
484                error = GBS_global_string("You can't merge organisms (%s) into a non-genome DB.\n"
485                                          "Only pseudo-species are possible", name1);
486            }
487        }
488    }
489    else {
490        if (is_genome_db2) { // non-genome -> genome
491            error = GBS_global_string("You can't merge non-genome species (%s) into a genome DB", name1);
492        }
493        // else: non-genome -> non-genome ok
494    }
495
496    GBDATA *gb_species2 = 0;
497    if (!error) {
498        gb_species2 = dest_species_hash
499            ? (GBDATA*)GBS_read_hash(dest_species_hash, name1)
500            : GBT_find_species_rel_species_data(gb_species_data2, name1);
501       
502        if (gb_species2) error = GB_delete(gb_species2);
503    }
504    if (!error) {
505        gb_species2 = GB_create_container(gb_species_data2, "species");
506        if (!gb_species2) error = GB_get_error();
507    }
508    if (!error) error = GB_copy(gb_species2, gb_species1);
509    if (!error && transfer_fields) {
510        mg_assert(is_genome_db1);
511        error = MG_export_fields(aw_root, gb_species1, gb_species2, error_suppressor, source_organism_hash);
512    }
513    if (!error) GB_write_flag(gb_species2, 1);
514    if (!error) error = MG_transfer_sequence(&remap, gb_species1, gb_species2);
515    if (!error && dest_species_hash) GBS_write_hash(dest_species_hash, name1, (long)gb_species2);
516
517    return error;
518}
519
520
521
522void MG_transfer_selected_species(AW_window *aww) {
523    if (MG_check_alignment(aww,1)) return;
524
525    AW_root  *aw_root = aww->get_root();
526    char     *source  = aw_root->awar(AWAR_SPECIES1)->read_string();
527    GB_ERROR  error   = NULL;
528
529    if (!source || !source[0]) {
530        error = "Please select a species in the left list";
531    }
532    else {
533        aw_openstatus("Transferring selected species");
534       
535        GB_begin_transaction(GLOBAL_gb_merge);
536        GB_begin_transaction(GLOBAL_gb_dest);
537
538        MG_remaps rm(GLOBAL_gb_merge,GLOBAL_gb_dest,aw_root);
539
540        GBDATA *gb_species_data1 = GB_search(GLOBAL_gb_merge,"species_data",GB_CREATE_CONTAINER);
541        GBDATA *gb_species_data2 = GB_search(GLOBAL_gb_dest,"species_data",GB_CREATE_CONTAINER);
542
543        bool is_genome_db1 = GEN_is_genome_db(GLOBAL_gb_merge, -1);
544        bool is_genome_db2 = GEN_is_genome_db(GLOBAL_gb_dest, -1);
545
546        error = MG_transfer_one_species(aw_root, rm,
547                                        gb_species_data1, gb_species_data2,
548                                        is_genome_db1, is_genome_db2,
549                                        NULL, source,
550                                        NULL, NULL,
551                                        NULL);
552
553        if (error) {
554            GB_abort_transaction(GLOBAL_gb_merge);
555            GB_abort_transaction(GLOBAL_gb_dest);
556        }
557        else {
558            MG_transfer_fields_info();
559            GB_commit_transaction(GLOBAL_gb_merge);
560            GB_commit_transaction(GLOBAL_gb_dest);
561        }
562        aw_closestatus();
563    }
564
565    if (error) aw_message(error);
566}
567
568#undef IS_QUERIED
569#define IS_QUERIED(gb_species) (1 & GB_read_usr_private(gb_species))
570
571void MG_transfer_species_list(AW_window *aww) {
572    if (MG_check_alignment(aww,1)) return;
573
574    GB_ERROR error = NULL;
575    aw_openstatus("Transferring species");
576    GB_begin_transaction(GLOBAL_gb_merge);
577    GB_begin_transaction(GLOBAL_gb_dest);
578
579    bool is_genome_db1 = GEN_is_genome_db(GLOBAL_gb_merge, -1);
580    bool is_genome_db2 = GEN_is_genome_db(GLOBAL_gb_dest, -1);
581
582    GB_HASH *error_suppressor     = GBS_create_hash(50, GB_IGNORE_CASE);
583    GB_HASH *dest_species_hash    = GBT_create_species_hash(GLOBAL_gb_dest);
584    GB_HASH *source_organism_hash = is_genome_db1 ? GBT_create_organism_hash(GLOBAL_gb_merge) : 0;
585
586    MG_remaps rm(GLOBAL_gb_merge,GLOBAL_gb_dest,aww->get_root());
587
588    GBDATA *gb_species1;
589    int     queried = 0;
590    int     count   = 0;
591
592    for (gb_species1 = GBT_first_species(GLOBAL_gb_merge); gb_species1; gb_species1 = GBT_next_species(gb_species1)) {
593        if (IS_QUERIED(gb_species1)) queried++;
594    }
595
596    for (gb_species1 = GBT_first_species(GLOBAL_gb_merge); gb_species1; gb_species1 = GBT_next_species(gb_species1)) {
597        if (IS_QUERIED(gb_species1)) {
598            GBDATA *gb_species_data2 = GB_search(GLOBAL_gb_dest,"species_data",GB_CREATE_CONTAINER);
599
600            error = MG_transfer_one_species(aww->get_root(), rm,
601                                            NULL, gb_species_data2,
602                                            is_genome_db1, is_genome_db2,
603                                            gb_species1, NULL,
604                                            source_organism_hash, dest_species_hash,
605                                            error_suppressor);
606            aw_status(++count/double(queried));
607        }
608    }
609
610    GBS_free_hash(dest_species_hash);
611    if (source_organism_hash) GBS_free_hash(source_organism_hash);
612    GBS_free_hash(error_suppressor);
613   
614    if (error) {
615        GB_abort_transaction(GLOBAL_gb_merge);
616        GB_abort_transaction(GLOBAL_gb_dest);
617        aw_message(error);
618    }
619    else {
620        MG_transfer_fields_info();
621        GB_commit_transaction(GLOBAL_gb_merge);
622        GB_commit_transaction(GLOBAL_gb_dest);
623    }
624    aw_closestatus();
625}
626
627void MG_transfer_fields_cb(AW_window *aww){
628    if (MG_check_alignment(aww,1)) return;
629    char *field = aww->get_root()->awar(AWAR_FIELD1)->read_string();
630    long append = aww->get_root()->awar(AWAR_APPEND)->read_int();
631
632    if (!strlen(field)) {
633        delete field;
634        aw_message("ERROR: Please select a field you want to transfer");
635        return;
636    }
637    if (!strcmp(field,"name")) {
638        delete field;
639        aw_message("ERROR: You are not allowed to transfer the name field");
640        return;
641    }
642
643    aw_openstatus("Transferring fields");
644    GB_begin_transaction(GLOBAL_gb_merge);
645    GB_begin_transaction(GLOBAL_gb_dest);
646
647    GBDATA *gb_dest_species_data = GB_search(GLOBAL_gb_dest,"species_data",GB_CREATE_CONTAINER);
648
649    GBDATA *gb_species1;
650    GBDATA *gb_species2;
651    GBDATA *gb_name1;
652    GBDATA *gb_name2;
653    GBDATA *gb_field1;
654    GBDATA *gb_field2;
655    int type1;
656    int type2;
657    GB_ERROR error = 0;
658    GB_BOOL transfer_of_alignment = GB_FALSE;
659    if (GBS_string_matches(field,"ali_*/data",GB_MIND_CASE)){
660        transfer_of_alignment = GB_TRUE;
661    }
662    MG_remaps rm(GLOBAL_gb_merge,GLOBAL_gb_dest,aww->get_root());
663    for (gb_species1 = GBT_first_species(GLOBAL_gb_merge);
664         gb_species1;
665         gb_species1 = GBT_next_species(gb_species1))
666    {
667        if (IS_QUERIED(gb_species1)) {
668            gb_name1 = GB_entry(gb_species1,"name");
669            if (!gb_name1) continue;    // no name what happend ???
670            gb_species2 = GB_find_string(gb_dest_species_data,"name", GB_read_char_pntr(gb_name1), GB_IGNORE_CASE, down_2_level);
671
672            if (!gb_species2) {
673                gb_species2 = GB_create_container(gb_dest_species_data,"species");
674                if (!gb_species2) {
675                    error = GB_get_error();
676                    break;
677                }
678                gb_name2 = GB_search(gb_species2,"name",GB_STRING);
679                if (!gb_name2) {
680                    error = GB_get_error();
681                    break;
682                }
683                char *name = GB_read_string(gb_name1);
684                error = GB_write_string(gb_name2,name);
685                delete name;
686                if (error) break;
687            }else{
688                gb_species2 = GB_get_father(gb_species2);
689            }
690
691            gb_field1 = GB_search(gb_species1,field,GB_FIND);
692            gb_field2 = GB_search(gb_species2,field,GB_FIND);
693
694            if (gb_field2 && gb_field1){
695                type1 = GB_read_type(gb_field1);
696                type2 = GB_read_type(gb_field2);
697                if ( (type1==type2) && (GB_DB != type1) ) {
698                    if (append && type1 == GB_STRING) {
699                        char *s1 = GB_read_string(gb_field1);
700                        char *s2 = GB_read_string(gb_field2);
701                        if ( !GBS_find_string(s2,s1,0) ) {
702                            char *s = (char *)malloc(strlen(s1) + strlen(s2) + 2);
703                            sprintf(s,"%s %s",s2,s1);
704                            error = GB_write_string(gb_field2,s);
705                            delete s;
706                            GB_write_flag(gb_species2,1);
707                        }
708
709                        delete s1;
710                        delete s2;
711                    }else{
712                        error = GB_copy(gb_field2,gb_field1);
713                        GB_write_flag(gb_species2,1);
714                        if (transfer_of_alignment && !error){
715                            error = MG_transfer_sequence(&rm,gb_species1,gb_species2);
716                        }
717                    }
718                    if (error) break;
719                    continue;
720                }
721            }
722
723            if (gb_field2){
724                if (gb_field1 && !append)   error = GB_delete(gb_field2);
725                if (error) break;
726            }
727            if (!gb_field1) continue;
728
729            type1 = GB_read_type(gb_field1);
730            gb_field2 = GB_search(gb_species2,field,type1);
731            if (!gb_field2) {
732                error = GB_get_error();
733                break;
734            }
735            if (!error) error = GB_copy(gb_field2,gb_field1);
736            if (error) break;
737        }
738    }
739
740    if (error){
741        GB_abort_transaction(GLOBAL_gb_merge);
742        GB_abort_transaction(GLOBAL_gb_dest);
743        aw_message(error);
744    }else{
745        MG_transfer_fields_info(field);
746        GB_commit_transaction(GLOBAL_gb_merge);
747        GB_commit_transaction(GLOBAL_gb_dest);
748    }
749    aw_closestatus();
750    delete field;
751}
752
753AW_window *MG_transfer_fields(AW_root *aw_root)
754{
755    GB_transaction dummy(GLOBAL_gb_merge);
756    //  awt_selection_list_rescan(gb_merge,AWT_NDS_FILTER);
757
758    AW_window_simple *aws = new AW_window_simple;
759    aws->init( aw_root, "MERGE_TRANSFER_FIELD", "TRANSFER FIELD");
760    aws->load_xfig("merge/mg_transfield.fig");
761    aws->button_length(13);
762
763    aws->callback( AW_POPDOWN);
764    aws->at("close");
765    aws->create_button("CLOSE","CLOSE","C");
766
767    aws->at("go");
768    aws->callback(MG_transfer_fields_cb);
769    aws->create_button("GO","GO");
770
771    aws->at("help");
772    aws->callback(AW_POPUP_HELP,(AW_CL)"mg_spec_sel_field.hlp");
773    aws->create_button("HELP","HELP");
774
775    aws->at("append");
776    aws->create_toggle(AWAR_APPEND);
777
778    awt_create_selection_list_on_scandb(GLOBAL_gb_merge,
779                                        (AW_window*)aws,AWAR_FIELD1,
780                                        AWT_NDS_FILTER,
781                                        "scandb","rescandb", &AWT_species_selector, 20, 10);
782
783    return (AW_window*)aws;
784}
785
786void MG_move_field_cb(AW_window *aww){
787    AW_root *aw_root = aww->get_root();
788    if (MG_check_alignment(aww,1)) return;
789    char *field = aww->get_root()->awar(AWAR_FIELD1)->read_string();
790
791    if (!strlen(field)) {
792        delete field;
793        aw_message("ERROR: Please select a field you want to transfer");
794        return;
795    }
796    if (!strcmp(field,"name")) {
797        delete field;
798        aw_message("ERROR: You are not allowed to transfer the name field");
799        return;
800    }
801
802    aw_openstatus("Cross Move field");
803    GB_begin_transaction(GLOBAL_gb_merge);
804    GB_begin_transaction(GLOBAL_gb_dest);
805
806    char   *source      = aw_root->awar(AWAR_SPECIES1)->read_string();
807    GBDATA *gb_species1 = GBT_find_species(GLOBAL_gb_merge,source);
808    delete source;
809    if (!gb_species1){
810        aw_closestatus();
811        aw_message("Please select a species in left hitlist");
812        return;
813    }
814
815    char   *dest        = aw_root->awar(AWAR_SPECIES2)->read_string();
816    GBDATA *gb_species2 = GBT_find_species(GLOBAL_gb_dest,dest);
817    delete dest;
818    if (!gb_species2){
819        aw_closestatus();
820        aw_message("Please select a species in right hitlist");
821        return;
822    }
823
824    GBDATA   *gb_field1;
825    GBDATA   *gb_field2;
826    int       type1;
827    int       type2;
828    GB_ERROR  error = 0;
829
830    gb_field1 = GB_search(gb_species1,field,GB_FIND);
831    if (!gb_field1) {
832        error = GB_export_error("Species 1 has no field '%s'",field);
833    }
834    gb_field2 = GB_search(gb_species2,field,GB_FIND);
835    while (!error) {
836        if (gb_field2){
837            type1 = GB_read_type(gb_field1);
838            type2 = GB_read_type(gb_field2);
839            if ( (type1==type2) && (GB_DB != type1) ) {
840                error = GB_copy(gb_field2,gb_field1);
841                break;
842            }
843        }
844        if (gb_field2){
845            error = GB_delete(gb_field2);
846            if (error) break;
847        }
848
849        type1 = GB_read_type(gb_field1);
850        gb_field2 = GB_search(gb_species2,field,type1);
851        if (!gb_field2) error = GB_get_error();
852        if (!error) error = GB_copy(gb_field2,gb_field1);
853        break;
854    }
855
856
857    if (error){
858        GB_abort_transaction(GLOBAL_gb_merge);
859        GB_abort_transaction(GLOBAL_gb_dest);
860        aw_message(error);
861    }else{
862        GB_write_flag(gb_species2,1);
863        MG_transfer_fields_info(field);
864        GB_commit_transaction(GLOBAL_gb_merge);
865        GB_commit_transaction(GLOBAL_gb_dest);
866    }
867    aw_closestatus();
868    delete field;
869}
870
871AW_window *create_mg_move_fields(AW_root *aw_root)
872{
873    GB_transaction dummy(GLOBAL_gb_merge);
874
875    AW_window_simple *aws = new AW_window_simple;
876    aws->init( aw_root, "MERGE_CROSS_MOVE_FIELD", "CROSS MOVE FIELD");
877    aws->load_xfig("merge/mg_movefield.fig");
878    aws->button_length(13);
879
880    aws->callback( AW_POPDOWN);
881    aws->at("close");
882    aws->create_button("CLOSE","CLOSE","C");
883
884    aws->at("go");
885    aws->callback(MG_move_field_cb);
886    aws->create_button("GO","GO");
887
888    aws->at("help");
889    aws->callback(AW_POPUP_HELP,(AW_CL)"movefield.hlp");
890    aws->create_button("HELP","HELP");
891
892
893    awt_create_selection_list_on_scandb(GLOBAL_gb_merge,
894                                        (AW_window*)aws,AWAR_FIELD1,
895                                        AWT_NDS_FILTER,
896                                        "scandb","rescandb", &AWT_species_selector, 20, 10);
897
898    return (AW_window*)aws;
899}
900
901void MG_merge_tagged_field_cb(AW_window *aww){
902    AW_root *awr = aww->get_root();
903    GB_begin_transaction(GLOBAL_gb_dest);
904    GB_transaction dummy(GLOBAL_gb_merge);
905    GB_ERROR error =  0;
906    char *f1 = awr->awar(AWAR_FIELD1)->read_string();
907    char *f2 = awr->awar(AWAR_FIELD2)->read_string();
908    char *tag1 = awr->awar(AWAR_TAG1)->read_string();
909    char *tag2= awr->awar(AWAR_TAG2)->read_string();
910
911    char *tag_del1= awr->awar(AWAR_TAG_DEL1)->read_string();
912
913
914    GBDATA *gb_dest_species_data = GB_search(GLOBAL_gb_dest,"species_data",GB_CREATE_CONTAINER);
915
916    GBDATA *gb_species1;
917    GBDATA *gb_species2;
918    GBDATA *gb_name1;
919    GBDATA *gb_field1;
920    GBDATA *gb_field2;
921    int type1;
922    int type2;
923    char *name = 0;
924    for (gb_species1 = GBT_first_species(GLOBAL_gb_merge);
925         gb_species1;
926         gb_species1 = GBT_next_species(gb_species1)){
927        if (IS_QUERIED(gb_species1)) {
928            gb_name1 = GB_entry(gb_species1,"name");
929            if (!gb_name1) continue;    // no name what happend ???
930            delete name;
931            name = GB_read_string(gb_name1);
932            gb_species2 = GBT_create_species_rel_species_data(gb_dest_species_data,name);
933
934            if (!gb_species2) {
935                error = GB_get_error();
936                break;
937            }
938
939            char *s1;
940            char *s2;
941
942            gb_field1 = GB_search(gb_species1,f1,GB_FIND);
943            if (gb_field1) {
944                type1 = GB_read_type(gb_field1);
945                if (type1 != GB_STRING) {
946                    error = GB_export_error("Field '%s' in species '%s' in DB1 is not of type STRING",f1,name);
947                    break;
948                }
949                s1 = GB_read_string(gb_field1);
950            }else{
951                s1 = strdup("");
952            }
953
954            gb_field2 = GBT_search_string(gb_species2,f2,"");
955            if (gb_field2) {
956                type2 = GB_read_type(gb_field2);
957                if (type2 != GB_STRING) {
958                    error = GB_export_error("Field '%s' in species '%s' in DB2 is not of type STRING",f2,name);
959                    break;
960                }
961                s2 = GB_read_string(gb_field2);
962            }else{
963                error = GB_get_error();
964                break;
965            }
966
967            char *sum = GBS_merge_tagged_strings(s1,tag1,tag_del1,s2,tag2,tag_del1);
968            if (!sum) error = GB_get_error();
969
970            if (!error) error = GB_write_string (gb_field2,sum);
971            delete sum;
972            delete s1;
973            delete s2;
974
975            GB_write_flag(gb_species2,1);
976            if (error) break;
977        }
978    }
979    delete name;
980    delete  tag_del1;
981    delete  tag2;
982    delete  tag1;
983    delete  f2;
984    delete  f1;
985
986    if (error) {
987        aw_message(error);
988        GB_abort_transaction(GLOBAL_gb_dest);
989    }else{
990        GB_commit_transaction(GLOBAL_gb_dest);
991    }
992}
993
994AW_window *create_mg_merge_tagged_fields(AW_root *aw_root)
995{
996    static AW_window_simple *aws = 0;
997    if (aws) return aws;
998
999    GB_transaction dummy(GLOBAL_gb_merge);
1000
1001    aw_root->awar_string( AWAR_FIELD1,"full_name");
1002    aw_root->awar_string( AWAR_FIELD2,"full_name");
1003
1004    aw_root->awar_string( AWAR_TAG1,"S");
1005    aw_root->awar_string( AWAR_TAG2,"D");
1006
1007    aw_root->awar_string( AWAR_TAG_DEL1,"S*");
1008
1009    aws = new AW_window_simple;
1010    aws->init( aw_root, "MERGE_TAGGED_FIELDS", "MERGE TAGGED FIELDS");
1011    aws->load_xfig("merge/mg_mergetaggedfield.fig");
1012    aws->button_length(13);
1013
1014    aws->callback( AW_POPDOWN);
1015    aws->at("close");
1016    aws->create_button("CLOSE","CLOSE","C");
1017
1018    aws->at("go");
1019    aws->callback(MG_merge_tagged_field_cb);
1020    aws->create_button("GO","GO");
1021
1022    aws->at("help");
1023    aws->callback(AW_POPUP_HELP,(AW_CL)"mergetaggedfield.hlp");
1024    aws->create_button("HELP","HELP");
1025
1026    aws->at("tag1");    aws->create_input_field(AWAR_TAG1,5);
1027    aws->at("tag2");    aws->create_input_field(AWAR_TAG2,5);
1028
1029    aws->at("del1");    aws->create_input_field(AWAR_TAG_DEL1,5);
1030
1031    awt_create_selection_list_on_scandb(GLOBAL_gb_merge, (AW_window*)aws,AWAR_FIELD1,AWT_NDS_FILTER,"fields1",0, &AWT_species_selector, 20, 10);
1032    awt_create_selection_list_on_scandb(GLOBAL_gb_dest, (AW_window*)aws,AWAR_FIELD2,AWT_NDS_FILTER,"fields2",0, &AWT_species_selector, 20, 10);
1033
1034    return (AW_window*)aws;
1035}
1036
1037
1038const char *NEW_NAME_AWAR = "tmp/simple_import/new_species_name";
1039
1040
1041
1042GB_ERROR MG_equal_alignments(bool autoselect_equal_alignment_name) {
1043    /** First big job:  Make the alignment names equal */
1044    char **   M_alignment_names = GBT_get_alignment_names(GLOBAL_gb_merge);
1045    char **   D_alignment_names = GBT_get_alignment_names(GLOBAL_gb_dest);
1046    GB_ERROR  error             = 0;
1047    char     *dest              = 0;
1048
1049    if (M_alignment_names[0] == 0) {
1050        error =  GB_export_error("No source sequences found");
1051    }
1052    else {
1053        char *type = GBT_get_alignment_type_string(GLOBAL_gb_merge,M_alignment_names[0]);
1054        int   s;
1055        int   d;
1056
1057        for (s=0,d=0;D_alignment_names[s];s++){
1058            char *type2 = GBT_get_alignment_type_string(GLOBAL_gb_dest,D_alignment_names[s]);
1059            if (strcmp(type, type2) == 0) {
1060                D_alignment_names[d] = D_alignment_names[s];
1061                if (d != s) D_alignment_names[s] = 0;
1062                ++d;
1063            }
1064            else {
1065                free(D_alignment_names[s]);
1066                D_alignment_names[s] = 0;
1067            }
1068            free(type2);
1069        }
1070
1071        GBS_strstruct *str;
1072        char          *b;
1073        int            aliid;
1074
1075        switch (d) {
1076            case 0:
1077                error = GB_export_error("Cannot find a target alignment with a type of '%s'\n"
1078                                        "You should create one first or select a different alignment type\n"
1079                                        "during sequence import",type);
1080                break;
1081            case 1:
1082                dest = D_alignment_names[0];
1083                break;
1084
1085            default:
1086                int i;
1087
1088                if (autoselect_equal_alignment_name) {
1089                    for (i = 0; i<d; ++i) {
1090                        if (ARB_stricmp(M_alignment_names[0], D_alignment_names[i]) == 0) {
1091                            dest = D_alignment_names[i];
1092                            break;
1093                        }
1094                    }
1095                }
1096
1097                if (!dest) {
1098                    str = GBS_stropen(100);
1099
1100                    for (i=0;i<d;i++){
1101                        GBS_strcat(str,D_alignment_names[i]);
1102                        GBS_chrcat(str,',');
1103                    }
1104                    GBS_strcat(str,"ABORT");
1105
1106                    b = GBS_strclose(str);
1107                    aliid = aw_message("There are more than one possible alignment targets\n"
1108                                       "Choose one destination alignment or ABORT",b);
1109                    free(b);
1110                    if (aliid >= d) {
1111                        error = "Operation Aborted";
1112                        break;
1113                    }
1114                    dest = D_alignment_names[aliid];
1115                }
1116                break;
1117        }
1118        if (!error && dest && strcmp(M_alignment_names[0], dest) != 0) {
1119            error = GBT_rename_alignment(GLOBAL_gb_merge,M_alignment_names[0], dest, 1, 1);
1120            if (error) {
1121                error = GBS_global_string("Failed to rename alignment '%s' to '%s' (Reason: %s)",
1122                                          M_alignment_names[0], dest, error);
1123            }
1124            else {
1125                awt_add_new_changekey(GLOBAL_gb_merge, GBS_global_string("%s/data",dest),GB_STRING);
1126            }
1127        }
1128        free(type);
1129    }
1130    GBT_free_names(M_alignment_names);
1131    GBT_free_names(D_alignment_names);
1132
1133    return error;
1134}
1135
1136/** Merge the sequences of two databases */
1137GB_ERROR MG_simple_merge(AW_root *awr) {
1138    static char *m_name         = 0;
1139    GB_ERROR     error          = 0;
1140    GBDATA      *M_species_data = 0;
1141    GBDATA      *D_species_data = 0;
1142    int          overwriteall   = 0;
1143    int          autorenameall  = 0;
1144    GB_HASH     *D_species_hash = 0;
1145
1146    GB_push_my_security(GLOBAL_gb_merge);
1147    GB_push_my_security(GLOBAL_gb_dest);
1148    GB_begin_transaction(GLOBAL_gb_merge);
1149    GB_begin_transaction(GLOBAL_gb_dest);
1150
1151    error = MG_equal_alignments(true);
1152    if (error) goto end;
1153
1154    M_species_data = GB_search(GLOBAL_gb_merge,"species_data",GB_CREATE_CONTAINER);
1155    D_species_data = GB_search(GLOBAL_gb_dest,"species_data",GB_CREATE_CONTAINER);
1156
1157    GBDATA *M_species;
1158    GBDATA *D_species;
1159    free(m_name); m_name = 0;
1160
1161    {
1162        long M_species_count = GB_number_of_subentries(M_species_data);
1163        long D_species_count = GB_number_of_subentries(D_species_data);
1164
1165        // create hash containing all species from gb_dest,
1166        // but sized to hold all species from both DBs:
1167        D_species_hash = GBT_create_species_hash_sized(GLOBAL_gb_dest, M_species_count+D_species_count);
1168    }
1169
1170    for (M_species = GB_entry(M_species_data,"species"); M_species; M_species = GB_nextEntry(M_species)) {
1171        GBDATA *M_name       = GB_search(M_species,"name",GB_STRING);
1172        free(m_name); m_name = GB_read_string(M_name);
1173
1174        int count = 1;
1175
1176    new_try:
1177
1178        count++;
1179       
1180        D_species = (GBDATA*)GBS_read_hash(D_species_hash, m_name);
1181        if (D_species){
1182            if (overwriteall) {
1183                error = GB_delete(D_species);
1184            }
1185            else if (autorenameall) {
1186                GB_ERROR  dummy;
1187                char     *newname = AWTC_create_numbered_suffix(D_species_hash, m_name, dummy);
1188
1189                mg_assert(newname);
1190
1191                free(m_name);
1192                m_name = newname;
1193            }
1194            else {
1195                switch (aw_message(GBS_global_string(
1196                                                     "Warning:  There is a name conflict for species '%s'\n"
1197                                                     "  You may:\n"
1198                                                     "  - Overwrite existing species\n"
1199                                                     "  - Overwrite all species with name conflicts\n"
1200                                                     "  - Not import species\n"
1201                                                     "  - Rename imported species\n"
1202                                                     "  - Automatically rename species (append .NUM)\n"
1203                                                     "  - Abort everything", m_name),
1204                                   "overwrite, overwrite all, don't import, rename, auto-rename, abort")){
1205                    case 1:
1206                        overwriteall = 1;
1207                    case 0:
1208                        GB_delete(D_species);
1209                        break;
1210                       
1211                    case 2:
1212                        continue;
1213
1214                    case 3: {
1215                        GB_ERROR  dummy;
1216                        char     *newname = AWTC_create_numbered_suffix(D_species_hash, m_name, dummy);
1217                        awr->awar_string(NEW_NAME_AWAR)->write_string(newname ? newname : "???");
1218                        free(newname);
1219
1220                        free(m_name);
1221                        m_name = aw_input("New name of species",NEW_NAME_AWAR);
1222
1223                        goto new_try;
1224                    }
1225                    case 4:
1226                        autorenameall = 1;
1227                        goto new_try;
1228                       
1229                    case 5:
1230                        error = "Operation aborted";
1231                        goto end;
1232                }
1233            }
1234        }
1235
1236        if (!error) {
1237            D_species      = GB_create_container(D_species_data,"species");
1238            if (!D_species) {
1239                error = GB_get_error();
1240            }
1241            else {
1242                error             = GB_copy(D_species, M_species);
1243                if (!error) error = GB_write_flag(D_species,1); // mark species
1244                if (!error) error = GB_write_usr_private(D_species,255); // put in hitlist
1245                if (!error) {
1246                    GBDATA *D_name = GB_search(D_species,"name",GB_STRING);
1247                    if (!D_name) {
1248                        error = GB_get_error();
1249                    }
1250                    else {
1251                        error = GB_write_string(D_name,m_name);
1252                    }
1253                }
1254            }
1255
1256            GBS_write_hash(D_species_hash, m_name, (long)D_species);
1257        }
1258
1259        if (error) break;
1260    }
1261
1262 end:
1263
1264    if (D_species_hash) GBS_free_hash(D_species_hash);
1265   
1266    if (error) {
1267        GB_abort_transaction(GLOBAL_gb_merge);
1268        GB_abort_transaction(GLOBAL_gb_dest);
1269        aw_message(error);
1270    }
1271    else {
1272        MG_transfer_fields_info();
1273        GB_commit_transaction(GLOBAL_gb_merge);
1274        GB_commit_transaction(GLOBAL_gb_dest);
1275
1276        awr->awar(AWAR_SPECIES_NAME)->write_string(m_name);
1277    }
1278   
1279    GB_pop_my_security(GLOBAL_gb_merge);
1280    GB_pop_my_security(GLOBAL_gb_dest);
1281    return error;
1282}
1283
1284//  ---------------------------
1285//      MG_species_selector
1286//  ---------------------------
1287
1288static void mg_select_species1(GBDATA* , AW_root *aw_root, const char *item_name) {
1289    aw_root->awar(AWAR_SPECIES1)->write_string(item_name);
1290}
1291static void mg_select_species2(GBDATA* , AW_root *aw_root, const char *item_name) {
1292    aw_root->awar(AWAR_SPECIES2)->write_string(item_name);
1293}
1294
1295static GBDATA *mg_get_first_species_data1(GBDATA *, AW_root *, AWT_QUERY_RANGE) {
1296    return GBT_get_species_data(GLOBAL_gb_merge);
1297}
1298static GBDATA *mg_get_first_species_data2(GBDATA *, AW_root *, AWT_QUERY_RANGE) {
1299    return GBT_get_species_data(GLOBAL_gb_dest);
1300}
1301
1302static GBDATA *mg_get_selected_species1(GBDATA */*gb_main*/, AW_root *aw_root) {
1303    GB_transaction dummy(GLOBAL_gb_merge);
1304    char   *species_name            = aw_root->awar(AWAR_SPECIES1)->read_string();
1305    GBDATA *gb_species              = 0;
1306    if (species_name[0]) gb_species = GBT_find_species(GLOBAL_gb_merge, species_name);
1307    free(species_name);
1308    return gb_species;
1309}
1310static GBDATA *mg_get_selected_species2(GBDATA */*gb_main*/, AW_root *aw_root) {
1311    GB_transaction dummy(GLOBAL_gb_dest);
1312    char   *species_name            = aw_root->awar(AWAR_SPECIES2)->read_string();
1313    GBDATA *gb_species              = 0;
1314    if (species_name[0]) gb_species = GBT_find_species(GLOBAL_gb_dest, species_name);
1315    free(species_name);
1316    return gb_species;
1317}
1318
1319static struct ad_item_selector MG_species_selector[2];
1320
1321static void mg_initialize_species_selectors() {
1322    static int initialized = 0;
1323    if (!initialized) {
1324        MG_species_selector[0] = AWT_species_selector;
1325        MG_species_selector[1] = AWT_species_selector;
1326
1327        for (int s = 0; s <= 1; ++s) {
1328            ad_item_selector& sel = MG_species_selector[s];
1329
1330            sel.update_item_awars        = s ? mg_select_species2 : mg_select_species1;
1331            sel.get_first_item_container = s ? mg_get_first_species_data2 : mg_get_first_species_data1;
1332            sel.get_selected_item = s ? mg_get_selected_species2 : mg_get_selected_species1;
1333        }
1334
1335        initialized = 1;
1336    }
1337}
1338
1339AW_window *MG_merge_species_cb(AW_root *awr){
1340    static AW_window_simple_menu *aws = 0;
1341    if (aws) return (AW_window *)aws;
1342
1343    awr->awar_string(AWAR_REMAP_SPECIES_LIST, "ecoli",GLOBAL_gb_dest);
1344    awr->awar_int(AWAR_REMAP_ENABLE, 0, GLOBAL_gb_dest);
1345
1346    aws = new AW_window_simple_menu;
1347    aws->init( awr, "MERGE_TRANSFER_SPECIES", "TRANSFER SPECIES");
1348    aws->load_xfig("merge/species.fig");
1349
1350    aws->at("close");aws->callback((AW_CB0)AW_POPDOWN);
1351    aws->create_button("CLOSE","CLOSE","C");
1352
1353    aws->at("help");
1354    aws->callback(AW_POPUP_HELP,(AW_CL)"mg_species.hlp");
1355    aws->create_button("HELP","HELP","H");
1356
1357    awt_query_struct awtqs;
1358    aws->create_menu(0,"DB_I_Expert","D");
1359
1360    awtqs.gb_main             = GLOBAL_gb_merge;
1361    awtqs.gb_ref              = GLOBAL_gb_dest;
1362    awtqs.look_in_ref_list    = AW_FALSE;
1363    awtqs.species_name        = AWAR_SPECIES1;
1364    awtqs.tree_name           = 0; // no selected tree here -> can't use tree related ACI commands without specifying a tree
1365    awtqs.select_bit          = 1;
1366    awtqs.ere_pos_fig         = "ere1";
1367    awtqs.by_pos_fig          = "by1";
1368    awtqs.qbox_pos_fig        = "qbox1";
1369    awtqs.rescan_pos_fig      = "rescan1";
1370    awtqs.key_pos_fig         = 0;
1371    awtqs.query_pos_fig       = "content1";
1372    awtqs.result_pos_fig      = "result1";
1373    awtqs.count_pos_fig       = "count1";
1374    awtqs.do_query_pos_fig    = "doquery1";
1375    awtqs.config_pos_fig      = "doconfig1";
1376    awtqs.do_mark_pos_fig     = 0;
1377    awtqs.do_unmark_pos_fig   = 0;
1378    awtqs.do_delete_pos_fig   = "dodelete1";
1379    awtqs.do_set_pos_fig      = "doset1";
1380    awtqs.do_refresh_pos_fig  = "dorefresh1";
1381    awtqs.open_parser_pos_fig = "openparser1";
1382    awtqs.use_menu            = 1;
1383
1384    mg_initialize_species_selectors();
1385    awtqs.selector = &(MG_species_selector[0]);
1386
1387    awt_create_query_box((AW_window*)aws,&awtqs);
1388
1389    AW_CL scannerid      = awt_create_arbdb_scanner(GLOBAL_gb_merge, aws, "box1",0,0,0,AWT_SCANNER,0,0,AWT_NDS_FILTER, awtqs.selector);
1390    ad_global_scannerid1 = scannerid;
1391    aws->get_root()->awar(AWAR_SPECIES1)->add_callback(AD_map_species1);
1392
1393    aws->create_menu(0,"DB_II_Expert","B");
1394
1395    awtqs.gb_main             = GLOBAL_gb_dest;
1396    awtqs.gb_ref              = GLOBAL_gb_merge;
1397    awtqs.look_in_ref_list    = AW_TRUE;
1398    awtqs.species_name        = AWAR_SPECIES2;
1399    awtqs.select_bit          = 1;
1400    awtqs.ere_pos_fig         = "ere2";
1401    awtqs.by_pos_fig          = "by2";
1402    awtqs.qbox_pos_fig        = "qbox2";
1403    awtqs.rescan_pos_fig      = "rescan2";
1404    awtqs.key_pos_fig         = 0;
1405    awtqs.query_pos_fig       = "content2";
1406    awtqs.result_pos_fig      = "result2";
1407    awtqs.count_pos_fig       = "count2";
1408    awtqs.do_query_pos_fig    = "doquery2";
1409    awtqs.config_pos_fig      = "doconfig2";
1410    awtqs.do_mark_pos_fig     = 0;
1411    awtqs.do_unmark_pos_fig   = 0;
1412    awtqs.do_delete_pos_fig   = "dodelete2";
1413    awtqs.do_set_pos_fig      = "doset2";
1414    awtqs.do_refresh_pos_fig  = "dorefresh2";
1415    awtqs.open_parser_pos_fig = "openparser2";
1416
1417    awtqs.selector = &(MG_species_selector[1]);
1418
1419    awt_create_query_box((AW_window*)aws,&awtqs);
1420
1421    scannerid            = awt_create_arbdb_scanner(GLOBAL_gb_dest, aws, "box2",0,0,0,AWT_SCANNER,0,0,AWT_NDS_FILTER, awtqs.selector);
1422    ad_global_scannerid2 = scannerid;
1423    aws->get_root()->awar(AWAR_SPECIES2)->add_callback(AD_map_species2);
1424
1425    // big transfer buttons:
1426    aws->button_length(13);
1427    {
1428        aws->shadow_width(3);
1429
1430        aws->at("transsspec");
1431        aws->callback(MG_transfer_selected_species);
1432        aws->create_button("TRANSFER_SELECTED_DELETE_DUPLICATED",
1433                           "TRANSFER\nSELECTED\nSPECIES\n\nDELETE\nDUPLICATE\nIN DB II","T");
1434
1435        aws->at("translspec");
1436        aws->callback(MG_transfer_species_list);
1437        aws->create_button("TRANSFER_LISTED_DELETE_DUPLI",
1438                           "TRANSFER\nLISTED\nSPECIES\n\nDELETE\nDUPLICATES\nIN DB II","T");
1439
1440        aws->at("transfield");
1441        aws->callback(AW_POPUP,(AW_CL)MG_transfer_fields,0);
1442        aws->create_button("TRANSFER_FIELD_OF_LISTED_DELETE_DUPLI",
1443                           "TRANSFER\nFIELD\nOF LISTED\nSPECIES\n\nDELETE\nDUPLICATES\nIN DB II","T");
1444
1445        aws->shadow_width(1);
1446    }
1447
1448    // adapt alignments
1449    aws->button_length(7);
1450    aws->at("adapt");
1451    aws->create_toggle(AWAR_REMAP_ENABLE);
1452
1453    aws->at("reference");
1454    aws->create_text_field(AWAR_REMAP_SPECIES_LIST);
1455
1456    aws->at("pres_sel");
1457    aws->callback((AW_CB1)AW_POPUP,(AW_CL)MG_select_preserves_cb);
1458    aws->create_button("SELECT", "SELECT", "S");
1459
1460    // top icon
1461    aws->button_length(0);
1462    aws->at("icon");
1463    aws->callback(AW_POPUP_HELP,(AW_CL)"mg_species.hlp");
1464    aws->create_button("HELP_MERGE", "#merge/icon.bitmap");
1465
1466    aws->create_menu(0,"DB1->DB2","-");
1467    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);
1468    aws->insert_menu_topic( "move_field_of_selected",   "Move one field of selected left species to same field of selected right species","M",
1469                            "movefield.hlp", AWM_ALL, AW_POPUP,(AW_CL)create_mg_move_fields,0);
1470    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",
1471                            "mergetaggedfield.hlp", AWM_ALL, AW_POPUP,(AW_CL)create_mg_merge_tagged_fields,0);
1472
1473    aws->insert_separator();
1474    aws->insert_menu_topic("def_gene_species_field_xfer", "Define field transfer for gene-species", "g", "gene_species_field_transfer.hlp",
1475                           AWM_ALL, AW_POPUP, (AW_CL)MG_gene_species_create_field_transfer_def_window, 0);
1476
1477    return (AW_window *)aws;
1478}
Note: See TracBrowser for help on using the repository browser.