source: branches/port5/PARSIMONY/PARS_dtree.cxx

Last change on this file was 5837, checked in by westram, 16 years ago
  • fixed error handling in classes AP_tree + AP_tree_root
    • many functions returned GB_ERROR, but NEVER failed
    • some functions now crash instead of reporting error (AP_tree::moveTo, AP_tree::swap_assymetric) when they are used in an illegal way.
  • when using the current tree, sequence quality calculation removed that tree, if no species was marked and 'marked species only' was checked
    • fixed that problem in sequence quality (using GBT_remove_leafs)
    • column statistic is completely based on AP_tree(_root), can't fix there.
  • Instead fixed behavior of AP_tree/AP_tree_root
    • when tree gets emptied by tree operations, AP_tree_root only remembers to delete the tree from DB
    • saveTree() finally deletes previously remembered tree
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.5 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include <arbdb.h>
6#include <arbdbt.h>
7#include <aw_root.hxx>
8#include <aw_device.hxx>
9#include <aw_window.hxx>
10#include <aw_preset.hxx>
11#include <awt_canvas.hxx>
12#include <awt_tree.hxx>
13#include <awt_seq_dna.hxx>
14#include <awt_seq_protein.hxx>
15
16#include <awt_csp.hxx>
17#include <awt.hxx>
18#include <awt_dtree.hxx>
19#include <awt_sel_boxes.hxx>
20#include "pars_dtree.hxx"
21
22#include "AP_buffer.hxx"
23#include "parsimony.hxx"
24#include "ap_tree_nlen.hxx"
25#include "pars_main.hxx"
26#include "pars_debug.hxx"
27
28extern AWT_csp *awt_csp;
29
30char *AWT_graphic_parsimony_root_changed(void *cd, AP_tree *old, AP_tree *newroot)
31{
32    AWT_graphic_tree *agt = (AWT_graphic_tree*)cd;
33    if (old == agt->tree_root_display) agt->tree_root_display = newroot;
34    if (old == agt->tree_root) agt->tree_root = newroot;
35    if (old == GLOBAL_NT->tree->tree_root) GLOBAL_NT->tree->tree_root = newroot;
36    return 0;
37}
38
39
40/**************************
41tree_init()
42
43        Filter & weights setup
44        loads sequences at the leafs and
45        initalize filters & weights for the tree
46        ( AP_tree_nlen expected )
47
48**************************/
49void NT_tree_init(AWT_graphic_tree *agt, adfiltercbstruct *pars_global_filter) {
50
51    AP_tree *tree = agt->tree_root;
52    GB_transaction dummy(GLOBAL_gb_main);
53
54    if (!tree) {
55        return;
56    }
57    char *use = GBT_read_string(GLOBAL_gb_main,AWAR_ALIGNMENT);
58
59    long ali_len = GBT_get_alignment_len(GLOBAL_gb_main,use);
60    if (ali_len <=1) {
61        aw_popup_exit("No valid alignment selected! Try again");
62    }
63
64
65    GB_BOOL is_aa = GBT_is_alignment_protein(GLOBAL_gb_main,use);
66    //
67    // filter & weights setup
68    //
69    if (!tree->tree_root->sequence_template) {
70        AP_tree_root *tr = tree->tree_root;
71        AP_sequence *sproto;
72        if (is_aa) {
73            sproto = (AP_sequence *)new AP_sequence_protein(tr);
74        }else{
75            sproto = (AP_sequence *)new AP_sequence_parsimony(tr);
76        }
77
78        tr->sequence_template = sproto;
79        tr->filter = awt_get_filter(agt->aw_root, pars_global_filter);
80        tr->weights = new AP_weights();
81
82        awt_csp->go(0);
83        int i;
84        if (awt_csp->rates){
85            for (i=0;i<ali_len;i++){
86                if (awt_csp->rates[i]>0.0000001){
87                    awt_csp->weights[i] *= (int)(2.0/ awt_csp->rates[i]);
88                }
89            }
90            tr->weights->init(awt_csp->weights , tr->filter);
91        }else{
92            tr->weights->init(tr->filter);
93        }
94        tree->load_sequences_rek(use,GB_FALSE,GB_TRUE);         // load with sequences
95    }
96    tree->tree_root->root_changed_cd = (void*)agt;
97    tree->tree_root->root_changed = AWT_graphic_parsimony_root_changed;
98
99    ap_main->use = use;
100}
101
102static int ap_global_abort_flag;
103
104double funktion_quadratisch(double x,double *param_list,int param_anz) {
105    AP_FLOAT ergebnis;
106    double wert = (double)x;
107    if (param_anz != 3) {
108        AW_ERROR("funktion_quadratisch: Falsche Parameteranzahl !");
109        return (AP_FLOAT)0;
110    }
111    ergebnis = wert * wert * param_list[0] + wert * param_list[1] + param_list[2];
112    return ergebnis;
113}
114
115
116void PARS_kernighan_cb(AP_tree *tree) {
117
118    GB_push_transaction(GLOBAL_gb_main);
119
120    AP_sequence::global_combineCount = 0;
121
122    AP_FLOAT pars_start, pars_prev;
123    pars_prev  = pars_start = GLOBAL_NT->tree->tree_root->costs();
124
125    int rek_deep_max = *GBT_read_int(GLOBAL_gb_main,"genetic/kh/maxdepth");
126
127    AP_KL_FLAG funktype = (AP_KL_FLAG)*GBT_read_int(GLOBAL_gb_main,"genetic/kh/function_type");
128
129    int param_anz;
130    double param_list[3];
131    double f_startx,f_maxy,f_maxx,f_max_deep;
132    f_max_deep = (double)rek_deep_max;                   //             x2
133    f_startx = (double)*GBT_read_int(GLOBAL_gb_main,"genetic/kh/dynamic/start");
134    f_maxy = (double)*GBT_read_int(GLOBAL_gb_main,"genetic/kh/dynamic/maxy");
135    f_maxx = (double)*GBT_read_int(GLOBAL_gb_main,"genetic/kh/dynamic/maxx");
136
137    double (*funktion)(double wert,double *param_list,int param_anz);
138    switch (funktype) {
139        default:
140        case AP_QUADRAT_START:
141            funktion = funktion_quadratisch;
142            param_anz = 3;
143            param_list[2] = f_startx;
144            param_list[0] = (f_startx - f_maxy) / (f_maxx * f_maxx);
145            param_list[1] = -2.0 * param_list[0] * f_maxx;
146            break;
147        case AP_QUADRAT_MAX:    // parameter liste fuer quadratische gleichung (y =ax^2 +bx +c)
148            funktion = funktion_quadratisch;
149            param_anz = 3;
150            param_list[0] =  - f_maxy / (( f_max_deep -  f_maxx) * ( f_max_deep - f_maxx));
151            param_list[1] =  -2.0 * param_list[0] * f_maxx;
152            param_list[2] =  f_maxy  + param_list[0] * f_maxx * f_maxx;
153            break;
154    }
155
156
157    AP_KL_FLAG searchflag=(AP_KL_FLAG)0;
158    if (*GBT_read_int(GLOBAL_gb_main,"genetic/kh/dynamic/enable")){
159        searchflag = AP_DYNAMIK;
160    }
161    if (*GBT_read_int(GLOBAL_gb_main,"genetic/kh/static/enable")){
162        searchflag = (AP_KL_FLAG)(searchflag|AP_STATIC);
163    }
164
165    int rek_breite[8];
166    rek_breite[0] = *GBT_read_int(GLOBAL_gb_main,"genetic/kh/static/depth0");
167    rek_breite[1] = *GBT_read_int(GLOBAL_gb_main,"genetic/kh/static/depth1");
168    rek_breite[2] = *GBT_read_int(GLOBAL_gb_main,"genetic/kh/static/depth2");
169    rek_breite[3] = *GBT_read_int(GLOBAL_gb_main,"genetic/kh/static/depth3");
170    rek_breite[4] = *GBT_read_int(GLOBAL_gb_main,"genetic/kh/static/depth4");
171    int rek_breite_anz = 5;
172
173    int anzahl = (int)(*GBT_read_float(GLOBAL_gb_main,"genetic/kh/nodes")*tree->arb_tree_leafsum2());
174    AP_tree **list;
175    list = tree->getRandomNodes(anzahl);
176    int i =0;
177
178
179    i = 0;
180    aw_openstatus("KL Optimizer");
181    {
182        char buffer[100];
183        sprintf(buffer,"Old Parsimony: %f",pars_start);
184        aw_status(buffer);
185    }
186    int abort_flag = AP_FALSE;
187
188    GB_pop_transaction(GLOBAL_gb_main);
189
190    for (i=0;i<anzahl && ! abort_flag; i++) {
191        abort_flag |= aw_status(i/(double)anzahl);
192        if (abort_flag) break;
193
194        AP_tree_nlen *tree_elem = (AP_tree_nlen *)list[i];
195
196        if (tree_elem->gr.hidden ||
197            (tree_elem->father && tree_elem->father->gr.hidden)){
198            continue;   // within a folded group
199        }
200        {
201            AP_BOOL better_tree_found = AP_FALSE;
202            ap_main->push();
203            display_clear(funktion,param_list,param_anz,(int)pars_start,(int)rek_deep_max);
204
205            tree_elem->kernighan_rek(0,
206                                     rek_breite,rek_breite_anz,rek_deep_max,
207                                     funktion, param_list,param_anz,
208                                     pars_start,  pars_start, pars_prev,
209                                     searchflag,&better_tree_found);
210
211            if (better_tree_found) {
212                ap_main->clear();
213                pars_start =  GLOBAL_NT->tree->tree_root->costs();
214                char buffer[100];
215                sprintf(buffer,"New Parsimony: %f",pars_start);
216                abort_flag |= aw_status(buffer);
217            } else {
218                ap_main->pop();
219            }
220        }
221    }
222    aw_closestatus();
223    delete list;
224    ap_global_abort_flag |= abort_flag;
225    printf("Combines: %li\n", AP_sequence::global_combineCount);
226    return;
227}
228
229void PARS_optimizer_cb(AP_tree *tree) {
230    AP_tree *oldrootleft  = GLOBAL_NT->tree->tree_root->leftson;
231    AP_tree *oldrootright = GLOBAL_NT->tree->tree_root->rightson;
232
233    for (ap_global_abort_flag = 0;!ap_global_abort_flag;){
234        AP_FLOAT old_pars = GLOBAL_NT->tree->tree_root->costs();
235       
236        ((AP_tree_nlen *)tree)->nn_interchange_rek(AP_TRUE,ap_global_abort_flag,-1,AP_BL_NNI_ONLY, GB_TRUE); // only not hidden
237        if (ap_global_abort_flag) break;
238        PARS_kernighan_cb(tree);
239        if (old_pars == GLOBAL_NT->tree->tree_root->costs()) {
240            ap_global_abort_flag = 1;
241        }
242    }
243    if (oldrootleft->father == oldrootright) oldrootleft->set_root();
244    else oldrootright->set_root();
245    GLOBAL_NT->tree->tree_root->costs();
246    aw_closestatus();
247}
248
249AWT_graphic_parsimony::AWT_graphic_parsimony(AW_root *root, GBDATA *gb_maini):AWT_graphic_tree(root,gb_maini)
250{;}
251
252AWT_graphic_tree *PARS_generate_tree(AW_root *root) {
253    AWT_graphic_parsimony *apdt  = new AWT_graphic_parsimony(root,GLOBAL_gb_main);
254    AP_tree_nlen          *aptnl = new AP_tree_nlen(0);
255
256    apdt->init((AP_tree *)aptnl);
257    ap_main->tree_root = &apdt->tree_root;
258   
259    delete aptnl;
260    return apdt;
261}
262
263AW_gc_manager
264AWT_graphic_parsimony::init_devices(AW_window *aww, AW_device *device, AWT_canvas* ntw, AW_CL cd2)
265{
266    AW_init_color_group_defaults("arb_pars");
267
268    AW_gc_manager preset_window =
269        AW_manage_GC(aww,device,AWT_GC_CURSOR, AWT_GC_MAX, /*AWT_GC_CURSOR+7,*/ AW_GCM_DATA_AREA,
270                     (AW_CB)AWT_resize_cb, (AW_CL)ntw, cd2,
271                     true,      // uses color groups
272                     "#AAAA55",
273
274                     // Important note :
275                     // Many gc indices are shared between ABR_NTREE and ARB_PARSIMONY
276                     // e.g. the tree drawing routines use same gc's for drawing both trees
277                     // (check AWT_dtree.cxx AWT_graphic_tree::init_devices)
278
279                     "Cursor$#FFFFFF",
280                     "Branch remarks$#DBE994",
281                     "+-Bootstrap$#DBE994",    "-B.(limited)$white",
282                     "--unused$#ff0000",
283                     "Marked$#FFFF00",
284                     "Some marked$#eeee88",
285                     "Not marked$black",
286                     "Zombies etc.$#cc5924",
287
288                     "--unused", "--unused", // these reserve the numbers which are used for probe colors in ARB_NTREE
289                     "--unused", "--unused", // (this is necessary because ARB_PARS and ARB_NTREE use the same tree painting routines)
290                     "--unused", "--unused",
291                     "--unused", "--unused",
292
293                     NULL);
294    return preset_window;
295}
296
297void AWT_graphic_parsimony::show(AW_device *device)
298{
299    long parsval = 0;
300    if (GLOBAL_NT->tree->tree_root) parsval = (long)GLOBAL_NT->tree->tree_root->costs();
301    GLOBAL_NT->awr->awar(AWAR_PARSIMONY)->write_int( parsval);
302    long best = GLOBAL_NT->awr->awar(AWAR_BEST_PARSIMONY)->read_int();
303    if (parsval < best || 0==best) {
304        GLOBAL_NT->awr->awar(AWAR_BEST_PARSIMONY)->write_int( parsval);
305    }
306    this->AWT_graphic_tree::show(device);
307}
308
309
310void AWT_graphic_parsimony::command(AW_device *device, AWT_COMMAND_MODE cmd, int button, AW_key_mod key_modifier, AW_key_code key_code, char key_char,
311                                    AW_event_type type, AW_pos x, AW_pos y,
312                                    AW_clicked_line *cl, AW_clicked_text *ct)
313{
314    static int bl_drag_flag;
315
316    AWUSE(ct);
317    AP_tree *at;
318
319    bool compute_tree = false;
320    bool recalc_branch_lengths = false;
321    bool beautify_tree = false;
322
323    //GBDATA *gb_main = this->tree_static->gb_main;
324    switch(cmd){
325        case AWT_MODE_MOVE:                             // two point commands !!!!!
326            if(button==AWT_M_MIDDLE){
327                break;
328            }
329            switch(type){
330                case AW_Mouse_Press:
331                    if( !(cl && cl->exists) ){
332                        break;
333                    }
334
335                    /*** check security level @@@ ***/
336                    at = (AP_tree *)cl->client_data1;
337                    if(at && at->father){
338                        bl_drag_flag = 1;
339                        this->rot_at = at;
340                        this->rot_cl = *cl;
341                        this->old_rot_cl = *cl;
342                    }
343                    break;
344
345                case AW_Mouse_Drag:
346                    if( bl_drag_flag && this->rot_at && this->rot_at->father){
347                        this->rot_show_line(device);
348                        if (cl->exists) {
349                            this->rot_cl = *cl;
350                        }else{
351                            rot_cl = old_rot_cl;
352                        }
353                        this->rot_show_line(device);
354                    }
355                    break;
356                case AW_Mouse_Release:
357                    if( bl_drag_flag && this->rot_at && this->rot_at->father){
358                        this->rot_show_line(device);
359                        AP_tree *dest= 0;
360                        if (cl->exists) dest = (AP_tree *)cl->client_data1;
361                        AP_tree *source = rot_at;
362                        if (!(source && dest)) {
363                            aw_message("Please Drag Line to a valid branch");
364                            break;
365                        }
366                        if (source == dest) {
367                            aw_message("Please drag mouse from source to destination");
368                            break;
369                        }
370                        //                         if ( dest->is_son(source)) {
371                        //                             aw_message("This operation is only allowed with two independent subtrees");
372                        //                             break;
373                        //                         }
374                        const char *error = 0;
375
376                        //                         switch(cmd){
377                        //                             case AWT_MODE_MOVE:
378
379                        switch(button){
380                            case AWT_M_LEFT:
381                                error = source->cantMoveTo(dest);
382                                if (!error) {
383                                    source->moveTo(dest,cl->length);
384                                    recalc_branch_lengths = true;
385                                }
386                                break;
387                            case AWT_M_RIGHT:
388                                error = source->move_group_info(dest);
389                                break;
390                            default:
391                                error = "????? 45338";
392                        }
393
394                        //                             default:
395                        //                                 error = "????? 45338";
396                        //                         }
397
398                        if (error) aw_message(error);
399                        this->exports.refresh = 1;
400                        this->exports.save = 1;
401                        this->exports.resize = 1;
402                        this->tree_root->test_tree();
403                        //this->tree_root->compute_tree(gb_main);
404                        compute_tree = true;
405                    }
406                    break;
407                default:
408                    break;
409            }
410            break;
411
412#ifdef NNI_MODES
413        case AWT_MODE_NNI:
414            if(type==AW_Mouse_Press){
415                GB_pop_transaction(gb_main);
416                switch(button){
417                    case AWT_M_LEFT:
418                        if (!cl->exists) break;
419                        at = (AP_tree *)cl->client_data1;
420                        ap_global_abort_flag = AP_FALSE;
421                        ((AP_tree_nlen *)at)->nn_interchange_rek(AP_TRUE,ap_global_abort_flag,-1);
422                        this->exports.refresh = 1;
423                        this->exports.save = 1;
424                        this->tree_root->test_tree();
425                        recalc_branch_lengths = true;
426                        break;
427                    case AWT_M_RIGHT:
428                        AP_sequence::global_combineCount = 0;
429                        ap_global_abort_flag = AP_FALSE;
430                        ((AP_tree_nlen *)this->tree_root)->nn_interchange_rek(AP_TRUE,ap_global_abort_flag,-1);
431                        printf("Combines: %li\n", AP_sequence::global_combineCount);
432                        this->exports.refresh = 1;
433                        this->exports.save = 1;
434                        this->tree_root->test_tree();
435                        recalc_branch_lengths = true;
436                        break;
437                }
438                GB_begin_transaction(gb_main);
439            } /* if type */
440            break;
441        case AWT_MODE_KERNINGHAN:
442            if(type==AW_Mouse_Press){
443                GB_pop_transaction(gb_main);
444                switch(button){
445                    case AWT_M_LEFT:
446                        if (!cl->exists) break;
447                        at = (AP_tree *)cl->client_data1;
448                        PARS_kernighan_cb(at);
449                        this->exports.refresh = 1;
450                        this->exports.save = 1;
451                        this->tree_root->test_tree();
452                        recalc_branch_lengths = true;
453                        break;
454                    case AWT_M_RIGHT:
455                        PARS_kernighan_cb(this->tree_root);
456                        this->exports.refresh = 1;
457                        this->exports.save = 1;
458                        this->tree_root->test_tree();
459                        recalc_branch_lengths = true;
460                        break;
461                }
462                GB_begin_transaction(gb_main);
463            } /* if type */
464            break;
465        case AWT_MODE_OPTIMIZE:
466            if(type==AW_Mouse_Press){
467                GB_pop_transaction(gb_main);
468                switch(button){
469                    case AWT_M_LEFT:
470                        if (!cl->exists) break;
471                        at = (AP_tree *)cl->client_data1;
472                        if (at) PARS_optimizer_cb(at);
473                        this->exports.refresh = 1;
474                        this->exports.save = 1;
475                        this->tree_root->test_tree();
476                        recalc_branch_lengths = true;
477                        break;
478                    case AWT_M_RIGHT:
479                        PARS_optimizer_cb(this->tree_root);
480                        this->exports.refresh = 1;
481                        this->exports.save = 1;
482                        this->tree_root->test_tree();
483                        recalc_branch_lengths = true;
484                        break;
485                }
486                GB_begin_transaction(gb_main);
487            } /* if type */
488            break;
489#endif // NNI_MODES
490
491        default:
492            AWT_graphic_tree::command(device,cmd,button, key_modifier, key_code, key_char, type, x, y, cl, ct);
493            break;
494    }
495
496    if (recalc_branch_lengths) {
497        int abort_flag = AP_FALSE;
498        rootEdge()->nni_rek(AP_FALSE,abort_flag,-1, GB_FALSE,AP_BL_BL_ONLY);
499
500        beautify_tree = true; // beautify after recalc_branch_lengths
501    }
502
503    if (beautify_tree) {
504        this->resort_tree(0);
505        this->exports.save = 1;
506
507        compute_tree = true; // compute_tree after beautify_tree
508    }
509
510    if (compute_tree) {
511        this->tree_root->compute_tree(gb_main);
512        this->exports.refresh = 1;
513    }
514}
Note: See TracBrowser for help on using the repository browser.