~ubuntu-branches/ubuntu/raring/njplot/raring-proposed

« back to all changes in this revision

Viewing changes to njplot-vib.c

  • Committer: Bazaar Package Importer
  • Author(s): Charles Plessy
  • Date: 2009-02-25 22:35:05 UTC
  • mfrom: (1.2.6 upstream) (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090225223505-hot2lplnzrw7knh7
Tags: 2.3-2
* debian/control:
  - Mention that the trees are phylogenetic and in Newick format.
    Closes: #517010
  - Added missing comma in the Depends field.
* debian/get-orig-source: obsolete, removed. (Also in debian/rules).

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
/usr/X11R6/lib/X11/app-defaults/Vibrant    (Linux)
25
25
/usr/openwin/lib/X11/app-defaults/Vibrant   (Solaris)
26
26
*/
27
 
#define NJPLOTVERSION "2.2"
 
27
#define NJPLOTVERSION "2.3"
28
28
 
29
29
#include <math.h>
30
30
#include <time.h>
61
61
 
62
62
#else
63
63
 
 
64
#ifdef WIN_MAC
 
65
#include <Carbon.h> /* must be before <vib*.h> or it does not compile */
 
66
#endif
64
67
#include <vibtypes.h>
65
68
#include <vibprocs.h>
66
69
 
69
72
#endif
70
73
 
71
74
#ifdef WIN_MAC
72
 
 
73
 
#ifdef verify
74
 
#undef verify
75
 
#endif
76
 
#include <Carbon.h>
77
75
#define myWaitAndProcessNextEvent Nlm_ProcessAnEvent
78
76
extern int Nlm_textScrapFull;
79
77
 
336
334
void mydrawstring(double x, double y, char *nom, char option);
337
335
void moveto(double x,double y);
338
336
void lineto(double x,double y);
339
 
double tree_bal(struct noeud *centre, struct noeud *p1, struct noeud *p2);
340
 
void get_next_br(struct noeud *pere, struct noeud *fils, 
341
 
        double **abdown, double **abup, struct noeud **f1, struct noeud **f2);
 
337
int calc_brl_for_lengthless(struct noeud *centre, struct noeud *pere);
 
338
void add_value_downstream(struct noeud *centre, int value);
342
339
void place_midpoint_root(void);
343
340
void parcourir_branches(struct noeud *centre, struct noeud *origine);
344
341
void process_branche(struct noeud *cote1, struct noeud *cote2, double length);
1212
1209
 
1213
1210
void new_callback(IteM ob)
1214
1211
{
1215
 
char fname[200];
1216
 
 
1217
1212
fd_nj_plot = create_win_nj_plot();
1218
1213
fd_nj_plot->notu = 0;
1219
1214
Nlm_Show(fd_nj_plot->nj_plot);
2970
2965
        fd_nj_plot->racine = *(fd_nj_plot->tabtax+num_noeud);
2971
2966
        fd_nj_plot->root_br_l= fd_nj_plot->racine->l1 + fd_nj_plot->racine->l2;
2972
2967
        fd_nj_plot->root_num = num_noeud;
2973
 
        if(!fd_nj_plot->has_br_length) tree_bal(fd_nj_plot->racine,fd_nj_plot->racine->v1,fd_nj_plot->racine->v2);
 
2968
        if(!fd_nj_plot->has_br_length) calc_brl_for_lengthless(fd_nj_plot->racine, NULL);
2974
2969
/* y a-t-il un bootstrap sur l'une des branches racine ? */
2975
2970
        i = get_br_from_bouts(fd_nj_plot->racine, fd_nj_plot->racine->v1); 
2976
2971
        if(i == -1) i = get_br_from_bouts(fd_nj_plot->racine, fd_nj_plot->racine->v2);
3049
3044
p2=unrootedset(debb,debc-2,&int_br_d);
3050
3045
p = *(fd_nj_plot->tabtax+(++num_noeud));
3051
3046
if(num_noeud >= 2*fd_nj_plot->notu + 1) bad_format("Error: incorrect tree file");
3052
 
if(!fd_nj_plot->has_br_length) {
3053
 
        p1->l3 = 0.5*p1->l3;
3054
 
        p2->l3 = 0.5*p2->l3;
3055
 
        }
3056
3047
p->v1=p1; p1->v3=p; p->l1=p1->l3;
3057
3048
if(int_br_g!=NULL) { int_br_g->bouta=p; int_br_g->boutb=p1; }
3058
3049
p->v2=p2; p2->v3=p; p->l2=p2->l3;
3103
3094
if(*deb != '(') { /* une feuille */
3104
3095
        virg = strchr(deb, ':');
3105
3096
        if(virg != NULL && virg < fin) {
3106
 
                if(fd_nj_plot->has_br_length == 0) goto problem;
 
3097
//              if(fd_nj_plot->has_br_length == 0) goto problem;
3107
3098
                sscanf(virg+1, "%le", &brlength);
3108
3099
                fd_nj_plot->has_br_length=1;
3109
3100
                }
3110
3101
        else    {
3111
 
                if(fd_nj_plot->has_br_length == 1) goto problem;
 
3102
//              if(fd_nj_plot->has_br_length == 1) goto problem;
3112
3103
                brlength = 1;
3113
3104
                fd_nj_plot->has_br_length=0;
3114
3105
                virg = fin + 1;
3151
3142
if(int_br != NULL) { int_br->bouta = p; int_br->boutb = pp; }
3152
3143
virg = strchr(ferme, ':');
3153
3144
if(virg != NULL && virg < fin) { /* traitement longueur */
3154
 
        if(fd_nj_plot->has_br_length == 0) goto problem;
 
3145
//      if(fd_nj_plot->has_br_length == 0) goto problem;
3155
3146
        sscanf(virg+1, "%le", &brlength);
3156
3147
        fd_nj_plot->has_br_length=1;
3157
3148
        if(*fin == ']') { /* bootstrap entre [] apres longueurs */
3171
3162
                }
3172
3163
        }
3173
3164
else    {
3174
 
        if(fd_nj_plot->has_br_length == 1) goto problem;
 
3165
//      if(fd_nj_plot->has_br_length == 1) goto problem;
3175
3166
        brlength = 1;
3176
3167
        fd_nj_plot->has_br_length=0;
3177
3168
        virg = fin + 1;
3267
3258
        p++;
3268
3259
        }
3269
3260
if(virg > 1) { /* multifurcation */
3270
 
        /* make sure tree has branch lengths */
3271
 
        if( memchr(debut, ':', fin - debut + 1) == NULL) 
3272
 
                bad_format("Cannot process multibranched tree without branch lengths");
3273
3261
        /* recherche de la 2eme virgule */
3274
3262
        p = debut; l = 0;
3275
3263
        while(TRUE) {
3347
3335
dir_lineto(px,py);
3348
3336
}
3349
3337
 
3350
 
/* pour un arbre sans longueur de branche, les calculer de facon a ce
3351
 
que toutes les feuilles arrivent a la meme profondeur */
3352
 
double tree_bal(struct noeud *centre, struct noeud *p1, struct noeud *p2)
3353
 
{
3354
 
double ld, lg, pg, pd, *abup1, *abup2, *abdown1, *abdown2;
3355
 
struct noeud *f1, *f2;
3356
 
get_next_br(centre,p1,&abup1,&abdown1,&f1,&f2);
3357
 
if(f1!=NULL) lg=tree_bal(p1,f1,f2);
3358
 
else lg=0.0;
3359
 
get_next_br(centre,p2,&abup2,&abdown2,&f1,&f2);
3360
 
if(f1!=NULL) ld=tree_bal(p2,f1,f2);
3361
 
else ld=0.0;
3362
 
pg=lg+1; pd=ld+1;
3363
 
if(pg>pd) pd=pg;
3364
 
else pg=pd;
3365
 
*abup1 = *abdown1 = pg-lg;
3366
 
*abup2 = *abdown2 = pd-ld;
3367
 
return (pg);
3368
 
}
3369
 
 
3370
 
 
3371
 
void get_next_br(struct noeud *pere, struct noeud *fils, 
3372
 
double **abdown, double **abup, struct noeud **f1, struct noeud **f2)
3373
 
/* pour une branche pere->fils donnee, calculer dans *f1, *f2 les deux autres
3374
 
voisins de fils et dans *abdown et *abup les adresses des longeurs de la
3375
 
branche pere->fils dans les deux sens */
3376
 
{
3377
 
if(pere->v1==fils) *abdown= &(pere->l1);
3378
 
else if(pere->v2==fils) *abdown=&(pere->l2);
3379
 
else *abdown=&(pere->l3);
3380
 
if(fils->v1==pere) {
3381
 
        *abup=&(fils->l1);
3382
 
        *f1=fils->v2;
3383
 
        *f2=fils->v3;
3384
 
        }
3385
 
else if(fils->v2==pere) {
3386
 
        *abup=&(fils->l2);
3387
 
        *f1=fils->v1;
3388
 
        *f2=fils->v3;
3389
 
        }
3390
 
else    {
3391
 
        *abup=&(fils->l3);
3392
 
        *f1=fils->v1;
3393
 
        *f2=fils->v2;
3394
 
        }
3395
 
}
3396
 
 
 
3338
                                        
 
3339
int calc_brl_for_lengthless(struct noeud *centre, struct noeud *pere)
 
3340
/* Recursively computes branch lengths of a lengthless tree having some branches fixed to 0 to allow
 
3341
multifurcations so that all tips align to the right of the plot.
 
3342
*/
 
3343
{
 
3344
int n1 = 0, n2, depth;
 
3345
volatile double l;
 
3346
if(centre->v1 == NULL && centre->v2 == NULL) return 0;//a leaf
 
3347
//rearrange with centre->v3 towards root
 
3348
if(centre->v1 == pere) {
 
3349
centre->v1 = centre->v3;
 
3350
centre->v3 = pere;
 
3351
l = centre->l3;
 
3352
centre->l3 = centre->l1;
 
3353
centre->l1 = l;
 
3354
}
 
3355
else if(centre->v2 == pere) {
 
3356
centre->v2 = centre->v3;
 
3357
centre->v3 = pere;
 
3358
l = centre->l3;
 
3359
centre->l3 = centre->l2;
 
3360
centre->l2 = l;
 
3361
}
 
3362
n1 = calc_brl_for_lengthless(centre->v1, centre);
 
3363
n2 = calc_brl_for_lengthless(centre->v2, centre);
 
3364
depth = n1;
 
3365
if(centre->l1 != 0) depth++;
 
3366
if(depth < n2) depth = n2;
 
3367
if(centre->l2 != 0 && n2 + 1 > depth) depth++;
 
3368
if(centre->l1 != 0) {
 
3369
centre->l1 = depth - n1; 
 
3370
centre->v1->l3 = depth - n1;
 
3371
}
 
3372
else if(depth - n1 > 0) add_value_downstream(centre->v1, depth - n1);
 
3373
if(centre->l2 != 0) {
 
3374
centre->l2 = depth - n2; 
 
3375
centre->v2->l3 = depth - n2;
 
3376
}
 
3377
else if(depth - n2 > 0) add_value_downstream(centre->v2, depth - n2);
 
3378
return depth;
 
3379
}
 
3380
 
 
3381
void add_value_downstream(struct noeud *centre, int value)
 
3382
{
 
3383
if(centre->l1 != 0) {
 
3384
        centre->l1 += value;
 
3385
        centre->v1->l3 = centre->l1;
 
3386
        }
 
3387
else add_value_downstream(centre->v1, value);
 
3388
if(centre->l2 != 0) {
 
3389
        centre->l2 += value;
 
3390
        centre->v2->l3 = centre->l1;
 
3391
        }
 
3392
else add_value_downstream(centre->v2, value);
 
3393
}
 
3394
                                        
3397
3395
 
3398
3396
void place_midpoint_root(void)
3399
3397
/* enraciner l'arbre sans racine en cherchant son centre 
3631
3629
                fd_nj_plot->racine->l1=b1; fd_nj_plot->racine->l2=b2;
3632
3630
                }
3633
3631
        else    {
3634
 
                tree_bal(fd_nj_plot->racine,p1,p2);
 
3632
                fd_nj_plot->racine->l1 = p1->l3;
 
3633
                if (p2->v1 == fd_nj_plot->racine )
 
3634
                                        fd_nj_plot->racine->l2 = p2->l1;
 
3635
                else if (p2->v2 == fd_nj_plot->racine)
 
3636
                                        fd_nj_plot->racine->l2 = p2->l2;
 
3637
                else
 
3638
                                        fd_nj_plot->racine->l2 = p2->l3;
 
3639
                calc_brl_for_lengthless(fd_nj_plot->racine, NULL);
3635
3640
                }
3636
3641
        }
3637
3642
/* initialize leave and node names */
3638
3643
for(i = 0; i <= 2*fd_nj_plot->notu; i++) fd_nj_plot->tabnames[i][0] = 0;
3639
 
if (fd_nj_plot->choix == depl_racine)
3640
 
        for(i=0; i<=2*fd_nj_plot->notu-1; i++) sprintf(fd_nj_plot->tabnames[i],"# ");
 
3644
if (fd_nj_plot->choix == depl_racine) {
 
3645
        for(i=0; i <= 2*fd_nj_plot->notu - 1; i++) {
 
3646
//              if(i == fd_nj_plot->root_num) continue;//skip current root
 
3647
                if( !fd_nj_plot->has_br_length) {
 
3648
                        if(fd_nj_plot->tabtax[i]->l3 == 0) continue;//skip internal multifurcation nodes that can't be broken by root
 
3649
                        }
 
3650
                sprintf(fd_nj_plot->tabnames[i], "# ");
 
3651
                }
 
3652
        }
3641
3653
else if(fd_nj_plot->choix == permutation)
3642
3654
        for(i=fd_nj_plot->notu+1; i<=2*fd_nj_plot->notu; i++) sprintf(fd_nj_plot->tabnames[i],"#");
3643
3655
else if(fd_nj_plot->choix == subtree)
3881
3893
}
3882
3894
 
3883
3895
 
 
3896
/* ecriture d'un arbre non racine au format phylip, multifurcations allowed */
3884
3897
char *ecrit_arbre_parenth_unrooted(struct noeud *root)
3885
3898
{
3886
3899
struct noeud *t1, *t2, *t3;
3910
3923
}
3911
3924
 
3912
3925
 
3913
 
/* ecriture d'un arbre racine au format phylip */
 
3926
/* ecriture d'un arbre racine au format phylip, multifurcations allowed */
3914
3927
char *ecrit_arbre_parenth(struct noeud *root)
3915
3928
{
3916
3929
char *arbre, *fin, *p;
3939
3952
char *recur_ecrit_arbre(struct noeud *centre, char *arbre, char *finarbre)
3940
3953
{
3941
3954
int num, l;
3942
 
char *p;
 
3955
char *p, *q;
3943
3956
 
3944
3957
if(centre->v1==NULL && centre->v2==NULL) {
3945
3958
        num=0;
3951
3964
        }
3952
3965
else    {
3953
3966
        *arbre='(';
 
3967
        p = arbre;
3954
3968
        arbre=recur_ecrit_arbre(centre->v1,arbre+1,finarbre);
3955
3969
        if(arbre==NULL) return NULL;
3956
3970
        if(fd_nj_plot->has_br_length) {
3970
3984
        else arbre++;
3971
3985
        *arbre=')';
3972
3986
        /* ecriture des fd_nj_plot->labels internes */
3973
 
        if( (p=get_br_label(centre,centre->v3))!=NULL ) {
3974
 
                l=strlen(p);
 
3987
        if( (q=get_br_label(centre,centre->v3)) != NULL  && (fd_nj_plot->has_br_length || (centre->l3 != 0) ) ) {
 
3988
                l=strlen(q);
3975
3989
                if(arbre+l>=finarbre) return NULL;
3976
 
                memcpy(arbre+1,p,l);
 
3990
                memcpy(arbre+1,q,l);
3977
3991
                arbre+=l;
3978
3992
                }
 
3993
        else if(centre->v3 != NULL && (!fd_nj_plot->has_br_length) && (centre->l3 == 0) ) {//multibranches processed here
 
3994
                memmove(p, p + 1, arbre - p);
 
3995
                arbre -= 2;
 
3996
                }
3979
3997
        }
3980
3998
return arbre;
3981
3999
}