source: tags/initial/NTREE/NT_edconf.cxx

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.4 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <assert.h>
5
6#include <arbdb.h>
7#include <arbdbt.h>
8#include <aw_awars.hxx>
9#include <aw_root.hxx>
10#include <aw_device.hxx>
11#include <aw_window.hxx>
12
13#include "nt_edconf.hxx"
14
15#include <awt.hxx>
16#include <awt_canvas.hxx>
17#include <awt_tree.hxx>
18#include <awt_dtree.hxx>
19
20extern GBDATA *gb_main;
21
22// stores a amount of species:
23
24class Store_species 
25{
26    GBT_TREE *node;
27    Store_species *next;
28public:   
29    Store_species(GBT_TREE *aNode) {
30        node = aNode;
31        next = 0;
32    }
33    ~Store_species();
34   
35    Store_species* add(Store_species *list) {
36        assert(next==0);
37        next = list;
38        return this;
39    }   
40   
41    Store_species* remove() {
42        Store_species *follower = next;
43        next = 0;
44        return follower;
45    }
46   
47    GBT_TREE *getNode() const { return node; }
48   
49    void call(void (*aPizza)(GBT_TREE*)) const;
50};
51
52Store_species::~Store_species() {
53    delete next;
54}
55
56void Store_species::call(void (*aPizza)(GBT_TREE*)) const {
57    aPizza(node);
58    if (next) next->call(aPizza);
59}   
60
61static void unmark_species(GBT_TREE *node) {   
62    assert(node);
63    assert(node->gb_node);
64    assert(GB_read_flag(node->gb_node)!=0);
65    GB_write_flag(node->gb_node, 0);
66}
67
68static void mark_species(GBT_TREE *node, Store_species **extra_marked_species) {   
69    assert(node);
70    assert(node->gb_node);
71    assert(GB_read_flag(node->gb_node)==0);
72    GB_write_flag(node->gb_node, 1);
73   
74    *extra_marked_species = (new Store_species(node))->add(*extra_marked_species);
75}
76
77
78/** Builds a configuration string from a tree. Returns the number of marked species */
79/* Syntax:
80   
81   TAG  1 byte  'GFELS'
82   
83        G       group
84        F       folded group
85        E       end of group
86        L       species
87        S       SAI
88       
89   String       
90   Seperator (char)1
91
92        X::     Y '\0'
93        Y::     eps
94        Y::     '\AL' 'Name' Y
95        Y::     '\AS' 'Name' Y
96        Y::     '\AG' 'Gruppenname' '\A' Y '\AE'
97        Y::     '\AF' 'Gruppenname' '\A' Y '\AE'
98*/
99
100GBT_TREE *rightmost_leaf(GBT_TREE *node) {
101    assert(node);
102    while (!node->is_leaf) {
103        node = node->rightson;
104        assert(node);
105    }   
106    return node;
107}
108
109GBT_TREE *left_neighbour_leaf(GBT_TREE *node) {
110    if (node) {
111        GBT_TREE *father = node->father;
112        while (father) {
113            if (father->rightson==node) {
114                node = rightmost_leaf(father->leftson);
115                assert(node->is_leaf);
116                if (!node->gb_node) { // Zombie
117                    node = left_neighbour_leaf(node);
118                }
119                return node;
120            }
121            node = father;
122            father = node->father;
123        }
124    }
125    return 0;
126}
127
128int nt_build_conf_string_rek(GB_HASH *used,GBT_TREE *tree, void *memfile,
129                             Store_species **extra_marked_species, // all extra marked species are inserted here
130                             int use_species_aside, // # of species to mark left and right of marked species
131                             int *auto_mark, // # species to extra-mark (if not already marked)
132                             int marked_at_left, // # of species which were marked (looking to left)
133                             int *marked_at_right) // # of species which are marked (when returning from rekursion)
134{
135    if (!tree) return 0;
136    if (tree->is_leaf){
137        if (!tree->gb_node) {
138            *marked_at_right = marked_at_left;
139            return 0;   // Zombie
140        }
141       
142        if (!GB_read_flag(tree->gb_node)) { // unmarked species
143            if (*auto_mark) {
144                (*auto_mark)--;
145                mark_species(tree, extra_marked_species);
146            }
147            else {
148                *marked_at_right = 0;
149                return 0;       
150            }
151        }
152        else { // marked species
153            if (marked_at_left<use_species_aside) {
154                assert(marked_at_left>=0);
155                GBT_TREE *leaf_at_left = tree;
156                int step_over = marked_at_left+1; // step over myself
157                int then_mark = use_species_aside-marked_at_left;
158           
159                while (step_over--) {
160                    leaf_at_left = left_neighbour_leaf(leaf_at_left);
161                }
162               
163                Store_species *marked_back = 0;
164                while (then_mark--) {
165                    mark_species(leaf_at_left, extra_marked_species);
166                    marked_back = (new Store_species(leaf_at_left))->add(marked_back);             
167                    leaf_at_left = left_neighbour_leaf(leaf_at_left);
168                }
169               
170                while (marked_back) {               
171                    GBS_chrcat(memfile,1);                              // Seperated by 1
172                    GBS_strcat(memfile,"L");
173                    GBS_strcat(memfile,marked_back->getNode()->name);
174                    GBS_write_hash(used,marked_back->getNode()->name,1);                // Mark species
175       
176                    Store_species *rest = marked_back->remove();
177                    delete marked_back;
178                    marked_back = rest;
179                }
180               
181                marked_at_left = use_species_aside;
182            }
183            // now use_species_aside species to left are marked!           
184            *auto_mark = use_species_aside;
185        }
186       
187        GBS_chrcat(memfile,1);                          // Seperated by 1
188        GBS_strcat(memfile,"L");
189        GBS_strcat(memfile,tree->name);
190        GBS_write_hash(used,tree->name,1);              // Mark species
191       
192        *marked_at_right = marked_at_left+1;   
193        return 1;
194    }
195   
196    long oldpos = GBS_memoffset(memfile);
197    if (tree->gb_node && tree->name){           // but we are a group
198        GBDATA *gb_grouped = GB_find(tree->gb_node,"grouped",0,down_level);
199        GBS_chrcat(memfile,1);                          // Seperated by 1
200        if (gb_grouped && GB_read_byte(gb_grouped)) {
201            GBS_strcat(memfile,"F");
202        }else{
203            GBS_strcat(memfile,"G");
204        }
205
206        GBS_strcat(memfile,tree->name);
207    }   
208   
209    int right_of_leftson;
210    long nspecies = nt_build_conf_string_rek(used, tree->leftson, memfile, extra_marked_species, use_species_aside, auto_mark, marked_at_left, &right_of_leftson);   
211    nspecies += nt_build_conf_string_rek(used, tree->rightson, memfile, extra_marked_species, use_species_aside, auto_mark, right_of_leftson, marked_at_right);
212
213    if (tree->gb_node && tree->name){           // but we are a group
214        GBS_chrcat(memfile,1);                  // Seperated by 1
215        GBS_chrcat(memfile,'E');                // Group end indicated by 'E'
216    }
217
218    if (!nspecies) {
219        long newpos = GBS_memoffset(memfile);
220        GBS_str_cut_tail(memfile,newpos-oldpos);        // delete group info
221    }
222    return nspecies;
223}
224
225static void *nt_build_sai_middle_file;
226static const char *nt_build_sai_last_group_name;
227long nt_build_sai_sort_strings(const char *k0,long v0,const char *k1,long v1){
228    AWUSE(v0); AWUSE(v1);
229    return strcmp(k0,k1);
230}
231
232#ifdef __cplusplus
233extern "C" {
234#endif
235   
236    static long nt_build_sai_string_by_hash(const char *key,long val){
237        char *sep = strchr(key,1);
238        if (!sep) return val;   // what's wrong
239   
240        if (!nt_build_sai_last_group_name || strncmp(key,nt_build_sai_last_group_name,sep-key)){ // new group
241            if (nt_build_sai_last_group_name){
242                GBS_chrcat(nt_build_sai_middle_file,1);                         // Seperated by 1
243                GBS_chrcat(nt_build_sai_middle_file,'E');                               // End of old group
244            }
245            GBS_chrcat(nt_build_sai_middle_file,1);                             // Seperated by 1
246            GBS_strcat(nt_build_sai_middle_file,"FSAI:");
247            GBS_strncat(nt_build_sai_middle_file,key,sep-key);
248            nt_build_sai_last_group_name = key;   
249        }
250        GBS_chrcat(nt_build_sai_middle_file,1);                         // Seperated by 1
251        GBS_strcat(nt_build_sai_middle_file,"S");
252        GBS_strcat(nt_build_sai_middle_file,sep+1);
253        return val;
254    }
255   
256#ifdef __cplusplus
257}
258#endif
259   
260/** collect all Sais, place some SAI in top area, rest in middle */
261void nt_build_sai_string(void *topfile, void *middlefile){
262        GBDATA *gb_sai_data = GB_search(gb_main,"extended_data",GB_FIND);
263        if (!gb_sai_data) return;
264        GB_HASH *hash = GBS_create_hash(100,1);
265        GBDATA *gb_sai;
266        for (   gb_sai = GBT_first_SAI_rel_exdata(gb_sai_data);
267                gb_sai;
268                gb_sai = GBT_next_SAI(gb_sai)){
269                GBDATA *gb_name = GB_search(gb_sai,"name",GB_FIND);
270                if (!gb_name) continue;
271                char *name = GB_read_string(gb_name);
272                if (
273                        (!strcmp(name,  "HELIX")) ||
274                        (!strcmp(name,  "HELIX_NR")) ||
275                        (!strcmp(name,  "ECOLI"))
276                        ){
277                        GBS_chrcat(topfile,1);                          // Seperated by 1
278                        GBS_strcat(topfile,"S");
279                        GBS_strcat(topfile,name);
280                }else{
281                    GBDATA *gb_gn = GB_search(gb_sai,"sai_group",GB_FIND);
282                    char *gn;
283                    if (gb_gn){
284                        gn = GB_read_string(gb_gn);
285                    }else{
286                        gn = strdup("SAI's");
287                    }
288                    char *cn = new char[strlen(gn) + strlen(name) + 2];
289                    sprintf(cn,"%s%c%s",gn,1,name);
290                    GBS_write_hash(hash,cn,1);
291                    delete name;
292                    delete cn;
293                    delete gn;
294                }
295        }
296       
297        // open surrounding SAI-group:
298        GBS_chrcat(middlefile, 1);     
299        GBS_strcat(middlefile, "GSAI-Maingroup");
300       
301        nt_build_sai_last_group_name = 0;
302        nt_build_sai_middle_file = middlefile;
303        GBS_hash_do_sorted_loop(hash,nt_build_sai_string_by_hash,(gbs_hash_sort_func_type)nt_build_sai_sort_strings);
304        if (nt_build_sai_last_group_name){
305            GBS_chrcat(middlefile,1);                           // Seperated by 1
306            GBS_chrcat(middlefile,'E');                         // End of old group
307        }
308       
309        // close surrounding SAI-group:
310        GBS_chrcat(middlefile,1);
311        GBS_chrcat(middlefile,'E');
312       
313        GBS_free_hash(hash);
314}
315
316void nt_build_conf_marked(GB_HASH *used, void *file){
317    GBS_chrcat(file,1);                         // Seperated by 1
318    GBS_strcat(file,"FMore Sequences");
319    GBDATA *gb_species;
320    for (gb_species = GBT_first_marked_species(gb_main);
321         gb_species;
322         gb_species = GBT_next_marked_species(gb_species)){
323        char *name = GBT_read_string(gb_species,"name");
324        if (GBS_read_hash(used,name)){
325            delete name;
326            continue;
327        }
328        GBS_chrcat(file,1);
329        GBS_strcat(file,"L");
330        GBS_strcat(file,name);
331        delete name;
332    }
333
334    GBS_chrcat(file,1); // Seperated by 1
335    GBS_chrcat(file,'E');       // Group end indicated by 'E'
336}
337
338#define CONFNAME "default_configuration"
339
340void 
341nt_start_editor_on_configuration(AW_window *aww){
342    aww->hide();
343    char *cn = aww->get_root()->awar(AWAR_CONFIGURATION)->read_string();
344    char *com = (char *)GBS_global_string("arb_edit4 -c '%s' &",cn);
345    GBCMC_system(gb_main, com);
346    delete cn;
347}
348
349AW_window *
350NT_start_editor_on_old_configuration(AW_root *awr){
351    static AW_window_simple *aws = 0;
352    if (aws) return (AW_window *)aws;
353    awr->awar_string(AWAR_CONFIGURATION,"default_configuration",gb_main);
354    aws = new AW_window_simple;
355    aws->init( awr, "SELECT_CONFIFURATION", "SELECT A CONFIGURATION", 400, 200 );
356    aws->at(10,10);
357    aws->auto_space(0,0);
358    awt_create_selection_list_on_configurations(gb_main,(AW_window *)aws,AWAR_CONFIGURATION);
359    aws->at_newline();
360
361    aws->callback((AW_CB0)nt_start_editor_on_configuration);
362    aws->create_button("START","START");                       
363
364    aws->callback(AW_POPDOWN);
365    aws->create_button("CLOSE","CLOSE","C");                   
366       
367    aws->window_fit();
368    return (AW_window *)aws;
369}
370
371GB_ERROR NT_create_configuration(AW_window *, GBT_TREE **ptree,const char *conf_name, int use_species_aside){
372        GBT_TREE *tree = *ptree;
373        char *to_free = 0;
374       
375        if (!conf_name) conf_name = to_free = aw_input("Enter Name of Config.",0);
376        if (!conf_name) return GB_export_error("no config name");
377       
378        if (use_species_aside==-1) {
379            char *use_species = aw_input("Enter number of extra species to view aside marked:", 0);
380           
381            if (use_species) use_species_aside = atoi(use_species);
382            if (use_species_aside<1) return GB_export_error("illegal # of species aside");
383        }
384       
385        GB_transaction dummy2(gb_main);         // open close transaction
386        GB_HASH *used = GBS_create_hash(10000,0);
387        void *topfile = GBS_stropen(1000);
388        void *topmid = GBS_stropen(10000);
389        {
390            void *middlefile = GBS_stropen(10000);
391            nt_build_sai_string(topfile,topmid);
392           
393            if (use_species_aside) {
394                        Store_species *extra_marked_species = 0;
395                        int auto_mark = 0;
396                        int marked_at_right;
397                        nt_build_conf_string_rek(used, tree, middlefile, &extra_marked_species, use_species_aside, &auto_mark, use_species_aside, &marked_at_right);           
398                        if (extra_marked_species) {
399                                extra_marked_species->call(unmark_species);
400                                delete extra_marked_species;
401                        }
402            }
403            else {
404                        int dummy_1=0, dummy_2;
405                        nt_build_conf_string_rek(used, tree, middlefile, 0, 0, &dummy_1, 0, &dummy_2);
406            }
407            nt_build_conf_marked(used,topmid);
408            char *mid = GBS_strclose(middlefile,0);
409            GBS_strcat(topmid,mid);
410            delete mid;
411        }
412               
413        char *middle = GBS_strclose(topmid,0);
414        char *top = GBS_strclose(topfile,0);
415       
416        GBDATA *gb_configuration = GBT_create_configuration(gb_main,conf_name);
417        GB_ERROR error = 0;
418        if (!gb_configuration){
419            error = GB_get_error();
420        }else{
421            GBDATA *gb_top_area = GB_search(gb_configuration,"top_area",GB_STRING);
422            GBDATA *gb_middle_area = GB_search(gb_configuration,"middle_area",GB_STRING);
423            error = GB_write_string(gb_top_area,top);
424            if (!error){
425                error = GB_write_string(gb_middle_area,middle);
426            }
427        }
428        delete to_free;
429        delete middle;
430        delete top;
431        GBS_free_hash(used);
432        if (error) aw_message(error);
433        return error;
434}
435
436void NT_start_editor_on_tree(AW_window *, GBT_TREE **ptree, int use_species_aside){
437    GB_ERROR error = NT_create_configuration(0,ptree,CONFNAME, use_species_aside);
438    if (!error) {
439        GBCMC_system(gb_main, "arb_edit4 -c "CONFNAME" &");
440    }
441}
442
443void nt_extract_configuration(AW_window *aww){
444    aww->hide();
445    GB_transaction dummy2(gb_main);             // open close transaction
446    char *cn = aww->get_root()->awar(AWAR_CONFIGURATION)->read_string();
447    GBDATA *gb_configuration = GBT_find_configuration(gb_main,cn);
448    if (!gb_configuration){
449        aw_message(GBS_global_string("Configuration '%s' not fould in the database",cn));
450    }else{
451        GBDATA *gb_middle_area = GB_search(gb_configuration,"middle_area",GB_STRING);
452        char *md = 0;
453        if (gb_middle_area){
454            GBT_mark_all(gb_main,0);
455            md = GB_read_string(gb_middle_area);
456            if (md){
457                char *p;
458                char tokens[2];
459                tokens[0] = 1;
460                tokens[1] = 0;
461                for ( p = strtok(md,tokens); p; p = strtok(NULL,tokens)){
462                    if (p[0] != 'L') continue;
463                    GBDATA *gb_species = GBT_find_species(gb_main,p+1);
464                    if (gb_species){
465                        GB_write_flag(gb_species,1);
466                    }
467                }
468            }
469        }
470        delete md;
471    }
472    delete cn;
473}
474
475void nt_delete_configuration(AW_window *aww){
476    GB_transaction transaction_var(gb_main);
477    char *cn = aww->get_root()->awar(AWAR_CONFIGURATION)->read_string();
478    GBDATA *gb_configuration = GBT_find_configuration(gb_main,cn);
479    if (gb_configuration){
480        GB_ERROR error = GB_delete(gb_configuration);
481        if (error) aw_message(error);
482    }
483    delete cn;
484}
485
486AW_window *NT_extract_configuration(AW_root *awr){
487    static AW_window_simple *aws = 0;
488    if (aws) return (AW_window *)aws;
489    awr->awar_string(AWAR_CONFIGURATION,"default_configuration",gb_main);
490    aws = new AW_window_simple;
491    aws->init( awr, "EXTRACT_CONFIGURATION", "EXTRACT A CONFIGURATION", 400, 200 );
492    aws->at(10,10);
493    aws->auto_space(0,0);
494    awt_create_selection_list_on_configurations(gb_main,(AW_window *)aws,AWAR_CONFIGURATION);
495    aws->at_newline();
496
497    aws->callback((AW_CB0)nt_extract_configuration);
498    aws->create_button("EXTRACT","EXTRACT","E");                       
499
500    aws->callback(nt_delete_configuration);
501    aws->create_button("DELETE","DELETE");                     
502   
503    aws->callback(AW_POPDOWN);
504    aws->create_button("CLOSE","CLOSE","C");                   
505       
506    aws->callback(AW_POPUP_HELP,(AW_CL)"configuration.hlp");
507    aws->create_button("HELP","HELP","H");                     
508       
509    aws->window_fit();
510    return (AW_window *)aws;
511}
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
Note: See TracBrowser for help on using the repository browser.