3
one of WIN_MOTIF WIN_MAC WIN_MSWIN must be defined for normal compilation
5
under WIN_MOTIF, one can also define NO_PDF so the PDFLibLite library is not used,
6
and one can also define HELPFILENAME to the full pathname (with enclosing "") of the help file
10
compile with -DTTY to have it output text-only tree without GUI
12
compile with -DADDROOT to have it root the unrooted input tree and write tree on stdout (no GUI)
14
compile with -DNO_GUI to have it work without GUI at all and convert tree to PDF/PostScript file
18
Vibrant.systemfont : helvetica,14,b
19
Njplot.systemfont : times,14,b
20
Vibrant.programfont : fixed,14
24
/usr/X11R6/lib/X11/app-defaults/Vibrant (Linux)
25
/usr/openwin/lib/X11/app-defaults/Vibrant (Solaris)
27
#define NJPLOTVERSION "2.3"
34
#if defined(WIN_MSWIN)
36
#elif defined(WIN_MOTIF) && ! defined(NO_PDF)
38
#elif defined(NO_GUI) && ! defined(NO_PDF)
50
#if defined(TTY) || defined (ADDROOT)
65
#include <Carbon.h> /* must be before <vib*.h> or it does not compile */
70
#if defined(WIN_MSWIN) || defined (WIN_MAC)
75
#define myWaitAndProcessNextEvent Nlm_ProcessAnEvent
76
extern int Nlm_textScrapFull;
78
#elif defined(WIN_MSWIN)
80
extern HDC Nlm_currentHDC;
81
extern HDC Nlm_GetPicWinHDC ( void );
82
char *get_prog_dir(void);
83
#define myWaitAndProcessNextEvent Nlm_ProcessAnEvent
84
#define tempnam _tempnam
89
#include <X11/Intrinsic.h>
91
extern XtAppContext Nlm_appContext;
92
extern Nlm_CharPtr Nlm_XrmGetResource(const Nlm_Char PNTR _resource);
93
void set_systemfont(char *systemfont);
95
void myWaitAndProcessNextEvent (void)
98
if( XtAppPending(Nlm_appContext) & XtIMXEvent ) {
102
/* wait until next event and catch it */
103
XtAppNextEvent (Nlm_appContext, &event);
104
XtDispatchEvent (&event);
111
#include <document.h> /* need this include after the other mac includes */
113
#ifdef WIN_MAC /* need the mac version of each of these functions */
121
struct win_help_extra {
128
Nlm_Int4 left, top, right, bottom;
134
typedef enum { times = 1, helvetica, courier} font_name;
135
enum { font_tiny = 1, font_small,
136
font_normal, font_medium, font_large, font_bold, font_italic };
137
typedef enum { A4 = 1, LETTER }
142
struct noeud *v1,*v2,*v3;
145
typedef struct branche { /* une branche definie par ses deux extremites */
151
#define s_noeud sizeof(struct noeud)
152
#define myrint(d) ((int)(d + 0.5)) /* not correct if d < 0 but irrelevant for plotting */
166
typedef struct _moments {
167
int N; /* nbre de fils */
168
double somme, carres; /* somme des longueurs jusqu'aux feuilles, et somme des carres */
170
enum operations {show_tree = 1, depl_racine, permutation, subtree};
176
Nlm_IteM open_button;
177
Nlm_PrompT click_message;
178
Nlm_MenU tree_font_menu;
180
Nlm_IteM win_menu_item;
181
Nlm_IteM save_plot_button;
182
Nlm_IteM save_tree_button;
183
Nlm_IteM save_unrooted_button;
186
Nlm_ChoicE choix_font, choix_taille;
187
Nlm_IteM bold_item, italic_item;
188
Nlm_ButtoN branch_length_button;
189
Nlm_ButtoN bootstrap_button;
190
Nlm_GrouP choix_group;
191
Nlm_ButtoN reroot_button;
192
Nlm_ButtoN subtree_up_button;
193
Nlm_IteM exit_button;
196
Nlm_PrompT zoomprompt;
198
Nlm_FonT current_font;
207
struct noeud **tabtax;
208
struct noeud *racine;
211
struct branche *branches;
213
struct trait *traits;
214
struct mon_point *points;
222
enum operations choix;
225
int long_arbre_parenth; /* long de la chaine decrivant l'arbre lu */
226
struct noeud *subtree_center, *subtree_ascend;
233
int font_family_rank;
234
char font_bold_italic[3];
238
/* prototypes of included functions */
240
FD_nj_plot *create_win_nj_plot(void);
241
void cre_help_win(IteM item);
242
FILE *open_path(char *fname);
243
void topic_callback(LisT list);
244
void help_ok_callback(ButtoN bouton);
246
void show_apropos_njplot(Nlm_IteM item);
247
void mac_timer(void);
248
void window_callback(IteM item);
250
void load_help_topics(FILE *fich, LisT topic_list);
251
void subtree_up_callback(ButtoN bouton);
252
void open_callback(Nlm_IteM );
253
void new_callback(IteM ob);
254
void font_callback(Nlm_ChoicE);
255
void paper_callback(Nlm_ChoicE);
256
void save_plot_callback(Nlm_IteM);
257
void save_tree_callback(Nlm_IteM);
258
void toggle_branch_callback(Nlm_ButtoN);
259
void toggle_bootstrap_callback(Nlm_ButtoN);
260
void operation_callback(Nlm_GrouP);
261
void subtree_callback(void);
262
void swap_callback(void);
263
void new_outgroup_callback(void);
264
void show_tree_callback(void);
265
void exit_callback(Nlm_IteM);
266
void tree_draw_proc(Nlm_PaneL);
267
void tree_click_proc(Nlm_PaneL, Nlm_PoinT);
268
static void closeproc(WindoW);
269
void closefrommenu(Nlm_IteM item);
270
void win_resize_proc(WindoW);
271
void change_panel_size(PaneL panel, int change_x, int change_y);
272
void string_callback(ButtoN item);
273
void search_callback(IteM item);
274
void process_keys(Nlm_Char key);
275
void change_page_count(ButtoN item);
276
void page_count_callback(IteM item);
277
void clear_tree(IteM);
278
void scrollnotu(int count);
279
void paste_tree(IteM);
280
void scrollcallback(Nlm_BaR b, Nlm_SlatE g, Nlm_Int2 before, Nlm_Int2 after);
281
void zoomcallback(Nlm_SwitcH s, Nlm_Int2 before, Nlm_Int2 after);
283
void copy_plot(IteM);
284
void print_title(int x, int y, char *text, Nlm_FonT title_font, int p,int totp);
285
void print_plot(IteM);
288
extern void add_apropos(char *progname, Nlm_ActnProc my_show_apropos);
289
void create_win_if_needed(char *fname);
291
int crefpict(char *, PicHandle );
292
void example_tree(IteM unused);
293
void pict_plot(void);
294
extern int MG_GetInputFName(char *fname, int maxl);
295
extern int MG_GetOutputFName(char *fname, int maxl, char *dfault);
296
extern char *mac_fname_to_roman(char *);
297
extern QDPictRef MyPictToQDPict(PicHandle mypicture);
298
extern int MyQDPictToPDFfile (QDPictRef picture, char *fname);
299
extern char *MG_GetBundleResourcesDir(void);
300
#elif defined(WIN_MSWIN)
301
extern int MG_GetInputFName(char *fname, int maxl);
302
extern int MG_GetOutputFName(char *fname, int maxl, char *dfault);
304
#define MG_GetOutputFName Nlm_GetOutputFileName
305
#define MG_GetInputFName(a,b) Nlm_GetInputFileName(a, b, NULL, NULL)
307
extern Nlm_WindoW Nlm_GetNext(Nlm_WindoW);
310
void process_args(int *argc, char *argv[], char **pred, int *pboot_arg, int *p_plot_br_l, int *p_font_size_rank);
311
void prepare_fonts(void);
312
void prepare_pdf_font(int fontnum, int use_bold, int use_italic);
313
int direct_pdf_plot(char *fname);
314
int calc_otu(struct noeud *pere, struct noeud *centre);
316
int calc_text_size(char *text, int *pheight, int *pascent);
317
void plotstring(char *nom);
318
void dir_moveto(double x,double y);
319
void dir_lineto(double x,double y);
320
void scale_window(double lxmin, double lxmax, double lymin, double lymax,
321
double pxmin, double pxmax, double pymin, double pymax);
322
void ch_echelle(double lx, double ly, double *px, double *py);
323
void convert_mem_point(void);
324
void init_tree(char *fname, char *displayname);
325
char *preptree(char *fname);
326
char *check_alloc(int nbrelt, int sizelt);
327
void err_message(const char *text);
328
void loadphylip(char *arbre, char *last_bootstrap);
329
struct noeud *unrootedset(char *deb, char *fin, branche **p_int_br);
330
char *extract_filename(char *name);
331
char *nextpar(char *pospar);
332
void make_binary_or_unrooted(char *arbre);
333
int make_binary(char *arbre, char *debut, char *fin, int go_down);
334
void mydrawstring(double x, double y, char *nom, char option);
335
void moveto(double x,double y);
336
void lineto(double x,double y);
337
int calc_brl_for_lengthless(struct noeud *centre, struct noeud *pere);
338
void add_value_downstream(struct noeud *centre, int value);
339
void place_midpoint_root(void);
340
void parcourir_branches(struct noeud *centre, struct noeud *origine);
341
void process_branche(struct noeud *cote1, struct noeud *cote2, double length);
342
double get_length_down(struct noeud *, struct noeud *);
343
moments stat_from_node(struct noeud *pere, struct noeud *racine);
345
void mem_plot(struct noeud *pere, struct noeud *centre, double currx,
347
void mem_point(double x, double y, int number);
348
void mem_nom(double x, double y, char *nom, char option);
349
void mem_trait(double xd, double yd, double xf, double yf);
350
char *get_br_label(struct noeud *a, struct noeud *b);
351
int get_br_from_bouts(struct noeud *a, struct noeud *b);
352
void free_tree(void);
353
char *ecrit_arbre_parenth_unrooted(struct noeud *root);
354
char *ecrit_arbre_parenth(struct noeud *root);
355
char *recur_ecrit_arbre(struct noeud *centre, char *arbre, char *finarbre);
356
void removeroot(void);
357
void remove_arg(int target, int *argc, char *argv[]);
358
double length_log_phys(double p);
359
double length_phys_log(double p);
360
double arrondi_echelle(double x);
361
double calc_echelle(double larg);
362
void draw_scale(void);
363
int calc_n_desc(struct noeud *pere);
364
void bad_format(char *);
365
void majuscules(char *p);
366
void postscript_plot(void);
368
void plot_to_pdf(void);
377
extern Nlm_WindoW Nlm_desktopWindow;
378
int tag_njplot, tag_help;
380
FD_nj_plot *fd_nj_plot;
383
double physx,physy,physx_min,physy_min,physx_corr,physy_corr;
384
/* window scaling variables */
385
double tek_xmin,tek_xmax,tek_ymin,tek_ymax,tek_dx,tek_dy;
386
double tek_minx,tek_maxx,tek_miny,tek_maxy;
387
double maxx, maxy, nexty;
388
/* max length of taxa names */
389
int pdf_plot = 0, file_plot,
390
num_noeud, nextotu, no_title = FALSE,
392
char current_ps_font[40];
393
int list_font_size[] = { 0, 6, 8, 10, 12, 14, 18 };
395
char list_font_name[4][40] = {"", "Times New Roman", "Lucida Sans", "Courier New"};
396
int default_font_size_rank = font_normal;
398
char list_font_name[4][15] = {"", "Times", "Helvetica", "Courier"};
399
int default_font_size_rank = font_medium;
401
char list_ps_font_name[4][15] = {"", "Times", "Helvetica", "Courier"};
402
paper_item paper_choice = A4;
403
char plotfilename[200], rooted_fname[200];
405
FILE *help_file = NULL;
407
int ps_width = 500, ps_height = 0 /* 0 means not defined by this variable */;
408
/* variables globales pour memoriser la meilleure branche:
409
celle qui partage l'arbre en 2 parties les plus egales possibles en prof moyenne
411
double current_best_diff, current_br_length, current_balance;
412
struct noeud *current_cote1=NULL, *current_cote2=NULL;
413
#define VERY_BIG 9.e99
415
int doing_copy = FALSE;
416
int doing_print = FALSE;
417
float postscript_ratio = 0.60;
418
char *tty_prefix = NULL;
422
char *outotu = NULL; /* value of optional argument -outotu name */
432
int pdf_plot_only = TRUE;
433
int main(int argc, char **argv)
436
int boot_arg, plot_br_l;
437
fd_nj_plot = (FD_nj_plot *)calloc(1, sizeof(FD_nj_plot));
440
int pdf_plot_only = FALSE;
450
Nlm_Int2 Nlm_Main(void)
453
int boot_arg, plot_br_l;
455
argc = Nlm_GetArgc();
456
argv = Nlm_GetArgv();
462
if( ! is_macosx() ) argc = 1;
463
else if(argc > 1 && strncmp(argv[1], "-psn_", 5) == 0) remove_arg(1, &argc, argv);
465
process_args(&argc, argv, &red, &boot_arg, &plot_br_l, &default_font_size_rank);
473
putenv("LC_NUMERIC=C");
477
fd_nj_plot->tree_name = fname;
478
fd_nj_plot->show_bootstrap = boot_arg;
479
fd_nj_plot->plot_br_l = plot_br_l;
480
fd_nj_plot->font_size_rank = default_font_size_rank;
481
fd_nj_plot->font_family_rank = times;
482
if( fname != NULL) status = direct_pdf_plot(fname);
489
font = Nlm_XrmGetResource("systemfont");
490
if(font != NULL) set_systemfont(font);
491
font = Nlm_XrmGetResource("programfont");
492
if(font != NULL) Nlm_programFont = Nlm_ParseFont(font);
496
add_apropos("njplot", show_apropos_njplot);
501
p = MG_GetBundleResourcesDir();
502
strcat(p, "/njplot.help");
503
help_file = fopen(p, "r");
505
#elif defined(HELPFILENAME)
506
help_file = fopen(HELPFILENAME, "r");
508
help_file = open_path("njplot.help");
510
Nlm_KeyboardView(process_keys);
511
memcpy(&tag_njplot, "NJPL", sizeof(int));
512
memcpy(&tag_help, "HELP", sizeof(int));
513
fd_nj_plot = create_win_nj_plot();
514
SetStatus(fd_nj_plot->bootstrap_button, boot_arg);
515
SetStatus(fd_nj_plot->branch_length_button, plot_br_l);
516
if(fname != NULL) init_tree( fname, NULL );
517
else SetTitle(fd_nj_plot->nj_plot, "njplot");
518
Show(fd_nj_plot->nj_plot);
519
Nlm_ObjectRect(fd_nj_plot->nj_plot, &(fd_nj_plot->old_rect));
520
if(red != NULL) search_callback( (Nlm_IteM)red );
523
Nlm_Metronome(mac_timer);
532
FD_nj_plot *create_win_nj_plot(void)
538
FD_nj_plot *fdui = (FD_nj_plot *) calloc(1, sizeof(FD_nj_plot));
540
Nlm_Handle obj; int left, right;
541
static int countwin = 0;
544
fdui->tag = tag_njplot;
545
fdui->nj_plot = win = DocumentWindow(-50 - countwin, -33 - countwin, -3, -3, "Njplot",
546
closeproc, win_resize_proc);
547
countwin += 3; countwin %= 15;
549
static FD_nj_plot *mac_menu_bar_extra = NULL;
550
if(mac_menu_bar_extra != NULL) {
551
fdui->open_button = mac_menu_bar_extra->open_button;
552
fdui->save_plot_button = mac_menu_bar_extra->save_plot_button;
553
fdui->save_tree_button = mac_menu_bar_extra->save_tree_button;
554
fdui->save_unrooted_button = mac_menu_bar_extra->save_unrooted_button;
555
fdui->SearchItem = mac_menu_bar_extra->SearchItem;
556
fdui->AgainItem = mac_menu_bar_extra->AgainItem;
557
fdui->tree_font_menu = mac_menu_bar_extra->tree_font_menu;
558
fdui->choix_font = mac_menu_bar_extra->choix_font;
559
fdui->choix_taille = mac_menu_bar_extra->choix_taille;
560
fdui->bold_item = mac_menu_bar_extra->bold_item;
561
fdui->italic_item = mac_menu_bar_extra->italic_item;
562
fdui->paper_menu = mac_menu_bar_extra->paper_menu;
565
#define OPEN_LABEL "Open O"
566
#define NEW_LABEL "New N"
567
#define CLOSE_LABEL "Close W"
568
#define SAVE_PLOT_LABEL "Save as PDF S"
569
#define PRINT_LABEL "Print P"
570
#define QUIT_LABEL "Quit Q"
571
#define COPY_LABEL "Copy C"
572
#define PASTE_LABEL "Paste V"
573
#define FIND_LABEL "Find F"
574
#define AGAIN_LABEL "Again A"
575
#define PLACE_OF_MENUS NULL
577
#define OPEN_LABEL "Open ^O"
578
#define NEW_LABEL "New ^N"
579
#define CLOSE_LABEL "Close ^W"
580
#define PRINT_LABEL "Print ^P"
581
#define SAVE_PLOT_LABEL "Save as PDF ^S"
582
#define QUIT_LABEL "Quit ^Q"
583
#define COPY_LABEL "Copy ^C"
584
#define PASTE_LABEL "Paste ^V"
585
#define FIND_LABEL "Find ^F"
586
#define AGAIN_LABEL "Again ^A"
587
#define PLACE_OF_MENUS fdui->nj_plot
589
menu = PulldownMenu(PLACE_OF_MENUS, "File");
590
fdui->open_button = CommandItem(menu, OPEN_LABEL, open_callback);
591
CommandItem(menu, NEW_LABEL, new_callback);
592
fdui->save_plot_button =
593
#if ( ! defined(WIN_MOTIF) ) || defined(WITH_PDF)
594
CommandItem(menu, SAVE_PLOT_LABEL, save_plot_callback);
597
CommandItem(menu, "Save as PostScript", save_plot_callback);
599
fdui->save_tree_button = CommandItem(menu, "Save Rooted Tree", save_tree_callback);
600
fdui->save_unrooted_button = CommandItem(menu, "Save Unrooted Tree", save_tree_callback);
602
CommandItem(menu, PRINT_LABEL, print_plot);
604
CommandItem(menu, CLOSE_LABEL, closefrommenu);
608
CommandItem(menu, QUIT_LABEL, exit_callback);
609
Advance(PLACE_OF_MENUS);
610
menu = PulldownMenu(PLACE_OF_MENUS, "Edit");
611
CommandItem(menu, "Clear", clear_tree);
613
CommandItem(menu, COPY_LABEL, copy_plot);
615
CommandItem(menu, PASTE_LABEL, paste_tree);
618
CommandItem(menu, "Example", example_tree);
621
fdui->SearchItem = CommandItem(menu, FIND_LABEL, search_callback);
622
fdui->AgainItem = CommandItem(menu, AGAIN_LABEL, search_callback);
623
/* Disable(fdui->AgainItem); */
624
Advance(PLACE_OF_MENUS);
625
fdui->tree_font_menu = PulldownMenu(PLACE_OF_MENUS, "Font");
626
fdui->choix_font = ChoiceGroup(fdui->tree_font_menu, font_callback);
627
Nlm_ChoiceItem(fdui->choix_font, list_font_name[1]);
628
Nlm_ChoiceItem(fdui->choix_font, list_font_name[2]);
629
Nlm_ChoiceItem(fdui->choix_font, list_font_name[3]);
630
SeparatorItem(fdui->tree_font_menu);
631
fdui->choix_taille = ChoiceGroup(fdui->tree_font_menu, font_callback);
632
ChoiceItem(fdui->choix_taille, "6");
633
ChoiceItem(fdui->choix_taille, "8");
634
ChoiceItem(fdui->choix_taille, "10");
635
ChoiceItem(fdui->choix_taille, "12");
636
ChoiceItem(fdui->choix_taille, "14");
637
ChoiceItem(fdui->choix_taille, "18");
638
SeparatorItem(fdui->tree_font_menu);
639
fdui->bold_item = StatusItem(fdui->tree_font_menu, "Bold",
640
(Nlm_ItmActnProc) font_callback);
641
fdui->italic_item = StatusItem(fdui->tree_font_menu, "Italic",
642
(Nlm_ItmActnProc) font_callback);
643
SetStatus(fdui->bold_item, FALSE);
644
SetStatus(fdui->italic_item, FALSE);
646
Advance(PLACE_OF_MENUS);
647
fdui->paper_menu = PulldownMenu(PLACE_OF_MENUS, "Paper");
648
choix_paper = ChoiceGroup(fdui->paper_menu, paper_callback);
649
ChoiceItem(choix_paper, "A4");
650
ChoiceItem(choix_paper, "US letter");
651
SetValue(choix_paper, paper_choice);
652
SeparatorItem(fdui->paper_menu);
653
#ifdef WIN_MSWIN /* SetTitle ne marche pas sur PC! */
654
CommandItem(fdui->paper_menu, "Page count", page_count_callback);
655
#elif defined(WIN_MAC) /* en 2 temps car () ds menu ne marche pas sur Mac ! */
656
{ Nlm_IteM item; char nom[25];
657
item = CommandItem(fdui->paper_menu, "tmp", page_count_callback);
658
sprintf(nom, "Page count (%d)", page_count);
663
sprintf(nom, "Page count (%d)", page_count);
664
CommandItem(fdui->paper_menu, nom, page_count_callback);
669
static Nlm_MenU window_menu;
670
window_menu = PulldownMenu(NULL, "Window");
672
Advance(PLACE_OF_MENUS);
673
obj = PulldownMenu(PLACE_OF_MENUS, "Help");
674
CommandItem(obj, "Help", cre_help_win);
676
Break(PLACE_OF_MENUS);
678
mac_menu_bar_extra = (FD_nj_plot *) calloc(1, sizeof(FD_nj_plot));
679
*mac_menu_bar_extra = *fdui;
681
{static Nlm_IteM mac_win_item[50];
682
static int mac_win_item_count = 0; int i;
683
for(i=0; i<mac_win_item_count; i++) {
684
if(!Nlm_Enabled(mac_win_item[i])) {
685
Nlm_Enable(mac_win_item[i]);
686
fdui->win_menu_item = mac_win_item[i];
690
if(i>=mac_win_item_count) {
691
fdui->win_menu_item = mac_win_item[mac_win_item_count] = CommandItem(window_menu, "njplot", window_callback);
692
mac_win_item_count++;
696
fdui->choix_group = NormalGroup(win, 4, 1, "Operation", programFont, operation_callback);
697
RadioButton(fdui->choix_group, "Full tree");
698
fdui->reroot_button = RadioButton(fdui->choix_group, "New outgroup");
699
RadioButton(fdui->choix_group, "Swap nodes");
700
RadioButton(fdui->choix_group, "Subtree");
701
SetValue(fdui->choix_group, show_tree);
704
group = NormalGroup(win, 2, 1, "Display", programFont, NULL);
705
fdui->branch_length_button = CheckBox(group, "Branch lengths",
706
toggle_branch_callback);
707
SetStatus(fdui->branch_length_button, fdui->plot_br_l);
708
fdui->bootstrap_button = CheckBox(group, "Bootstrap values",
709
toggle_bootstrap_callback);
712
group = NormalGroup(win, 2, 1, "Zoom", programFont, NULL);
713
obj = Nlm_UpDownSwitch(group, 0, zoomcallback);
714
fdui->zoomvalue = 1.;
715
Nlm_SetSwitchParams( (Nlm_SwitcH)obj, 1, 100);
716
fdui->zoomprompt = Nlm_StaticPrompt(group, "100%", 35, Nlm_stdLineHeight, Nlm_programFont, 'l');
719
GetNextPosition(win, &position);
722
SetNextPosition(win, position);
723
obj = fdui->subtree_up_button = PushButton(win, "Subtree Up", subtree_up_callback);
724
Disable(fdui->subtree_up_button);
728
Nlm_GetPosition(obj, &(fdui->old_rect));
729
right = fdui->old_rect.right;
730
Nlm_GetNextPosition(win, &position);
734
#define PLOT_HEIGHT 430
735
#elif defined(WIN_MAC)
736
#define PLOT_HEIGHT 300
738
#define PLOT_HEIGHT 350
741
fdui->tree_plot = Nlm_AutonomousPanel(win, right - left + 1, PLOT_HEIGHT,
742
tree_draw_proc, scrollcallback, NULL, sizeof(int), NULL, NULL);
743
{int hidebar = TRUE; /* put TRUE iff scrollbar should be hidden */
744
Nlm_SetPanelExtra(fdui->tree_plot, &hidebar);
746
SetPanelClick(fdui->tree_plot, tree_click_proc, NULL, NULL, NULL);
747
obj = Nlm_GetSlateVScrollBar((SlatE)fdui->tree_plot);
749
Nlm_SetBarValue(obj, 0);
750
Nlm_SetBarMax(obj, 1);
752
{int space = 0; /* some space at the bottom of the window */
753
#if defined(__APPLE__) || defined(WIN_MAC)
754
space = Nlm_hScrollBarHeight;
755
#elif defined(WIN_MOTIF)
760
Nlm_StaticPrompt(win, "", 4, space, Nlm_programFont, 'l');
764
fdui->old_rect.left = -1;
765
SetWindowExtra(win, fdui, NULL);
766
fdui->font_size_rank = default_font_size_rank;
767
fdui->font_family_rank = times;
768
Nlm_SetValue(fdui->choix_taille, default_font_size_rank);
769
Nlm_SetValue(fdui->choix_font, times);
770
Nlm_SetStatus(fdui->bold_item, FALSE);
771
Nlm_SetStatus(fdui->italic_item, FALSE);
773
{ /* contre bug fenetre mange un peu du panel */
776
GetNextPosition(win, &position);
777
right = position.x + 5;
778
SetNextPosition(win, position);
780
GetNextPosition(win, &position);
783
SetNextPosition(win, position);
784
StaticPrompt(win, "", 1, 1, programFont, 'l');
791
int update_tree_w_data(Nlm_Handle h)
796
w = Nlm_FrontWindow();
797
#elif defined(WIN_MSWIN)
798
if(h == NULL) w = Nlm_FrontWindow();
799
else w = Nlm_ParentWindow(h);
801
if(h == NULL) w = fd_nj_plot->nj_plot;
802
else w = Nlm_ParentWindow(h);
804
f = (FD_nj_plot *)Nlm_GetWindowExtra(w);
805
if(f== NULL || f->tag != tag_njplot) return FALSE;
810
FILE *open_path(char *fname) /* to open in read-only file fname searching for
811
it through all path directories */
814
static char dir[Mxdir+1];
815
char *path, *deb, *fin;
819
static char vmspath[] = "njplot";
822
path = getenv("PATH"); /* get the list of path directories,
825
#elif defined(WIN_MSWIN)
826
/* try first dir where program was launched */
827
path = get_prog_dir();
832
fich = fopen(fname,"r");
842
fin = strchr(deb,':');
845
{ strncpy(dir,deb,fin-deb); ltot=fin-deb; }
847
{ strcpy(dir,deb); ltot=strlen(dir); }
848
/* now one directory is in string dir */
849
if( ltot + lf + 1 <= Mxdir)
853
#elif defined(WIN_MSWIN)
854
if(dir[ltot-1] == '\\') ltot--;
855
else dir[ltot] = '\\';
859
strcpy(dir+ltot+1,fname); /* now dir is appended with filename */
860
fich = fopen(dir,"r");
861
if( fich != NULL) break;
868
fich=fopen(fname,"r"); /* try also current directory */
875
void cre_help_win(IteM bouton)
879
static struct win_help_extra win_data;
880
static int first = TRUE;
885
if(help_file == NULL) {
889
"Sorry, no help resource available."
891
"Sorry, help file njplot.help is not found."
897
win = DocumentWindow( -50, -33, -3, -3, "Njplot Help", (Nlm_WndActnProc)help_ok_callback, NULL);
898
group = HiddenGroup(win, -1, -2, NULL);
899
SetGroupSpacing(group, 0, 5);
900
topic_list = SingleList(group, 7, 8, topic_callback);
901
load_help_topics(help_file, topic_list);
902
DefaultButton(group, "Ok", help_ok_callback);
905
win_data.police = ParseFont("Courier New,10");
907
win_data.police = programFont;
909
SelectFont(win_data.police);
910
larg = 81 * Nlm_TextWidth("Q", 1);
911
win_data.document = DocumentPanel(win, larg, 20 * Nlm_LineHeight() );
912
win_data.tag = tag_help;
913
SetWindowExtra(win, &win_data, NULL);
920
void topic_callback(LisT list)
924
static int last_topic = 0;
926
static char txt[5000];
929
struct win_help_extra *p_win_data;
931
num_topic = GetValue(list);
932
if(num_topic == 0 || num_topic == last_topic) return;
933
last_topic = num_topic;
934
win = ParentWindow(list);
935
p_win_data = (struct win_help_extra *)GetWindowExtra(win);
936
help_doc = p_win_data->document;
938
GetDocParams(help_doc, &total, NULL);
939
while(total > 0) DeleteItem(help_doc, total--);
941
while(fgets(ligne, sizeof(ligne), help_file) != NULL) {
942
if(strncmp(ligne, ">>>", 3) != 0) continue;
943
if( --num_topic == 0) break;
945
if(num_topic != 0) return;
947
while(fgets(ligne, sizeof(ligne), help_file) != NULL) {
948
if(strncmp(ligne, ">>>", 3) == 0) break;
949
if(strncmp(ligne, "Version:", 8) == 0) sprintf(ligne, "Version: %s\n", NJPLOTVERSION);
950
strcpy(p, ligne); p += strlen(ligne);
952
AppendText(help_doc, txt, NULL, NULL, p_win_data->police);
957
void help_ok_callback(ButtoN bouton)
961
h = Nlm_ParentWindow(bouton);
965
void load_help_topics(FILE *fich, LisT topic_list)
967
char ligne[100], topic[50];
971
while(fgets(ligne, sizeof(ligne), fich) != NULL) {
972
if(strncmp(ligne, ">>>", 3) != 0) continue;
973
strcpy(topic, ligne + 3);
974
l = strlen(topic) - 1;
976
ListItem(topic_list, topic);
981
void subtree_up_callback(ButtoN bouton)
983
fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(bouton) );
984
if(fd_nj_plot->subtree_center == NULL) return;
985
fd_nj_plot->subtree_center = fd_nj_plot->subtree_ascend;
986
if(fd_nj_plot->subtree_center != NULL) {
987
fd_nj_plot->subtree_ascend = fd_nj_plot->subtree_center->v3;
988
if(fd_nj_plot->subtree_ascend == NULL) {
989
SetValue(fd_nj_plot->choix_group, show_tree);
990
Disable(fd_nj_plot->subtree_up_button);
991
fd_nj_plot->choix = show_tree;
992
show_tree_callback();
995
fd_nj_plot->subtree_notu = calc_n_desc(fd_nj_plot->subtree_center) - 1;
996
scrollnotu(fd_nj_plot->subtree_notu);
998
fd_nj_plot->need_runtree = TRUE;
999
tree_draw_proc(fd_nj_plot->tree_plot);
1003
void process_keys(Nlm_Char key)
1006
/* combinaison command-lettre */
1007
#define test_key(a) (Nlm_cmmdKey && Nlm_currentKey == a)
1009
/* combinaison control-lettre */
1010
#define test_key(a) key == a - 96
1013
if( (!(test_key('o') || test_key('n'))) && ! update_tree_w_data(NULL) ) return;
1017
else if( test_key('o') ) {
1018
if(fd_nj_plot == NULL) fd_nj_plot = create_win_nj_plot();
1019
open_callback(fd_nj_plot->open_button);
1021
else if( test_key('n') )
1023
else if( test_key('w') )
1024
closefrommenu(fd_nj_plot->open_button);
1025
else if( test_key('s') )
1026
save_plot_callback(fd_nj_plot->save_plot_button);
1027
else if( test_key('f') )
1028
search_callback(fd_nj_plot->SearchItem);
1029
else if( test_key('a') ) {
1030
if(Enabled(fd_nj_plot->AgainItem) )
1031
search_callback(fd_nj_plot->AgainItem);
1034
else if( test_key('c') )
1036
else if( test_key('p') )
1039
else if( test_key('v') )
1045
static void closeproc(WindoW i)
1049
fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( i );
1050
tofree = fd_nj_plot; /* necessary because with MSWIN fd_nj_plot changes after Remove(i) */
1053
Nlm_Disable(tofree->win_menu_item);
1057
w = Nlm_desktopWindow;
1058
while(w != NULL) { /* is there another tree window ? */
1059
fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( w );
1060
if( fd_nj_plot != NULL && fd_nj_plot->tag == tag_njplot) {
1061
Nlm_Select(fd_nj_plot->nj_plot);
1074
void closefrommenu(Nlm_IteM item)
1077
if( update_tree_w_data(NULL) ) closeproc(fd_nj_plot->nj_plot);
1079
if( update_tree_w_data(item) ) closeproc(Nlm_ParentWindow(item));
1083
void win_resize_proc(WindoW win)
1085
RecT *old_rect, rect;
1086
int change_x, change_y, old_height, new_height;
1088
fd_nj_plot = (FD_nj_plot *)GetWindowExtra(win);
1089
old_rect = &(fd_nj_plot->old_rect);
1090
if(old_rect->left == -1) return;
1091
ObjectRect(win, &rect);
1092
old_height = old_rect->bottom - old_rect->top;
1093
new_height = rect.bottom - rect.top;
1094
change_y = (new_height - old_height);
1095
old_height = old_rect->right - old_rect->left;
1096
new_height = rect.right - rect.left;
1097
change_x = (new_height - old_height);
1098
if(change_x != 0 || change_y != 0) {
1099
change_panel_size(fd_nj_plot->tree_plot, change_x, change_y);
1105
void change_panel_size(PaneL panel, int change_x, int change_y)
1111
Nlm_Boolean in_group;
1114
static int recursive = FALSE;
1117
GetPosition(panel, &r);
1119
if(recursive) return;
1121
bar = Nlm_GetSlateVScrollBar( (Nlm_SlatE)panel);
1122
visible = Nlm_Visible(bar);
1123
group = Parent(panel);
1124
in_group = (group != ParentWindow(panel));
1126
GetPosition(group, &r_group);
1132
r.bottom += change_y;
1133
r.right += change_x;
1134
SetPosition(panel, &r);
1137
r_group.bottom += change_y;
1138
r_group.right += change_x;
1139
SetPosition( group, &r_group);
1143
if( !visible) Nlm_Hide(bar);
1149
void font_callback(ChoicE choix)
1151
if( ! update_tree_w_data(choix) ) return;
1153
fd_nj_plot->need_runtree = TRUE;
1154
tree_draw_proc(fd_nj_plot->tree_plot);
1158
void prepare_fonts(void)
1160
Nlm_Boolean use_bold, use_italic;
1161
char font_full_name[40], *p;
1163
/* prepare vibrant font */
1164
use_bold = GetStatus(fd_nj_plot->bold_item);
1165
use_italic = GetStatus(fd_nj_plot->italic_item);
1166
fd_nj_plot->font_family_rank = GetValue(fd_nj_plot->choix_font);
1167
fd_nj_plot->font_size_rank = GetValue(fd_nj_plot->choix_taille);
1168
sprintf(font_full_name, "%s,%d", list_font_name[fd_nj_plot->font_family_rank],
1169
list_font_size[fd_nj_plot->font_size_rank]);
1170
if(use_bold || use_italic) strcat(font_full_name, ",");
1171
if(use_bold) strcat(font_full_name, "b");
1172
if(use_italic) strcat(font_full_name, "i");
1173
fd_nj_plot->current_font = ParseFont(font_full_name);
1174
if((p = strchr(font_full_name, ',')) != NULL) strcpy(fd_nj_plot->font_bold_italic, p + 1);
1175
else fd_nj_plot->font_bold_italic[0] = 0;
1176
prepare_pdf_font(fd_nj_plot->font_family_rank, use_bold, use_italic);
1180
/* callbacks for form nj_plot */
1181
#if defined(WIN_MOTIF) && defined(__APPLE__)
1182
/* bug sur mac/darwin : Nlm_GetOutputFileName crashes if Nlm_GetInputFileName was not used before ! */
1183
static int can_run_getoutputfname = FALSE;
1185
static int can_run_getoutputfname = TRUE;
1189
void open_callback(IteM ob)
1193
can_run_getoutputfname = TRUE;
1194
if(!MG_GetInputFName(fname, sizeof(fname))) {
1195
if(fd_nj_plot != NULL) tree_draw_proc(fd_nj_plot->tree_plot);
1198
if(fd_nj_plot == NULL || fd_nj_plot->notu != 0) fd_nj_plot = create_win_nj_plot();
1199
fd_nj_plot->notu = 0;
1200
init_tree( fname, NULL );
1201
if(fd_nj_plot->notu == 0) {
1202
closeproc(fd_nj_plot->nj_plot);
1205
Nlm_Show(fd_nj_plot->nj_plot);
1206
Nlm_ObjectRect(fd_nj_plot->nj_plot, &(fd_nj_plot->old_rect));
1210
void new_callback(IteM ob)
1212
fd_nj_plot = create_win_nj_plot();
1213
fd_nj_plot->notu = 0;
1214
Nlm_Show(fd_nj_plot->nj_plot);
1215
Nlm_ObjectRect(fd_nj_plot->nj_plot, &(fd_nj_plot->old_rect));
1219
void paper_callback(ChoicE ob)
1221
paper_choice = (paper_item) GetValue(ob);
1225
void save_plot_callback(IteM ob)
1228
if(!update_tree_w_data(ob)) return;
1229
strcpy(plotfilename, fd_nj_plot->tree_name);
1230
p = strchr(extract_filename(plotfilename), '.');
1231
if(p == NULL) p = plotfilename + strlen(plotfilename);
1236
pdf_plot = (ob == fd_nj_plot->save_plot_button);
1244
if(can_run_getoutputfname) {
1245
if( ! MG_GetOutputFName(plotfilename, sizeof(plotfilename),
1246
extract_filename(plotfilename) ) ) return;
1263
void save_tree_callback(IteM ob)
1265
char *p, *arbre, ajout[10], *name_part;
1269
if(!update_tree_w_data(ob)) return;
1270
if(fd_nj_plot->notu==0)return;
1271
unrooted = (ob == fd_nj_plot->save_unrooted_button);
1272
/* build out file name */
1273
strcpy(rooted_fname, fd_nj_plot->tree_name);
1274
name_part = extract_filename(rooted_fname);
1275
/* ajouter _root. dans le nom */
1276
strcpy(ajout, unrooted ? "_noroot." : "_root.");
1277
if(strstr(name_part, ajout) == NULL) {
1278
p = strchr(name_part, '.');
1279
if(p == NULL) p = name_part + strlen(name_part);
1282
name_part = extract_filename(fd_nj_plot->tree_name);
1283
p = strchr(name_part, '.');
1285
strcat(rooted_fname, "ph");
1287
strcpy( strchr(extract_filename(rooted_fname), '.'), p);
1288
if( !MG_GetOutputFName(rooted_fname, sizeof(rooted_fname), extract_filename(rooted_fname) ) )
1290
if(unrooted) arbre = ecrit_arbre_parenth_unrooted(fd_nj_plot->racine);
1291
else arbre = ecrit_arbre_parenth(fd_nj_plot->racine);
1293
err_message("Sorry, not enough memory");
1296
out = fopen(rooted_fname,"w");
1298
fputs(arbre, out); putc('\n', out);
1303
sprintf(mess, "Sorry, cannot write to file %s",
1304
extract_filename(rooted_fname) );
1311
void toggle_branch_callback(ButtoN ob)
1313
fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(ob) );
1314
fd_nj_plot->plot_br_l = GetStatus(ob);
1315
fd_nj_plot->need_runtree = TRUE;
1316
tree_draw_proc(fd_nj_plot->tree_plot);
1320
void toggle_bootstrap_callback(ButtoN ob)
1322
fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(ob) );
1323
fd_nj_plot->show_bootstrap = !fd_nj_plot->show_bootstrap;
1324
fd_nj_plot->need_runtree = TRUE;
1325
tree_draw_proc(fd_nj_plot->tree_plot);
1329
void operation_callback(GrouP group)
1331
fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(group) );
1332
fd_nj_plot->choix = (enum operations) GetValue(group);
1333
if(fd_nj_plot->choix == permutation)
1335
else if(fd_nj_plot->choix == depl_racine)
1336
new_outgroup_callback();
1337
else if(fd_nj_plot->choix == subtree)
1340
show_tree_callback();
1344
void subtree_callback(void)
1346
fd_nj_plot->choix = subtree;
1347
/* Disable(fd_nj_plot->save_plot_button); */
1348
Disable(fd_nj_plot->save_tree_button);
1349
Disable(fd_nj_plot->save_unrooted_button);
1350
Enable(fd_nj_plot->subtree_up_button);
1351
if(fd_nj_plot->has_br_length) {
1352
SetStatus(fd_nj_plot->branch_length_button, FALSE);
1353
Disable(fd_nj_plot->branch_length_button);
1354
fd_nj_plot->plot_br_l=0;
1356
SetStatus(fd_nj_plot->bootstrap_button, FALSE);
1357
fd_nj_plot->show_bootstrap = FALSE;
1358
Disable(fd_nj_plot->bootstrap_button);
1359
Disable(fd_nj_plot->reroot_button);
1360
fd_nj_plot->need_runtree = TRUE;
1361
tree_draw_proc(fd_nj_plot->tree_plot);
1364
void swap_callback(void)
1366
fd_nj_plot->choix = permutation;
1367
Disable(fd_nj_plot->save_plot_button);
1368
Disable(fd_nj_plot->save_tree_button);
1369
Disable(fd_nj_plot->save_unrooted_button);
1370
if(fd_nj_plot->has_br_length) {
1371
SetStatus(fd_nj_plot->branch_length_button, FALSE);
1372
Disable(fd_nj_plot->branch_length_button);
1373
fd_nj_plot->plot_br_l=0;
1375
SetStatus(fd_nj_plot->bootstrap_button, FALSE);
1376
fd_nj_plot->show_bootstrap = FALSE;
1377
Disable(fd_nj_plot->bootstrap_button);
1378
fd_nj_plot->need_runtree = TRUE;
1379
tree_draw_proc(fd_nj_plot->tree_plot);
1382
void new_outgroup_callback(void)
1384
fd_nj_plot->choix = depl_racine;
1385
Disable(fd_nj_plot->save_plot_button);
1386
Disable(fd_nj_plot->save_tree_button);
1387
Disable(fd_nj_plot->save_unrooted_button);
1388
if(fd_nj_plot->has_br_length) {
1389
SetStatus(fd_nj_plot->branch_length_button, FALSE);
1390
Disable(fd_nj_plot->branch_length_button);
1391
fd_nj_plot->plot_br_l=0;
1393
SetStatus(fd_nj_plot->bootstrap_button, FALSE);
1394
fd_nj_plot->show_bootstrap = FALSE;
1395
Disable(fd_nj_plot->bootstrap_button);
1396
fd_nj_plot->need_runtree = TRUE;
1397
tree_draw_proc(fd_nj_plot->tree_plot);
1401
void show_tree_callback(void)
1403
fd_nj_plot->choix = show_tree;
1404
Enable(fd_nj_plot->save_plot_button);
1405
Enable(fd_nj_plot->save_tree_button);
1406
Enable(fd_nj_plot->save_unrooted_button);
1407
Disable(fd_nj_plot->subtree_up_button);
1408
if(fd_nj_plot->has_br_length) {
1409
Enable(fd_nj_plot->branch_length_button);
1411
if(fd_nj_plot->has_internal) {
1412
Enable(fd_nj_plot->bootstrap_button);
1414
Enable(fd_nj_plot->reroot_button);
1415
fd_nj_plot->need_runtree = TRUE;
1416
fd_nj_plot->subtree_notu = fd_nj_plot->notu;
1417
if(fd_nj_plot->subtree_center != NULL) scrollnotu(fd_nj_plot->notu);
1418
fd_nj_plot->subtree_center = NULL;
1419
tree_draw_proc(fd_nj_plot->tree_plot);
1423
void exit_callback(IteM ob)
1429
void tree_draw_proc(PaneL panel)
1433
static Int2 previous_h = 0, previous_w = 0;
1437
fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(panel) );
1439
bar = Nlm_GetSlateVScrollBar((Nlm_SlatE)panel);
1440
Nlm_GetPanelExtra(panel, &hidebar);
1441
if(hidebar && Nlm_Visible(bar)) Nlm_Hide(bar);
1442
else if( !hidebar && !Nlm_Visible(bar)) Nlm_Show(bar);
1444
ObjectRect(panel, &ob_rect);
1445
EraseRect(&ob_rect);
1446
FrameRect(&ob_rect);
1447
Nlm_ClipRect(&ob_rect);
1448
if(fd_nj_plot->notu == 0) {
1452
width = ob_rect.right - ob_rect.left;
1453
height = ob_rect.bottom - ob_rect.top;
1454
SelectFont(fd_nj_plot->current_font);
1456
if( fd_nj_plot->need_runtree || /* recalcul des positions des # si window re-size */
1457
(fd_nj_plot->choix != show_tree && (height != previous_h || width != previous_w))) {
1460
fd_nj_plot->need_runtree = FALSE;
1464
previous_h = height;
1470
void tree_click_proc(PaneL panel, PoinT click)
1473
int i, found=0, node_num;
1475
Int2 panel_x, panel_y, panel_h;
1476
fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(panel) );
1477
if(fd_nj_plot->notu == 0) return;
1478
if(fd_nj_plot->choix != permutation && fd_nj_plot->choix != depl_racine && fd_nj_plot->choix != subtree)
1480
ObjectRect(panel, &ob_rect);
1481
panel_x = ob_rect.left; panel_y = ob_rect.top; panel_h = ob_rect.bottom - ob_rect.top;
1482
eps = fd_nj_plot->char_height/2;
1483
x = click.x - panel_x;
1485
y = panel_h - click.y;
1486
for(i=0; i<=fd_nj_plot->totpoints; i++ ) {
1487
if(fabs(x - (fd_nj_plot->points+i)->x) > eps)
1489
if(fabs(y - (fd_nj_plot->points+i)->y) > eps)
1495
node_num=(fd_nj_plot->points+i)->number;
1496
if(fd_nj_plot->choix==depl_racine) {
1497
if(node_num >= 1 && node_num <= 2*fd_nj_plot->notu &&
1498
node_num-1 != fd_nj_plot->root_num) {
1499
fd_nj_plot->root_num = node_num-1;
1503
else if(fd_nj_plot->choix==permutation) {
1504
if(node_num >= fd_nj_plot->notu+2 && node_num <= 2*fd_nj_plot->notu+1)
1509
else if(fd_nj_plot->choix==subtree) {
1510
if(node_num < fd_nj_plot->notu+2 || node_num > 2*fd_nj_plot->notu+1) return;
1511
fd_nj_plot->subtree_center = fd_nj_plot->tabtax[node_num - 1];
1512
fd_nj_plot->subtree_ascend = fd_nj_plot->subtree_center->v3;
1513
fd_nj_plot->subtree_notu = calc_n_desc(fd_nj_plot->subtree_center) - 1;
1514
scrollnotu(fd_nj_plot->subtree_notu);
1515
fd_nj_plot->choix = show_tree;
1516
SetValue(fd_nj_plot->choix_group, 0);
1517
Nlm_InvalObject(fd_nj_plot->choix_group);
1518
if(fd_nj_plot->has_br_length) {
1519
Enable(fd_nj_plot->branch_length_button);
1520
Nlm_InvalObject(fd_nj_plot->branch_length_button);
1522
if(fd_nj_plot->has_internal) {
1523
Enable(fd_nj_plot->bootstrap_button);
1524
Nlm_InvalObject(fd_nj_plot->bootstrap_button);
1527
fd_nj_plot->need_runtree = TRUE;
1528
tree_draw_proc(panel);
1532
void paste_tree(IteM ob)
1535
char *buff, *tmpfname;
1536
if(!update_tree_w_data(ob)) return;
1537
if(fd_nj_plot->notu != 0) {
1538
err_message("Do \"Edit:clear\" before pasting tree data");
1543
Nlm_textScrapFull = FALSE; /* arrange un bug de Nlm_ClipboardHasString */
1545
if( ! Nlm_ClipboardHasString() ) {
1546
err_message("No text describing tree present in clipboard");
1549
buff = Nlm_ClipboardToString();
1550
tmpfname = tempnam(NULL, "njplottemp_");
1551
tmp=fopen(tmpfname,"w");
1552
fwrite(buff, 1, strlen(buff), tmp);
1554
init_tree(tmpfname, "pasted tree");
1560
void clear_tree(IteM i)
1562
if(!update_tree_w_data(i)) return;
1563
if(fd_nj_plot->notu != 0) free_tree();
1564
fd_nj_plot->notu = 0;
1565
SetTitle(fd_nj_plot->nj_plot, "njplot");
1567
SetTitle(fd_nj_plot->win_menu_item, "njplot");
1569
tree_draw_proc(fd_nj_plot->tree_plot);
1573
void change_page_count(ButtoN item)
1577
pdone = (Nlm_Boolean *)GetWindowExtra( Nlm_ParentWindow(item) );
1582
void page_count_callback(IteM item)
1585
static Nlm_Boolean done;
1586
static TexT select_box;
1588
static int first = TRUE;
1590
win = FixedWindow(-50,-50,-5,-5,"Page count:",NULL);
1591
sprintf(select, "%d", page_count);
1592
select_box=DialogText(win,select,8,NULL);
1594
DefaultButton(win,"ok",change_page_count);
1595
SetWindowExtra(win, &done, NULL);
1599
Select(win); Select(select_box);
1602
myWaitAndProcessNextEvent();
1604
GetTitle(select_box, select, sizeof(select));
1605
sscanf(select, "%d", &page_count);
1607
#ifndef WIN_MSWIN /* changement titre menu item impossible sur PC ! */
1608
sprintf(select,"Page count (%d)", page_count);
1609
Nlm_SetTitle(item, select);
1611
Select(fd_nj_plot->nj_plot);
1617
void string_callback(ButtoN item)
1621
pdone = (Nlm_Boolean *)GetWindowExtra( Nlm_ParentWindow(item) );
1626
void search_callback(IteM item)
1629
static Nlm_Boolean search_done;
1630
static TexT select_box;
1631
static char select[500];
1634
static int first = TRUE;
1636
if(!update_tree_w_data(item)) return;
1637
if(item == fd_nj_plot->SearchItem) {
1639
win = FixedWindow(-50,-50,-5,-5,"Name searched:",NULL);
1640
select_box=DialogText(win,"",15,NULL);
1642
DefaultButton(win,"ok",string_callback);
1643
SetWindowExtra(win, &search_done, NULL);
1647
Select(win); Select(select_box);
1649
while(! search_done) {
1650
myWaitAndProcessNextEvent();
1652
GetTitle(select_box, select, sizeof(select));
1655
/* Enable(fd_nj_plot->AgainItem); */
1656
Select(fd_nj_plot->nj_plot);
1658
else if(item != fd_nj_plot->AgainItem) { /* happens only when called after start */
1659
strcpy(select, (char *)item);
1662
if(strlen(select) == 0) return;
1664
for(num = 0; num <= fd_nj_plot->totnoms; num++) {
1665
strcpy(aux, (fd_nj_plot->noms+num)->nom);
1667
if(strstr( aux, select) != NULL) {
1668
(fd_nj_plot->noms+num)->disp_option = 'r';
1673
tree_draw_proc(fd_nj_plot->tree_plot);
1678
void init_tree(char *fname, char *displayname)
1683
if(displayname == NULL) displayname = extract_filename(fname);
1684
fd_nj_plot->choix = show_tree;
1686
/* read tree file */
1687
if( (pname=preptree(fname)) != NULL ) {
1690
fd_nj_plot->tree_name = NULL;
1691
fd_nj_plot->notu = 0;
1692
SetTitle(fd_nj_plot->nj_plot, "njplot");
1693
tree_draw_proc(fd_nj_plot->tree_plot);
1694
taille = strlen(pname) + strlen(fname) + 3;
1695
message = check_alloc(1, taille);
1696
strcpy(message, pname);
1697
strcat(message, " ");
1698
strcat(message, extract_filename(fname) );
1699
err_message(message);
1705
fd_nj_plot->deltay = maxy/fd_nj_plot->notu;
1706
if(fd_nj_plot->notu > 0) fd_nj_plot->tree_name = strdup(fname);
1707
fd_nj_plot->need_runtree = TRUE;
1708
fd_nj_plot->subtree_center = NULL;
1710
strcpy(titre_l, displayname );
1711
if(fd_nj_plot->notu > 0) sprintf(titre_l + strlen(titre_l), " (%d tips)", fd_nj_plot->notu + 1);
1714
p = mac_fname_to_roman(titre_l);
1715
SetTitle(fd_nj_plot->win_menu_item, displayname);
1717
SetTitle(fd_nj_plot->nj_plot, p);
1719
tree_draw_proc(fd_nj_plot->tree_plot);
1720
if(fd_nj_plot->has_br_length) {
1721
Enable(fd_nj_plot->branch_length_button);
1724
Disable(fd_nj_plot->branch_length_button);
1725
if(fd_nj_plot->has_internal) {
1726
Enable(fd_nj_plot->bootstrap_button);
1729
Disable(fd_nj_plot->bootstrap_button);
1733
/* fenetre message d'alerte.
1734
Operation Select dans la boucle des evenements qui ramene toujours la fenetre
1735
au premier plan. Lent, mais interessant.
1737
static void alert_ok_action(ButtoN bouton)
1739
Nlm_Boolean *alert_done;
1740
alert_done = (Nlm_Boolean *)GetWindowExtra(Parent(bouton));
1745
void err_message(const char *in)
1748
Nlm_Boolean alert_done;
1752
static char texte[1000];
1756
alwin = Nlm_FixedWindow(-50,-50,-5,-5,"MESSAGE",NULL); // Bug: ModalWindow crashes when return key hit
1758
alwin = Nlm_ModalWindow(-50,-50,-5,-5,NULL);
1759
Nlm_SetTitle(alwin, "Message");
1761
Nlm_SelectFont (Nlm_systemFont);
1762
nl = 0; p = (char *)in; r = texte; width = 0;
1765
if(q == NULL) q = p + strlen(p);
1767
if( (r - texte) + (q - p) + 2 >= sizeof(texte) ) break;
1769
memcpy(r, p, q - p);
1770
w = Nlm_TextWidth(p, q - p);
1771
if(w > width) width = w;
1784
if(q == NULL) break;
1788
width = ( width + 20 ) / Nlm_stdCharWidth;
1789
t = Nlm_ScrollText(alwin, width, nl , Nlm_systemFont, TRUE, NULL);
1791
Nlm_SetTitle(t, texte);
1793
Nlm_DefaultButton(alwin,"ok",alert_ok_action);
1796
Nlm_SetWindowExtra(alwin, &alert_done, NULL);
1798
while(! alert_done) {
1800
if(! Nlm_InFront(alwin) )
1801
Nlm_Select(alwin); // to emulate modal window on mac
1803
myWaitAndProcessNextEvent();
1810
void err_message(const char *in)
1812
fprintf(stderr, "%s\n", in);
1818
void prepare_pdf_font(int font_num, int use_bold, int use_italic)
1820
/* prepare PDF name of font */
1821
strcpy(current_ps_font, list_ps_font_name[font_num]);
1822
if( use_bold && use_italic )
1823
if(font_num == times)
1824
strcat(current_ps_font,"-BoldItalic");
1826
strcat(current_ps_font,"-BoldOblique");
1828
strcat(current_ps_font,"-Bold");
1829
else if( use_italic ) {
1830
if(font_num == times)
1831
strcat(current_ps_font,"-Italic");
1833
strcat(current_ps_font,"-Oblique");
1835
else if(font_num == times)
1836
strcat(current_ps_font,"-Roman");
1840
int direct_pdf_plot(char *fname)
1844
fd_nj_plot->choix = show_tree;
1845
/* read tree file */
1846
if( (p = preptree(fname) ) != NULL ) {
1847
fprintf(stderr, "%s\n", p);
1850
strcpy(plotfilename, fname);
1851
q = extract_filename(plotfilename);
1853
if(p == NULL) p = plotfilename + strlen(plotfilename);
1864
prepare_pdf_font(times, FALSE, FALSE);
1867
fd_nj_plot->deltay = maxy/fd_nj_plot->notu;
1870
/* calcul du nombre de feuilles (tres obligatoire !!!) */
1871
calc_otu(NULL, fd_nj_plot->racine);
1872
/* calcul de son format phylip */
1873
p = ecrit_arbre_parenth(fd_nj_plot->racine);
1875
fprintf(stderr, "Sorry, not enough memory\n");
1878
/* ecriture de son format phylip */
1882
#elif !defined(WIN_MAC)
1892
int calc_otu(struct noeud *pere, struct noeud *centre)
1894
struct noeud *gauche, *droite;
1895
double bg, bd, bpere;
1897
if(centre == NULL) return 0;
1899
/* orienter le noeud centre de maniere standard: centre->v3=pere */
1900
if( centre->v1 == pere ) {
1901
gauche =centre->v2; droite = centre->v3;
1902
bg = centre->l2; bd = centre->l3; bpere = centre->l1;
1904
else if( centre->v2 == pere ) {
1905
gauche =centre->v1; droite = centre->v3;
1906
bg = centre->l1; bd = centre->l3; bpere = centre->l2;
1909
gauche =centre->v1; droite = centre->v2;
1910
bg = centre->l1; bd = centre->l2; bpere = centre->l3;
1912
centre->v3=pere; centre->v1=gauche; centre->v2=droite;
1913
centre->l3=bpere; centre->l1=bg; centre->l2=bd;
1915
return calc_otu(centre, centre->v1) + calc_otu(centre, centre->v2);
1919
void remove_arg(int target, int *argc, char *argv[])
1922
for(num = target; num < *argc - 1; num++)
1923
argv[num] = argv[num+1];
1928
#define PDFONLY "-psonly"
1930
#define PDFONLY "-pdfonly"
1933
void process_args(int *argc, char *argv[], char **pred, int *pboot_arg, int *p_plot_br_l, int *p_font_size_rank)
1937
for(num = 1; num < *argc; num++) {
1938
if( strncmp(argv[num], "-h", 2) == 0 ){
1941
"Usage: %s [-options] [tree_file_name]\n"
1942
"where options are:\n"
1943
"-h print out this message\n"
1945
"-outotu name name of species to use as outgroup for rooting\n"
1947
"-txtw n width of output text (default = 120)\n"
1948
"-prefix string string to prefix to all leaf names in output tree\n"
1950
"-us PDF or PostScript tree file prepared for US Letter paper size\n"
1952
PDFONLY" no window interface, just write the PDF/PostScript tree plot\n"
1953
" to file named as input tree file with .pdf/.ps extension\n"
1954
"-red xxxx highlight in red all taxon names containing string xxxx\n"
1956
"-pc n number of pages for PDF/PostScript output\n"
1957
"-size n font size n used for taxon names\n"
1958
"-lengths show branch lengths if they appear in tree file\n"
1959
"-boot show bootstrap values if they appear in tree file\n"
1960
"-psize size of page for PDF/PostScript expressed as WIDTHxHEIGHT\n"
1961
"-notitle don't include title in PDF/PostScript output\n"
1964
"and where tree_file_name is the name of a tree file in the Newick format\n"
1966
"the output goes to file <tree_file_name>.txt\n"
1967
#elif defined(ADDROOT)
1968
"the output goes to stdout\n"
1969
#elif defined(NO_GUI)
1970
"the output goes to file <tree_file_name>.pdf or <tree_file_name>.ps\n"
1972
, extract_filename(argv[0]) );
1984
*pboot_arg = FALSE; *p_plot_br_l = FALSE;
1985
for(num = 1; num < *argc; num++) {
1986
if( strncmp(argv[num], "-us", 3) == 0) {
1987
paper_choice = LETTER;
1988
remove_arg(num, argc, argv);
1993
for(num = 1; num < *argc; num++) {
1994
if( strncmp(argv[num], "-size", 5) == 0) {
1995
const int maxi = sizeof(list_font_size) / sizeof(int);
1997
if(num + 1 < *argc) {
1998
sscanf(argv[num + 1], "%d", &taille);
1999
remove_arg(num + 1, argc, argv);
2001
remove_arg(num, argc, argv);
2002
for(num = 0; num < maxi; num++)
2003
if(taille <= list_font_size[num]) break;
2006
*p_font_size_rank = num;
2010
for(num = 1; num < *argc; num++) {
2011
if( strncmp(argv[num], "-pc", 3) == 0) {
2012
if(num + 1 < *argc) {
2013
sscanf(argv[num + 1], "%d", &page_count);
2014
remove_arg(num + 1, argc, argv);
2016
remove_arg(num, argc, argv);
2020
for(num = 1; num < *argc; num++) {
2021
if( strncmp(argv[num], PDFONLY, 9) == 0) {
2022
pdf_plot_only = TRUE;
2023
remove_arg(num, argc, argv);
2027
for(num = 1; num < *argc; num++) {
2028
if( strncmp(argv[num], "-lengths", 8) == 0) {
2029
*p_plot_br_l = TRUE;
2030
remove_arg(num, argc, argv);
2034
for(num = 1; num < *argc; num++) {
2035
if( strncmp(argv[num], "-boot", 5) == 0) {
2037
remove_arg(num, argc, argv);
2041
for(num = 1; num < *argc; num++) {
2042
if( strncmp(argv[num], "-psize", 6) == 0) {
2043
if(num + 1 < *argc) {
2044
sscanf(argv[num + 1], "%dx%d", &ps_width, &ps_height);
2045
remove_arg(num + 1, argc, argv);
2047
remove_arg(num, argc, argv);
2051
for(num = 1; num < *argc; num++) {
2052
if( strncmp(argv[num], "-notitle", 8) == 0) {
2054
remove_arg(num, argc, argv);
2060
for(num = 1; num < *argc; num++) {
2061
if( strncmp(argv[num], "-red", 4) == 0) {
2062
if(num + 1 < *argc) {
2063
*pred = argv[num+1];
2064
remove_arg(num + 1, argc, argv);
2066
remove_arg(num, argc, argv);
2071
physx = 120; /* default width of text output */
2072
for(num = 1; num < *argc; num++) {
2073
if( strncmp(argv[num], "-txtw", 5) == 0) {
2074
if(num + 1 < *argc) {
2076
sscanf(argv[num+1], "%d", &val);
2077
physx = (double)val;
2078
remove_arg(num + 1, argc, argv);
2080
remove_arg(num, argc, argv);
2084
for(num = 1; num < *argc; num++) {
2085
if( strncmp(argv[num], "-prefix", 7) == 0) {
2086
if(num + 1 < *argc) {
2087
tty_prefix = argv[num+1];
2088
remove_arg(num + 1, argc, argv);
2090
remove_arg(num, argc, argv);
2094
#elif defined(ADDROOT)
2095
for(num = 1; num < *argc; num++) {
2096
if(strcmp(argv[num], "-outotu") == 0) {
2097
if(num + 1 < *argc) {
2098
outotu = argv[num+1];
2099
remove_arg(num + 1, argc, argv);
2101
remove_arg(num, argc, argv);
2109
double length_log_phys(double p)
2114
double length_phys_log(double p)
2120
double arrondi_echelle(double x)
2121
{ /* arrondi x a une valeur 1, 2, 5 pour echelle */
2124
static int corresp[] = {1,1,2,2,5,5,5,10,10,10,10,10};
2125
/* 0,1,2,3,4,5,6, 7, 8, 9,10,11 */
2128
l = x * pow(10., -n); /* 10. plutot que 10 necessaire pour alpha! */
2129
r = myrint(l); r = corresp[r];
2130
return r * pow(10., n); /* 10. plutot que 10 necessaire pour alpha! */
2134
void scale_window(double lxmin, double lxmax, double lymin, double lymax,
2135
double pxmin, double pxmax, double pymin, double pymax)
2136
/* to scale the plot window for logical coords l... in physical coords p... */
2138
tek_xmin=lxmin; tek_xmax=lxmax; tek_ymin=lymin; tek_ymax=lymax;
2139
tek_minx=pxmin; tek_maxx=pxmax; tek_miny=pymin; tek_maxy=pymax;
2140
tek_dx = (tek_maxx-tek_minx)/(tek_xmax-tek_xmin < 1e-4 ? 1e-4 : tek_xmax-tek_xmin);
2141
tek_dy = (tek_maxy-tek_miny)/(tek_ymax-tek_ymin);
2145
void ch_echelle(double lx, double ly, double *px, double *py)
2146
/* conversion coord logique lx,ly en coord physique px,py */
2148
*px = (lx-tek_xmin)*tek_dx + tek_minx;
2149
*py = (ly-tek_ymin)*tek_dy + tek_miny;
2153
void convert_mem_point(void)
2156
if(converted) return;
2157
for (i=0; i<=fd_nj_plot->totpoints; i++) {
2158
ch_echelle( (fd_nj_plot->points+i)->x, (fd_nj_plot->points+i)->y, &((fd_nj_plot->points+i)->x),
2159
&((fd_nj_plot->points+i)->y) );
2160
(fd_nj_plot->points+i)->x += fd_nj_plot->char_height / 6.;
2166
double calc_echelle(double larg)
2167
{ /* rend taille logique pour echelle optimale */
2168
double log_val, phys_val;
2170
log_val = length_phys_log(phys_val);
2171
log_val = arrondi_echelle(log_val);
2176
void draw_scale(void)
2179
double phys_w, y, xd, xf, lc;
2182
log_val = calc_echelle(physx);
2183
phys_w = myrint(length_log_phys(log_val));
2184
y = physy - 1.35 * fd_nj_plot->char_height;
2187
sprintf(ech_name, "%.1g", log_val);
2188
lc = calc_text_size(ech_name, NULL, NULL);
2192
dir_moveto(xd, y - fd_nj_plot->char_height/3.);
2193
dir_lineto(xd, y + fd_nj_plot->char_height/3.);
2194
dir_moveto(xf, y - fd_nj_plot->char_height/3.);
2195
dir_lineto(xf, y + fd_nj_plot->char_height/3.);
2197
dir_moveto( (xd + xf)/2 - lc/2,
2198
y + fd_nj_plot->char_height/6. );
2199
plotstring(ech_name);
2204
void scrollcallback(Nlm_BaR b, Nlm_SlatE g, Nlm_Int2 after, Nlm_Int2 before)
2206
fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(b) );
2207
tree_draw_proc(fd_nj_plot->tree_plot);
2211
void zoomcallback(Nlm_SwitcH s, Nlm_Int2 after, Nlm_Int2 before)
2216
fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(s) );
2217
if(after == 1) fd_nj_plot->zoomvalue = 1.;
2218
else if(after > before) fd_nj_plot->zoomvalue *= 1.4;
2219
else if(after < before) fd_nj_plot->zoomvalue /= 1.4;
2220
sprintf(aux, "%d%%", (int)(100. * fd_nj_plot->zoomvalue + 0.5) );
2221
Nlm_SetTitle(fd_nj_plot->zoomprompt, aux);
2222
Nlm_InvalObject(fd_nj_plot->zoomprompt);
2223
scrollnotu(fd_nj_plot->subtree_notu);
2224
hide = (after == 1);
2225
Nlm_SetPanelExtra(fd_nj_plot->tree_plot, &hide);
2226
tree_draw_proc(fd_nj_plot->tree_plot);
2230
void scrollnotu(int count)
2232
Nlm_BaR obj; int lines;
2235
obj = Nlm_GetSlateVScrollBar( (SlatE)fd_nj_plot->tree_plot );
2236
old = Nlm_GetBarValue(obj) / (float)Nlm_GetBarMax(obj);
2237
lines = (count + 1) * (1 - 1/fd_nj_plot->zoomvalue) + 0.5;
2238
if(lines < 3) lines = 3;
2239
Nlm_CorrectBarMax(obj, lines);
2240
Nlm_CorrectBarValue(obj, old * lines);
2241
Nlm_CorrectBarPage(obj, lines/fd_nj_plot->zoomvalue, lines/fd_nj_plot->zoomvalue);
2250
double factor, value, m = 1, v = 0, zoom = 1;
2253
/* size of the tree plot window */
2254
if( ! (file_plot || doing_print) ) {
2255
Nlm_RecT ob_rect; Nlm_BaR bar;
2256
Nlm_ObjectRect(fd_nj_plot->tree_plot, &ob_rect);
2257
bar = Nlm_GetSlateVScrollBar((Nlm_SlatE)fd_nj_plot->tree_plot);
2258
v = (double)Nlm_GetBarValue(bar);
2259
m = (double)Nlm_GetBarMax(bar);
2260
physx = ob_rect.right - ob_rect.left;
2261
physy = (ob_rect.bottom - ob_rect.top);
2262
zoom = fd_nj_plot->zoomvalue;
2267
for(num=0; num<=fd_nj_plot->notu; num++) {
2268
if(fd_nj_plot->profs[num] == 0) continue;
2269
if(fd_nj_plot->profs[num] <= 0) continue; /* new */
2270
value = (physx - fd_nj_plot->widnames[num] - 2 * fd_nj_plot->ascent) / fd_nj_plot->profs[num];
2271
if(value < factor) factor = value;
2274
physx_min = fd_nj_plot->ascent;
2275
physx_corr = maxx * factor + physx_min;
2276
if(physx_corr <= physx_min + 1) {
2277
physx_corr = physx_min + 1;
2279
physy_corr = physy - 2*fd_nj_plot->char_height;
2280
physy_min = fd_nj_plot->char_height;
2282
physy_corr = physy - 3;
2285
/* scale_window(0, maxx, 0, maxy,
2286
physx_min, physx_corr, physy_min, physy_corr); */
2287
scale_window(0, maxx,
2288
((m-v)/m) * (maxy - maxy/zoom),
2289
((m-v)/m) * (maxy - maxy/zoom) + maxy/zoom,
2290
physx_min, physx_corr, physy_min, physy_corr);
2292
for(num=0; num<=fd_nj_plot->totnoms; num++) {
2293
mydrawstring( (fd_nj_plot->noms+num)->x, (fd_nj_plot->noms+num)->y , (fd_nj_plot->noms+num)->nom,
2294
(fd_nj_plot->noms+num)->disp_option );
2296
for(num=0; num<=fd_nj_plot->tottraits; num++) {
2297
p= fd_nj_plot->traits+num;
2298
moveto(p->xd,p->yd);
2299
lineto(p->xf,p->yf);
2302
if(fd_nj_plot->has_br_length){
2306
convert_mem_point();
2307
} /* end of do_plot */
2311
int calc_text_size(char *text, int *pheight, int *pascent)
2313
int ascent, descent, width;
2317
font_size = list_font_size[fd_nj_plot->font_size_rank];
2320
static FontInfo macfontinfo;
2321
width = TextWidth(text, 0, strlen(text));
2322
GetFontInfo(&macfontinfo);
2323
ascent = macfontinfo.ascent;
2324
descent = macfontinfo.descent;
2327
width = strlen(text);
2328
ascent = 1; descent = 0;
2329
#elif defined(NO_GUI)
2330
width = strlen(text) * font_size * postscript_ratio + 0.5;
2331
ascent = font_size; descent = 0;
2335
if(pdf_plot && pdf != NULL) width = PDF_stringwidth(pdf, text, pdf_font, font_size);
2337
#endif /* faire calculer taille en mode ecran et appliquer ratio ecran->postscript */
2338
width = Nlm_TextWidth(text, strlen(text) ) * postscript_ratio + 0.5;
2339
ascent = font_size; descent = 0;
2345
HDC picHDC = Nlm_currentHDC;
2347
Nlm_currentHDC = Nlm_GetPicWinHDC();
2348
Nlm_SelectFont(fd_nj_plot->current_font);
2351
ascent = Nlm_Ascent(); descent = Nlm_Descent();
2352
width = Nlm_TextWidth(text, strlen(text) );
2354
if(doing_copy) Nlm_currentHDC = picHDC;
2358
if(pheight != NULL) *pheight = ascent + descent;
2359
if(pascent != NULL) *pascent = ascent;
2364
static int lastmovex, lastmovey;
2365
#define bound_int2(i) ( i > INT2_MAX ? INT2_MAX : (i < INT2_MIN ? INT2_MIN : i) )
2367
void plotstring(char *nom)
2371
static char copy[255];
2375
memcpy(copy + 1, nom, l + 1);
2376
DrawString( (ConstStr255Param) copy);
2378
memcpy(tty_page[tty_y]+tty_x+1, nom, strlen(nom));
2383
PDF_show_xy(pdf, nom, lastmovex, lastmovey);
2387
fprintf(plotfile,"(%s) show\n",nom);
2393
int y; y = lastmovey - (doing_copy ? fd_nj_plot->ascent : 0) ;
2395
Nlm_PaintStringEx(nom, lastmovex, y );
2397
Nlm_PaintString(nom);
2404
void dir_moveto(double x,double y)
2405
/* move to physical coord x,y */
2412
yi = physy - y + margin;
2415
tty_x = x + 0.5; tty_y = y + 0.5;
2420
PDF_moveto(pdf, xi, yi);
2421
lastmovex = xi; lastmovey = yi;
2425
fprintf(plotfile,"%d %d moveto\n",xi,yi);
2431
lastmovex = myrint(x) + print_rect.left;
2432
lastmovey = print_rect.bottom - myrint(y);
2433
Nlm_MoveTo(lastmovex, bound_int2(lastmovey) );
2437
ObjectRect(fd_nj_plot->tree_plot, &obrect);
2438
lastmovex = myrint(x) + obrect.left;
2439
lastmovey = obrect.bottom - myrint(y);
2440
if(lastmovey >= INT2_MAX)
2441
lastmovey = INT2_MAX - 1;
2442
else if(lastmovey < 0)
2444
Nlm_MoveTo((Nlm_Int2)lastmovex, (Nlm_Int2)lastmovey );
2451
void dir_lineto(double x,double y)
2452
/* draw line from current pos to physical coord x,y */
2460
yi = physy - y + margin;
2463
if(tty_y == (int)(y + 0.5)) {
2465
while(tty_x != xi) {
2466
p = tty_page[tty_y] + tty_x;
2467
*p = (*p == '|' ? '+' : '-');
2468
if(tty_x < xi) ++tty_x; else --tty_x;
2470
p = tty_page[tty_y] + tty_x;
2471
*p = (*p == '|' ? '+' : '-');
2475
while(tty_y != yi) {
2476
p = tty_page[tty_y] + tty_x;
2477
*p = (*p == '-' ? '+' : '|');
2478
if(tty_y < yi) ++tty_y; else --tty_y;
2480
p = tty_page[tty_y] + tty_x;
2481
*p = (*p == '-' ? '+' : '|');
2487
PDF_lineto(pdf, xi, yi);
2492
fprintf(plotfile,"%d %d lineto stroke\n",xi,yi);
2498
xi = myrint(x) + print_rect.left; yi = print_rect.bottom - myrint(y) ;
2499
yi = bound_int2(yi);
2500
Nlm_LineTo( xi, yi );
2504
ObjectRect(fd_nj_plot->tree_plot, &obrect);
2506
j = obrect.bottom - myrint(y);
2511
Nlm_LineTo(myrint(x) + obrect.left, (Nlm_Int2)j);
2522
static void closewinproc(Nlm_WindoW w)
2524
Nlm_Remove(Nlm_ParentWindow(w));
2527
void show_apropos_njplot(Nlm_IteM item)
2529
Nlm_WindoW win; int larg; Nlm_DoC doc;
2530
char ligne[100], *p;
2531
static char txt[5000];
2533
if(help_file == NULL) return;
2534
win = Nlm_FixedWindow( -50, -33, -3, -3, "about Njplot", closewinproc);
2535
Nlm_SelectFont(Nlm_programFont);
2536
larg = 81 * Nlm_TextWidth("Q", 1);
2537
doc = Nlm_DocumentPanel(win, larg, 25 * Nlm_LineHeight() );
2539
fgets(ligne, sizeof(ligne), help_file);
2541
while(fgets(ligne, sizeof(ligne), help_file) != NULL) {
2542
if(strncmp(ligne, ">>>", 3) == 0) break;
2543
if(strncmp(ligne, "Version:", 8) == 0) sprintf(ligne, "Version: %s\n", NJPLOTVERSION);
2544
strcpy(p, ligne); p += strlen(ligne);
2546
Nlm_AppendText(doc, txt, NULL, NULL, Nlm_programFont);
2548
Nlm_DefaultButton(win, "ok", (Nlm_BtnActnProc)closewinproc);
2554
void mac_timer(void)
2556
static FD_nj_plot *current, *previous = NULL;
2557
current = (FD_nj_plot *)Nlm_GetWindowExtra(Nlm_FrontWindow());
2558
if(current != previous && current != NULL && current->tag == tag_njplot ) {
2560
Nlm_SetValue(current->choix_taille, current->font_size_rank);
2561
Nlm_SetValue(current->choix_font, current->font_family_rank);
2562
Nlm_SetStatus(current->bold_item, strchr(current->font_bold_italic, 'b') != NULL);
2563
Nlm_SetStatus(current->italic_item, strchr(current->font_bold_italic, 'i') != NULL);
2568
void window_callback(IteM item)
2570
Nlm_WindoW w = Nlm_desktopWindow;
2572
FD_nj_plot *data = Nlm_GetWindowExtra(w);
2573
if(data != NULL && data->tag == tag_njplot && data->win_menu_item == item) {
2575
Nlm_Select(fd_nj_plot->nj_plot);
2583
void create_win_if_needed(char *fname)
2585
if( (!update_tree_w_data(NULL)) || fd_nj_plot->notu != 0) fd_nj_plot = create_win_nj_plot();
2586
init_tree( fname, NULL);
2587
Nlm_Show(fd_nj_plot->nj_plot);
2588
Nlm_ObjectRect(fd_nj_plot->nj_plot, &(fd_nj_plot->old_rect));
2595
Gestalt (gestaltSystemVersion, &val);
2596
return (val >= 0x1000);
2600
int crefpict(char *fname, PicHandle picture)
2605
myqdpict = MyPictToQDPict(picture);
2606
if(myqdpict != NULL) err = MyQDPictToPDFfile(myqdpict, fname);
2608
KillPicture(picture);
2613
void example_tree(IteM unused)
2617
if(!update_tree_w_data(NULL)) return;
2618
if(fd_nj_plot->notu > 0) free_tree();
2619
fd_nj_plot->notu = 0;
2620
p = MG_GetBundleResourcesDir();
2621
strcat(p, "/example.phb");
2624
err_message("Sorry, no example available");
2632
void copy_plot(IteM unused)
2634
extern void MyCopyPictToClipboard (PicHandle mypicture);
2636
if(!update_tree_w_data(NULL)) return;
2637
if(fd_nj_plot->notu == 0) return;
2641
MyCopyPictToClipboard (mypicture );
2643
KillPicture(mypicture);
2645
fd_nj_plot->need_runtree = TRUE;
2651
void pict_plot(void)
2654
double currx, curry;
2657
Style mystyle=normal;
2661
myrect.bottom=760 * page_count;
2664
mypicture = OpenPicture(&myrect);
2666
macfont = GetValue(fd_nj_plot->choix_font);
2667
if(macfont == courier)
2669
else if(macfont == helvetica)
2671
else if(macfont == times)
2676
TextSize( list_font_size[fd_nj_plot->font_size_rank] );
2677
if( GetStatus(fd_nj_plot->bold_item) )
2679
if( GetStatus(fd_nj_plot->italic_item) )
2682
physx = myrect.right-myrect.left - 2 * margin;
2683
physy = myrect.bottom-myrect.top - 2 * margin;
2687
fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1;
2688
end_br_length = fd_nj_plot->br_length_txt;
2691
nexty = -fd_nj_plot->deltay;
2692
if(fd_nj_plot->subtree_center == NULL)
2693
mem_plot(NULL, fd_nj_plot->racine, currx, &curry);
2695
mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry);
2697
file_plot = FALSE; /* pour eviter boucle infernale! */
2699
if(doing_copy) return;
2700
erreur = crefpict(plotfilename, mypicture);
2701
if( !erreur ) sprintf(mess, "Tree plot is now in file %s in PDF format",
2702
extract_filename(plotfilename) );
2703
else sprintf(mess, "Error while writing to file %s",
2704
extract_filename(plotfilename) );
2707
fd_nj_plot->need_runtree = TRUE;
2717
#define TITLEFONT "Times New Roman,10"
2719
#define TITLEFONT "Times,10"
2722
void print_title(int x, int y, char *text,
2723
Nlm_FonT title_font, int p, int totp)
2725
static char ligne[200];
2731
text = mac_fname_to_roman(text);
2733
sprintf(ligne, "njplot %s %s", text, ctime(&heure) );
2734
h = strlen(ligne) - 1; ligne[h] = 0;
2735
if(totp > 1) sprintf(ligne + h, " Page %d of %d", p, totp);
2737
Nlm_SelectFont(title_font);
2738
Nlm_PaintStringEx(ligne, x, y);
2742
void print_plot(IteM item)
2744
double currx, curry;
2746
int h, page, superpos;
2747
Nlm_RecT true_print_rect, title_rect;
2748
Nlm_FonT title_font;
2750
if(!update_tree_w_data(item)) return;
2751
if(fd_nj_plot->notu == 0) return;
2752
w = Nlm_StartPrinting();
2753
if(w == NULL) return;
2756
Nlm_PrintingRect(&true_print_rect);
2757
title_rect = true_print_rect;
2758
title_font = Nlm_ParseFont(TITLEFONT);
2759
Nlm_SelectFont(title_font);
2760
calc_text_size("Mq", &fd_nj_plot->char_height, &fd_nj_plot->ascent);
2761
title_rect.bottom = title_rect.top + fd_nj_plot->ascent - 1;
2762
true_print_rect.top += fd_nj_plot->char_height;
2764
print_rect.left = true_print_rect.left; print_rect.right = true_print_rect.right;
2765
print_rect.top = true_print_rect.top; print_rect.bottom = true_print_rect.bottom;
2766
h = print_rect.bottom - print_rect.top + 1;
2768
print_rect.bottom = print_rect.top + (page_count - 1) * (h - superpos) + h - 1;
2770
fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1;
2771
end_br_length = fd_nj_plot->br_length_txt;
2774
nexty = -fd_nj_plot->deltay;
2775
if(fd_nj_plot->subtree_center == NULL)
2776
mem_plot(NULL, fd_nj_plot->racine, currx, &curry);
2778
mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry);
2780
for(page = 0; page < page_count; page++) {
2782
Nlm_ClipPrintingRect( &title_rect);
2783
print_title(title_rect.left, title_rect.bottom, fd_nj_plot->tree_name,
2784
title_font, page + 1, page_count);
2785
Nlm_ClipPrintingRect( &true_print_rect);
2786
Nlm_SelectFont(fd_nj_plot->current_font);
2788
Nlm_FrameRect(&true_print_rect);
2790
physx = print_rect.right - print_rect.left;
2791
physy = print_rect.bottom - print_rect.top;
2794
print_rect.top -= (h - superpos); print_rect.bottom -= (h - superpos);
2797
fd_nj_plot->need_runtree = TRUE;
2798
doing_print = FALSE;
2806
void copy_plot(IteM item)
2808
double currx, curry;
2812
if(!update_tree_w_data(item)) return;
2813
if(fd_nj_plot->notu == 0) return;
2814
/* dans la picture, les calculs de taille de caractere ne marchent pas!
2815
il faut les faire dans le DC de la fenetre
2819
Nlm_GetPosition( fd_nj_plot->tree_plot , &r);
2820
w = Nlm_StartPicture(&r);
2821
fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1;
2822
end_br_length = fd_nj_plot->br_length_txt;
2825
nexty = -fd_nj_plot->deltay;
2827
Nlm_SelectFont(fd_nj_plot->current_font);
2828
if(fd_nj_plot->subtree_center == NULL)
2829
mem_plot(NULL, fd_nj_plot->racine, currx, &curry);
2831
mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry);
2834
fd_nj_plot->need_runtree = TRUE;
2841
char *preptree(char *fname)
2843
int i, c, steparbre, maxarbre, maxlname, v;
2845
char *arbre, *der_arbre, *finarbre, *tmp;
2846
static char message[200];
2847
char *last_bootstrap, *p;
2849
if( (njfile=fopen(fname,"r")) == NULL ){
2850
sprintf(message, "Tree file %s not found.", fname);
2853
/* recherche du debut de la description de l'arbre */
2855
while ( isspace(c) );
2856
/* for fastDNAml format, skip initial [comment] */
2858
do c=fgetc(njfile); while (c != ']');
2859
do c=fgetc(njfile); while ( isspace(c) );
2865
/* lecture de l'arbre par paquets de steparbre caracteres*/
2868
arbre=check_alloc(maxarbre,1);
2869
der_arbre = arbre+maxarbre;
2871
fd_nj_plot->notu=2; i=3; v = 0;
2873
while( (c=fgetc(njfile)) != EOF && c != ';') {
2874
if( c=='\n' || c=='\r') continue;
2875
if(++finarbre >= der_arbre-2) {
2876
maxarbre += steparbre;
2877
tmp=check_alloc(maxarbre,1);
2878
memcpy(tmp,arbre,finarbre-arbre);
2879
finarbre=tmp+(finarbre-arbre);
2882
der_arbre=arbre+maxarbre;
2885
if(c == ')') fd_nj_plot->notu++;
2891
if(i != fd_nj_plot->notu)goto erreur;
2892
finarbre = nextpar(arbre) + 1;
2893
/* memorize bootstrap value after last ) */
2894
while(isspace(*finarbre)) finarbre++;
2895
if(*finarbre != ';' && *finarbre != 0) {
2896
last_bootstrap = strdup(finarbre);
2897
p = strchr(last_bootstrap, ';');
2898
if(p != NULL) *p = 0;
2900
else last_bootstrap = NULL;
2902
arbre = (char *)realloc(arbre, strlen(arbre) + 4 * v + 5 ); /* worst case add 4 chars for each , */
2903
make_binary_or_unrooted(arbre);
2904
fd_nj_plot->long_arbre_parenth = strlen(arbre);
2905
fd_nj_plot->notu = v ; /* after this fd_nj_plot->notu = number of OTUs - 1 */
2906
fd_nj_plot->totbranches= -1;
2907
/* allocate all memory */
2908
fd_nj_plot->tabtax = (struct noeud **)check_alloc(2*fd_nj_plot->notu +1,sizeof(struct noeud *));
2909
fd_nj_plot->branches = (branche *)check_alloc(fd_nj_plot->notu, sizeof(branche));
2910
fd_nj_plot->tabnames = (char **)check_alloc(2*fd_nj_plot->notu+1, sizeof(char *));
2911
for(i=0; i<2*fd_nj_plot->notu+1; i++) *(fd_nj_plot->tabtax+i)=
2912
(struct noeud *)check_alloc(1,s_noeud);
2913
fd_nj_plot->noms = (struct nom *)check_alloc(5*fd_nj_plot->notu+1,sizeof(struct nom));
2914
fd_nj_plot->points = (struct mon_point *)check_alloc(4*fd_nj_plot->notu+1,sizeof(struct mon_point));
2915
fd_nj_plot->traits = (struct trait *)check_alloc(3*fd_nj_plot->notu,sizeof(struct trait));
2916
fd_nj_plot->labels = (char **)check_alloc(fd_nj_plot->notu+1, sizeof(char *));
2917
fd_nj_plot->widnames = (int *)check_alloc(fd_nj_plot->notu+1, sizeof(int));
2918
fd_nj_plot->profs = (double *)check_alloc(fd_nj_plot->notu+1, sizeof(double));
2919
fd_nj_plot->br_length_txt = (char *)check_alloc(2*fd_nj_plot->notu,10);
2920
loadphylip(arbre, last_bootstrap);
2922
maxlname = 0; /* largeur max des noms des feuilles */
2924
if(nextotu != fd_nj_plot->notu) bad_format("Error: incorrect tree file");
2927
if(tty_prefix != NULL) {
2930
lp = strlen(tty_prefix);
2931
for(i=0; i <= fd_nj_plot->notu; i++) {
2932
l = strlen(fd_nj_plot->labels[i]) + lp;
2933
p = (char *)check_alloc(l + 1, 1);
2934
strcpy(p, tty_prefix);
2935
strcat(p, fd_nj_plot->labels[i]);
2936
free(fd_nj_plot->labels[i]);
2937
fd_nj_plot->labels[i] = p;
2942
for(i = 0; i <= nextotu; i++) {
2943
c = strlen(fd_nj_plot->labels[i]);
2944
if(c > maxlname) maxlname = c;
2946
for(i = 0; i < 2*fd_nj_plot->notu+1; i++) {
2947
fd_nj_plot->tabnames[i] = (char *)check_alloc(maxlname + 2 + 1, 1); /*2=place pour # */
2950
if(!fd_nj_plot->rooted) {
2951
fd_nj_plot->racine = *(fd_nj_plot->tabtax+(++num_noeud));
2952
if(num_noeud >= 2*fd_nj_plot->notu + 1) bad_format("Error: incorrect tree file");
2953
if(fd_nj_plot->has_br_length) {
2954
place_midpoint_root();
2955
fd_nj_plot->root_num = -1;
2958
/* ancienne version: derniere espece est groupe externe
2960
fd_nj_plot->racine->v3 = NULL;
2961
fd_nj_plot->root_num = fd_nj_plot->notu;
2965
fd_nj_plot->racine = *(fd_nj_plot->tabtax+num_noeud);
2966
fd_nj_plot->root_br_l= fd_nj_plot->racine->l1 + fd_nj_plot->racine->l2;
2967
fd_nj_plot->root_num = num_noeud;
2968
if(!fd_nj_plot->has_br_length) calc_brl_for_lengthless(fd_nj_plot->racine, NULL);
2969
/* y a-t-il un bootstrap sur l'une des branches racine ? */
2970
i = get_br_from_bouts(fd_nj_plot->racine, fd_nj_plot->racine->v1);
2971
if(i == -1) i = get_br_from_bouts(fd_nj_plot->racine, fd_nj_plot->racine->v2);
2972
if(i != -1 && get_br_from_bouts(fd_nj_plot->racine, NULL) == -1) {
2973
fd_nj_plot->branches[i].bouta = fd_nj_plot->racine->v1;
2974
fd_nj_plot->branches[i].boutb = fd_nj_plot->racine->v2;
2977
if(fd_nj_plot->notu+1<3) return ("Tree should contain at least 3 elements.");
2978
fd_nj_plot->subtree_notu = fd_nj_plot->notu;
2980
if(!pdf_plot_only) scrollnotu(fd_nj_plot->notu);
2986
return ("File or pasted data does not contain correct tree.");
2988
return ("File does not contain correct tree data.");
2990
} /* end of preptree */
2993
char *check_alloc(int nbrelt, int sizelt)
2996
if( (retval=(char *)calloc(nbrelt,sizelt)) != NULL ) return retval;
2997
err_message("ERROR: Not enough memory.");
3002
void loadphylip(char *arbre, char *last_bootstrap)
3004
char *deba,*debb,*debc, *finarbre;
3005
struct noeud *p1, *p2, *p3, *p;
3006
branche *int_br_g, *int_br_d;
3008
fd_nj_plot->has_br_length = 2;
3009
fd_nj_plot->has_internal = FALSE;
3010
/* ignore all stuff after last closing parenthesis
3011
(needed for fastDNAml output)
3013
finarbre= nextpar(arbre);
3014
fd_nj_plot->rooted=0;
3017
while(*debb != ',') {
3018
if(*debb == 0) bad_format("Incorrect tree file");
3019
if(*debb == '(')debb=nextpar(debb);
3024
while(*debc != ',' && debc<finarbre) {
3025
if(*debc == '(')debc=nextpar(debc);
3029
/* the tree is unrooted <==> it has 3 subtrees at its bottommost level */
3033
/* the tree is rooted */
3035
fd_nj_plot->rooted=1;
3037
fd_nj_plot->notu--; //useless now
3041
num_noeud=fd_nj_plot->notu;
3043
p1=unrootedset(deba,debb-2,&int_br_g);
3044
p2=unrootedset(debb,debc-2,&int_br_d);
3045
p = *(fd_nj_plot->tabtax+(++num_noeud));
3046
if(num_noeud >= 2*fd_nj_plot->notu + 1) bad_format("Error: incorrect tree file");
3047
p->v1=p1; p1->v3=p; p->l1=p1->l3;
3048
if(int_br_g!=NULL) { int_br_g->bouta=p; int_br_g->boutb=p1; }
3049
p->v2=p2; p2->v3=p; p->l2=p2->l3;
3050
if(int_br_d!=NULL) { int_br_d->bouta=p; int_br_d->boutb=p2; }
3051
if(!fd_nj_plot->rooted) {
3052
p3=unrootedset(debc,finarbre-1,&int_br_g);
3053
if(int_br_g!=NULL) { int_br_g->bouta=p; int_br_g->boutb=p3; }
3054
p->v3=p3; p3->v3=p; p->l3=p3->l3;
3058
/* recherche d'un dernier label interne */
3060
while(*debc!=0 && *debc!=':' && *debc!='[') debc++;
3061
if(debc-finarbre>1) {
3062
int l=debc-finarbre-1;
3063
fd_nj_plot->has_internal = TRUE;
3064
fd_nj_plot->totbranches++;
3065
fd_nj_plot->branches[fd_nj_plot->totbranches].br_label=check_alloc(l+1,1);
3066
memcpy(fd_nj_plot->branches[fd_nj_plot->totbranches].br_label,finarbre+1,l);
3067
fd_nj_plot->branches[fd_nj_plot->totbranches].br_label[l]=0;
3068
fd_nj_plot->branches[fd_nj_plot->totbranches].bouta=p1;
3069
fd_nj_plot->branches[fd_nj_plot->totbranches].boutb=p2;
3072
if(fd_nj_plot->rooted && last_bootstrap != NULL) {
3073
/* attach last_bootstrap to branch racine <--> NULL */
3074
fd_nj_plot->totbranches++;
3075
fd_nj_plot->branches[fd_nj_plot->totbranches].br_label = strdup(last_bootstrap);
3076
fd_nj_plot->branches[fd_nj_plot->totbranches].bouta=p;
3077
fd_nj_plot->branches[fd_nj_plot->totbranches].boutb=NULL;
3079
if(last_bootstrap != NULL) free(last_bootstrap);
3083
struct noeud *unrootedset(char *deb, char *fin, branche **p_int_br)
3085
struct noeud *p, *pp;
3089
static double brlength;
3092
while(*deb==' ')deb++;
3093
while(*fin==' ')fin--;
3094
if(*deb != '(') { /* une feuille */
3095
virg = strchr(deb, ':');
3096
if(virg != NULL && virg < fin) {
3097
// if(fd_nj_plot->has_br_length == 0) goto problem;
3098
sscanf(virg+1, "%le", &brlength);
3099
fd_nj_plot->has_br_length=1;
3102
// if(fd_nj_plot->has_br_length == 1) goto problem;
3104
fd_nj_plot->has_br_length=0;
3108
while(*deb==' ' || *deb=='\'')deb++;
3109
if( virg-1 >= deb && *virg == '\'' ) virg--;
3111
fd_nj_plot->labels[ ++nextotu] = (char *)check_alloc(l + 1, 1);
3112
memcpy(fd_nj_plot->labels[nextotu], deb, l);
3113
fd_nj_plot->labels[nextotu][l] = 0;
3115
if(strchr(fd_nj_plot->labels[nextotu], '(') != NULL || strchr(fd_nj_plot->labels[nextotu], ')') != NULL) {
3116
char *tmp = (char *)malloc(strlen(fd_nj_plot->labels[nextotu]) + 60);
3117
sprintf(tmp, "Error: parentheses in name: %s", fd_nj_plot->labels[nextotu]);
3121
p = *(fd_nj_plot->tabtax + nextotu);
3123
p->v1 = p->v2 = p->v3 = NULL;
3128
if(num_noeud >= 2*fd_nj_plot->notu + 1) bad_format("Error: incorrect tree file");
3129
p = *(fd_nj_plot->tabtax + num_noeud);
3130
ferme = nextpar(deb);
3132
while(*virg != ',' && virg < fin) {
3133
if(*virg == '(') virg=nextpar(virg);
3136
if(virg>=ferme) bad_format("Error: incorrect tree file");
3137
pp = unrootedset(deb + 1, virg - 1, &int_br);
3138
p->v1 = pp; pp->v3 = p; p->l1 = pp->l3;
3139
if(int_br != NULL) { int_br->bouta = p; int_br->boutb = pp; }
3140
pp = unrootedset(virg + 1, ferme - 1, &int_br);
3141
p->v2 = pp; pp->v3 = p; p->l2 = pp->l3;
3142
if(int_br != NULL) { int_br->bouta = p; int_br->boutb = pp; }
3143
virg = strchr(ferme, ':');
3144
if(virg != NULL && virg < fin) { /* traitement longueur */
3145
// if(fd_nj_plot->has_br_length == 0) goto problem;
3146
sscanf(virg+1, "%le", &brlength);
3147
fd_nj_plot->has_br_length=1;
3148
if(*fin == ']') { /* bootstrap entre [] apres longueurs */
3151
while(q > virg && *q != '[') q--;
3152
if(*q == '[' && fin - q >= 2) {
3153
fd_nj_plot->has_internal = TRUE;
3154
fd_nj_plot->totbranches++;
3156
fd_nj_plot->branches[fd_nj_plot->totbranches].br_label =
3158
memcpy(fd_nj_plot->branches[fd_nj_plot->totbranches].br_label,q+1,l);
3159
fd_nj_plot->branches[fd_nj_plot->totbranches].br_label[l]=0;
3160
*p_int_br= &fd_nj_plot->branches[fd_nj_plot->totbranches];
3165
// if(fd_nj_plot->has_br_length == 1) goto problem;
3167
fd_nj_plot->has_br_length=0;
3170
/* recherche bootstrap (internal label) */
3173
fd_nj_plot->has_internal = TRUE;
3174
fd_nj_plot->totbranches++;
3175
fd_nj_plot->branches[fd_nj_plot->totbranches].br_label=
3177
memcpy(fd_nj_plot->branches[fd_nj_plot->totbranches].br_label,ferme+1,l);
3178
fd_nj_plot->branches[fd_nj_plot->totbranches].br_label[l]=0;
3179
*p_int_br= &fd_nj_plot->branches[fd_nj_plot->totbranches];
3185
err_message("Error: Inconsistent tree file for branch lengths.");
3190
char *nextpar(char *pospar)
3194
while(*pos != ')') {
3195
if(*pos == 0) bad_format("Error: unbalanced parentheses");
3196
if(*pos == '(') pos=nextpar(pos);
3203
void bad_format(char *mess)
3211
void make_binary_or_unrooted(char *arbre)
3213
char *finarbre, *deba, *debb, *debc;
3215
finarbre= nextpar(arbre);
3216
*(finarbre + 1) = 0;
3219
while(*debb != ',') {
3220
if(*debb == 0) bad_format("Incorrect tree file");
3221
if(*debb == '(')debb=nextpar(debb);
3226
while(*debc != ',' && debc<finarbre) {
3227
if(*debc == '(')debc=nextpar(debc);
3231
/* the tree is unrooted <==> it has 3 subtrees or more at its bottommost level */
3232
make_binary(arbre , debb, finarbre - 1, TRUE);
3233
make_binary(arbre , deba, debb - 2, TRUE);
3235
else make_binary(arbre , deba, finarbre - 1, TRUE);
3240
int make_binary(char *arbre, char *debut, char *fin, int go_down)
3242
int virg, l, retval;
3245
p = debut; virg = 0; retval = 0;
3247
if(*p == ',') virg++;
3248
else if(*p == '(') {
3251
l = make_binary(arbre, p+1, q-1, TRUE);
3260
if(virg > 1) { /* multifurcation */
3261
/* recherche de la 2eme virgule */
3268
else if(*p == '(') {
3274
memmove(p + 4, p, l + 1);
3275
memmove(debut + 1, debut, p - debut);
3277
memcpy(p + 1, "):0", 3);
3280
if(virg > 2) retval += make_binary(arbre, debut, fin, FALSE);
3286
void mydrawstring(double x, double y, char *nom, char option)
3288
static double px,py;
3290
ch_echelle(x,y,&px,&py);
3293
/* ecrire une chaine en la montant d'un chouia */
3294
py += fd_nj_plot->char_height/6.;
3296
else if(option == 'c' || option == 'r') {
3297
/* ecrire une chaine en la centrant vert. sur cette position*/
3298
py -= fd_nj_plot->char_height/3.;
3299
px += fd_nj_plot->char_height/6.;
3301
else if(option == 't') {
3302
py -= (5./6.) * fd_nj_plot->char_height;
3304
else if(option == 'b') {
3305
py += fd_nj_plot->char_height/6.;
3321
void moveto(double x,double y)
3322
/* move from current pos to logical coord x,y */
3324
static double px,py;
3325
ch_echelle(x,y,&px,&py);
3330
void lineto(double x,double y)
3331
/* draw line from current pos to logical coord x,y */
3333
static double px,py;
3334
ch_echelle(x,y,&px,&py);
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.
3344
int n1 = 0, n2, depth;
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;
3352
centre->l3 = centre->l1;
3355
else if(centre->v2 == pere) {
3356
centre->v2 = centre->v3;
3359
centre->l3 = centre->l2;
3362
n1 = calc_brl_for_lengthless(centre->v1, centre);
3363
n2 = calc_brl_for_lengthless(centre->v2, centre);
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;
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;
3377
else if(depth - n2 > 0) add_value_downstream(centre->v2, depth - n2);
3381
void add_value_downstream(struct noeud *centre, int value)
3383
if(centre->l1 != 0) {
3384
centre->l1 += value;
3385
centre->v1->l3 = centre->l1;
3387
else add_value_downstream(centre->v1, value);
3388
if(centre->l2 != 0) {
3389
centre->l2 += value;
3390
centre->v2->l3 = centre->l1;
3392
else add_value_downstream(centre->v2, value);
3396
void place_midpoint_root(void)
3397
/* enraciner l'arbre sans racine en cherchant son centre
3403
current_best_diff = VERY_BIG;
3404
if(outotu != NULL) {
3406
for(i=0; i <= fd_nj_plot->notu; i++) {
3407
if(fd_nj_plot->labels[i] != NULL && strcmp(fd_nj_plot->labels[i], outotu) == 0) break;
3409
if(i > fd_nj_plot->notu) {
3410
fprintf(stderr, "Error: outotu %s not found in tree\n", outotu);
3413
process_branche(fd_nj_plot->tabtax[i], fd_nj_plot->tabtax[i]->v3, fd_nj_plot->tabtax[i]->l3);
3416
current_cote1=current_cote2=NULL;
3417
parcourir_branches(*fd_nj_plot->tabtax, NULL);
3419
fd_nj_plot->rooted = TRUE;
3420
fd_nj_plot->root_br_l = current_br_length;
3421
/* il faut toujours que la racine soit telle que racine->v1->v3=racine */
3422
if (current_cote1->v1 == current_cote2 ) {
3423
/* echanger les voisins v1 et v3 de cote1 */
3424
aux=current_cote1->v1;
3425
current_cote1->v1=current_cote1->v3;
3426
current_cote1->v3=aux;
3427
laux=current_cote1->l1;
3428
current_cote1->l1=current_cote1->l3;
3429
current_cote1->l3=laux;
3431
else if (current_cote1->v2 == current_cote2) {
3432
/* echanger les voisins v2 et v3 de cote1 */
3433
aux=current_cote1->v2;
3434
current_cote1->v2=current_cote1->v3;
3435
current_cote1->v3=aux;
3436
laux=current_cote1->l2;
3437
current_cote1->l2=current_cote1->l3;
3438
current_cote1->l3=laux;
3440
current_cote1->v3 = fd_nj_plot->racine;
3442
if (current_cote2->v1 == current_cote1 )
3443
current_cote2->v1 = fd_nj_plot->racine;
3444
else if (current_cote2->v2 == current_cote1)
3445
current_cote2->v2 = fd_nj_plot->racine;
3447
current_cote2->v3 = fd_nj_plot->racine;
3448
fd_nj_plot->racine->v1=current_cote1;
3449
fd_nj_plot->racine->v2=current_cote2;
3450
fd_nj_plot->racine->v3=NULL;
3451
fd_nj_plot->racine->l3=0;
3452
/* avoid very unbalanced division of root branch */
3453
if(current_balance > MAX_FRAC) current_balance = MAX_FRAC;
3454
else if(current_balance < 1 - MAX_FRAC) current_balance = 1 - MAX_FRAC;
3455
fd_nj_plot->racine->l1 = current_br_length * current_balance;
3456
fd_nj_plot->racine->l2 = current_br_length - fd_nj_plot->racine->l1;
3460
void parcourir_branches(struct noeud *centre, struct noeud *origine)
3461
/* parcourir recursivement toutes les branches de l'arbre sans racine
3462
a partir de centre et dans la direction opposee a son voisin origine
3465
if(centre==NULL) return;
3466
if(centre->v1!=origine) {
3467
process_branche(centre,centre->v1,centre->l1);
3468
parcourir_branches(centre->v1,centre);
3470
if(centre->v2!=origine) {
3471
process_branche(centre,centre->v2,centre->l2);
3472
parcourir_branches(centre->v2,centre);
3474
if(centre->v3!=origine) {
3475
process_branche(centre,centre->v3,centre->l3);
3476
parcourir_branches(centre->v3,centre);
3481
void process_branche(struct noeud *cote1, struct noeud *cote2, double length)
3482
/* calculer la variance des distances racine - feuilles si racine est sur branche cote1 - cote2
3483
et memoriser la meilleure branche dans les variables globales
3486
double x ; /* partage de branche par facteur x */
3488
double A, B, C; /* variance(x) = A x x + B x + C */
3489
double mini_val; /* meilleure variance pour toutes valeurs de x entre 0 et 1 */
3491
if(cote1 == NULL || cote2 == NULL) return;
3492
if( length < 0 ) length = 0;
3494
m1 = stat_from_node(cote2, cote1);
3495
m2 = stat_from_node(cote1, cote2);
3496
A = 4 * m1.N * ( m2.N * length ) * length;
3497
B = 4 * length * ( m2.N * m1.somme - m1.N * m2.somme - length * m1.N * m2.N);
3498
C = (m1.N + m2.N) * (m1.carres + m2.carres) + m1.N * length * m2.N * length +
3499
2 * m1.N * length * m2.somme - 2 * m2.N * length * m1.somme -
3500
(m1. somme + m2.somme) * (m1. somme + m2.somme);
3503
mini_val = VERY_BIG * 0.99 ;
3507
mini_val = C - (B * B) / 4 / A;
3510
x = 0; mini_val = C;
3513
x = 1; mini_val = A + B + C;
3516
if(mini_val < current_best_diff ) {
3517
current_best_diff = mini_val;
3518
current_cote1 = cote1;
3519
current_cote2 = cote2;
3520
current_br_length = length;
3521
current_balance = x;
3526
/* no longer useful */
3527
double get_length_down(struct noeud *pere, struct noeud *racine)
3528
/* compute the average length of the tree down a node */
3530
if(racine == NULL) return 0.0;
3532
struct noeud *gauche, *droite;
3534
if( racine->v1 == pere ) {
3535
gauche =racine->v2; droite = racine->v3;
3536
bg = (racine->l2); bd = (racine->l3);
3538
else if( racine->v2 == pere ) {
3539
gauche =racine->v1; droite = racine->v3;
3540
bg = (racine->l1); bd = (racine->l3);
3543
gauche =racine->v1; droite = racine->v2;
3544
bg = (racine->l1); bd = (racine->l2);
3546
/* conserver cette ecriture sinon plante sur PC */
3548
if(gauche != NULL) lg = get_length_down(racine,gauche);
3550
if(droite != NULL) ld = get_length_down(racine,droite);
3557
moments stat_from_node(struct noeud *pere, struct noeud *racine)
3558
/* compute the moments down a node to all descending tips */
3560
struct noeud *gauche, *droite;
3562
static moments mtmp;
3565
if( racine->v1 == pere ) {
3566
gauche =racine->v2; droite = racine->v3;
3567
bg = (racine->l2); bd = (racine->l3);
3569
else if( racine->v2 == pere ) {
3570
gauche =racine->v1; droite = racine->v3;
3571
bg = (racine->l1); bd = (racine->l3);
3574
gauche =racine->v1; droite = racine->v2;
3575
bg = (racine->l1); bd = (racine->l2);
3577
if(gauche != NULL) {
3578
mtmp = stat_from_node(racine, gauche);
3579
m.N = mtmp.N; /* nbre de fils */
3580
m.somme = mtmp.somme + bg * mtmp.N;
3581
m.carres = mtmp.carres + 2 * bg * mtmp.somme + mtmp.N * bg * bg;
3583
mtmp = stat_from_node(racine, droite);
3584
m.N += mtmp.N; /* nbre de fils */
3585
m.somme += mtmp.somme + bd * mtmp.N;
3586
m.carres += mtmp.carres + 2 * bd * mtmp.somme + mtmp.N * bd * bd;
3600
double currx, curry;
3602
struct noeud *p1, *p2;
3603
double b1,b2,frac_gauche;
3604
if(!fd_nj_plot->rooted) {
3605
/* place root at user-chosen place: node # fd_nj_plot->root_num */
3606
fd_nj_plot->rooted = !fd_nj_plot->rooted;
3607
p1 = *(fd_nj_plot->tabtax+fd_nj_plot->root_num);
3609
fd_nj_plot->root_br_l = p1->l3;
3610
if(fd_nj_plot->has_br_length) {
3611
current_best_diff = VERY_BIG;
3612
process_branche(p1, p2, fd_nj_plot->root_br_l);
3614
p1->v3 = fd_nj_plot->racine;
3616
p2->v1 = fd_nj_plot->racine;
3617
else if (p2->v2 == p1)
3618
p2->v2 = fd_nj_plot->racine;
3620
p2->v3 = fd_nj_plot->racine;
3621
fd_nj_plot->racine->v1=p1;
3622
fd_nj_plot->racine->v2=p2;
3623
fd_nj_plot->racine->v3=NULL;
3624
if(fd_nj_plot->has_br_length) {
3625
frac_gauche = current_balance;
3626
if(frac_gauche>MAX_FRAC) frac_gauche=MAX_FRAC;
3627
else if(frac_gauche<1-MAX_FRAC) frac_gauche=1-MAX_FRAC;
3628
b1 = frac_gauche*fd_nj_plot->root_br_l; b2 = fd_nj_plot->root_br_l - b1;
3629
fd_nj_plot->racine->l1=b1; fd_nj_plot->racine->l2=b2;
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;
3638
fd_nj_plot->racine->l2 = p2->l3;
3639
calc_brl_for_lengthless(fd_nj_plot->racine, NULL);
3642
/* initialize leave and node names */
3643
for(i = 0; i <= 2*fd_nj_plot->notu; i++) fd_nj_plot->tabnames[i][0] = 0;
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
3650
sprintf(fd_nj_plot->tabnames[i], "# ");
3653
else if(fd_nj_plot->choix == permutation)
3654
for(i=fd_nj_plot->notu+1; i<=2*fd_nj_plot->notu; i++) sprintf(fd_nj_plot->tabnames[i],"#");
3655
else if(fd_nj_plot->choix == subtree)
3656
for(i=fd_nj_plot->notu+1; i<=2*fd_nj_plot->notu-1; i++) sprintf(fd_nj_plot->tabnames[i],"#");
3658
for(i=0; i<=fd_nj_plot->notu; i++) {
3660
j = strlen(fd_nj_plot->tabnames[i]);
3661
strcpy(fd_nj_plot->tabnames[i] + j, fd_nj_plot->labels[i]);
3664
fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1;
3665
end_br_length = fd_nj_plot->br_length_txt;
3668
memset(fd_nj_plot->profs, 0, (fd_nj_plot->notu+1)*sizeof(double));
3669
if(fd_nj_plot->subtree_center != NULL)
3670
fd_nj_plot->deltay = maxy / fd_nj_plot->subtree_notu;
3672
fd_nj_plot->deltay = maxy / fd_nj_plot->notu;
3673
fd_nj_plot->subtree_notu = fd_nj_plot->notu;
3675
nexty = -fd_nj_plot->deltay;
3676
calc_text_size("Mq", &fd_nj_plot->char_height, &fd_nj_plot->ascent);
3677
if(fd_nj_plot->subtree_center == NULL)
3678
mem_plot(NULL, fd_nj_plot->racine, currx, &curry);
3680
mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry);
3683
} /* end of runtree */
3686
void mem_plot(struct noeud *pere, struct noeud *centre, double currx,
3688
/* prepare tree by memorizing all graphic requests */
3692
struct noeud *gauche, *droite;
3693
double bg, bd, bpere;
3695
while( *(fd_nj_plot->tabtax+num) != centre) num++;
3697
(centre->v1 == NULL || centre->v2 == NULL || centre->v3 == NULL) ) {
3698
/* orienter le noeud centre de maniere standard: centre->v3=pere */
3699
if( centre->v1 == pere ) {
3700
gauche =centre->v2; droite = centre->v3;
3701
bg = centre->l2; bd = centre->l3; bpere = centre->l1;
3703
else if( centre->v2 == pere ) {
3704
gauche =centre->v1; droite = centre->v3;
3705
bg = centre->l1; bd = centre->l3; bpere = centre->l2;
3708
gauche =centre->v1; droite = centre->v2;
3709
bg = centre->l1; bd = centre->l2; bpere = centre->l3;
3711
centre->v3=pere; centre->v1=gauche; centre->v2=droite;
3712
centre->l3=bpere; centre->l1=bg; centre->l2=bd;
3713
/* write taxon name */
3714
nexty += fd_nj_plot->deltay;
3715
mem_nom(currx,nexty,fd_nj_plot->tabnames[num],'c');
3716
fd_nj_plot->profs[num] = currx;
3717
fd_nj_plot->widnames[num] = calc_text_size(fd_nj_plot->tabnames[num], NULL, NULL);
3718
if(fd_nj_plot->choix==depl_racine) mem_point(currx,nexty,num+1);
3722
double yg, yd, xg, xd;
3725
static struct noeud *tmp;
3726
/* doswap vrai ssi permutation de 2 descendants necessaire ici */
3727
doswap = (swap != 0 && *(fd_nj_plot->tabtax+swap) == centre);
3728
if( centre->v1 == pere ) {
3730
tmp= centre->v2;centre->v2= centre->v3;centre->v3= tmp;
3731
bg= centre->l2; centre->l2= centre->l3; centre->l3= bg;
3733
gauche =centre->v2; droite = centre->v3;
3734
bg = centre->l2; bd = centre->l3; bpere = centre->l1;
3736
else if( centre->v2 == pere ) {
3738
tmp= centre->v1;centre->v1= centre->v3;centre->v3= tmp;
3739
bg= centre->l1; centre->l1= centre->l3; centre->l3= bg;
3741
gauche =centre->v1; droite = centre->v3;
3742
bg = centre->l1; bd = centre->l3; bpere = centre->l2;
3746
tmp= centre->v1;centre->v1= centre->v2;centre->v2= tmp;
3747
bg= centre->l1; centre->l1= centre->l2; centre->l2= bg;
3749
gauche =centre->v1; droite = centre->v2;
3750
bg = centre->l1; bd = centre->l2; bpere = centre->l3;
3752
/* orienter le noeud centre de maniere standard: centre->v3=pere */
3753
centre->v3=pere; centre->v1=gauche; centre->v2=droite;
3754
centre->l3=bpere; centre->l1=bg; centre->l2=bd;
3755
xg=currx+bg; xd=currx+bd;
3757
mem_plot(centre,gauche,xg,&yg);
3758
mem_plot(centre,droite,xd,&yd);
3760
mem_trait(currx,yg,xg,yg);
3761
mem_trait(currx,yd,xd,yd);
3762
mem_trait(currx,yg,currx,yd);
3765
/* write internal fd_nj_plot->labels */
3766
if(fd_nj_plot->choix==show_tree && fd_nj_plot->show_bootstrap) {
3767
if(pere != NULL) { /* for all but root node */
3768
if( (p=get_br_label(centre, gauche)) != NULL ) mem_nom(currx,yg,p,'t');
3769
if( (p=get_br_label(centre, droite)) != NULL ) mem_nom(currx,yd,p,'b');
3771
else {/* for root node */
3772
if( (p=get_br_label(centre, NULL)) != NULL ) { /* if root bootstrap exists */
3773
mem_nom(currx,*curry,p,'c');
3774
if( (p=get_br_label(centre, gauche)) != NULL ) mem_nom(currx,yg,p,'t');
3775
if( (p=get_br_label(centre, droite)) != NULL ) mem_nom(currx,yd,p,'b');
3777
else {/* if no root bootstrap any bootstrap is to be centered */
3778
if( (p=get_br_label(centre, gauche)) != NULL ) mem_nom(currx,*curry,p,'c');
3779
if( (p=get_br_label(centre, droite)) != NULL ) mem_nom(currx,*curry,p,'c');
3780
if( (p=get_br_label(gauche, droite)) != NULL ) mem_nom(currx,*curry,p,'c');
3785
/* write node number */
3786
mem_nom(currx,*curry,fd_nj_plot->tabnames[num],'c');
3787
mem_point(currx,*curry,num+1);
3788
if(fd_nj_plot->plot_br_l && fd_nj_plot->has_br_length) {
3789
/* write branch length */
3790
double min_br_l = 0.008; /* minimum branch length displayed */
3792
sprintf(end_br_length,"%.3f",bg);
3793
mem_nom(currx+bg/10,yg,end_br_length,'1');
3794
end_br_length += (strlen(end_br_length)+1);
3797
sprintf(end_br_length,"%.3f",bd);
3798
mem_nom(currx+bd/10,yd,end_br_length,'1');
3799
end_br_length += (strlen(end_br_length)+1);
3803
} /* end of mem_plot */
3805
void mem_point(double x, double y, int number)
3807
++fd_nj_plot->totpoints;
3808
(fd_nj_plot->points+fd_nj_plot->totpoints)->x = x;
3809
(fd_nj_plot->points+fd_nj_plot->totpoints)->y = y;
3810
(fd_nj_plot->points+fd_nj_plot->totpoints)->number = number;
3813
void mem_nom(double x, double y, char *nom, char option)
3814
/* x,y: logical coordinates of beginning of string
3815
nom: address of string to be displayed later
3816
option: 'c' use for position of center of character height
3817
'1' put bottom of characters at y+1 pixel
3818
't' use for position of top of character
3819
'b' use for position of bottom of character
3822
if(strlen(nom) != 0) {
3823
fd_nj_plot->totnoms++;
3824
if(x > maxx) maxx = x;
3825
(fd_nj_plot->noms+fd_nj_plot->totnoms)->x = x;
3826
(fd_nj_plot->noms+fd_nj_plot->totnoms)->y = y;
3827
(fd_nj_plot->noms+fd_nj_plot->totnoms)->nom = nom;
3828
(fd_nj_plot->noms+fd_nj_plot->totnoms)->disp_option = option;
3833
void mem_trait(double xd, double yd, double xf, double yf)
3835
fd_nj_plot->tottraits++;
3836
if(xd>maxx) maxx=xd;
3837
if(xf>maxx) maxx=xf;
3838
(fd_nj_plot->traits+fd_nj_plot->tottraits)->xd = xd;
3839
(fd_nj_plot->traits+fd_nj_plot->tottraits)->yd = yd;
3840
(fd_nj_plot->traits+fd_nj_plot->tottraits)->xf = xf;
3841
(fd_nj_plot->traits+fd_nj_plot->tottraits)->yf = yf;
3845
char *get_br_label(struct noeud *a, struct noeud *b)
3848
for(i=0; i<=fd_nj_plot->totbranches; i++) {
3849
if(fd_nj_plot->branches[i].bouta==a && fd_nj_plot->branches[i].boutb==b)
3850
return fd_nj_plot->branches[i].br_label;
3851
if(fd_nj_plot->branches[i].boutb==a && fd_nj_plot->branches[i].bouta==b)
3852
return fd_nj_plot->branches[i].br_label;
3858
int get_br_from_bouts(struct noeud *a, struct noeud *b)
3861
for(i=0; i<=fd_nj_plot->totbranches; i++) {
3862
if(fd_nj_plot->branches[i].bouta==a && fd_nj_plot->branches[i].boutb==b)
3864
if(fd_nj_plot->branches[i].boutb==a && fd_nj_plot->branches[i].bouta==b)
3871
void free_tree(void)
3874
if(fd_nj_plot->notu == 0) return;
3875
/* de-allocate all memory */
3876
for(i=0; i<2*fd_nj_plot->notu+1; i++)
3877
free(fd_nj_plot->tabtax[i]);
3878
free(fd_nj_plot->tabtax);
3879
for(i=0; i<fd_nj_plot->notu; i++)
3880
if(fd_nj_plot->branches[i].br_label != NULL) free(fd_nj_plot->branches[i].br_label);
3881
free(fd_nj_plot->branches);
3882
for(i = 0; i < 2 * fd_nj_plot->notu + 1; i++) free(fd_nj_plot->tabnames[i]);
3883
free(fd_nj_plot->tabnames);
3884
free(fd_nj_plot->widnames);
3885
free(fd_nj_plot->noms);
3886
free(fd_nj_plot->points);
3887
free(fd_nj_plot->traits);
3888
free(fd_nj_plot->profs);
3889
for(i = 0; i < fd_nj_plot->notu + 1; i++) free(fd_nj_plot->labels[i]);
3890
free(fd_nj_plot->labels);
3891
free(fd_nj_plot->br_length_txt);
3892
if(fd_nj_plot->tree_name != NULL) free(fd_nj_plot->tree_name);
3896
/* ecriture d'un arbre non racine au format phylip, multifurcations allowed */
3897
char *ecrit_arbre_parenth_unrooted(struct noeud *root)
3899
struct noeud *t1, *t2, *t3;
3900
char *p1, *p2, *p3, *p, *bootstrap;
3904
t1 = root->v1->v1; t2 = root->v1->v2; t3 = root->v2;
3905
l1 = root->v1->l1; l2 = root->v1->l2;
3907
t1 = root->v2->v1; t2 = root->v2->v2; t3 = root->v1;
3908
l1 = root->v2->l1; l2 = root->v2->l2;
3910
l3 = root->l1 + root->l2;
3911
bootstrap = get_br_label(root->v1, root->v2);
3912
if(bootstrap == NULL) bootstrap = "";
3914
p1 = ecrit_arbre_parenth(t1); *(p1 + strlen(p1) - 1) = 0;
3915
p2 = ecrit_arbre_parenth(t2); *(p2 + strlen(p2) - 1) = 0;
3916
p3 = ecrit_arbre_parenth(t3); *(p3 + strlen(p3) - 1) = 0;
3917
l = strlen(p1) + strlen(p2)+ strlen(p3) + 150;
3918
p = (char *)check_alloc(l, 1);
3919
if(fd_nj_plot->has_br_length) sprintf(p, "(%s:%.5f,%s:%.5f,%s%s:%.5f);", p1, l1, p2, l2, p3, bootstrap, l3);
3920
else sprintf(p, "(%s,%s,%s%s);", p1, p2, p3, bootstrap);
3921
free(p1); free(p2); free(p3);
3926
/* ecriture d'un arbre racine au format phylip, multifurcations allowed */
3927
char *ecrit_arbre_parenth(struct noeud *root)
3929
char *arbre, *fin, *p;
3930
int l, maxarbre = 2 * fd_nj_plot->long_arbre_parenth + 1000;
3932
arbre=check_alloc( maxarbre+20,1);
3933
fin=recur_ecrit_arbre(root,arbre,arbre+maxarbre-1);
3934
/* ecriture du dernier label interne */
3935
if( fin != NULL && (p=get_br_label(root->v1,root->v2)) != NULL ) {
3937
if(fin+l>=arbre+maxarbre) fin= NULL;
3952
char *recur_ecrit_arbre(struct noeud *centre, char *arbre, char *finarbre)
3957
if(centre->v1==NULL && centre->v2==NULL) {
3959
while( *(fd_nj_plot->tabtax+num) != centre) num++;
3960
l=strlen(fd_nj_plot->tabnames[num]);
3961
if(arbre+l>=finarbre) return NULL;
3962
memcpy(arbre,fd_nj_plot->tabnames[num],l);
3968
arbre=recur_ecrit_arbre(centre->v1,arbre+1,finarbre);
3969
if(arbre==NULL) return NULL;
3970
if(fd_nj_plot->has_br_length) {
3971
if(arbre+10>=finarbre) return NULL;
3972
sprintf(++arbre,":%.5f",centre->l1);
3973
while(*arbre!=0) arbre++;
3977
arbre=recur_ecrit_arbre(centre->v2,arbre+1,finarbre);
3978
if(arbre==NULL) return NULL;
3979
if(fd_nj_plot->has_br_length) {
3980
if(arbre+10>=finarbre) return NULL;
3981
sprintf(++arbre,":%.5f",centre->l2);
3982
while(*arbre!=0) arbre++;
3986
/* ecriture des fd_nj_plot->labels internes */
3987
if( (q=get_br_label(centre,centre->v3)) != NULL && (fd_nj_plot->has_br_length || (centre->l3 != 0) ) ) {
3989
if(arbre+l>=finarbre) return NULL;
3990
memcpy(arbre+1,q,l);
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);
4002
void removeroot(void)
4004
struct noeud *p1, *p2;
4005
p1=fd_nj_plot->racine->v1;
4006
p2=fd_nj_plot->racine->v2;
4007
if(p1->v1 == fd_nj_plot->racine )
4008
{p1->v1 = p2; p1->l1 = fd_nj_plot->root_br_l;}
4009
else if (p1->v2 == fd_nj_plot->racine)
4010
{p1->v2 = p2; p1->l2 = fd_nj_plot->root_br_l;}
4012
{p1->v3 = p2; p1->l3 = fd_nj_plot->root_br_l;}
4013
if(p2->v1 == fd_nj_plot->racine )
4014
{p2->v1 = p1; p2->l1 = fd_nj_plot->root_br_l;}
4015
else if (p2->v2 == fd_nj_plot->racine)
4016
{p2->v2 = p1; p2->l2 = fd_nj_plot->root_br_l;}
4018
{p2->v3 = p1; p2->l3 = fd_nj_plot->root_br_l;}
4019
fd_nj_plot->rooted = 0;
4023
int calc_n_desc(struct noeud *pere)
4025
if(pere->v1 == NULL) return 1;
4026
else return calc_n_desc(pere->v1) + calc_n_desc(pere->v2);
4030
void postscript_plot(void)
4032
double currx, curry;
4033
int page, erreur = FALSE, offset;
4034
int paper_h, sheets_h, recouvre, font_size;
4035
const int a4_h = 750, letter_h = 700;
4037
float screen_w, ps_w;
4038
static int first = TRUE;
4039
const char alphabet[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
4040
/* partie dessinable 500(ps_width) x a4_h decalee de 50 x 50 par rapport a coin inferieur gauche du papier
4041
cadre exterieur de 10 sur les 4 cotes, correspond aussi a zone de clip
4044
if(fd_nj_plot->notu == 0) return;
4045
if(paper_choice == A4) {
4051
if(ps_height != 0) paper_h = ps_height;
4057
font_size = list_font_size[fd_nj_plot->font_size_rank];
4063
Nlm_SelectFont( Nlm_ParseFont( "Courier New,12" ) );
4065
Nlm_SelectFont( Nlm_ParseFont( "Courier,12" ) );
4067
screen_w = Nlm_TextWidth(alphabet, 26);/*taille sur ecran*/
4068
ps_w = 12 * 0.60 * 26; /*taille en postscript pour courier,12*/
4069
postscript_ratio = ps_w / screen_w ;
4070
Nlm_SelectFont(fd_nj_plot->current_font);/*retour a police courante pour ecran */
4074
/* recouvre = paper_h / 30; */
4076
sheets_h = (paper_h - recouvre) * page_count + recouvre;
4077
offset = paper_h - recouvre;
4081
plotfile=fopen(plotfilename,"w");
4082
if(plotfile == NULL) {
4084
sprintf(tmp, "Error opening %s for writing\n", plotfilename);
4092
fprintf(plotfile,"%%!PS-Adobe-1.0\n"
4093
"%%%%DocumentFonts: Times-Roman %s\n"
4094
"%%%%Creator: njplot\n"
4097
"%%%%BeginFeature: *PageSize \n"
4100
"%%%%EndComments\n",
4101
current_ps_font, page_count, fd_nj_plot->tree_name, paper_choice == A4 ? "a4" : "letter" );
4103
"/setpacking where {true setpacking} if\n"
4104
"1 setlinecap 1 setlinejoin 1 setlinewidth 0 setgray\n"
4105
"/basefont /%s findfont %d scalefont def\n",
4106
current_ps_font, font_size);
4107
fprintf(plotfile,"/titlefont /Times-Roman findfont 12 scalefont def\n");
4108
fprintf(plotfile, "/setclip {40 40 moveto %d 40 lineto %d %d lineto 40 %d "
4109
"lineto closepath clip newpath} def\n",
4110
ps_width + 60, ps_width + 60, paper_h+60, paper_h+60);
4112
fprintf(plotfile, "/title {titlefont setfont\n"
4113
"40 %d moveto (%s %s) show ( Page ) show show ( of %d) show\n"
4115
paper_h+65, extract_filename(fd_nj_plot->tree_name), ctime(&heure), page_count);
4116
fprintf(plotfile,"%%%%EndProlog\n");
4118
fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1;
4119
end_br_length = fd_nj_plot->br_length_txt;
4122
nexty = -fd_nj_plot->deltay;
4123
if(fd_nj_plot->subtree_center == NULL)
4124
mem_plot(NULL, fd_nj_plot->racine, currx, &curry);
4126
mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry);
4127
for(page = 0; page < page_count ; page++) {
4128
fprintf(plotfile,"%%%%Page: ? %d\n", page+1);
4129
if( ! no_title) fprintf(plotfile,"(%d) title ", page+1);
4130
fprintf(plotfile,"setclip\n");
4131
fprintf(plotfile,"0 %d translate\n", - (page_count - page - 1) * offset);
4132
fprintf(plotfile,"basefont setfont\n");
4133
fprintf(plotfile,"50 50 translate\n");
4134
fprintf(plotfile,"0.7 setgray -10 -10 moveto %d -10 lineto %d %d lineto "
4135
"-10 %d lineto closepath stroke 0 setgray \n",
4136
ps_width + 10, ps_width + 10, sheets_h+10, sheets_h+10);
4138
fprintf(plotfile,"showpage\n");
4140
fprintf(plotfile, "%%%%Trailer\n");
4141
if(ferror(plotfile)) erreur = TRUE;
4142
if(fclose(plotfile) != 0) erreur = TRUE;
4144
fd_nj_plot->need_runtree = TRUE;
4148
if(!pdf_plot_only ) {
4152
"Tree plot is now in file %s in Postscript format",
4153
extract_filename(plotfilename) );
4156
sprintf(mess, "Error while writing to file %s",
4157
extract_filename(plotfilename) );
4166
void plot_to_pdf(void)
4168
int t_font, font_size;
4171
double currx, curry;
4174
int sheets_h, recouvre;
4175
const int a4_h = 750, letter_h = 700;
4177
/* partie dessinable 500(ps_width) x a4_h decalee de 50 x 50 par rapport a coin inferieur gauche du papier
4178
cadre exterieur de 10 sur les 4 cotes, correspond aussi a zone de clip
4182
encoding = "macroman";
4184
encoding = "iso8859-1";
4187
if(fd_nj_plot->notu == 0) return;
4190
if(pdf == NULL) return;
4192
if( PDF_begin_document(pdf, plotfilename, 0, "compatibility=1.3") == -1) {
4195
sprintf(tmp, "Error opening %s for writing\n", plotfilename);
4206
PDF_set_info(pdf, "Title", fd_nj_plot->tree_name );
4207
PDF_set_info(pdf, "Creator", "njplot");
4208
t_font = PDF_load_font(pdf, "Times-Roman", 0, encoding, "");
4209
pdf_font = PDF_load_font(pdf, current_ps_font, 0, encoding, "");
4210
font_size = list_font_size[fd_nj_plot->font_size_rank];
4212
if(paper_choice == A4) { paper_h = a4_h; }
4213
else /* LETTER */ { paper_h = letter_h; }
4214
if(ps_height != 0) paper_h = ps_height;
4219
pdf_plot = TRUE; file_plot = TRUE;
4222
/* recouvre = paper_h / 30; */
4224
sheets_h = (paper_h - recouvre) * page_count + recouvre;
4225
offset = paper_h - recouvre;
4231
fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1;
4232
end_br_length = fd_nj_plot->br_length_txt;
4235
nexty = -fd_nj_plot->deltay;
4236
if(fd_nj_plot->subtree_center == NULL)
4237
mem_plot(NULL, fd_nj_plot->racine, currx, &curry);
4239
mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry);
4240
for(page = 0; page < page_count ; page++) {
4241
PDF_begin_page_ext(pdf,
4242
paper_choice == A4 ? a4_width : letter_width,
4243
paper_choice == A4 ? a4_height : letter_height,
4246
PDF_setfont(pdf, t_font, 12);
4247
sprintf(bigline, "%s %s Page %d of %d", extract_filename(fd_nj_plot->tree_name), ctime(&heure), page+1, page_count);
4248
PDF_show_xy(pdf, bigline, 40, paper_h+65);
4251
PDF_setlinewidth(pdf, 1);
4252
PDF_moveto(pdf, 40, 40); PDF_lineto(pdf, ps_width + 60, 40); PDF_lineto(pdf, ps_width + 60, paper_h+60);
4253
PDF_lineto(pdf, 40, paper_h+60);
4254
PDF_closepath(pdf); PDF_clip(pdf);
4255
PDF_translate(pdf, 0, - (page_count - page - 1) * offset);
4256
PDF_setfont(pdf, pdf_font, font_size);
4257
PDF_translate(pdf, 50, 50);
4258
PDF_setcolor(pdf, "stroke", "gray", 0.7, 0,0,0);
4259
PDF_moveto(pdf, -10, -10);
4260
PDF_lineto(pdf, ps_width + 10, -10);
4261
PDF_lineto(pdf, ps_width + 10, sheets_h+10);
4262
PDF_lineto(pdf, -10, sheets_h+10);
4263
PDF_closepath_stroke(pdf);
4264
PDF_setcolor(pdf, "stroke", "gray", 0, 0,0,0);
4266
PDF_end_page_ext(pdf, "");
4268
PDF_end_document(pdf, "");
4270
} /* end of PDF_TRY */
4272
sprintf(bigline, "Error while writing pdf file: [%d] %s: %s",
4273
PDF_get_errnum(pdf), PDF_get_apiname(pdf), PDF_get_errmsg(pdf) );
4274
err_message(bigline);
4279
fd_nj_plot->need_runtree = TRUE;
4283
if(!pdf_plot_only ) {
4286
"Tree plot is now in file %s in PDF format",
4287
extract_filename(plotfilename) );
4296
double currx, curry;
4297
int h, erreur = FALSE;
4300
if(fd_nj_plot->notu == 0) return;
4303
/* physx was set in process_args */
4304
physy = 2*(fd_nj_plot->notu + 1) + 4;
4305
tty_page = (char **)malloc(physy*sizeof(char *));
4306
for(h=0; h < physy; h++) {
4307
tty_page[h] = (char *)malloc(physx + 1);
4308
memset(tty_page[h], ' ', physx);
4309
tty_page[h][(int)physx] = 0;
4312
fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1;
4313
end_br_length = fd_nj_plot->br_length_txt;
4316
nexty = -fd_nj_plot->deltay;
4317
if(fd_nj_plot->subtree_center == NULL)
4318
mem_plot(NULL, fd_nj_plot->racine, currx, &curry);
4320
mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry);
4322
for(h=0; h < physy; h++) {
4323
p = tty_page[h] + strlen(tty_page[h]) - 1;
4324
while(p > tty_page[h] && *p == ' ') *(p--) = 0;
4327
plotfile=fopen(plotfilename, "w");
4328
for(h=1; h <= physy; h++) {
4329
fprintf(plotfile, "%s\n", tty_page[(int)physy - h]);
4331
if(ferror(plotfile)) erreur = TRUE;
4332
if(fclose(plotfile) != 0) erreur = TRUE;
4334
fd_nj_plot->need_runtree = TRUE;
4339
void majuscules(char *p)
4341
while(*p != 0) {*p = toupper(*p); p++;}
4346
#if TARGET_RT_MAC_MACHO
4347
#define DIR_DELIM '/'
4349
#define DIR_DELIM ':'
4351
#elif defined(WIN_MSWIN)
4352
#define DIR_DELIM '\\'
4354
#define DIR_DELIM '/'
4357
char *extract_filename(char *name)
4360
while( ( p = strchr(name, DIR_DELIM) ) != NULL) name = p + 1;
4366
#include <ncbiport.h>
4369
static void Nlm_GetFontData (Nlm_FonT f, Nlm_FontData * fdata)
4374
if (f != NULL && fdata != NULL) {
4375
fp = (Nlm_FntPtr) Nlm_HandLock (f);
4382
void set_systemfont(char *fname)
4385
XmFontListEntry entry;
4386
Nlm_FontData fontdata;
4387
extern XmFontList Nlm_XfontList;
4389
Nlm_systemFont = Nlm_ParseFont(fname);
4390
Nlm_GetFontData(Nlm_systemFont, &fontdata);
4391
font= (XFontStruct *)fontdata.handle;
4392
entry = XmFontListEntryCreate(XmFONTLIST_DEFAULT_TAG,
4393
XmFONT_IS_FONT, (XtPointer)font);
4394
Nlm_XfontList = XmFontListAppendEntry(NULL, entry);
4396
Nlm_SelectFont(Nlm_systemFont);
4397
Nlm_stdLineHeight=Nlm_LineHeight();
4398
Nlm_stdFontHeight=Nlm_FontHeight();
4399
Nlm_stdAscent=Nlm_Ascent();
4400
Nlm_stdDescent=Nlm_Descent();
4401
Nlm_stdLeading=Nlm_Leading();
4402
Nlm_stdCharWidth = Nlm_MaxCharWidth ();