source: branches/port5/PARSIMONY/PARS_main.cxx

Last change on this file was 6341, checked in by westram, 15 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 65.3 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4// #include <malloc.h>
5#include <iostream>
6#include <limits.h>
7#include <arbdb.h>
8#include <arbdbt.h>
9
10#include <aw_root.hxx>
11#include <aw_device.hxx>
12#include <aw_window.hxx>
13#include <aw_preset.hxx>
14#include <aw_awars.hxx>
15#include <awt_canvas.hxx>
16#include <awt.hxx>
17#include <awt_nds.hxx>
18
19#include <awt_tree.hxx>
20#include <awt_dtree.hxx>
21#include <awt_tree_cb.hxx>
22#include <awt_sel_boxes.hxx>
23
24#include <awt_csp.hxx>
25
26#include "AP_buffer.hxx"
27#include "parsimony.hxx"
28#include "ap_tree_nlen.hxx"
29#include "pars_main.hxx"
30#include "pars_dtree.hxx"
31
32#include <list>
33
34#if defined(DEBUG)
35# define TEST_FUNCTIONS
36#endif // DEBUG
37
38
39using namespace std;
40
41AW_HEADER_MAIN
42
43GBDATA    *GLOBAL_gb_main;                          // global gb_main for arb_pars
44NT_global *GLOBAL_NT;
45
46// waaah more globals :(
47AP_main *ap_main;
48AWT_csp *awt_csp = 0;
49
50AW_window *create_kernighan_window(AW_root *aw_root);
51
52static void pars_export_tree(void){
53    // GB_ERROR error = GLOBAL_NT->tree->tree_root->AP_tree::saveTree();
54    GB_ERROR error = GLOBAL_NT->tree->save(0, 0, 0, 0);
55    if (error) aw_message(error);
56}
57
58ATTRIBUTED(__ATTR__NORETURN, static void pars_exit(AW_window *aww)) {
59    aww->get_root()->unlink_awars_from_DB(GLOBAL_gb_main);
60#if defined(DEBUG)
61    AWT_browser_forget_db(GLOBAL_gb_main);
62#endif // DEBUG
63    GB_close(GLOBAL_gb_main);
64    exit(0);
65}
66
67void PARS_export_cb(AW_window *aww, AWT_canvas *, AW_CL mode){
68    if (mode &1){       // export tree
69        pars_export_tree();
70    }
71    if (mode &2) {
72        //quit
73        pars_exit(aww);
74    }
75}
76
77void AP_user_push_cb(AW_window *aww, AWT_canvas *)
78{
79    ap_main->user_push();
80    aww->get_root()->awar(AWAR_STACKPOINTER)->write_int(ap_main->user_push_counter);
81}
82
83void AP_user_pop_cb(AW_window *aww,AWT_canvas *ntw)
84{
85    if (ap_main->user_push_counter<=0) {
86        aw_message("No tree on stack.");
87        return;
88    }
89    ap_main->user_pop();
90    (*ap_main->tree_root)->compute_tree(GLOBAL_gb_main);
91    ntw->zoom_reset();
92    ntw->refresh();
93    (*ap_main->tree_root)->test_tree();
94    aww->get_root()->awar(AWAR_STACKPOINTER)->write_int(ap_main->user_push_counter);
95    pars_export_tree();
96
97    if (ap_main->user_push_counter <= 0) { // last tree was popped => push again
98        AP_user_push_cb(aww, ntw);
99    }
100}
101
102struct InsertData {
103    AP_BOOL quick_add_flag;
104    AP_BOOL singlestatus; // update status for single species addition
105    int     abort_flag;
106    long    maxspecies;
107    long    currentspecies;
108
109    InsertData(AP_BOOL quick)
110        : quick_add_flag(quick)
111        , singlestatus(AP_FALSE)
112        , abort_flag(AP_FALSE)
113        , maxspecies(0)
114        , currentspecies(0)
115    {
116    }
117};
118
119static long insert_species_in_tree_test(const char *key,long val, void *cd_isits) {
120    if (!val) return val;
121
122    InsertData *isits = (InsertData*)cd_isits;
123    if (isits->abort_flag) return val;
124
125    AP_tree *tree = (*ap_main->tree_root);
126    GBDATA *gb_node = (GBDATA *)val;
127
128    GB_begin_transaction(GLOBAL_gb_main);
129
130    GBDATA *gb_data = GBT_read_sequence(gb_node,ap_main->use);
131    if (!gb_data)
132    {
133        sprintf(AW_ERROR_BUFFER,"Warning Species '%s' has no sequence '%s'",
134                key,ap_main->use);
135        aw_message();
136        GB_commit_transaction(GLOBAL_gb_main);
137        return val;
138    }
139
140    AP_tree *leaf = tree->dup();
141    leaf->gb_node = gb_node;
142    leaf->name = strdup(key);
143    leaf->is_leaf = GB_TRUE;
144
145    leaf->sequence = leaf->tree_root->sequence_template->dup();
146    leaf->sequence->set(GB_read_char_pntr(gb_data));
147    GB_commit_transaction (GLOBAL_gb_main);
148
149    if (leaf->sequence->real_len() < MIN_SEQUENCE_LENGTH)
150    {
151        sprintf(AW_ERROR_BUFFER,
152                "Species %s has too short sequence (%i, minimum is %i)",
153                key,
154                (int)leaf->sequence->real_len(),
155                MIN_SEQUENCE_LENGTH);
156        aw_message();
157        delete leaf;
158        return val;
159    }
160
161    if (isits->singlestatus) {
162        sprintf(AW_ERROR_BUFFER,
163                "Inserting Species %s (%li:%li)",
164                key,
165                ++isits->currentspecies,
166                isits->maxspecies);
167        aw_openstatus(AW_ERROR_BUFFER);
168    }
169    else {
170        isits->abort_flag = aw_status(++isits->currentspecies/(double)isits->maxspecies);
171    }
172
173    {
174        AP_FLOAT best_val = 9999999999999.0;
175        AP_FLOAT this_val;
176        int      cnt      = 0;
177
178        while (cnt<2) {
179            char buf[200];
180
181            sprintf(buf,"Pre-optimize (pars=%f)",best_val);
182
183            aw_status(buf);
184            this_val = rootEdge()->nni_rek(AP_FALSE,isits->abort_flag,-1);
185            if (this_val<best_val) {
186                best_val = this_val;
187                cnt      = 0;
188            }
189            else if (this_val==best_val) {
190                cnt++;
191            }
192            else {
193                cnt = 0;
194            }
195        }
196    }
197
198    rootEdge()->dumpNNI=2;
199
200    aw_status("Searching best position");
201
202    AP_tree      **blist;
203    AP_tree_nlen  *bl,*blf;
204    long           bsum    = 0;
205    long           counter = 0;
206
207    tree->buildBranchList(blist,bsum,AP_TRUE,-1);   // get all branches
208    AP_sequence::global_combineCount = 0;
209
210    AP_tree *bestposl = tree->leftson;
211    AP_tree *bestposr = tree->rightson;
212    leaf->insert(bestposl);
213    AP_FLOAT best_parsimony,akt_parsimony;
214    best_parsimony = akt_parsimony = (*ap_main->tree_root)->costs();
215
216    for (counter = 0; !isits->abort_flag && blist[counter]; counter += 2)
217    {
218        if (isits->singlestatus && (counter & 0xf) == 0) {
219            isits->abort_flag = (AP_BOOL)aw_status(counter/(bsum*2.0));
220        }
221
222        bl = (AP_tree_nlen *)blist[counter];
223        blf = (AP_tree_nlen *)blist[counter+1];
224        if (blf->father == bl )
225        {
226            bl = (AP_tree_nlen *)blist[counter+1];
227            blf = (AP_tree_nlen *)blist[counter];
228        }
229
230        //      if (blf->father) {  //->father
231        //          blf->set_root();
232        //      }
233
234        if (bl->father)     //->father
235        {
236            bl->set_root();
237        }
238
239        leaf->moveTo(bl,0.5);
240        akt_parsimony = (*ap_main->tree_root)->costs();
241
242        if (akt_parsimony<best_parsimony)
243        {
244            best_parsimony = akt_parsimony;
245            bestposl = bl;
246            bestposr = blf;
247        }
248    }
249    delete blist;
250    blist = 0;
251    if (bestposl->father != bestposr) bestposl = bestposr;
252    leaf->moveTo(bestposl,0.5);
253
254    // calculate difference in father-sequence
255
256    int baseDiff = 0;
257
258    {
259        AP_tree_nlen *fath = ((AP_tree_nlen*)bestposl)->Father()->Father();
260        char *seq_with_leaf;
261        char *seq_without_leaf;
262        long len_with_leaf;
263        long len_without_leaf;
264        long i;
265
266        seq_with_leaf = fath->getSequence();
267        len_with_leaf = fath->sequence->sequence_len;
268
269
270        ap_main->push();
271        leaf->remove();
272
273        seq_without_leaf = fath->getSequence();
274        len_without_leaf = fath->sequence->sequence_len;
275
276
277        ap_main->pop();
278
279
280        if (len_with_leaf==len_without_leaf) {
281            for (i=0; i<len_with_leaf; i++) {
282                if (seq_with_leaf[i]!=seq_without_leaf[i]) {
283                    baseDiff++;
284                }
285            }
286        }
287        else {
288            cout << "Laenge der Sequenz hat sich geaendert!!!";
289        }
290
291        delete [] seq_with_leaf;
292        delete [] seq_without_leaf;
293    }
294
295    rootEdge()->countSpecies();
296
297    //    printf("Combines: %i\n",global_combineCount);
298
299    if (!isits->quick_add_flag ) {
300        int           deep    = -1;
301        AP_tree_nlen *bestpos = (AP_tree_nlen*)bestposl;
302        AP_tree_edge *e       = bestpos->edgeTo(bestpos->Father());
303
304        if ((isits->currentspecies & 0xf ) == 0)  deep = -1;
305
306        aw_status("optimization");
307        e->dumpNNI = 1;
308        e->distInsertBorder = e->distanceToBorder(INT_MAX,(AP_tree_nlen*)leaf);
309        e->basesChanged = baseDiff;
310        e->nni_rek(AP_FALSE, isits->abort_flag, deep);
311        e->dumpNNI = 0;
312    }
313
314    return val;
315}
316
317static int sort_sequences_by_length(const char*, long leaf0_ptr, const char*, long leaf1_ptr) {
318    AP_tree *leaf0 = (AP_tree*)leaf0_ptr;
319    AP_tree *leaf1 = (AP_tree*)leaf1_ptr;
320
321    AP_FLOAT len0 = leaf0->sequence->real_len();
322    AP_FLOAT len1 = leaf1->sequence->real_len();
323
324    return len0<len1 ? 1 : (len0>len1 ? -1 : 0); // longest sequence first
325}
326
327static long transform_gbd_to_leaf(const char *key,long val, void *) {
328    if (!val) return val;
329
330    AP_tree *tree    = (*ap_main->tree_root);
331    GBDATA  *gb_node = (GBDATA *)val;
332    GBDATA  *gb_data = GBT_read_sequence(gb_node,ap_main->use);
333   
334    if (!gb_data) {
335        sprintf(AW_ERROR_BUFFER,"Warning Species '%s' has no sequence '%s'",
336                key,ap_main->use);
337        aw_message();
338        return 0;
339    }
340    AP_tree *leaf = tree->dup();
341    leaf->gb_node = gb_node;
342    leaf->name = strdup(key);
343    leaf->is_leaf = GB_TRUE;
344    leaf->sequence = leaf->tree_root->sequence_template->dup();
345    leaf->sequence->set(GB_read_char_pntr(gb_data));
346    return (long)leaf;
347}
348
349static AP_tree *insert_species_in_tree(const char *key, AP_tree *leaf, void *cd_isits)
350{
351    if (!leaf) return leaf;
352
353    InsertData *isits = (InsertData*)cd_isits;
354    if (isits->abort_flag) return leaf;
355
356    AP_tree *tree = (*ap_main->tree_root);
357
358
359    if (leaf->sequence->real_len() < MIN_SEQUENCE_LENGTH) {
360        sprintf(AW_ERROR_BUFFER,"Species %s has too short sequence (%i, minimum is %i)",
361                key,    (int)leaf->sequence->real_len(),    MIN_SEQUENCE_LENGTH);
362        aw_message();
363        delete leaf;
364        return 0;
365    }
366
367    ++isits->currentspecies;
368    if (isits->singlestatus) {
369        sprintf(AW_ERROR_BUFFER, "Inserting Species %s (%li:%li)",
370                key, isits->currentspecies, isits->maxspecies);
371        aw_openstatus(AW_ERROR_BUFFER);
372    }
373    aw_status("Searching best position");
374
375    AP_tree      **blist;
376    AP_tree_nlen  *bl,*blf;
377    long           bsum    = 0;
378    long           counter = 0;
379
380    tree->buildBranchList(blist,bsum,AP_TRUE,-1);       // get all branches
381    AP_sequence::global_combineCount = 0;
382
383    AP_tree *bestposl = tree->leftson;
384    AP_tree *bestposr = tree->rightson;
385    leaf->insert(bestposl);
386    AP_FLOAT best_parsimony,akt_parsimony;
387    best_parsimony = akt_parsimony = (*ap_main->tree_root)->costs();
388
389    for (counter = 0;!isits->abort_flag && blist[counter];counter += 2) {
390        if (isits->singlestatus && (counter & 0xf) == 0) {
391            isits->abort_flag = (AP_BOOL)aw_status(counter/(bsum*2.0));
392        }
393        bl = (AP_tree_nlen *)blist[counter];
394        blf = (AP_tree_nlen *)blist[counter+1];
395        if (blf->father == bl ) {
396            bl = (AP_tree_nlen *)blist[counter+1];
397            blf = (AP_tree_nlen *)blist[counter];
398        }
399
400        if (bl->father) {   //->father
401            bl->set_root();
402        }
403
404        leaf->moveTo(bl,0.5);
405        akt_parsimony = (*ap_main->tree_root)->costs();
406        if (akt_parsimony < best_parsimony) {
407            best_parsimony = akt_parsimony;
408            bestposl = bl;
409            bestposr = blf;
410        }
411
412    }
413    delete blist;blist = 0;
414    if (bestposl->father != bestposr){
415        bestposl = bestposr;
416    }
417    leaf->moveTo(bestposl,0.5);
418
419    if (!isits->quick_add_flag) {
420        int deep = 5;
421        if ( (isits->currentspecies & 0xf ) == 0)  deep = -1;
422        aw_status("optimization");
423        ((AP_tree_nlen *)bestposl->father)->
424            nn_interchange_rek(AP_FALSE, isits->abort_flag, deep, AP_BL_NNI_ONLY, GB_TRUE);
425    }
426    AP_tree *brother = leaf->brother();
427    if (    brother->is_leaf &&     // brother is a short sequence
428            brother->sequence->real_len() *2  < leaf->sequence->real_len() &&
429            leaf->father->father){      // There are more than two species
430        brother->remove();
431        leaf->remove();
432        isits->currentspecies--;
433        char *label = GBS_global_string_copy("2:%s",leaf->name);
434        insert_species_in_tree(label, leaf, cd_isits); // reinsert species
435        delete label;
436        isits->currentspecies--;
437        label = GBS_global_string_copy("shortseq:%s",brother->name);
438        insert_species_in_tree(label, brother, cd_isits);  // reinsert short sequence
439        delete label;
440    }
441
442    if (!isits->singlestatus) {
443        isits->abort_flag |= aw_status(isits->currentspecies/(double)isits->maxspecies);
444    }
445
446    return leaf;
447}
448
449static long hash_insert_species_in_tree(const char *key, long leaf, void *cd_isits) {
450    return (long)insert_species_in_tree(key, (AP_tree*)leaf, cd_isits);
451}
452
453static long count_hash_elements(const char *,long val, void *cd_isits) {
454    if (val) {
455        InsertData *isits = (InsertData*)cd_isits;
456        isits->maxspecies++;
457    }
458    return val;
459}
460
461static void nt_add(AW_window *, AWT_canvas *ntw, int what, AP_BOOL quick, int test)
462{
463    GB_begin_transaction(GLOBAL_gb_main);
464    GB_HASH *hash = 0;
465    GB_ERROR error = 0;
466    AP_tree *oldrootleft = (*ap_main->tree_root)->leftson;
467    AP_tree *oldrootright = (*ap_main->tree_root)->rightson;
468    aw_openstatus("Search selected species");
469
470    if (what)
471    {
472        char *name = GBT_readOrCreate_string(GLOBAL_gb_main, AWAR_SPECIES_NAME, "");
473        if (name && strlen(name)) {
474            GBDATA *gb_species = GBT_find_species(GLOBAL_gb_main,name);
475            if (gb_species) {
476                hash = GBS_create_hash(10, GB_MIND_CASE);
477                GBS_write_hash(hash,name,(long)gb_species);
478            }
479            else {
480                error = "Error: Selected Species not found";
481            }
482        }
483        else {
484            error= "Please select an species"
485                "   to select an species:   1. arb_edit: enable global cursor and select sequence"
486                "               2. arb_ntree: species/search and select species";
487        }
488        free(name);
489    }
490    else {
491        hash = GBT_create_marked_species_hash(GLOBAL_gb_main);
492    }
493    GB_commit_transaction(GLOBAL_gb_main);
494
495    if (!error) {
496        NT_remove_species_in_tree_from_hash(*ap_main->tree_root,hash);
497
498        InsertData isits(quick);
499
500        GBS_hash_do_loop(hash, count_hash_elements, &isits);
501
502        aw_openstatus(GBS_global_string("Adding %li species", isits.maxspecies));
503
504        if (test) {
505            GBS_hash_do_loop(hash, insert_species_in_tree_test, &isits);
506        }
507        else {
508            aw_status("reading database");
509            GB_begin_transaction(GLOBAL_gb_main);
510            GBS_hash_do_loop(hash, transform_gbd_to_leaf, NULL);
511            GB_commit_transaction(GLOBAL_gb_main);
512            GBS_hash_do_sorted_loop(hash, hash_insert_species_in_tree, sort_sequences_by_length, &isits);
513        }
514        if (!quick ) {
515            aw_status("final optimization");
516            rootEdge()->nni_rek(AP_FALSE,isits.abort_flag,-1,GB_FALSE, AP_BL_NNI_ONLY);
517        }
518
519        aw_status("Calculating Branch lengths");
520        rootEdge()->nni_rek(AP_FALSE,isits.abort_flag,-1, GB_FALSE ,AP_BL_BL_ONLY);
521
522        rootNode()->test_tree();
523        rootNode()->compute_tree(GLOBAL_gb_main);
524
525        if (oldrootleft->father == oldrootright) oldrootleft->set_root();
526        else                     oldrootright->set_root();
527
528        aw_closestatus();
529    }
530
531    if (hash) GBS_free_hash(hash);
532    if (error) aw_message(error);
533
534    AWT_TREE(ntw)->resort_tree(0);
535    ntw->zoom_reset();
536    if (!error) pars_export_tree();
537}
538
539// -----------------------------------------
540//      Adding partial sequences to tree
541// -----------------------------------------
542
543class PartialSequence {
544    GBDATA          *gb_species;
545    mutable AP_tree *self;            // self converted to leaf (ready for insertion)
546    const AP_tree   *best_full_match; // full sequence position which matched best
547    long             overlap;         // size of overlapping region
548    long             penalty;         // weighted mismatches
549    bool             released;
550    bool             multi_match;
551    string           multi_list;      // list of equal-rated insertion-points (not containing self)
552
553    AP_tree *get_self() const {
554        if (!self) {
555            ap_assert(!released); // request not possible, because leaf has already been released!
556           
557            self = (AP_tree*)transform_gbd_to_leaf(GBT_read_name(gb_species), (long)gb_species, NULL);
558            ap_assert(self);
559        }
560        return self;
561    }
562
563public:
564    PartialSequence(GBDATA *gb_species_)
565        : gb_species(gb_species_), self(0), best_full_match(0)
566        , overlap(0) , penalty(LONG_MAX), released(false), multi_match(false)
567    {
568    }
569
570    ~PartialSequence() { ap_assert(self == 0); }
571
572    GBDATA *get_species() const { return gb_species; }
573    const AP_tree *get_best_match() const { return best_full_match; }
574    AP_FLOAT get_branchlength() const { return AP_FLOAT(penalty)/overlap; }
575    void test_match(const AP_tree *leaf_full);
576    bool is_multi_match() const { return multi_match; }
577
578    const char *get_name() const {
579        const char *name = get_self()->name;
580        ap_assert(name);
581        return name;
582    }
583
584    string get_multilist() const {
585        ap_assert(is_multi_match());
586        return string(best_full_match->name)+multi_list;
587    }
588
589    AP_tree *release() {
590        AP_tree *s = self;
591        self       = 0;
592        released   = true;
593        return s;
594    }
595
596    void dump() const {
597        printf("best match for '%s' is '%s' (overlap=%li penalty=%li)\n",
598               get_name(), best_full_match->name,
599               overlap, penalty);
600    }
601
602};
603
604void PartialSequence::test_match(const AP_tree *leaf_full) {
605    long curr_overlap;
606    long curr_penalty;
607
608    leaf_full->sequence->partial_match(get_self()->sequence, &curr_overlap, &curr_penalty);
609
610    bool better = false;
611
612    if (curr_overlap > overlap) {
613        better = true;
614    }
615    else if (curr_overlap == overlap) {
616        if (curr_penalty<penalty) {
617            better = true;
618        }
619        else if (curr_penalty == penalty) {
620            // found two equal-rated insertion points -> store data for warning
621#if defined(DEBUG)
622            if (!multi_match) dump();
623            printf("Another equal match is against '%s' (overlap=%li penalty=%li)\n", leaf_full->name, curr_overlap, curr_penalty);
624#endif // DEBUG
625            //             aw_message("Several full sequences match equal against one partial sequence");
626            //             aw_message("Please save a copy of the current database and inform Ralf!!!!");
627
628            multi_match  = true;
629            multi_list.append(1, '/');
630            multi_list.append(leaf_full->name);
631        }
632    }
633
634    if (better) {
635        overlap         = curr_overlap;
636        penalty         = curr_penalty;
637        best_full_match = leaf_full;
638        multi_match     = false;
639        multi_list      = "";
640    }
641}
642
643static GB_ERROR nt_best_partial_match_rek(list<PartialSequence>& partial, AP_tree *tree) {
644    GB_ERROR error = 0;
645
646    if (tree) {
647        if (tree->is_leaf && tree->name) {
648            if (tree->gb_node) {
649                int is_partial = GBT_is_partial(tree->gb_node, 0, true); // marks undef as 'full sequence'
650                if (is_partial == 0) { // do not consider other partial sequences
651                    list<PartialSequence>::iterator i = partial.begin();
652                    list<PartialSequence>::iterator e = partial.end();
653                    for (;  i != e; ++i) {
654                        i->test_match(tree);
655                    }
656                }
657                else if (is_partial == -1) {
658                    error = GB_await_error();
659                }
660            }
661        }
662        else {
663            error             = nt_best_partial_match_rek(partial, tree->leftson);
664            if (!error) error = nt_best_partial_match_rek(partial, tree->rightson);
665        }
666    }
667    return error;
668}
669
670static void count_partial_and_full(AP_tree *at, int *partial, int *full, int *zombies, int default_value, int define_if_undef) {
671    if (at->is_leaf) {
672        if (at->gb_node) {
673            int is_partial = GBT_is_partial(at->gb_node, default_value, define_if_undef);
674            if (is_partial) ++(*partial);
675            else ++(*full);
676        }
677        else {
678            ++(*zombies);
679        }
680    }
681    else {
682        count_partial_and_full(at->leftson,  partial, full, zombies, default_value, define_if_undef);
683        count_partial_and_full(at->rightson, partial, full, zombies, default_value, define_if_undef);
684    }
685}
686
687static AP_tree *find_least_deep_leaf(AP_tree *at, int depth, int *min_depth) {
688    if (depth >= *min_depth) {
689        return 0; // already found better or equal
690    }
691
692    if (at->is_leaf) {
693        if (at->gb_node) {
694            *min_depth = depth;
695            return at;
696        }
697        return 0;
698    }
699
700    AP_tree *left  = find_least_deep_leaf(at->leftson, depth+1, min_depth);
701    AP_tree *right = find_least_deep_leaf(at->rightson, depth+1, min_depth);
702
703    return right ? right : left;
704}
705
706static long push_partial(const char *, long val, void *cd_partial) {
707    list<PartialSequence> *partial = reinterpret_cast<list<PartialSequence> *>(cd_partial);
708    partial->push_back(PartialSequence((GBDATA*)val));
709    return val;
710}
711
712static void nt_add_partial(AW_window */*aww*/, AWT_canvas *ntw) {
713    GB_begin_transaction(GLOBAL_gb_main);
714    GB_ERROR error                    = 0;
715    int      full_marked_sequences    = 0;
716    int      partial_marked_sequences = 0;
717    int      no_data                  = 0; // no data in alignment
718
719    aw_openstatus("Adding partial sequences");
720
721    {
722        list<PartialSequence> partial;
723        {
724            GB_HASH *partial_hash = GBS_create_hash(GBT_get_species_hash_size(GLOBAL_gb_main), GB_MIND_CASE);
725            int      marked_found = 0;
726
727            for (GBDATA *gb_marked = GBT_first_marked_species(GLOBAL_gb_main);
728                 !error && gb_marked;
729                 gb_marked = GBT_next_marked_species(gb_marked))
730            {
731                ++marked_found;
732
733                if (GBT_read_sequence(gb_marked,ap_main->use)) { // species has sequence in alignment
734                    const char *name = GBT_read_name(gb_marked);
735
736                    switch (GBT_is_partial(gb_marked, 1, true)) { // marks undef as 'partial sequence'
737                        case 0: { // full sequences
738                            aw_message(GBS_global_string("'%s' is a full sequence (cannot add partial)", name));
739                            ++full_marked_sequences;
740                            break;
741                        }
742                        case 1:     // partial sequences
743                            ++partial_marked_sequences;
744                            GBS_write_hash(partial_hash, name, (long)gb_marked);
745                            break;
746                        case -1:    // error
747                            error = GB_await_error();
748                            break;
749                        default :
750                            ap_assert(0);
751                            break;
752                    }
753                }
754                else {
755                    no_data++;
756                }
757            }
758
759            if (!error && !marked_found) error = "There are no marked species";
760
761            if (!error) {
762                NT_remove_species_in_tree_from_hash(*ap_main->tree_root,partial_hash); // skip all species which are in tree
763                GBS_hash_do_loop(partial_hash, push_partial, &partial); // build partial list from hash
764
765                int partials_already_in_tree = partial_marked_sequences - partial.size();
766
767                if (no_data>0) aw_message(GBS_global_string("%i marked species have no data in '%s'", no_data, ap_main->use));
768                if (full_marked_sequences>0) aw_message(GBS_global_string("%i marked species are declared full sequences", full_marked_sequences));
769                if (partials_already_in_tree>0) aw_message(GBS_global_string("%i marked species are already in tree", partials_already_in_tree));
770
771                if (partial.empty()) error = "No species left to add";
772            }
773        }
774
775        if (!error) {
776            // find best matching full sequence for each partial sequence
777            error = nt_best_partial_match_rek(partial, *ap_main->tree_root);
778
779            list<PartialSequence>::iterator i = partial.begin();
780            list<PartialSequence>::iterator e = partial.end();
781           
782#if defined(DEBUG)
783            // show results :
784            for (; i != e; ++i) i->dump();
785            i = partial.begin();
786#endif // DEBUG
787
788            for (; i != e && !error; ++i) {
789                const char *name = i->get_name();
790               
791                if (i->is_multi_match()) {
792                    aw_message(GBS_global_string("Insertion of '%s' is ambiguous.\n"
793                                                 "(took first of equal scored insertion points: %s)",
794                                                 name, i->get_multilist().c_str()));
795                }
796
797                AP_tree *part_leaf  = i->release();
798                AP_tree *full_seq   = const_cast<AP_tree*>(i->get_best_match());
799                AP_tree *brother    = full_seq->brother();
800                int      is_partial = 0;
801                AP_tree *target     = 0;
802
803                if (brother->is_leaf) {
804                    if (brother->gb_node) {
805                        is_partial = GBT_is_partial(brother->gb_node, 0, 1);
806
807                        if (is_partial) { // brother is partial sequence
808                            target = brother; // insert as brother of brother
809                        }
810                        else {
811                            target = full_seq; // insert as brother of full_seq
812                        }
813                    }
814                    else {
815                        error = "There are zombies in your tree - please remove them";
816                    }
817                }
818                else {
819                    int partial_count = 0;
820                    int full_count    = 0;
821                    int zombie_count  = 0;
822
823                    count_partial_and_full(brother, &partial_count, &full_count, &zombie_count, 0, 1);
824
825                    if (zombie_count) {
826                        error = "There are zombies in your tree - please remove them";
827                    }
828                    else if (full_count) {
829                        // brother is a subtree containing full sequences
830                        // -> add new brother to full_seq found above
831                        target = full_seq;
832                    }
833                    else {      // brother subtree only contains partial sequences
834                        // find one of the least-deep leafs
835                        int depth  = INT_MAX;
836                        target     = find_least_deep_leaf(brother, 0, &depth);
837                        is_partial = 1;
838                    }
839                }
840
841
842                if (!error) {
843#if defined(DEBUG)
844                    printf("inserting '%s'\n", name);
845#endif // DEBUG
846                    part_leaf->insert(target);
847                   
848                    // we need to create the sequence of the father node!
849                    AP_tree *father = part_leaf->father;
850                    father->costs();
851
852                    // ensure full-sequence is always on top
853                    if (father->rightson == target) {
854                        father->swap_sons();
855                    }
856
857                    if (!error) {
858                        // now correct the branch lengths.
859                        // First calc the original branchlen
860                        GBT_LEN orglen = father->get_branchlength()+target->get_branchlength();
861
862                        if (is_partial) { // we now have a subtree of partial sequences
863                            brother->set_branchlength(orglen); // each partial sequence has it's branchlength.
864                            father->set_branchlength(0); // all father branches are zero length
865                        }
866                        else { // we have a subtree of one full+one partial sequence
867                            father->set_branchlength(orglen); // father branch represents original length (w/o partial seq)
868                            full_seq->set_branchlength(0); // full seq has no sub-branch length
869                        }
870                        part_leaf->set_branchlength(i->get_branchlength());
871                        printf("Adding with branchlength=%f\n", i->get_branchlength());
872                    }
873                }
874                else {
875                    delete part_leaf;
876                }
877            }
878        }
879    }
880
881    aw_closestatus();
882
883    if (full_marked_sequences) {
884        aw_message(GBS_global_string("%i marked full sequences were not added", full_marked_sequences));
885    }
886
887    if (error) {
888        aw_message(error);
889        GB_abort_transaction(GLOBAL_gb_main);
890    }
891    else {
892        GB_commit_transaction(GLOBAL_gb_main);
893    }
894
895//     AWT_TREE(ntw)->resort_tree(0);
896    ntw->zoom_reset();
897    if (!error) pars_export_tree();
898}
899
900// -----------------------------
901//      add marked / selected
902// -----------------------------
903
904// normal versions :
905
906static void NT_add(AW_window * aww, AWT_canvas *ntw, int what) {
907    // what == 0 marked  ==1 selected
908    nt_add(aww,ntw,what,AP_FALSE,0);
909}
910
911static void NT_quick_add(AW_window * aww, AWT_canvas *ntw, int what) {
912    // what == 0 marked  ==1 selected
913    nt_add(aww,ntw,what,AP_TRUE,0);
914}
915
916// test versions :
917
918#if defined(TEST_FUNCTIONS)
919static void NT_add_test(AW_window * aww, AWT_canvas *ntw, int what) {
920    // what == 0 marked  ==1 selected
921    nt_add(aww,ntw,what,AP_FALSE,1);
922}
923
924static void NT_quick_add_test(AW_window * aww, AWT_canvas *ntw, int what) {
925    // what == 0 marked  ==1 selected
926    nt_add(aww,ntw,what,AP_TRUE,1);
927}
928#endif // TEST_FUNCTIONS
929
930// -----------------------------------------
931//      remove and add marked / selected
932// -----------------------------------------
933
934static void NT_radd_internal(AW_window * aww, AWT_canvas *ntw, int what, AP_BOOL quick, int test) {
935    // what == 0 marked  ==1 selected
936
937    AW_awar *awar_best_pars = aww->get_root()->awar(AWAR_BEST_PARSIMONY);
938    int      oldparsval     = awar_best_pars->read_int();
939
940    NT_remove_leafs(0,ntw,AWT_REMOVE_BUT_DONT_FREE | AWT_REMOVE_MARKED);
941
942    // restore old parsimony value (otherwise the state where species were removed would count) :
943    awar_best_pars->write_int(oldparsval);
944
945    nt_add(aww,ntw,what,quick,test);
946}
947
948// normal versions :
949
950static void NT_radd(AW_window * aww, AWT_canvas *ntw, int what) {
951    // what == 0 marked  ==1 selected
952    NT_radd_internal(aww, ntw, what, AP_FALSE, 0);
953}
954
955static void NT_rquick_add(AW_window * aww, AWT_canvas *ntw, int what) {
956    // what == 0 marked  ==1 selected
957    NT_radd_internal(aww, ntw, what, AP_TRUE, 0);
958}
959
960// static void NT_radd_test_internal(AW_window * aww, AWT_canvas *ntw, int what, AP_BOOL quick) {
961//     // what == 0 marked  ==1 selected
962//     NT_remove_leafs(0,ntw,AWT_REMOVE_BUT_DONT_FREE | AWT_REMOVE_MARKED);
963//     nt_add(aww,ntw,what,quick,1);
964// }
965
966// test versions :
967
968#if defined(TEST_FUNCTIONS)
969static void NT_radd_test(AW_window * aww, AWT_canvas *ntw, int what) {
970    // what == 0 marked  ==1 selected
971    NT_radd_internal(aww, ntw, what, AP_FALSE, 1);
972}
973
974static void NT_rquick_add_test(AW_window * aww, AWT_canvas *ntw, int what) {
975    // what == 0 marked  ==1 selected
976    NT_radd_internal(aww, ntw, what, AP_TRUE, 1);
977}
978#endif // TEST_FUNCTIONS
979
980// --------------------------------------------------------------------------------
981// Add Partial sequences
982// --------------------------------------------------------------------------------
983
984
985static void NT_partial_add(AW_window *aww, AW_CL cl_ntw, AW_CL) {
986    AWT_canvas *ntw = (AWT_canvas*)cl_ntw;
987    nt_add_partial(aww, ntw);
988}
989
990// --------------------------------------------------------------------------------
991
992static void NT_branch_lengths(AW_window *, AWT_canvas *ntw) {
993    aw_openstatus("Calculating Branch Lengths");
994    int abort_flag = AP_FALSE;
995    rootEdge()->nni_rek(AP_FALSE, abort_flag, -1, GB_FALSE, AP_BL_BL_ONLY);
996
997    aw_closestatus();
998    AWT_TREE(ntw)->resort_tree(0);
999
1000    ntw->zoom_reset();
1001    ntw->refresh();
1002    pars_export_tree();
1003}
1004
1005static void NT_bootstrap(AW_window *aw,AWT_canvas *ntw,AW_CL limit_only)
1006{
1007    AW_POPUP_HELP(aw, (AW_CL)"pa_bootstrap.hlp");
1008    aw_openstatus("Calculating Bootstrap Limit");
1009    int abort_flag = AP_FALSE;
1010    rootEdge()->nni_rek(AP_FALSE, abort_flag, -1, GB_FALSE,
1011                        limit_only ? AP_BL_BOOTSTRAP_LIMIT : AP_BL_BOOTSTRAP_ESTIMATE);
1012    aw_closestatus();
1013
1014    AWT_TREE(ntw)->resort_tree(0);
1015
1016    AWT_TREE(ntw)->tree_root_display = AWT_TREE(ntw)->tree_root;
1017    ntw->zoom_reset();
1018    ntw->refresh();
1019    pars_export_tree();
1020}
1021
1022static void NT_optimize(AW_window *, AWT_canvas *ntw)
1023{
1024    aw_openstatus("Optimize Tree");
1025
1026    PARS_optimizer_cb((*ap_main->tree_root));
1027    rootNode()->test_tree();
1028
1029    aw_openstatus("Calculating Branch Lengths");
1030    int abort_flag = AP_FALSE;
1031    rootEdge()->nni_rek(AP_FALSE, abort_flag, -1, GB_FALSE, AP_BL_BL_ONLY);
1032    AWT_TREE(ntw)->resort_tree(0);
1033    rootNode()->compute_tree(GLOBAL_gb_main);
1034    aw_closestatus();
1035    ntw->zoom_reset();
1036    ntw->refresh();
1037    pars_export_tree();
1038}
1039
1040static void NT_recursiveNNI(AW_window *,AWT_canvas *ntw)
1041{
1042    aw_openstatus("Recursive NNI");
1043    int abort_flag = AP_FALSE;
1044
1045    AP_FLOAT thisPars = rootNode()->costs();
1046    AP_FLOAT lastPars = -1.0;
1047
1048    aw_status(GBS_global_string("Old parsimony: %f", thisPars));
1049    while (thisPars!=lastPars && abort_flag == AP_FALSE) {
1050        lastPars    = thisPars;
1051        thisPars    = rootEdge()->nni_rek(AP_FALSE, abort_flag, -1, GB_TRUE);
1052        abort_flag |= aw_status(GBS_global_string("New Parsimony: %f",thisPars));
1053    }
1054
1055    aw_status("Calculating Branch Lengths");
1056    abort_flag = AP_FALSE;
1057    rootEdge()->nni_rek(AP_FALSE, abort_flag, -1, GB_FALSE, AP_BL_BL_ONLY);
1058
1059    AWT_TREE(ntw)->resort_tree(0);
1060    rootNode()->compute_tree(GLOBAL_gb_main);
1061    aw_closestatus();
1062    ntw->zoom_reset();
1063    ntw->refresh();
1064    pars_export_tree();
1065}
1066
1067static AW_window *NT_create_tree_setting(AW_root *aw_root)
1068{
1069    static AW_window_simple *aws = 0;
1070    if (aws) return (AW_window *)aws;
1071
1072    aws = new AW_window_simple;
1073    aws->init( aw_root, "SAVE_DB","SAVE ARB DB");
1074    aws->load_xfig("awt/tree_settings.fig");
1075
1076    aws->at("close");aws->callback((AW_CB0)AW_POPDOWN);
1077    aws->create_button("CLOSE","CLOSE","C");
1078
1079    aws->at("help");aws->callback(AW_POPUP_HELP,(AW_CL)"nt_tree_settings.hlp");
1080    aws->create_button("HELP","HELP","H");
1081
1082    aws->at("button");
1083    aws->auto_space(10,10);
1084    aws->label_length(30);
1085
1086    aws->label("Base Line Width");
1087    aws->create_input_field(AWAR_DTREE_BASELINEWIDTH,4);
1088    aws->at_newline();
1089
1090    aws->label("Relative vert. Dist");
1091    aws->create_input_field(AWAR_DTREE_VERICAL_DIST,4);
1092    aws->at_newline();
1093
1094    aws->label("Auto Jump (list tree)");
1095    aws->create_toggle(AWAR_DTREE_AUTO_JUMP);
1096    aws->at_newline();
1097
1098
1099    return (AW_window *)aws;
1100
1101}
1102
1103static void PA_focus_cb(AW_window *,GBDATA *gb_main_par)
1104{
1105    GB_transaction dummy(gb_main_par);
1106}
1107
1108/******************************************************
1109    Test-Funktionen
1110******************************************************/
1111
1112#if defined(TEST_FUNCTIONS)
1113static void refreshTree(AWT_canvas *ntw) {
1114    GB_transaction gb_dummy(ntw->gb_main);
1115   
1116    AWT_TREE(ntw)->check_update(ntw->gb_main);
1117    GB_ERROR error = AWT_TREE(ntw)->save(ntw->gb_main,0,0,0);
1118    if (error) aw_message(error);
1119    ntw->zoom_reset();
1120    ntw->refresh();
1121}
1122
1123static void testTree(AP_tree_nlen *tree,int *nodeCount, int *edgeCount)
1124{
1125    tree->test();
1126    (*nodeCount)++;
1127
1128    if (tree->father)   // we do only test edges if were not at root
1129    {
1130        AP_tree_edge *e =0;
1131        int skipTest=0;
1132
1133        if (tree->father->father)
1134        {
1135            e = tree->edgeTo(tree->Father());
1136        }
1137        else        // son of root!
1138        {
1139            if (tree->father->leftson==(AP_tree*)tree)  // to not test twice
1140            {
1141                e = tree->edgeTo(tree->Brother());
1142            }
1143            else
1144            {
1145                skipTest=1;
1146            }
1147        }
1148
1149        if (!skipTest)
1150        {
1151            if (e)
1152            {
1153                int dist2bord;
1154
1155                e->test();
1156                (*edgeCount)++;
1157
1158                dist2bord = e->distanceToBorder();
1159                if (dist2bord != e->Distance())
1160                {
1161                    cout << *e << "distance error: should=" << dist2bord << " is=" << e->Distance() << endl;
1162                }
1163            }
1164            else
1165            {
1166                cout << *tree << "has no edge to father\n";
1167            }
1168        }
1169    }
1170
1171    if (!tree->is_leaf)
1172    {
1173        testTree((AP_tree_nlen*)tree->leftson,nodeCount,edgeCount);
1174        testTree((AP_tree_nlen*)tree->rightson,nodeCount,edgeCount);
1175    }
1176}
1177
1178static void TEST_testWholeTree(AW_window *, AWT_canvas *)
1179// Tests the whole tree structure (edges and nodes) for consistency
1180{
1181    AP_tree_nlen *root  = (AP_tree_nlen*)*ap_main->tree_root;
1182    int           nodes = 0;
1183    int           edges = 0;
1184
1185    if (root->father)
1186    {
1187        int m = INT_MAX;
1188
1189        cout << "OOPS! Root has father:\n" << *root << '\n';
1190        while (m-- && root->father) root = root->Father();
1191
1192        if (root->father)
1193        {
1194            cout << "Root node lost between:\n"
1195                 << *root << '\n'
1196                 << *(root->Father()) << '\n';
1197        }
1198        else
1199        {
1200            cout << "Found a root:\n" << *root << "\n Let's test from here:\n";
1201        }
1202    }
1203
1204    root->test_tree();
1205    testTree(root, &nodes, &edges);
1206
1207    cout << "Nodes tested: " << nodes << '\n'
1208         << "Edges tested: " << edges << '\n';
1209}
1210#endif // TEST_FUNCTIONS
1211
1212static int dumpNodes(AP_tree_nlen *node)
1213{
1214    int cnt = 1;
1215
1216    cout << *node
1217         << "(llen=" << node->leftlen
1218         << ",rlen=" << node->rightlen << ")\n";
1219
1220    if (!node->is_leaf)
1221    {
1222        cnt += dumpNodes(node->Leftson());
1223        cnt += dumpNodes(node->Rightson());
1224    }
1225
1226    return cnt;
1227}
1228
1229#if defined(TEST_FUNCTIONS)
1230static void TEST_dumpNodes(AW_window *, AWT_canvas *)
1231{
1232    AP_tree_nlen *root = (AP_tree_nlen*)*ap_main->tree_root;
1233    int cnt;
1234
1235    cout << "----- Dumping all nodes in tree\n";
1236    cnt = dumpNodes(root);
1237    cout << "----- " << cnt << "nodes dumped!\n";
1238}
1239#endif // TEST_FUNCTIONS
1240
1241static void setBranchlens(AP_tree_nlen *node,double newLen)
1242{
1243    node->setBranchlen(newLen,newLen);
1244
1245    if (!node->is_leaf)
1246    {
1247        setBranchlens(node->Leftson(),newLen);
1248        setBranchlens(node->Rightson(),newLen);
1249    }
1250}
1251#if defined(TEST_FUNCTIONS)
1252static void TEST_setBranchlen(AW_window *, AWT_canvas *ntw)
1253{
1254    AP_tree_nlen *root = (AP_tree_nlen*)*ap_main->tree_root;
1255
1256    setBranchlens(root,1.0);
1257    refreshTree(ntw);
1258}
1259#endif // TEST_FUNCTIONS
1260
1261/*
1262static AP_tree_nlen *getRandomSonOf(AP_tree_nlen *daddy, int innerNodeAllowed,int rootAllowed)
1263{
1264    if (daddy->is_leaf) return daddy;
1265    int r = rand() % (innerNodeAllowed && rootAllowed ? 3 : 2);
1266    if (r==2) return daddy;
1267    return getRandomSonOf(r ? daddy->Leftson() : daddy->Rightson(),
1268              innerNodeAllowed, 1);
1269}
1270static void TEST_performRandomMoves(AW_window *aww,AWT_canvas *ntw)
1271{
1272    AWUSE(aww);
1273
1274    int cnt=10000;
1275
1276    while(cnt)
1277    {
1278    AP_tree_nlen *root = (AP_tree_nlen*)*ap_main->tree_root;
1279    AP_tree_nlen *source = getRandomSonOf(root,1,0);
1280    AP_tree_nlen *dest = getRandomSonOf(root,1,0);
1281
1282    if (source!=dest && !dest->is_son(source))
1283    {
1284        root->setBranchlen(1.0,1.0);
1285        source->setBranchlen(1.0,1.0);
1286        dest->setBranchlen(1.0,1.0);
1287
1288        char *error = source->move(dest,0.5);
1289
1290        if (error)
1291        {
1292        cout << error << '\n';
1293        break;
1294        }
1295
1296        cnt--;
1297//      cout << "Moves left: " << cnt << '\n';
1298    }
1299    }
1300
1301    cout << "Testing tree\n";
1302    TEST_testWholeTree(aww,ntw);
1303
1304//    cout << "setting branchlens\n";
1305//    TEST_setBranchlen(aww,ntw);
1306
1307//    cout << "dumping nodes\n";
1308//    TEST_dumpNodes(aww,ntw);
1309
1310    cout << "done\n";
1311//    refreshTree(ntw);
1312}
1313*/
1314
1315#if defined(TEST_FUNCTIONS)
1316static void TEST_mixTree(AW_window *, AWT_canvas *ntw)
1317{
1318    rootEdge()->mixTree(100);
1319    refreshTree(ntw);
1320}
1321
1322static void TEST_sortTreeByName(AW_window *, AWT_canvas *ntw)
1323{
1324    AP_tree_nlen *root = (AP_tree_nlen*)*ap_main->tree_root;
1325
1326    root->sortByName();
1327    refreshTree(ntw);
1328}
1329
1330static void TEST_buildAndDumpChain(AW_window *, AWT_canvas *)
1331{
1332    AP_tree_nlen *root = (AP_tree_nlen*)*ap_main->tree_root;
1333
1334    root->Leftson()->edgeTo(root->Rightson())->testChain(2);
1335    root->Leftson()->edgeTo(root->Rightson())->testChain(3);
1336    root->Leftson()->edgeTo(root->Rightson())->testChain(4);
1337    root->Leftson()->edgeTo(root->Rightson())->testChain(5);
1338    root->Leftson()->edgeTo(root->Rightson())->testChain(6);
1339    root->Leftson()->edgeTo(root->Rightson())->testChain(7);
1340    root->Leftson()->edgeTo(root->Rightson())->testChain(8);
1341    root->Leftson()->edgeTo(root->Rightson())->testChain(9);
1342    root->Leftson()->edgeTo(root->Rightson())->testChain(10);
1343    root->Leftson()->edgeTo(root->Rightson())->testChain(11);
1344    root->Leftson()->edgeTo(root->Rightson())->testChain(-1);
1345}
1346
1347static void init_TEST_menu(AW_window_menu_modes *awm,AWT_canvas *ntw)
1348{
1349    awm->create_menu("Test[debug]", "T", "",  AWM_ALL );
1350
1351    awm->insert_menu_topic(0, "Test edges",         "T", "", AWM_ALL, (AW_CB)TEST_testWholeTree,     (AW_CL)ntw, 0);
1352    awm->insert_menu_topic(0, "Mix tree",           "M", "", AWM_ALL, (AW_CB)TEST_mixTree,           (AW_CL)ntw, 0);
1353    awm->insert_menu_topic(0, "Dump nodes",         "D", "", AWM_ALL, (AW_CB)TEST_dumpNodes,         (AW_CL)ntw, 0);
1354    awm->insert_menu_topic(0, "Set branchlens",     "b", "", AWM_ALL, (AW_CB)TEST_setBranchlen,      (AW_CL)ntw, 0);
1355    awm->insert_menu_topic(0, "Sort tree by name",  "S", "", AWM_ALL, (AW_CB)TEST_sortTreeByName,    (AW_CL)ntw, 0);
1356    awm->insert_menu_topic(0, "Build & dump chain", "c", "", AWM_ALL, (AW_CB)TEST_buildAndDumpChain, (AW_CL)ntw, 0);
1357    awm->insert_separator();
1358    awm->insert_menu_topic(0, "Add marked species",          "A", "pa_quick.hlp", AWM_ALL, (AW_CB)NT_quick_add_test,  (AW_CL)ntw, 0);
1359    awm->insert_menu_topic(0, "Add marked species + NNI",    "N", "pa_add.hlp",   AWM_ALL, (AW_CB)NT_add_test,        (AW_CL)ntw, 0);
1360    awm->insert_menu_topic(0, "Remove & add marked species", "o", "pa_add.hlp",   AWM_ALL, (AW_CB)NT_rquick_add_test, (AW_CL)ntw, 0);
1361    awm->insert_menu_topic(0, "Remove & add marked + NNI",   "v", "pa_add.hlp",   AWM_ALL, (AW_CB)NT_radd_test,       (AW_CL)ntw, 0);
1362    awm->insert_separator();
1363    awm->insert_menu_topic(0, "Add selected species",       "l", "pa_quick_sel.hlp", AWM_ALL, (AW_CB)NT_quick_add_test, (AW_CL)ntw, 1);
1364    awm->insert_menu_topic(0, "Add selected species + NNI", "I", "pa_add_sel.hlp",   AWM_ALL, (AW_CB)NT_add_test,       (AW_CL)ntw, 1);
1365}
1366#endif // TEST_FUNCTIONS
1367
1368static GB_ERROR pars_check_size(AW_root *awr){
1369    char *tree_name = awr->awar(AWAR_TREE)->read_string();
1370    char *filter = awr->awar(AWAR_FILTER_FILTER)->read_string();
1371    GB_ERROR error = 0;
1372    long ali_len = 0;
1373    if (strlen(filter)){
1374        int i;
1375        for (i=0;filter[i];i++){
1376            if (filter[i] != '0') ali_len++;
1377        }
1378    }else{
1379        char *ali_name = awr->awar(AWAR_ALIGNMENT)->read_string();
1380        ali_len = GBT_get_alignment_len(GLOBAL_gb_main,ali_name);
1381        delete ali_name;
1382    }
1383
1384    long tree_size = GBT_size_of_tree(GLOBAL_gb_main,tree_name);
1385    if (tree_size == -1) {
1386        error = GB_export_error("Please select an existing tree");
1387    }
1388    else {
1389        if ((unsigned long)(ali_len * tree_size * 4/ 1000) > GB_get_physical_memory()){
1390            error  = GB_export_error("Very big tree");
1391        }
1392    }
1393    free(filter);
1394    free(tree_name);
1395    return error;
1396}
1397
1398static void pars_reset_optimal_parsimony(AW_window *aww, AW_CL *cl_ntw) {
1399    AW_root *awr = aww->get_root();
1400    awr->awar(AWAR_BEST_PARSIMONY)->write_int(awr->awar(AWAR_PARSIMONY)->read_int());
1401
1402    AWT_canvas *ntw = (AWT_canvas*)cl_ntw;
1403    ntw->refresh();
1404}
1405
1406/******************************************************
1407
1408******************************************************/
1409
1410static void pars_start_cb(AW_window *aw_parent, AW_CL cd_adfiltercbstruct) {
1411    AW_root *awr = aw_parent->get_root();
1412    GB_begin_transaction(GLOBAL_gb_main);
1413    {
1414        GB_ERROR error = pars_check_size(awr);
1415        if (error){
1416            if (!aw_ask_sure("This program will need a lot of computer memory\n"
1417                             "    (Hint: the use of a filter often helps)\n"
1418                             "Do you want to continue?")) {
1419                GB_commit_transaction(GLOBAL_gb_main);
1420                return;
1421            }
1422        }
1423    }
1424
1425
1426    AW_window_menu_modes *awm = new AW_window_menu_modes();
1427    awm->init(awr,"ARB_PARSIMONY", "ARB_PARSIMONY", 400,200);
1428
1429    AW_gc_manager aw_gc_manager = 0;
1430    GLOBAL_NT->tree             = PARS_generate_tree(awr);
1431
1432    AWT_canvas *ntw;
1433    {
1434        AP_tree_sort  old_sort_type = GLOBAL_NT->tree->tree_sort;
1435        GLOBAL_NT->tree->set_tree_type(AP_LIST_SIMPLE); // avoid NDS warnings during startup
1436        ntw = new AWT_canvas(GLOBAL_gb_main, (AW_window *)awm, GLOBAL_NT->tree, aw_gc_manager, AWAR_TREE);
1437        GLOBAL_NT->tree->set_tree_type(old_sort_type);
1438    }
1439
1440    {
1441        aw_openstatus("load tree");
1442        NT_reload_tree_event(awr,ntw,GB_TRUE);          // load first tree and set delete callbacks
1443        if (!GLOBAL_NT->tree->tree_root) {
1444            aw_closestatus();
1445            aw_popup_exit("I cannot load the selected tree");
1446        }
1447
1448        AP_tree_edge::initialize((AP_tree_nlen*)*ap_main->tree_root);   // builds edges
1449        GLOBAL_NT->tree->tree_root->remove_leafs(ntw->gb_main, AWT_REMOVE_DELETED);
1450
1451        adfiltercbstruct *acbs = (adfiltercbstruct*)cd_adfiltercbstruct;
1452        NT_tree_init(GLOBAL_NT->tree, acbs);
1453           
1454        GLOBAL_NT->tree->tree_root->remove_leafs(ntw->gb_main, AWT_REMOVE_DELETED | AWT_REMOVE_NO_SEQUENCE);
1455
1456        GB_commit_transaction(ntw->gb_main);
1457        aw_status("Calculating inner nodes");
1458        GLOBAL_NT->tree->tree_root->costs();
1459
1460        aw_closestatus();
1461    }
1462
1463    awr->awar( AWAR_COLOR_GROUPS_USE)->add_callback( (AW_RCB)NT_recompute_cb, (AW_CL)ntw,0);
1464
1465    if (ap_main->commands.add_marked)           NT_quick_add(awm,ntw,0);
1466    if (ap_main->commands.add_selected)         NT_quick_add(awm,ntw,1);
1467    if (ap_main->commands.calc_branch_lenths)   NT_branch_lengths(awm,ntw);
1468    if (ap_main->commands.calc_bootstrap)       NT_bootstrap(awm,ntw,0);
1469    if (ap_main->commands.quit)                 pars_exit(awm);
1470
1471    GB_transaction dummy(ntw->gb_main);
1472
1473    GBDATA *gb_arb_presets = GB_search(ntw->gb_main,"arb_presets", GB_CREATE_CONTAINER);
1474    GB_add_callback(gb_arb_presets,GB_CB_CHANGED, (GB_CB)AWT_expose_cb,(int *)ntw);
1475
1476#if defined(DEBUG)
1477    AWT_create_debug_menu(awm);
1478#endif // DEBUG
1479
1480    awm->create_menu("File",     "F", "pars_file.hlp",  AWM_ALL );
1481    {
1482        awm->insert_menu_topic("print_tree", "Print Tree ...",          "P","tree2prt.hlp", AWM_ALL, AWT_popup_print_window, (AW_CL)ntw, 0 );
1483        awm->insert_menu_topic( "quit",     "Quit",             "Q","quit.hlp",     AWM_ALL, (AW_CB)PARS_export_cb, (AW_CL)ntw,2);
1484    }
1485
1486    awm->create_menu("Species", "S", "nt_tree.hlp",  AWM_ALL );
1487    {
1488        NT_insert_mark_submenus(awm, ntw, 0);
1489
1490    }
1491    awm->create_menu("Tree", "T", "nt_tree.hlp",  AWM_ALL );
1492    {
1493
1494        awm->insert_menu_topic( "nds",      "NDS (Node Display Setup) ...",      "N","props_nds.hlp",    AWM_ALL, AW_POPUP, (AW_CL)AWT_create_nds_window, (AW_CL)ntw->gb_main );
1495
1496        awm->insert_separator();
1497        awm->insert_menu_topic("tree_2_xfig", "Edit Tree View using XFIG ...",  "E", "tree2file.hlp", AWM_ALL, AWT_popup_tree_export_window, (AW_CL)ntw, 0);
1498        awm->insert_menu_topic("tree_print",  "Print Tree View to Printer ...", "P", "tree2prt.hlp",  AWM_ALL, AWT_popup_print_window,       (AW_CL)ntw, 0);
1499        awm->insert_separator();
1500        awm->insert_sub_menu("Collapse/Expand Tree",         "C");
1501        {
1502            awm->insert_menu_topic("tree_group_all",        "Group All",            "A","tgroupall.hlp",    AWM_ALL,    (AW_CB)NT_group_tree_cb,    (AW_CL)ntw, 0 );
1503            awm->insert_menu_topic("tree_group_not_marked", "Group All Except Marked",  "M","tgroupnmrkd.hlp",  AWM_ALL,    (AW_CB)NT_group_not_marked_cb,  (AW_CL)ntw, 0 );
1504            awm->insert_menu_topic("tree_ungroup_all",      "Ungroup All",          "U","tungroupall.hlp",  AWM_ALL,    (AW_CB)NT_ungroup_all_cb,   (AW_CL)ntw, 0 );
1505            awm->insert_separator();
1506            NT_insert_color_collapse_submenu(awm, ntw);
1507        }
1508        awm->close_sub_menu();
1509        awm->insert_separator();
1510        awm->insert_sub_menu("Remove Species from Tree",     "R");
1511        {
1512            awm->insert_menu_topic("tree_remove_deleted", "Remove Zombies", "Z", "trm_del.hlp",    AWM_ALL, (AW_CB)NT_remove_leafs, (AW_CL)ntw, AWT_REMOVE_DELETED|AWT_REMOVE_BUT_DONT_FREE);
1513            awm->insert_menu_topic("tree_remove_marked",  "Remove Marked",  "M", "trm_mrkd.hlp",   AWM_ALL, (AW_CB)NT_remove_leafs, (AW_CL)ntw, AWT_REMOVE_MARKED|AWT_REMOVE_BUT_DONT_FREE);
1514            awm->insert_menu_topic("tree_keep_marked",    "Keep Marked",    "K", "tkeep_mrkd.hlp", AWM_ALL, (AW_CB)NT_remove_leafs, (AW_CL)ntw, AWT_REMOVE_NOT_MARKED|AWT_REMOVE_DELETED|AWT_REMOVE_BUT_DONT_FREE);
1515        }
1516        awm->close_sub_menu();
1517        awm->insert_sub_menu("Add Species to Tree",      "A");
1518        {
1519            awm->insert_menu_topic("add_marked",         "Add Marked Species",                              "M", "pa_quick.hlp",     AWM_ALL, (AW_CB)NT_quick_add,  (AW_CL)ntw, 0);
1520            awm->insert_menu_topic("add_marked_nni",     "Add Marked Species + Local Optimization (NNI)",   "N", "pa_add.hlp",       AWM_ALL, (AW_CB)NT_add,        (AW_CL)ntw, 0);
1521            awm->insert_menu_topic("rm_add_marked",      "Remove & Add Marked Species",                     "R", "pa_add.hlp",       AWM_ALL, (AW_CB)NT_rquick_add, (AW_CL)ntw, 0);
1522            awm->insert_menu_topic("rm_add_marked_nni|", "Remove & Add Marked + Local Optimization (NNI)",  "L", "pa_add.hlp",       AWM_ALL, (AW_CB)NT_radd,       (AW_CL)ntw, 0);
1523            awm->insert_separator();
1524            awm->insert_menu_topic("add_marked_partial", "Add Marked Partial Species",                      "P", "pa_partial.hlp",   AWM_ALL, NT_partial_add,       (AW_CL)ntw, (AW_CL)0);
1525            awm->insert_separator();
1526            awm->insert_menu_topic("add_selected",       "Add Selected Species",                            "S", "pa_quick_sel.hlp", AWM_ALL, (AW_CB)NT_quick_add,  (AW_CL)ntw, 1);
1527            awm->insert_menu_topic("add_selected_nni",   "Add Selected Species + Local Optimization (NNI)", "O", "pa_add_sel.hlp",   AWM_ALL, (AW_CB)NT_add,        (AW_CL)ntw, 1);
1528        }
1529        awm->close_sub_menu();
1530        awm->insert_separator();
1531        awm->insert_sub_menu("Tree Optimization",        "O");
1532        {
1533            awm->insert_menu_topic("nni",           "Local Optimization (NNI) of Marked Visible Nodes", "L","",         AWM_ALL,    (AW_CB)NT_recursiveNNI, (AW_CL)ntw, 0 );
1534            awm->insert_menu_topic("kl_optimization",   "Global Optimization of Marked Visible Nodes",      "G","pa_optimizer.hlp", AWM_ALL,    (AW_CB)NT_optimize, (AW_CL)ntw, 0 );
1535        }
1536        awm->close_sub_menu();
1537        awm->insert_menu_topic("reset", "Reset optimal parsimony", "s", "", AWM_ALL, (AW_CB)pars_reset_optimal_parsimony, (AW_CL)ntw, 0);
1538        awm->insert_separator();
1539        awm->insert_menu_topic("beautify_tree",      "Beautify Tree",            "B", "resorttree.hlp",       AWM_ALL, (AW_CB)NT_resort_tree_cb, (AW_CL)ntw, 0);
1540        awm->insert_menu_topic("calc_branch_lenths", "Calculate Branch Lengths", "L", "pa_branchlengths.hlp", AWM_ALL, (AW_CB)NT_branch_lengths, (AW_CL)ntw, 0);
1541        awm->insert_separator();
1542        awm->insert_menu_topic("calc_upper_bootstrap_indep", "Calculate Upper Bootstrap Limit (dependent NNI)",   "d", "pa_bootstrap.hlp", AWM_ALL, (AW_CB)NT_bootstrap,        (AW_CL)ntw, 0);
1543        awm->insert_menu_topic("calc_upper_bootstrap_dep",   "Calculate Upper Bootstrap Limit (independent NNI)", "i", "pa_bootstrap.hlp", AWM_ALL, (AW_CB)NT_bootstrap,        (AW_CL)ntw, 1);
1544        awm->insert_menu_topic("tree_remove_remark",         "Remove Bootstrap Values",                           "V", "trm_boot.hlp",     AWM_ALL, (AW_CB)NT_remove_bootstrap, (AW_CL)ntw, 0);
1545    }
1546
1547#if defined(TEST_FUNCTIONS)
1548    init_TEST_menu(awm,ntw);
1549#endif // TEST_FUNCTIONS
1550
1551    awm->create_menu("Properties","r","properties.hlp", AWM_ALL);
1552    {
1553        awm->insert_menu_topic("props_menu",  "Menu: Colors and Fonts ...",              "M", "props_frame.hlp",      AWM_ALL, AW_POPUP,(AW_CL)AW_preset_window,        0);
1554        awm->insert_menu_topic("props_tree",  "Tree: Colors and Fonts ...",              "C", "pars_props_data.hlp",  AWM_ALL, AW_POPUP,(AW_CL)AW_create_gc_window,     (AW_CL)aw_gc_manager );
1555        awm->insert_menu_topic("props_tree2", "Tree: Settings ...",                      "T", "nt_tree_settings.hlp", AWM_ALL, AW_POPUP,(AW_CL)NT_create_tree_setting,  (AW_CL)ntw );
1556        awm->insert_menu_topic("props_kl",    "KERN. LIN ...",                           "K", "kernlin.hlp",          AWM_ALL, AW_POPUP,(AW_CL)create_kernighan_window, 0);
1557        awm->insert_menu_topic("save_props",  "Save Defaults (in ~/.arb_prop/pars.arb)", "D", "savedef.hlp",          AWM_ALL, (AW_CB)AW_save_defaults, 0, 0);
1558    }
1559    awm->button_length(5);
1560
1561    awm->create_menu("ETC","E","nt_etc.hlp", AWM_ALL);
1562    {
1563        awm->insert_menu_topic("reset_logical_zoom",    "Reset Logical Zoom",   "L","rst_log_zoom.hlp", AWM_ALL, (AW_CB)NT_reset_lzoom_cb, (AW_CL)ntw, 0 );
1564        awm->insert_menu_topic("reset_physical_zoom",   "Reset Physical Zoom",  "P","rst_phys_zoom.hlp",AWM_ALL, (AW_CB)NT_reset_pzoom_cb, (AW_CL)ntw, 0 );
1565    }
1566
1567    awm->insert_help_topic("How to use Help",    "H", "help.hlp",     AWM_ALL, (AW_CB)AW_POPUP_HELP, (AW_CL)"help.hlp",     0);
1568    awm->insert_help_topic("ARB Help",           "A", "arb.hlp",      AWM_ALL, (AW_CB)AW_POPUP_HELP, (AW_CL)"arb.hlp",      0);
1569    awm->insert_help_topic("ARB PARSIMONY Help", "N", "arb_pars.hlp", AWM_ALL, (AW_CB)AW_POPUP_HELP, (AW_CL)"arb_pars.hlp", 0);
1570
1571    awm->create_mode("select.bitmap", "mode_select.hlp", AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_SELECT);
1572    awm->create_mode("mark.bitmap",   "mode_mark.hlp",   AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_MARK);
1573    awm->create_mode("group.bitmap",  "mode_group.hlp",  AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_GROUP);
1574    awm->create_mode("pzoom.bitmap",  "mode_pzoom.hlp",  AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_ZOOM);
1575    awm->create_mode("lzoom.bitmap",  "mode_lzoom.hlp",  AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_LZOOM);
1576    awm->create_mode("swap.bitmap",   "mode_swap.hlp",   AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_SWAP);
1577    awm->create_mode("move.bitmap",   "mode_move.hlp",   AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_MOVE);
1578#ifdef NNI_MODES
1579    awm->create_mode("nearestn.bitmap", "mode_nni.hlp",      AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_NNI);
1580    awm->create_mode("kernlin.bitmap",  "mode_kernlin.hlp",  AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_KERNINGHAN);
1581    awm->create_mode("optimize.bitmap", "mode_optimize.hlp", AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_OPTIMIZE);
1582#endif // NNI_MODES
1583    awm->create_mode("setroot.bitmap", "mode_set_root.hlp", AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_SETROOT);
1584    awm->create_mode("reset.bitmap",   "mode_reset.hlp",    AWM_ALL, (AW_CB)nt_mode_event, (AW_CL)ntw, (AW_CL)AWT_MODE_RESET);
1585
1586    awm->at(5,2);
1587    awm->auto_space(0,-2);
1588    awm->shadow_width(1);
1589
1590
1591    int db_treex,db_treey;
1592    awm->get_at_position( &db_treex,&db_treey );
1593    awm->callback(AW_POPUP_HELP,(AW_CL)"nt_tree_select.hlp");
1594    awm->button_length(16);
1595    awm->help_text("nt_tree_select.hlp");
1596    awm->create_button(0,AWAR_TREE);
1597
1598
1599    int db_stackx,db_stacky;
1600    awm->label_length(8);
1601    awm->label("Stored");
1602    awm->get_at_position( &db_stackx,&db_stacky );
1603    awm->button_length(6);
1604    awm->callback( AW_POPUP_HELP, (AW_CL)"ap_stack.hlp");
1605    awm->help_text("ap_stack.hlp");
1606    awm->create_button(0,AWAR_STACKPOINTER);
1607
1608    int db_parsx,db_parsy;
1609    awm->label_length(14);
1610    awm->label("Current Pars:");
1611    awm->get_at_position( &db_parsx,&db_parsy );
1612
1613    awm->button_length(10);
1614    awm->create_button(0,AWAR_PARSIMONY);
1615
1616    awm->button_length(0);
1617
1618    awm->callback((AW_CB)NT_jump_cb,(AW_CL)ntw,1);
1619    awm->help_text("tr_jump.hlp");
1620    awm->create_button("JUMP","#pjump.bitmap",0);
1621
1622    awm->callback(AW_POPUP_HELP,(AW_CL)"arb_pars.hlp");
1623    awm->help_text("help.hlp");
1624    awm->create_button("HELP","HELP","H");
1625
1626    awm->at_newline();
1627
1628    awm->button_length(8);
1629    awm->at_x(db_stackx);
1630    awm->callback((AW_CB1)AP_user_pop_cb,(AW_CL)ntw);
1631    awm->help_text("ap_stack.hlp");
1632    awm->create_button("POP","RESTORE",0);
1633
1634    awm->button_length(6);
1635    awm->callback((AW_CB1)AP_user_push_cb,(AW_CL)ntw);
1636    awm->help_text("ap_stack.hlp");
1637    awm->create_button("PUSH", "STORE",0);
1638
1639    awm->button_length(7);
1640
1641    awm->at_x(db_treex);
1642    awm->callback((AW_CB)NT_set_tree_style,(AW_CL)ntw,(AW_CL)AP_TREE_RADIAL);
1643    awm->help_text("tr_type_radial.hlp");
1644    awm->create_button("RADIAL_TREE", "#radial.bitmap",0);
1645
1646    awm->callback((AW_CB)NT_set_tree_style,(AW_CL)ntw,(AW_CL)AP_TREE_NORMAL);
1647    awm->help_text("tr_type_list.hlp");
1648    awm->create_button("LIST_TREE", "#list.bitmap",0);
1649
1650    awm->at_x(db_parsx);
1651    awm->label_length(14);
1652    awm->label("Optimal Pars:");
1653
1654    awm->button_length(10);
1655    awm->create_button(0,AWAR_BEST_PARSIMONY);
1656
1657    awm->at_newline();
1658
1659    {
1660        AW_at_maxsize maxSize; // store size (so AWAR_FOOTER does not affect min. window size)
1661        maxSize.store(awm->_at);
1662        awm->button_length(AWAR_FOOTER_MAX_LEN);
1663        awm->create_button(0,AWAR_FOOTER);
1664        awm->at_newline();
1665        maxSize.restore(awm->_at);
1666    }
1667
1668//     awm->button_length(AWAR_FOOTER_MAX_LEN);
1669//     awm->create_button(0,AWAR_FOOTER);
1670
1671//     awm->at_newline();
1672    awm->get_at_position( &db_treex,&db_treey );
1673    awm->set_info_area_height( db_treey+6 );
1674
1675    awm->set_bottom_area_height( 0 );
1676    awm->set_focus_callback((AW_CB)PA_focus_cb,(AW_CL)ntw->gb_main,0);
1677
1678    aw_parent->hide(); // hide parent
1679    awm->show();
1680
1681    AP_user_push_cb(aw_parent, ntw); // push initial tree
1682}
1683
1684static AW_window *create_pars_init_window(AW_root *awr)
1685{
1686    AW_window_simple *aws = new AW_window_simple;
1687    aws->init( awr, "PARS_PROPS", "SET PARSIMONY OPTIONS");
1688    aws->load_xfig("pars/init.fig");
1689
1690    aws->button_length( 10 );
1691    aws->label_length( 10 );
1692
1693    aws->callback(pars_exit);
1694    aws->at("close");
1695    aws->create_button("ABORT","ABORT","A");
1696
1697    aws->callback(AW_POPUP_HELP,(AW_CL)"arb_pars_init.hlp");
1698    aws->at("help");
1699    aws->create_button("HELP","HELP","H");
1700
1701    aws->at("filter");
1702    adfiltercbstruct *filtercd = awt_create_select_filter(aws->get_root(),GLOBAL_gb_main,AWAR_FILTER_NAME);
1703    aws->callback(AW_POPUP, (AW_CL)awt_create_select_filter_win, (AW_CL)filtercd);
1704    aws->create_button("SELECT_FILTER",AWAR_FILTER_NAME);
1705
1706    aws->callback(pars_start_cb, (AW_CL)filtercd);
1707    aws->at("go");
1708    aws->create_button("GO","GO","G");
1709
1710    aws->at("alignment");
1711    awt_create_selection_list_on_ad(GLOBAL_gb_main,(AW_window *)aws,AWAR_ALIGNMENT,"*=");
1712
1713    aws->at("tree");
1714    awt_create_selection_list_on_trees(GLOBAL_gb_main,(AW_window *)aws,AWAR_TREE);
1715
1716    awt_csp = new AWT_csp(GLOBAL_gb_main,awr,"tmp/pars/csp/name");
1717
1718    aws->at("weights");
1719    aws->callback(AW_POPUP,(AW_CL)create_csp_window,(AW_CL)awt_csp);
1720    aws->sens_mask(AWM_EXP);
1721    aws->create_button("SELECT_CSP","tmp/pars/csp/name");
1722    aws->sens_mask(AWM_ALL);
1723
1724    return (AW_window *)aws;
1725}
1726
1727static void create_parsimony_variables(AW_root *aw_root, AW_default def)
1728{
1729    // parsimony
1730#if 0
1731    aw_root->awar_float("genetic/m_rate",0,def);
1732    aw_root->awar_int("genetic/input_1",0,def);
1733    aw_root->awar_int("genetic/input_2",0,def);
1734    aw_root->awar_float("genetic/input_3",0,def);
1735    aw_root->awar_float("genetic/input_4",0,def);
1736    aw_root->awar_float("genetic/input_5",0,def);
1737    aw_root->awar_float("genetic/input_6",0,def);
1738    aw_root->awar_float("genetic/input_7",0,def);
1739    aw_root->awar_float("genetic/input_8",0,def);
1740    aw_root->awar_float("genetic/input_9",0,def);
1741    aw_root->awar_float("genetic/input_10",0,def);
1742    aw_root->awar_float("genetic/input_11",0,def);
1743    aw_root->awar_int("genetic/out_1",0,def);
1744    aw_root->awar_float("genetic/out_2",0,def);
1745    aw_root->awar_float("genetic/out_3",0,def);
1746    aw_root->awar_float("genetic/out_4",0,def);
1747    aw_root->awar_float("genetic/out_5",0,def);
1748    aw_root->awar_float("genetic/out_6",0,def);
1749    aw_root->awar_float("genetic/out_7",0,def);
1750    aw_root->awar_float("genetic/out_8",0,def);
1751#endif
1752    // kernighan
1753
1754    aw_root->awar_float("genetic/kh/nodes",1.7,def);
1755    aw_root->awar_int("genetic/kh/maxdepth",15,def);
1756    aw_root->awar_int("genetic/kh/incdepth",5,def);
1757
1758    aw_root->awar_int("genetic/kh/static/enable",1,def);
1759    aw_root->awar_int("genetic/kh/static/depth0",2,def);
1760    aw_root->awar_int("genetic/kh/static/depth1",2,def);
1761    aw_root->awar_int("genetic/kh/static/depth2",2,def);
1762    aw_root->awar_int("genetic/kh/static/depth3",2,def);
1763    aw_root->awar_int("genetic/kh/static/depth4",1,def);
1764
1765    aw_root->awar_int("genetic/kh/dynamic/enable",1,def);
1766    aw_root->awar_int("genetic/kh/dynamic/start",100,def);
1767    aw_root->awar_int("genetic/kh/dynamic/maxx",6,def);
1768    aw_root->awar_int("genetic/kh/dynamic/maxy",150,def);
1769
1770    aw_root->awar_int("genetic/kh/function_type",AP_QUADRAT_START,def);
1771
1772    awt_create_dtree_awars(aw_root,def);
1773}
1774
1775static void pars_create_all_awars(AW_root *awr, AW_default aw_def)
1776{
1777    awr->awar_string(AWAR_SPECIES_NAME, "",     GLOBAL_gb_main);
1778    awr->awar_string(AWAR_FOOTER,       "",     aw_def);
1779    awr->awar_string(AWAR_FILTER_NAME,  "none", GLOBAL_gb_main);
1780
1781    {
1782        GB_transaction  ta(GLOBAL_gb_main);
1783        char           *dali = GBT_get_default_alignment(GLOBAL_gb_main);
1784       
1785        awr->awar_string( AWAR_ALIGNMENT,dali ,GLOBAL_gb_main )->write_string(dali);
1786        free(dali);
1787    }
1788
1789    awt_set_awar_to_valid_filter_good_for_tree_methods(GLOBAL_gb_main,awr,AWAR_FILTER_NAME);
1790
1791    awr->awar_string(AWAR_FILTER_FILTER,"" ,GLOBAL_gb_main);
1792    awr->awar_string(AWAR_FILTER_ALIGNMENT,"" ,aw_def)     ;
1793    awr->awar       (AWAR_FILTER_ALIGNMENT)                ->map(AWAR_ALIGNMENT);
1794
1795    awr->awar_string( "tmp/pars/csp/alignment",0 ,aw_def );
1796    awr->awar("tmp/pars/csp/alignment")->map(AWAR_ALIGNMENT);
1797
1798    awr->awar_int( AWAR_PARS_TYPE,PARS_WAGNER ,GLOBAL_gb_main );
1799
1800    {
1801        GB_transaction  ta(GLOBAL_gb_main);
1802        GBDATA *gb_tree_name = GB_search(GLOBAL_gb_main,AWAR_TREE,GB_STRING);
1803        char   *tree_name    = GB_read_string(gb_tree_name);
1804       
1805        awr->awar_string( AWAR_TREE,0 ,aw_def )->write_string(tree_name);
1806        free(tree_name);
1807    }
1808
1809    awr->awar_int(AWAR_PARSIMONY,      0, aw_def);
1810    awr->awar_int(AWAR_BEST_PARSIMONY, 0, aw_def);
1811    awr->awar_int(AWAR_STACKPOINTER,   0, aw_def);
1812
1813    create_parsimony_variables(awr, GLOBAL_gb_main);
1814    create_nds_vars(awr,aw_def,GLOBAL_gb_main);
1815
1816#if defined(DEBUG)
1817    AWT_create_db_browser_awars(awr, aw_def);
1818#endif // DEBUG
1819
1820    GB_ERROR error = ARB_init_global_awars(awr, aw_def, GLOBAL_gb_main);
1821    if (error) aw_message(error);
1822}
1823
1824static AW_root *AD_map_viewer_aw_root = 0;
1825
1826void AD_map_viewer(GBDATA *gb_species, AD_MAP_VIEWER_TYPE vtype) {
1827    if (vtype == ADMVT_SELECT && AD_map_viewer_aw_root && gb_species) {
1828        AD_map_viewer_aw_root->awar(AWAR_SPECIES_NAME)->write_string(GBT_read_name(gb_species));
1829    }
1830}
1831
1832int main(int argc, char **argv)
1833{
1834    AW_root *aw_root;
1835    AW_default aw_default;
1836    AW_window *aww;
1837
1838    aw_initstatus();
1839
1840    aw_root = new AW_root;
1841    aw_default = aw_root->open_default(".arb_prop/pars.arb");
1842    aw_root->init_variables(aw_default);
1843    aw_root->init_root("ARB_PARS", false);
1844
1845    AD_map_viewer_aw_root = aw_root;
1846
1847    ap_main = new AP_main;
1848
1849    GLOBAL_NT      = (NT_global *)calloc(sizeof(NT_global),1);
1850    GLOBAL_NT->awr = aw_root;
1851
1852    const char *db_server = ":";
1853
1854    while (argc>=2 && argv[1][0] == '-'){
1855        argc--;
1856        argv++;
1857        if (!strcmp(argv[0],"-quit")){
1858            ap_main->commands.quit = 1;
1859            continue;
1860        }
1861        if (!strcmp(argv[0],"-add_marked")){
1862            ap_main->commands.add_marked = 1;
1863            continue;
1864        }
1865        if (!strcmp(argv[0],"-add_selected")){
1866            ap_main->commands.add_selected = 1;
1867            continue;
1868        }
1869        if (!strcmp(argv[0],"-calc_branchlengths")){
1870            ap_main->commands.calc_branch_lenths = 1;
1871            continue;
1872        }
1873        if (!strcmp(argv[0],"-calc_bootstrap")){
1874            ap_main->commands.calc_bootstrap = 1;
1875            continue;
1876        }
1877        GB_export_errorf("Unknown option '%s'",argv[0]);
1878        GB_print_error();
1879        printf("    Options:                Meaning:\n"
1880               "\n"
1881               "    -add_marked             add marked species   (without changing topology)\n"
1882               "    -add_selected           add selected species (without changing topology)\n"
1883               "    -calc_branchlengths     calculate branch lengths only\n"
1884               "    -calc_bootstrap         estimate bootstrap values\n"
1885               "    -quit                   quit after performing operations\n"
1886               );
1887
1888        exit(-1);
1889    }
1890
1891
1892    if (argc==2) {
1893        db_server = argv[1];
1894    }
1895
1896    GLOBAL_gb_main = GBT_open(db_server,"rw",0);
1897    if (!GLOBAL_gb_main) aw_popup_exit(GB_await_error()); // exits
1898   
1899#if defined(DEBUG)
1900    AWT_announce_db_to_browser(GLOBAL_gb_main, GBS_global_string("ARB-database (%s)", db_server));
1901#endif // DEBUG
1902
1903    pars_create_all_awars(aw_root,aw_default);
1904
1905    aww = create_pars_init_window(aw_root);
1906    aww->show();
1907
1908    aw_root->main_loop();
1909    return EXIT_SUCCESS;
1910}
1911
1912
Note: See TracBrowser for help on using the repository browser.