njplot-2.4/0000755000002300003250000000000011701012430011316 5ustar mgouybgenjplot-2.4/njplot-vib.c0000644000002300003250000034655211700340237013575 0ustar mgouybge/* NJplot : a program that draws phylogenetic trees Copyright (C) Manolo Gouy 1996 onward All parts of the source code are distributed under the GNU public licence. See http://www.opensource.org for details. one of WIN_MOTIF WIN_MAC WIN_MSWIN must be defined for normal compilation under WIN_MOTIF, one can also define NO_PDF so the PDFLibLite library is not used, and one can also define HELPFILENAME to the full pathname (with enclosing "") of the help file Special compilations: compile with -DTTY to have it output text-only tree without GUI compile with -DADDROOT to have it root the unrooted input tree and write tree on stdout (no GUI) compile with -DNO_GUI to have it work without GUI at all and convert tree to PDF/PostScript file WIN_MOTIF resources: Vibrant.systemfont : helvetica,14,b Njplot.systemfont : times,14,b Vibrant.programfont : fixed,14 placed in file $HOME/.Xdefaults $XAPPLRESDIR/Vibrant /usr/X11R6/lib/X11/app-defaults/Vibrant (Linux) /usr/openwin/lib/X11/app-defaults/Vibrant (Solaris) */ #define NJPLOTVERSION "2.4" #include #include #include #if defined(WIN_MSWIN) #define WITH_PDF 1 #elif defined(WIN_MOTIF) && ! defined(NO_PDF) #define WITH_PDF 1 #elif defined(NO_GUI) && ! defined(NO_PDF) #define WITH_PDF 1 #endif #ifdef WITH_PDF #include "pdflib.h" PDF *pdf = NULL; int pdf_font; #endif #define MAX_FRAC 0.95 #if defined(TTY) || defined (ADDROOT) #define NO_GUI #endif #ifdef NO_GUI #define FALSE 0 #define TRUE (!FALSE) #include #include #include #else #ifdef WIN_MAC #include /* must be before or it does not compile */ #endif #include #include #if defined(WIN_MSWIN) || defined (WIN_MAC) #define MICRO #endif #ifdef WIN_MAC #define myWaitAndProcessNextEvent Nlm_ProcessAnEvent extern int Nlm_textScrapFull; #elif defined(WIN_MSWIN) #define HDC void * extern HDC Nlm_currentHDC; extern HDC Nlm_GetPicWinHDC ( void ); char *get_prog_dir(void); #define myWaitAndProcessNextEvent Nlm_ProcessAnEvent #define tempnam _tempnam #else /* unix */ #undef Boolean #include extern XtAppContext Nlm_appContext; extern Nlm_CharPtr Nlm_XrmGetResource(const Nlm_Char PNTR _resource); void set_systemfont(char *systemfont); void myWaitAndProcessNextEvent (void) { XEvent event; if( XtAppPending(Nlm_appContext) & XtIMXEvent ) { Nlm_ProcessAnEvent(); } else { /* wait until next event and catch it */ XtAppNextEvent (Nlm_appContext, &event); XtDispatchEvent (&event); } } #endif #include /* need this include after the other mac includes */ #ifdef WIN_MAC /* need the mac version of each of these functions */ #undef MoveTo #undef LineTo #undef ClipRect #undef TextWidth #undef DrawString #endif struct win_help_extra { int tag; DoC document; FonT police; }; struct my_RecT4 { Nlm_Int4 left, top, right, bottom; } print_rect; #endif /* NO_GUI */ /* typedefs */ typedef enum { times = 1, helvetica, courier} font_name; enum { font_tiny = 1, font_small, font_normal, font_medium, font_large, font_bold, font_italic }; typedef enum { A4 = 1, LETTER } paper_item; struct noeud { double l1,l2,l3; struct noeud *v1,*v2,*v3; }; typedef struct branche { /* une branche definie par ses deux extremites */ struct noeud *bouta; struct noeud *boutb; char *br_label; } branche; #define s_noeud sizeof(struct noeud) #define myrint(d) ((int)(d + 0.5)) /* not correct if d < 0 but irrelevant for plotting */ struct nom { double x,y; char *nom; char disp_option; }; struct mon_point { double x,y; int number; }; struct trait { double xd,yd,xf,yf; }; typedef struct _moments { int N; /* nbre de fils */ double somme, carres; /* somme des longueurs jusqu'aux feuilles, et somme des carres */ } moments; enum operations {show_tree = 1, depl_racine, permutation, subtree}; typedef struct { #ifndef NO_GUI int tag; Nlm_WindoW nj_plot; Nlm_IteM open_button; Nlm_PrompT click_message; Nlm_MenU tree_font_menu; Nlm_MenU paper_menu; Nlm_IteM win_menu_item; Nlm_IteM save_plot_button; Nlm_IteM save_tree_button; Nlm_IteM save_unrooted_button; Nlm_IteM SearchItem; Nlm_IteM AgainItem; Nlm_ChoicE choix_font, choix_taille; Nlm_IteM bold_item, italic_item; Nlm_ButtoN branch_length_button; Nlm_ButtoN bootstrap_button; Nlm_GrouP choix_group; Nlm_ButtoN reroot_button; Nlm_ButtoN subtree_up_button; Nlm_IteM exit_button; Nlm_PaneL tree_plot; float zoomvalue; Nlm_PrompT zoomprompt; Nlm_RecT old_rect; Nlm_FonT current_font; #endif /* NO_GUI */ char *tree_name; int notu; int totbranches; int has_br_length; int has_internal; int root_num; int rooted; struct noeud **tabtax; struct noeud *racine; char **tabnames; char **labels; struct branche *branches; struct nom *noms; struct trait *traits; struct mon_point *points; char *br_length_txt; int totnoms; int totpoints; int tottraits; double deltay; int show_bootstrap; int need_runtree; enum operations choix; int *widnames; double *profs; int long_arbre_parenth; /* long de la chaine decrivant l'arbre lu */ struct noeud *subtree_center, *subtree_ascend; int subtree_notu; int plot_br_l; double root_br_l; int char_height; int ascent; int font_size_rank; int font_family_rank; char font_bold_italic[3]; } FD_nj_plot; /* prototypes of included functions */ #ifndef NO_GUI FD_nj_plot *create_win_nj_plot(void); void cre_help_win(IteM item); FILE *open_path(char *fname); void topic_callback(LisT list); void help_ok_callback(ButtoN bouton); #ifdef WIN_MAC void show_apropos_njplot(Nlm_IteM item); void mac_timer(void); void window_callback(IteM item); #endif void load_help_topics(FILE *fich, LisT topic_list); void subtree_up_callback(ButtoN bouton); void open_callback(Nlm_IteM ); void new_callback(IteM ob); void font_callback(Nlm_ChoicE); void paper_callback(Nlm_ChoicE); void save_plot_callback(Nlm_IteM); void save_tree_callback(Nlm_IteM); void toggle_branch_callback(Nlm_ButtoN); void toggle_bootstrap_callback(Nlm_ButtoN); void operation_callback(Nlm_GrouP); void subtree_callback(void); void swap_callback(void); void new_outgroup_callback(void); void show_tree_callback(void); void exit_callback(Nlm_IteM); void tree_draw_proc(Nlm_PaneL); void tree_click_proc(Nlm_PaneL, Nlm_PoinT); static void closeproc(WindoW); void closefrommenu(Nlm_IteM item); void win_resize_proc(WindoW); void change_panel_size(PaneL panel, int change_x, int change_y); void string_callback(ButtoN item); void search_callback(IteM item); void process_keys(Nlm_Char key); void change_page_count(ButtoN item); void page_count_callback(IteM item); void clear_tree(IteM); void scrollnotu(int count); void paste_tree(IteM); void scrollcallback(Nlm_BaR b, Nlm_SlatE g, Nlm_Int2 before, Nlm_Int2 after); void zoomcallback(Nlm_SwitcH s, Nlm_Int2 before, Nlm_Int2 after); #ifdef MICRO void copy_plot(IteM); void print_title(int x, int y, char *text, Nlm_FonT title_font, int p,int totp); void print_plot(IteM); #endif #ifdef WIN_MAC extern void add_apropos(char *progname, Nlm_ActnProc my_show_apropos); void create_win_if_needed(char *fname); int is_macosx(void); int crefpict(char *, PicHandle ); void example_tree(IteM unused); void pict_plot(void); extern int MG_GetInputFName(char *fname, int maxl); extern int MG_GetOutputFName(char *fname, int maxl, char *dfault); extern char *mac_fname_to_roman(char *); extern QDPictRef MyPictToQDPict(PicHandle mypicture); extern int MyQDPictToPDFfile (QDPictRef picture, char *fname); extern char *MG_GetBundleResourcesDir(void); #elif defined(WIN_MSWIN) extern int MG_GetInputFName(char *fname, int maxl); extern int MG_GetOutputFName(char *fname, int maxl, char *dfault); #else #define MG_GetOutputFName Nlm_GetOutputFileName #define MG_GetInputFName(a,b) Nlm_GetInputFileName(a, b, NULL, NULL) #endif extern Nlm_WindoW Nlm_GetNext(Nlm_WindoW); #endif /* NO_GUI */ void process_args(int *argc, char *argv[], char **pred, int *pboot_arg, int *p_plot_br_l, int *p_font_size_rank); void prepare_fonts(void); void prepare_pdf_font(int fontnum, int use_bold, int use_italic); int direct_pdf_plot(char *fname); int calc_otu(struct noeud *pere, struct noeud *centre); void do_plot(void); int calc_text_size(char *text, int *pheight, int *pascent); void plotstring(char *nom); void dir_moveto(double x,double y); void dir_lineto(double x,double y); void scale_window(double lxmin, double lxmax, double lymin, double lymax, double pxmin, double pxmax, double pymin, double pymax); void ch_echelle(double lx, double ly, double *px, double *py); void convert_mem_point(void); void init_tree(char *fname, char *displayname); char *preptree(char *fname); char *check_alloc(int nbrelt, int sizelt); void err_message(const char *text); void loadphylip(char *arbre, char *last_bootstrap); struct noeud *unrootedset(char *deb, char *fin, branche **p_int_br); char *extract_filename(char *name); char *nextpar(char *pospar); void make_binary_or_unrooted(char *arbre); int make_binary(char *arbre, char *debut, char *fin, int go_down); void mydrawstring(double x, double y, char *nom, char option); void moveto(double x,double y); void lineto(double x,double y); int calc_brl_for_lengthless(struct noeud *centre, struct noeud *pere); void add_value_downstream(struct noeud *centre, int value); void place_midpoint_root(void); void parcourir_branches(struct noeud *centre, struct noeud *origine); void process_branche(struct noeud *cote1, struct noeud *cote2, double length); double get_length_down(struct noeud *, struct noeud *); moments stat_from_node(struct noeud *pere, struct noeud *racine); void runtree(void); void mem_plot(struct noeud *pere, struct noeud *centre, double currx, double *curry); void mem_point(double x, double y, int number); void mem_nom(double x, double y, char *nom, char option); void mem_trait(double xd, double yd, double xf, double yf); char *get_br_label(struct noeud *a, struct noeud *b); int get_br_from_bouts(struct noeud *a, struct noeud *b); void free_tree(void); char *ecrit_arbre_parenth_unrooted(struct noeud *root); char *ecrit_arbre_parenth(struct noeud *root); char *recur_ecrit_arbre(struct noeud *centre, char *arbre, char *finarbre); void removeroot(void); void remove_arg(int target, int *argc, char *argv[]); double length_log_phys(double p); double length_phys_log(double p); double arrondi_echelle(double x); double calc_echelle(double larg); void draw_scale(void); int calc_n_desc(struct noeud *pere); void bad_format(char *); void majuscules(char *p); void postscript_plot(void); #ifdef WITH_PDF void plot_to_pdf(void); #endif void tty_plot(void); /* globals */ #ifndef NO_GUI extern Nlm_WindoW Nlm_desktopWindow; int tag_njplot, tag_help; #endif FD_nj_plot *fd_nj_plot; int page_count = 1; char *end_br_length; double physx,physy,physx_min,physy_min,physx_corr,physy_corr; /* window scaling variables */ double tek_xmin,tek_xmax,tek_ymin,tek_ymax,tek_dx,tek_dy; double tek_minx,tek_maxx,tek_miny,tek_maxy; double maxx, maxy, nexty; /* max length of taxa names */ int pdf_plot = 0, file_plot, num_noeud, nextotu, no_title = FALSE, swap = 0; char current_ps_font[40]; int list_font_size[] = { 0, 6, 8, 10, 12, 14, 18 }; #ifdef WIN_MSWIN char list_font_name[4][40] = {"", "Times New Roman", "Lucida Sans", "Courier New"}; int default_font_size_rank = font_normal; #else char list_font_name[4][15] = {"", "Times", "Helvetica", "Courier"}; int default_font_size_rank = font_medium; #endif char list_ps_font_name[4][15] = {"", "Times", "Helvetica", "Courier"}; paper_item paper_choice = A4; char plotfilename[200], rooted_fname[200]; FILE *plotfile; FILE *help_file = NULL; int converted; int ps_width = 500, ps_height = 0 /* 0 means not defined by this variable */; /* variables globales pour memoriser la meilleure branche: celle qui partage l'arbre en 2 parties les plus egales possibles en prof moyenne */ double current_best_diff, current_br_length, current_balance; struct noeud *current_cote1=NULL, *current_cote2=NULL; #define VERY_BIG 9.e99 int doing_copy = FALSE; int doing_print = FALSE; float postscript_ratio = 0.60; char *tty_prefix = NULL; char **tty_page; int tty_x, tty_y; char *outotu = NULL; /* value of optional argument -outotu name */ #ifdef WIN_MAC Rect myrect; PicHandle mypicture; int margin; #endif #ifdef NO_GUI int pdf_plot_only = TRUE; int main(int argc, char **argv) { char *red, *fname; int boot_arg, plot_br_l; fd_nj_plot = (FD_nj_plot *)calloc(1, sizeof(FD_nj_plot)); #else int pdf_plot_only = FALSE; #ifdef hpux extern int argc; extern char **argv; #else int argc; char **argv; #endif Nlm_Int2 Nlm_Main(void) { char *red, *fname; int boot_arg, plot_br_l; #ifndef hpux argc = Nlm_GetArgc(); argv = Nlm_GetArgv(); #endif #endif /* NO_GUI */ fname = NULL; #ifdef WIN_MAC if( ! is_macosx() ) argc = 1; else if(argc > 1 && strncmp(argv[1], "-psn_", 5) == 0) remove_arg(1, &argc, argv); #endif process_args(&argc, argv, &red, &boot_arg, &plot_br_l, &default_font_size_rank); if(argc>=2) { fname = argv[1]; } else { fname = NULL; } #ifdef unix putenv("LC_NUMERIC=C"); #endif if(pdf_plot_only) { int status = 0; fd_nj_plot = (FD_nj_plot *)calloc(1, sizeof(FD_nj_plot)); fd_nj_plot->tree_name = fname; fd_nj_plot->show_bootstrap = boot_arg; fd_nj_plot->plot_br_l = plot_br_l; fd_nj_plot->font_size_rank = default_font_size_rank; fd_nj_plot->font_family_rank = times; if( fname != NULL) status = direct_pdf_plot(fname); return status; } #ifndef NO_GUI Nlm_WatchCursor(); #ifdef WIN_MOTIF {char *font; font = Nlm_XrmGetResource("systemfont"); if(font != NULL) set_systemfont(font); font = Nlm_XrmGetResource("programfont"); if(font != NULL) Nlm_programFont = Nlm_ParseFont(font); } #endif #ifdef WIN_MAC add_apropos("njplot", show_apropos_njplot); #endif #ifdef WIN_MAC { char *p; p = MG_GetBundleResourcesDir(); strcat(p, "/njplot.help"); help_file = fopen(p, "r"); } #elif defined(HELPFILENAME) help_file = fopen(HELPFILENAME, "r"); #else help_file = open_path("njplot.help"); #endif Nlm_KeyboardView(process_keys); memcpy(&tag_njplot, "NJPL", sizeof(int)); memcpy(&tag_help, "HELP", sizeof(int)); fd_nj_plot = create_win_nj_plot(); SetStatus(fd_nj_plot->bootstrap_button, boot_arg); SetStatus(fd_nj_plot->branch_length_button, plot_br_l); if(fname != NULL) init_tree( fname, NULL ); else SetTitle(fd_nj_plot->nj_plot, "njplot"); Show(fd_nj_plot->nj_plot); Nlm_ObjectRect(fd_nj_plot->nj_plot, &(fd_nj_plot->old_rect)); if(red != NULL) search_callback( (Nlm_IteM)red ); Nlm_ArrowCursor(); #ifdef WIN_MAC Nlm_Metronome(mac_timer); #endif ProcessEvents(); #endif return 0; } #ifndef NO_GUI FD_nj_plot *create_win_nj_plot(void) { WindoW win; MenU menu; ChoicE choix_paper; GrouP group; FD_nj_plot *fdui = (FD_nj_plot *) calloc(1, sizeof(FD_nj_plot)); PoinT position; Nlm_Handle obj; int left, right; static int countwin = 0; fdui->tag = tag_njplot; fdui->nj_plot = win = DocumentWindow(-50 - countwin, -33 - countwin, -3, -3, "Njplot", closeproc, win_resize_proc); countwin += 3; countwin %= 15; #ifdef WIN_MAC static FD_nj_plot *mac_menu_bar_extra = NULL; if(mac_menu_bar_extra != NULL) { fdui->open_button = mac_menu_bar_extra->open_button; fdui->save_plot_button = mac_menu_bar_extra->save_plot_button; fdui->save_tree_button = mac_menu_bar_extra->save_tree_button; fdui->save_unrooted_button = mac_menu_bar_extra->save_unrooted_button; fdui->SearchItem = mac_menu_bar_extra->SearchItem; fdui->AgainItem = mac_menu_bar_extra->AgainItem; fdui->tree_font_menu = mac_menu_bar_extra->tree_font_menu; fdui->choix_font = mac_menu_bar_extra->choix_font; fdui->choix_taille = mac_menu_bar_extra->choix_taille; fdui->bold_item = mac_menu_bar_extra->bold_item; fdui->italic_item = mac_menu_bar_extra->italic_item; fdui->paper_menu = mac_menu_bar_extra->paper_menu; goto after_menus; } #define OPEN_LABEL "Open O" #define NEW_LABEL "New N" #define CLOSE_LABEL "Close W" #define SAVE_PLOT_LABEL "Save as PDF S" #define PRINT_LABEL "Print P" #define QUIT_LABEL "Quit Q" #define COPY_LABEL "Copy C" #define PASTE_LABEL "Paste V" #define FIND_LABEL "Find F" #define AGAIN_LABEL "Again A" #define PLACE_OF_MENUS NULL #else #define OPEN_LABEL "Open ^O" #define NEW_LABEL "New ^N" #define CLOSE_LABEL "Close ^W" #define PRINT_LABEL "Print ^P" #define SAVE_PLOT_LABEL "Save as PDF ^S" #define QUIT_LABEL "Quit ^Q" #define COPY_LABEL "Copy ^C" #define PASTE_LABEL "Paste ^V" #define FIND_LABEL "Find ^F" #define AGAIN_LABEL "Again ^A" #define PLACE_OF_MENUS fdui->nj_plot #endif menu = PulldownMenu(PLACE_OF_MENUS, "File"); fdui->open_button = CommandItem(menu, OPEN_LABEL, open_callback); CommandItem(menu, NEW_LABEL, new_callback); fdui->save_plot_button = #if ( ! defined(WIN_MOTIF) ) || defined(WITH_PDF) CommandItem(menu, SAVE_PLOT_LABEL, save_plot_callback); #endif #ifdef WIN_MOTIF CommandItem(menu, "Save as PostScript", save_plot_callback); #endif fdui->save_tree_button = CommandItem(menu, "Save Rooted Tree", save_tree_callback); fdui->save_unrooted_button = CommandItem(menu, "Save Unrooted Tree", save_tree_callback); #ifdef MICRO CommandItem(menu, PRINT_LABEL, print_plot); #endif CommandItem(menu, CLOSE_LABEL, closefrommenu); #ifdef WIN_MAC if( ! is_macosx() ) #endif CommandItem(menu, QUIT_LABEL, exit_callback); Advance(PLACE_OF_MENUS); menu = PulldownMenu(PLACE_OF_MENUS, "Edit"); CommandItem(menu, "Clear", clear_tree); #ifdef MICRO CommandItem(menu, COPY_LABEL, copy_plot); #endif CommandItem(menu, PASTE_LABEL, paste_tree); #ifdef WIN_MAC SeparatorItem(menu); CommandItem(menu, "Example", example_tree); #endif SeparatorItem(menu); fdui->SearchItem = CommandItem(menu, FIND_LABEL, search_callback); fdui->AgainItem = CommandItem(menu, AGAIN_LABEL, search_callback); /* Disable(fdui->AgainItem); */ Advance(PLACE_OF_MENUS); fdui->tree_font_menu = PulldownMenu(PLACE_OF_MENUS, "Font"); fdui->choix_font = ChoiceGroup(fdui->tree_font_menu, font_callback); Nlm_ChoiceItem(fdui->choix_font, list_font_name[1]); Nlm_ChoiceItem(fdui->choix_font, list_font_name[2]); Nlm_ChoiceItem(fdui->choix_font, list_font_name[3]); SeparatorItem(fdui->tree_font_menu); fdui->choix_taille = ChoiceGroup(fdui->tree_font_menu, font_callback); ChoiceItem(fdui->choix_taille, "6"); ChoiceItem(fdui->choix_taille, "8"); ChoiceItem(fdui->choix_taille, "10"); ChoiceItem(fdui->choix_taille, "12"); ChoiceItem(fdui->choix_taille, "14"); ChoiceItem(fdui->choix_taille, "18"); SeparatorItem(fdui->tree_font_menu); fdui->bold_item = StatusItem(fdui->tree_font_menu, "Bold", (Nlm_ItmActnProc) font_callback); fdui->italic_item = StatusItem(fdui->tree_font_menu, "Italic", (Nlm_ItmActnProc) font_callback); SetStatus(fdui->bold_item, FALSE); SetStatus(fdui->italic_item, FALSE); Advance(PLACE_OF_MENUS); fdui->paper_menu = PulldownMenu(PLACE_OF_MENUS, "Paper"); choix_paper = ChoiceGroup(fdui->paper_menu, paper_callback); ChoiceItem(choix_paper, "A4"); ChoiceItem(choix_paper, "US letter"); SetValue(choix_paper, paper_choice); SeparatorItem(fdui->paper_menu); #ifdef WIN_MSWIN /* SetTitle ne marche pas sur PC! */ CommandItem(fdui->paper_menu, "Page count", page_count_callback); #elif defined(WIN_MAC) /* en 2 temps car () ds menu ne marche pas sur Mac ! */ { Nlm_IteM item; char nom[25]; item = CommandItem(fdui->paper_menu, "tmp", page_count_callback); sprintf(nom, "Page count (%d)", page_count); SetTitle(item, nom); } #else /* unix */ { char nom[25]; sprintf(nom, "Page count (%d)", page_count); CommandItem(fdui->paper_menu, nom, page_count_callback); } #endif #ifdef WIN_MAC Advance(NULL); static Nlm_MenU window_menu; window_menu = PulldownMenu(NULL, "Window"); #endif Advance(PLACE_OF_MENUS); obj = PulldownMenu(PLACE_OF_MENUS, "Help"); CommandItem(obj, "Help", cre_help_win); Break(PLACE_OF_MENUS); #ifdef WIN_MAC mac_menu_bar_extra = (FD_nj_plot *) calloc(1, sizeof(FD_nj_plot)); *mac_menu_bar_extra = *fdui; after_menus: {static Nlm_IteM mac_win_item[50]; static int mac_win_item_count = 0; int i; for(i=0; iwin_menu_item = mac_win_item[i]; break; } } if(i>=mac_win_item_count) { fdui->win_menu_item = mac_win_item[mac_win_item_count] = CommandItem(window_menu, "njplot", window_callback); mac_win_item_count++; } } #endif fdui->choix_group = NormalGroup(win, 4, 1, "Operation", programFont, operation_callback); RadioButton(fdui->choix_group, "Full tree"); fdui->reroot_button = RadioButton(fdui->choix_group, "New outgroup"); RadioButton(fdui->choix_group, "Swap nodes"); RadioButton(fdui->choix_group, "Subtree"); SetValue(fdui->choix_group, show_tree); Break(win); group = NormalGroup(win, 2, 1, "Display", programFont, NULL); fdui->branch_length_button = CheckBox(group, "Branch lengths", toggle_branch_callback); SetStatus(fdui->branch_length_button, fdui->plot_br_l); fdui->bootstrap_button = CheckBox(group, "Bootstrap values", toggle_bootstrap_callback); Advance(win); group = NormalGroup(win, 2, 1, "Zoom", programFont, NULL); obj = Nlm_UpDownSwitch(group, 0, zoomcallback); fdui->zoomvalue = 1.; Nlm_SetSwitchParams( (Nlm_SwitcH)obj, 1, 100); fdui->zoomprompt = Nlm_StaticPrompt(group, "100%", 35, Nlm_stdLineHeight, Nlm_programFont, 'l'); Advance(win); GetNextPosition(win, &position); position.x += 5; position.y += 10; SetNextPosition(win, position); obj = fdui->subtree_up_button = PushButton(win, "Subtree Up", subtree_up_callback); Disable(fdui->subtree_up_button); Break(win); Nlm_GetPosition(obj, &(fdui->old_rect)); right = fdui->old_rect.right; Nlm_GetNextPosition(win, &position); left = position.x; #ifdef WIN_MSWIN #define PLOT_HEIGHT 430 #elif defined(WIN_MAC) #define PLOT_HEIGHT 300 #else #define PLOT_HEIGHT 350 #endif fdui->tree_plot = Nlm_AutonomousPanel(win, right - left + 1, PLOT_HEIGHT, tree_draw_proc, scrollcallback, NULL, sizeof(int), NULL, NULL); {int hidebar = TRUE; /* put TRUE iff scrollbar should be hidden */ Nlm_SetPanelExtra(fdui->tree_plot, &hidebar); } SetPanelClick(fdui->tree_plot, tree_click_proc, NULL, NULL, NULL); obj = Nlm_GetSlateVScrollBar((SlatE)fdui->tree_plot); Nlm_Hide(obj); Nlm_SetBarValue(obj, 0); Nlm_SetBarMax(obj, 1); {int space = 0; /* some space at the bottom of the window */ #if defined(__APPLE__) || defined(WIN_MAC) space = Nlm_hScrollBarHeight; #elif defined(WIN_MOTIF) space = 3; #endif if(space > 0) { Nlm_Break(win); Nlm_StaticPrompt(win, "", 4, space, Nlm_programFont, 'l'); } } fdui->old_rect.left = -1; SetWindowExtra(win, fdui, NULL); fdui->font_size_rank = default_font_size_rank; fdui->font_family_rank = times; Nlm_SetValue(fdui->choix_taille, default_font_size_rank); Nlm_SetValue(fdui->choix_font, times); Nlm_SetStatus(fdui->bold_item, FALSE); Nlm_SetStatus(fdui->italic_item, FALSE); #ifdef WIN_MSWIN { /* contre bug fenetre mange un peu du panel */ Int2 right; Advance(win); GetNextPosition(win, &position); right = position.x + 5; SetNextPosition(win, position); Break(win); GetNextPosition(win, &position); position.x = right; position.y += 3; SetNextPosition(win, position); StaticPrompt(win, "", 1, 1, programFont, 'l'); } #endif return fdui; } int update_tree_w_data(Nlm_Handle h) { FD_nj_plot *f; Nlm_WindoW w; #if defined(WIN_MAC) w = Nlm_FrontWindow(); #elif defined(WIN_MSWIN) if(h == NULL) w = Nlm_FrontWindow(); else w = Nlm_ParentWindow(h); #else if(h == NULL) w = fd_nj_plot->nj_plot; else w = Nlm_ParentWindow(h); #endif f = (FD_nj_plot *)Nlm_GetWindowExtra(w); if(f== NULL || f->tag != tag_njplot) return FALSE; fd_nj_plot = f; return TRUE; } FILE *open_path(char *fname) /* to open in read-only file fname searching for it through all path directories */ { #define Mxdir 200 static char dir[Mxdir+1]; char *path, *deb, *fin; FILE *fich; int lf, ltot; #ifdef __VMS static char vmspath[] = "njplot"; path = vmspath; #elif defined(unix) path = getenv("PATH"); /* get the list of path directories, separated by : */ #elif defined(WIN_MSWIN) /* try first dir where program was launched */ path = get_prog_dir(); #else path = NULL; #endif if (path == NULL ) { fich = fopen(fname,"r"); return fich; } lf=strlen(fname); deb=path; do { #ifdef WIN_MSWIN fin = NULL; #else fin = strchr(deb,':'); #endif if(fin!=NULL) { strncpy(dir,deb,fin-deb); ltot=fin-deb; } else { strcpy(dir,deb); ltot=strlen(dir); } /* now one directory is in string dir */ if( ltot + lf + 1 <= Mxdir) { #ifdef __VMS dir[ltot]=':'; #elif defined(WIN_MSWIN) if(dir[ltot-1] == '\\') ltot--; else dir[ltot] = '\\'; #else dir[ltot]='/'; #endif strcpy(dir+ltot+1,fname); /* now dir is appended with filename */ fich = fopen(dir,"r"); if( fich != NULL) break; } else fich = NULL; deb=fin+1; } while (fin != NULL); if(fich == NULL) { fich=fopen(fname,"r"); /* try also current directory */ } return fich; #undef Mxdir } void cre_help_win(IteM bouton) { static WindoW win; LisT topic_list; static struct win_help_extra win_data; static int first = TRUE; int larg; GrouP group; if(first) { if(help_file == NULL) { Disable(bouton); err_message( #ifdef WIN_MAC "Sorry, no help resource available." #else "Sorry, help file njplot.help is not found." #endif ); return; } first = FALSE; win = DocumentWindow( -50, -33, -3, -3, "Njplot Help", (Nlm_WndActnProc)help_ok_callback, NULL); group = HiddenGroup(win, -1, -2, NULL); SetGroupSpacing(group, 0, 5); topic_list = SingleList(group, 7, 8, topic_callback); load_help_topics(help_file, topic_list); DefaultButton(group, "Ok", help_ok_callback); Advance(win); #ifdef WIN_MSWIN win_data.police = ParseFont("Courier New,10"); #else win_data.police = programFont; #endif SelectFont(win_data.police); larg = 81 * Nlm_TextWidth("Q", 1); win_data.document = DocumentPanel(win, larg, 20 * Nlm_LineHeight() ); win_data.tag = tag_help; SetWindowExtra(win, &win_data, NULL); } Show(win); Select(win); } void topic_callback(LisT list) { int num_topic; char ligne[100], *p; static int last_topic = 0; Int2 total; static char txt[5000]; WindoW win; DoC help_doc; struct win_help_extra *p_win_data; num_topic = GetValue(list); if(num_topic == 0 || num_topic == last_topic) return; last_topic = num_topic; win = ParentWindow(list); p_win_data = (struct win_help_extra *)GetWindowExtra(win); help_doc = p_win_data->document; Hide(help_doc); GetDocParams(help_doc, &total, NULL); while(total > 0) DeleteItem(help_doc, total--); rewind(help_file); while(fgets(ligne, sizeof(ligne), help_file) != NULL) { if(strncmp(ligne, ">>>", 3) != 0) continue; if( --num_topic == 0) break; } if(num_topic != 0) return; p = txt; while(fgets(ligne, sizeof(ligne), help_file) != NULL) { if(strncmp(ligne, ">>>", 3) == 0) break; if(strncmp(ligne, "Version:", 8) == 0) sprintf(ligne, "Version: %s\n", NJPLOTVERSION); strcpy(p, ligne); p += strlen(ligne); } AppendText(help_doc, txt, NULL, NULL, p_win_data->police); Show(help_doc); } void help_ok_callback(ButtoN bouton) { Nlm_WindoW h; h = Nlm_ParentWindow(bouton); Hide(h); } void load_help_topics(FILE *fich, LisT topic_list) { char ligne[100], topic[50]; int l; rewind(fich); while(fgets(ligne, sizeof(ligne), fich) != NULL) { if(strncmp(ligne, ">>>", 3) != 0) continue; strcpy(topic, ligne + 3); l = strlen(topic) - 1; topic[l] = 0; ListItem(topic_list, topic); } } void subtree_up_callback(ButtoN bouton) { fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(bouton) ); if(fd_nj_plot->subtree_center == NULL) return; fd_nj_plot->subtree_center = fd_nj_plot->subtree_ascend; if(fd_nj_plot->subtree_center != NULL) { fd_nj_plot->subtree_ascend = fd_nj_plot->subtree_center->v3; if(fd_nj_plot->subtree_ascend == NULL) { SetValue(fd_nj_plot->choix_group, show_tree); Disable(fd_nj_plot->subtree_up_button); fd_nj_plot->choix = show_tree; show_tree_callback(); return; } fd_nj_plot->subtree_notu = calc_n_desc(fd_nj_plot->subtree_center) - 1; scrollnotu(fd_nj_plot->subtree_notu); } fd_nj_plot->need_runtree = TRUE; tree_draw_proc(fd_nj_plot->tree_plot); } void process_keys(Nlm_Char key) { #ifdef WIN_MAC /* combinaison command-lettre */ #define test_key(a) (Nlm_cmmdKey && Nlm_currentKey == a) #else /* combinaison control-lettre */ #define test_key(a) key == a - 96 #endif #ifdef MICRO if( (!(test_key('o') || test_key('n'))) && ! update_tree_w_data(NULL) ) return; #endif if( test_key('q') ) exit(0); else if( test_key('o') ) { if(fd_nj_plot == NULL) fd_nj_plot = create_win_nj_plot(); open_callback(fd_nj_plot->open_button); } else if( test_key('n') ) new_callback(NULL); else if( test_key('w') ) closefrommenu(fd_nj_plot->open_button); else if( test_key('s') ) save_plot_callback(fd_nj_plot->save_plot_button); else if( test_key('f') ) search_callback(fd_nj_plot->SearchItem); else if( test_key('a') ) { if(Enabled(fd_nj_plot->AgainItem) ) search_callback(fd_nj_plot->AgainItem); } #ifdef MICRO else if( test_key('c') ) copy_plot(NULL); else if( test_key('p') ) print_plot(NULL); #endif else if( test_key('v') ) paste_tree(NULL); return; } static void closeproc(WindoW i) { Nlm_WindoW w; FD_nj_plot *tofree; fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( i ); tofree = fd_nj_plot; /* necessary because with MSWIN fd_nj_plot changes after Remove(i) */ free_tree(); #ifdef WIN_MAC Nlm_Disable(tofree->win_menu_item); #endif Nlm_Remove(i); free(tofree); w = Nlm_desktopWindow; while(w != NULL) { /* is there another tree window ? */ fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( w ); if( fd_nj_plot != NULL && fd_nj_plot->tag == tag_njplot) { Nlm_Select(fd_nj_plot->nj_plot); return; } w = Nlm_GetNext(w); } #ifdef WIN_MAC fd_nj_plot = NULL; #else exit(0); #endif } void closefrommenu(Nlm_IteM item) { #ifdef WIN_MAC if( update_tree_w_data(NULL) ) closeproc(fd_nj_plot->nj_plot); #else if( update_tree_w_data(item) ) closeproc(Nlm_ParentWindow(item)); #endif } void win_resize_proc(WindoW win) { RecT *old_rect, rect; int change_x, change_y, old_height, new_height; fd_nj_plot = (FD_nj_plot *)GetWindowExtra(win); old_rect = &(fd_nj_plot->old_rect); if(old_rect->left == -1) return; ObjectRect(win, &rect); old_height = old_rect->bottom - old_rect->top; new_height = rect.bottom - rect.top; change_y = (new_height - old_height); old_height = old_rect->right - old_rect->left; new_height = rect.right - rect.left; change_x = (new_height - old_height); if(change_x != 0 || change_y != 0) { change_panel_size(fd_nj_plot->tree_plot, change_x, change_y); *old_rect = rect; } } void change_panel_size(PaneL panel, int change_x, int change_y) { Nlm_RecT r; #ifdef WIN_MOTIF Nlm_RecT r_group; GrouP group; Nlm_Boolean in_group; Nlm_BaR bar; int visible; static int recursive = FALSE; #endif GetPosition(panel, &r); #ifdef WIN_MOTIF if(recursive) return; recursive = TRUE; bar = Nlm_GetSlateVScrollBar( (Nlm_SlatE)panel); visible = Nlm_Visible(bar); group = Parent(panel); in_group = (group != ParentWindow(panel)); if(in_group) { GetPosition(group, &r_group); Hide(group); } else Hide(panel); #endif r.bottom += change_y; r.right += change_x; SetPosition(panel, &r); #ifdef WIN_MOTIF if(in_group) { r_group.bottom += change_y; r_group.right += change_x; SetPosition( group, &r_group); Show(group); } else Show(panel); if( !visible) Nlm_Hide(bar); recursive = FALSE; #endif } void font_callback(ChoicE choix) { if( ! update_tree_w_data(choix) ) return; prepare_fonts(); fd_nj_plot->need_runtree = TRUE; tree_draw_proc(fd_nj_plot->tree_plot); } void prepare_fonts(void) { Nlm_Boolean use_bold, use_italic; char font_full_name[40], *p; /* prepare vibrant font */ use_bold = GetStatus(fd_nj_plot->bold_item); use_italic = GetStatus(fd_nj_plot->italic_item); fd_nj_plot->font_family_rank = GetValue(fd_nj_plot->choix_font); fd_nj_plot->font_size_rank = GetValue(fd_nj_plot->choix_taille); sprintf(font_full_name, "%s,%d", list_font_name[fd_nj_plot->font_family_rank], list_font_size[fd_nj_plot->font_size_rank]); if(use_bold || use_italic) strcat(font_full_name, ","); if(use_bold) strcat(font_full_name, "b"); if(use_italic) strcat(font_full_name, "i"); fd_nj_plot->current_font = ParseFont(font_full_name); if((p = strchr(font_full_name, ',')) != NULL) strcpy(fd_nj_plot->font_bold_italic, p + 1); else fd_nj_plot->font_bold_italic[0] = 0; prepare_pdf_font(fd_nj_plot->font_family_rank, use_bold, use_italic); } /* callbacks for form nj_plot */ #if defined(WIN_MOTIF) && defined(__APPLE__) /* bug sur mac/darwin : Nlm_GetOutputFileName crashes if Nlm_GetInputFileName was not used before ! */ static int can_run_getoutputfname = FALSE; #else static int can_run_getoutputfname = TRUE; #endif void open_callback(IteM ob) { char fname[200]; can_run_getoutputfname = TRUE; if(!MG_GetInputFName(fname, sizeof(fname))) { if(fd_nj_plot != NULL) tree_draw_proc(fd_nj_plot->tree_plot); return; } if(fd_nj_plot == NULL || fd_nj_plot->notu != 0) fd_nj_plot = create_win_nj_plot(); fd_nj_plot->notu = 0; init_tree( fname, NULL ); if(fd_nj_plot->notu == 0) { closeproc(fd_nj_plot->nj_plot); return; } Nlm_Show(fd_nj_plot->nj_plot); Nlm_ObjectRect(fd_nj_plot->nj_plot, &(fd_nj_plot->old_rect)); } void new_callback(IteM ob) { fd_nj_plot = create_win_nj_plot(); fd_nj_plot->notu = 0; Nlm_Show(fd_nj_plot->nj_plot); Nlm_ObjectRect(fd_nj_plot->nj_plot, &(fd_nj_plot->old_rect)); } void paper_callback(ChoicE ob) { paper_choice = (paper_item) GetValue(ob); } void save_plot_callback(IteM ob) { char *p; if(!update_tree_w_data(ob)) return; strcpy(plotfilename, fd_nj_plot->tree_name); p = strchr(extract_filename(plotfilename), '.'); if(p == NULL) p = plotfilename + strlen(plotfilename); #ifdef WIN_MAC strcpy(p,".pdf"); #else #ifdef WITH_PDF pdf_plot = (ob == fd_nj_plot->save_plot_button); if(pdf_plot) strcpy(p,".pdf"); else #endif strcpy(p,".ps"); #endif if(ob != NULL) { if(can_run_getoutputfname) { if( ! MG_GetOutputFName(plotfilename, sizeof(plotfilename), extract_filename(plotfilename) ) ) return; } } #ifdef WIN_MAC pict_plot(); #else #ifdef WITH_PDF if(pdf_plot) plot_to_pdf(); else #endif postscript_plot(); #endif } void save_tree_callback(IteM ob) { char *p, *arbre, ajout[10], *name_part; FILE *out; int unrooted; if(!update_tree_w_data(ob)) return; if(fd_nj_plot->notu==0)return; unrooted = (ob == fd_nj_plot->save_unrooted_button); /* build out file name */ strcpy(rooted_fname, fd_nj_plot->tree_name); name_part = extract_filename(rooted_fname); /* ajouter _root. dans le nom */ strcpy(ajout, unrooted ? "_noroot." : "_root."); if(strstr(name_part, ajout) == NULL) { p = strchr(name_part, '.'); if(p == NULL) p = name_part + strlen(name_part); strcpy(p, ajout); } name_part = extract_filename(fd_nj_plot->tree_name); p = strchr(name_part, '.'); if(p == NULL) strcat(rooted_fname, "ph"); else strcpy( strchr(extract_filename(rooted_fname), '.'), p); if( !MG_GetOutputFName(rooted_fname, sizeof(rooted_fname), extract_filename(rooted_fname) ) ) return; if(unrooted) arbre = ecrit_arbre_parenth_unrooted(fd_nj_plot->racine); else arbre = ecrit_arbre_parenth(fd_nj_plot->racine); if(arbre == NULL) { err_message("Sorry, not enough memory"); return; } out = fopen(rooted_fname,"w"); if(out != NULL) { fputs(arbre, out); putc('\n', out); fclose(out); } else { char mess[250]; sprintf(mess, "Sorry, cannot write to file %s", extract_filename(rooted_fname) ); err_message(mess); } free(arbre); } void toggle_branch_callback(ButtoN ob) { fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(ob) ); fd_nj_plot->plot_br_l = GetStatus(ob); fd_nj_plot->need_runtree = TRUE; tree_draw_proc(fd_nj_plot->tree_plot); } void toggle_bootstrap_callback(ButtoN ob) { fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(ob) ); fd_nj_plot->show_bootstrap = !fd_nj_plot->show_bootstrap; fd_nj_plot->need_runtree = TRUE; tree_draw_proc(fd_nj_plot->tree_plot); } void operation_callback(GrouP group) { fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(group) ); fd_nj_plot->choix = (enum operations) GetValue(group); if(fd_nj_plot->choix == permutation) swap_callback(); else if(fd_nj_plot->choix == depl_racine) new_outgroup_callback(); else if(fd_nj_plot->choix == subtree) subtree_callback(); else { show_tree_callback(); } } void subtree_callback(void) { fd_nj_plot->choix = subtree; /* Disable(fd_nj_plot->save_plot_button); */ Disable(fd_nj_plot->save_tree_button); Disable(fd_nj_plot->save_unrooted_button); Enable(fd_nj_plot->subtree_up_button); if(fd_nj_plot->has_br_length) { SetStatus(fd_nj_plot->branch_length_button, FALSE); Disable(fd_nj_plot->branch_length_button); fd_nj_plot->plot_br_l=0; } SetStatus(fd_nj_plot->bootstrap_button, FALSE); fd_nj_plot->show_bootstrap = FALSE; Disable(fd_nj_plot->bootstrap_button); Disable(fd_nj_plot->reroot_button); fd_nj_plot->need_runtree = TRUE; tree_draw_proc(fd_nj_plot->tree_plot); } void swap_callback(void) { fd_nj_plot->choix = permutation; Disable(fd_nj_plot->save_plot_button); Disable(fd_nj_plot->save_tree_button); Disable(fd_nj_plot->save_unrooted_button); if(fd_nj_plot->has_br_length) { SetStatus(fd_nj_plot->branch_length_button, FALSE); Disable(fd_nj_plot->branch_length_button); fd_nj_plot->plot_br_l=0; } SetStatus(fd_nj_plot->bootstrap_button, FALSE); fd_nj_plot->show_bootstrap = FALSE; Disable(fd_nj_plot->bootstrap_button); fd_nj_plot->need_runtree = TRUE; tree_draw_proc(fd_nj_plot->tree_plot); } void new_outgroup_callback(void) { fd_nj_plot->choix = depl_racine; Disable(fd_nj_plot->save_plot_button); Disable(fd_nj_plot->save_tree_button); Disable(fd_nj_plot->save_unrooted_button); if(fd_nj_plot->has_br_length) { SetStatus(fd_nj_plot->branch_length_button, FALSE); Disable(fd_nj_plot->branch_length_button); fd_nj_plot->plot_br_l=0; } SetStatus(fd_nj_plot->bootstrap_button, FALSE); fd_nj_plot->show_bootstrap = FALSE; Disable(fd_nj_plot->bootstrap_button); fd_nj_plot->need_runtree = TRUE; tree_draw_proc(fd_nj_plot->tree_plot); } void show_tree_callback(void) { fd_nj_plot->choix = show_tree; Enable(fd_nj_plot->save_plot_button); Enable(fd_nj_plot->save_tree_button); Enable(fd_nj_plot->save_unrooted_button); Disable(fd_nj_plot->subtree_up_button); if(fd_nj_plot->has_br_length) { Enable(fd_nj_plot->branch_length_button); } if(fd_nj_plot->has_internal) { Enable(fd_nj_plot->bootstrap_button); } Enable(fd_nj_plot->reroot_button); fd_nj_plot->need_runtree = TRUE; fd_nj_plot->subtree_notu = fd_nj_plot->notu; if(fd_nj_plot->subtree_center != NULL) scrollnotu(fd_nj_plot->notu); fd_nj_plot->subtree_center = NULL; tree_draw_proc(fd_nj_plot->tree_plot); } void exit_callback(IteM ob) { exit(0); } void tree_draw_proc(PaneL panel) { RecT ob_rect; Int2 width, height; static Int2 previous_h = 0, previous_w = 0; Nlm_BaR bar; int hidebar; fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(panel) ); WatchCursor(); bar = Nlm_GetSlateVScrollBar((Nlm_SlatE)panel); Nlm_GetPanelExtra(panel, &hidebar); if(hidebar && Nlm_Visible(bar)) Nlm_Hide(bar); else if( !hidebar && !Nlm_Visible(bar)) Nlm_Show(bar); Select (panel); ObjectRect(panel, &ob_rect); EraseRect(&ob_rect); FrameRect(&ob_rect); Nlm_ClipRect(&ob_rect); if(fd_nj_plot->notu == 0) { ArrowCursor(); return; } width = ob_rect.right - ob_rect.left; height = ob_rect.bottom - ob_rect.top; SelectFont(fd_nj_plot->current_font); Black(); if( fd_nj_plot->need_runtree || /* recalcul des positions des # si window re-size */ (fd_nj_plot->choix != show_tree && (height != previous_h || width != previous_w))) { runtree(); } fd_nj_plot->need_runtree = FALSE; swap = 0; do_plot(); previous_w = width; previous_h = height; Nlm_ResetClip(); ArrowCursor(); } void tree_click_proc(PaneL panel, PoinT click) { double eps, x, y; int i, found=0, node_num; RecT ob_rect; Int2 panel_x, panel_y, panel_h; fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(panel) ); if(fd_nj_plot->notu == 0) return; if(fd_nj_plot->choix != permutation && fd_nj_plot->choix != depl_racine && fd_nj_plot->choix != subtree) return; ObjectRect(panel, &ob_rect); panel_x = ob_rect.left; panel_y = ob_rect.top; panel_h = ob_rect.bottom - ob_rect.top; eps = fd_nj_plot->char_height/2; x = click.x - panel_x; click.y -= panel_y; y = panel_h - click.y; for(i=0; i<=fd_nj_plot->totpoints; i++ ) { if(fabs(x - (fd_nj_plot->points+i)->x) > eps) continue; if(fabs(y - (fd_nj_plot->points+i)->y) > eps) continue; found=1; break; } if(!found)return; node_num=(fd_nj_plot->points+i)->number; if(fd_nj_plot->choix==depl_racine) { if(node_num >= 1 && node_num <= 2*fd_nj_plot->notu && node_num-1 != fd_nj_plot->root_num) { fd_nj_plot->root_num = node_num-1; removeroot(); } } else if(fd_nj_plot->choix==permutation) { if(node_num >= fd_nj_plot->notu+2 && node_num <= 2*fd_nj_plot->notu+1) swap= node_num-1; else swap=0; } else if(fd_nj_plot->choix==subtree) { if(node_num < fd_nj_plot->notu+2 || node_num > 2*fd_nj_plot->notu+1) return; fd_nj_plot->subtree_center = fd_nj_plot->tabtax[node_num - 1]; fd_nj_plot->subtree_ascend = fd_nj_plot->subtree_center->v3; fd_nj_plot->subtree_notu = calc_n_desc(fd_nj_plot->subtree_center) - 1; scrollnotu(fd_nj_plot->subtree_notu); fd_nj_plot->choix = show_tree; SetValue(fd_nj_plot->choix_group, 0); Nlm_InvalObject(fd_nj_plot->choix_group); if(fd_nj_plot->has_br_length) { Enable(fd_nj_plot->branch_length_button); Nlm_InvalObject(fd_nj_plot->branch_length_button); } if(fd_nj_plot->has_internal) { Enable(fd_nj_plot->bootstrap_button); Nlm_InvalObject(fd_nj_plot->bootstrap_button); } } fd_nj_plot->need_runtree = TRUE; tree_draw_proc(panel); } void paste_tree(IteM ob) { FILE *tmp; char *buff, *tmpfname; if(!update_tree_w_data(ob)) return; if(fd_nj_plot->notu != 0) { err_message("Do \"Edit:clear\" before pasting tree data"); return; } #ifdef WIN_MAC Nlm_textScrapFull = FALSE; /* arrange un bug de Nlm_ClipboardHasString */ #endif if( ! Nlm_ClipboardHasString() ) { err_message("No text describing tree present in clipboard"); return; } buff = Nlm_ClipboardToString(); tmpfname = tempnam(NULL, "njplottemp_"); tmp=fopen(tmpfname,"w"); fwrite(buff, 1, strlen(buff), tmp); fclose(tmp); init_tree(tmpfname, "pasted tree"); remove(tmpfname); } void clear_tree(IteM i) { if(!update_tree_w_data(i)) return; if(fd_nj_plot->notu != 0) free_tree(); fd_nj_plot->notu = 0; SetTitle(fd_nj_plot->nj_plot, "njplot"); #ifdef WIN_MAC SetTitle(fd_nj_plot->win_menu_item, "njplot"); #endif tree_draw_proc(fd_nj_plot->tree_plot); } void change_page_count(ButtoN item) { Nlm_Boolean *pdone; pdone = (Nlm_Boolean *)GetWindowExtra( Nlm_ParentWindow(item) ); *pdone = TRUE; } void page_count_callback(IteM item) { static WindoW win; static Nlm_Boolean done; static TexT select_box; char select[100]; static int first = TRUE; if(first) { win = FixedWindow(-50,-50,-5,-5,"Page count:",NULL); sprintf(select, "%d", page_count); select_box=DialogText(win,select,8,NULL); Advance(win); DefaultButton(win,"ok",change_page_count); SetWindowExtra(win, &done, NULL); first = FALSE; } Show(win); Select(win); Select(select_box); done=FALSE; while(! done) { myWaitAndProcessNextEvent(); } GetTitle(select_box, select, sizeof(select)); sscanf(select, "%d", &page_count); Hide(win); #ifndef WIN_MSWIN /* changement titre menu item impossible sur PC ! */ sprintf(select,"Page count (%d)", page_count); Nlm_SetTitle(item, select); #endif Select(fd_nj_plot->nj_plot); } void string_callback(ButtoN item) { Nlm_Boolean *pdone; pdone = (Nlm_Boolean *)GetWindowExtra( Nlm_ParentWindow(item) ); *pdone = TRUE; } void search_callback(IteM item) { static WindoW win; static Nlm_Boolean search_done; static TexT select_box; static char select[500]; char aux[500]; int num, trouve; static int first = TRUE; if(!update_tree_w_data(item)) return; if(item == fd_nj_plot->SearchItem) { if(first) { win = FixedWindow(-50,-50,-5,-5,"Name searched:",NULL); select_box=DialogText(win,"",15,NULL); Advance(win); DefaultButton(win,"ok",string_callback); SetWindowExtra(win, &search_done, NULL); first = FALSE; } Show(win); Select(win); Select(select_box); search_done=FALSE; while(! search_done) { myWaitAndProcessNextEvent(); } GetTitle(select_box, select, sizeof(select)); majuscules(select); Hide(win); /* Enable(fd_nj_plot->AgainItem); */ Select(fd_nj_plot->nj_plot); } else if(item != fd_nj_plot->AgainItem) { /* happens only when called after start */ strcpy(select, (char *)item); majuscules(select); } if(strlen(select) == 0) return; trouve = FALSE; for(num = 0; num <= fd_nj_plot->totnoms; num++) { strcpy(aux, (fd_nj_plot->noms+num)->nom); majuscules(aux); if(strstr( aux, select) != NULL) { (fd_nj_plot->noms+num)->disp_option = 'r'; trouve = TRUE; } } if(trouve) { tree_draw_proc(fd_nj_plot->tree_plot); } } void init_tree(char *fname, char *displayname) { char *pname, *p; char titre_l[300]; if(displayname == NULL) displayname = extract_filename(fname); fd_nj_plot->choix = show_tree; WatchCursor(); /* read tree file */ if( (pname=preptree(fname)) != NULL ) { char *message; size_t taille; fd_nj_plot->tree_name = NULL; fd_nj_plot->notu = 0; SetTitle(fd_nj_plot->nj_plot, "njplot"); tree_draw_proc(fd_nj_plot->tree_plot); taille = strlen(pname) + strlen(fname) + 3; message = check_alloc(1, taille); strcpy(message, pname); strcat(message, " "); strcat(message, extract_filename(fname) ); err_message(message); free(message); return; } maxy = 1000.; prepare_fonts(); fd_nj_plot->deltay = maxy/fd_nj_plot->notu; if(fd_nj_plot->notu > 0) fd_nj_plot->tree_name = strdup(fname); fd_nj_plot->need_runtree = TRUE; fd_nj_plot->subtree_center = NULL; strcpy(titre_l, displayname ); if(fd_nj_plot->notu > 0) sprintf(titre_l + strlen(titre_l), " (%d tips)", fd_nj_plot->notu + 1); p = titre_l; #ifdef WIN_MAC p = mac_fname_to_roman(titre_l); SetTitle(fd_nj_plot->win_menu_item, displayname); #endif SetTitle(fd_nj_plot->nj_plot, p); tree_draw_proc(fd_nj_plot->tree_plot); if(fd_nj_plot->has_br_length) { Enable(fd_nj_plot->branch_length_button); } else Disable(fd_nj_plot->branch_length_button); if(fd_nj_plot->has_internal) { Enable(fd_nj_plot->bootstrap_button); } else Disable(fd_nj_plot->bootstrap_button); } /* fenetre message d'alerte. Operation Select dans la boucle des evenements qui ramene toujours la fenetre au premier plan. Lent, mais interessant. */ static void alert_ok_action(ButtoN bouton) { Nlm_Boolean *alert_done; alert_done = (Nlm_Boolean *)GetWindowExtra(Parent(bouton)); *alert_done = TRUE; } void err_message(const char *in) { Nlm_WindoW alwin; Nlm_Boolean alert_done; Nlm_TexT t; int nl; char *p, *q, *r; static char texte[1000]; int w, width; #ifdef WIN_MAC alwin = Nlm_FixedWindow(-50,-50,-5,-5,"MESSAGE",NULL); // Bug: ModalWindow crashes when return key hit #else alwin = Nlm_ModalWindow(-50,-50,-5,-5,NULL); Nlm_SetTitle(alwin, "Message"); #endif Nlm_SelectFont (Nlm_systemFont); nl = 0; p = (char *)in; r = texte; width = 0; while(TRUE) { q = strchr(p,'\n'); if(q == NULL) q = p + strlen(p); nl++; if( (r - texte) + (q - p) + 2 >= sizeof(texte) ) break; if(q > p) { memcpy(r, p, q - p); w = Nlm_TextWidth(p, q - p); if(w > width) width = w; } r += q - p; #ifdef WIN_MSWIN *(r++) = '\r'; #endif #ifdef WIN_MAC *(r++) = '\r'; #else *(r++) = '\n'; #endif *r = 0; q = strchr(p,'\n'); if(q == NULL) break; p = q + 1; } width = ( width + 20 ) / Nlm_stdCharWidth; t = Nlm_ScrollText(alwin, width, nl , Nlm_systemFont, TRUE, NULL); Nlm_SetTitle(t, texte); Nlm_Break(alwin); Nlm_DefaultButton(alwin,"ok",alert_ok_action); Nlm_Show(alwin); alert_done=FALSE; Nlm_SetWindowExtra(alwin, &alert_done, NULL); Nlm_ArrowCursor(); while(! alert_done) { #ifdef WIN_MAC if(! Nlm_InFront(alwin) ) Nlm_Select(alwin); // to emulate modal window on mac #endif myWaitAndProcessNextEvent(); } Nlm_Remove(alwin); } #else /* NO_GUI */ void err_message(const char *in) { fprintf(stderr, "%s\n", in); } #endif /* NO_GUI */ void prepare_pdf_font(int font_num, int use_bold, int use_italic) { /* prepare PDF name of font */ strcpy(current_ps_font, list_ps_font_name[font_num]); if( use_bold && use_italic ) if(font_num == times) strcat(current_ps_font,"-BoldItalic"); else strcat(current_ps_font,"-BoldOblique"); else if( use_bold ) strcat(current_ps_font,"-Bold"); else if( use_italic ) { if(font_num == times) strcat(current_ps_font,"-Italic"); else strcat(current_ps_font,"-Oblique"); } else if(font_num == times) strcat(current_ps_font,"-Roman"); } int direct_pdf_plot(char *fname) { char *p, *q; fd_nj_plot->choix = show_tree; /* read tree file */ if( (p = preptree(fname) ) != NULL ) { fprintf(stderr, "%s\n", p); return 1; } strcpy(plotfilename, fname); q = extract_filename(plotfilename); p = strchr(q, '.'); if(p == NULL) p = plotfilename + strlen(plotfilename); file_plot = TRUE; #ifdef TTY strcpy(p, ".txt"); #else #ifdef WITH_PDF strcpy(p, ".pdf" ); pdf_plot = TRUE; #else strcpy(p, ".ps"); #endif prepare_pdf_font(times, FALSE, FALSE); #endif maxy = 1000.; fd_nj_plot->deltay = maxy/fd_nj_plot->notu; runtree(); #ifdef ADDROOT /* calcul du nombre de feuilles (tres obligatoire !!!) */ calc_otu(NULL, fd_nj_plot->racine); /* calcul de son format phylip */ p = ecrit_arbre_parenth(fd_nj_plot->racine); if(p == NULL) { fprintf(stderr, "Sorry, not enough memory\n"); exit(1); } /* ecriture de son format phylip */ printf("%s\n", p); #elif defined(TTY) tty_plot(); #elif !defined(WIN_MAC) #ifdef WITH_PDF plot_to_pdf(); #else postscript_plot(); #endif #endif return 0; } int calc_otu(struct noeud *pere, struct noeud *centre) { struct noeud *gauche, *droite; double bg, bd, bpere; if(centre == NULL) return 0; /* orienter le noeud centre de maniere standard: centre->v3=pere */ if( centre->v1 == pere ) { gauche =centre->v2; droite = centre->v3; bg = centre->l2; bd = centre->l3; bpere = centre->l1; } else if( centre->v2 == pere ) { gauche =centre->v1; droite = centre->v3; bg = centre->l1; bd = centre->l3; bpere = centre->l2; } else { gauche =centre->v1; droite = centre->v2; bg = centre->l1; bd = centre->l2; bpere = centre->l3; } centre->v3=pere; centre->v1=gauche; centre->v2=droite; centre->l3=bpere; centre->l1=bg; centre->l2=bd; return calc_otu(centre, centre->v1) + calc_otu(centre, centre->v2); } void remove_arg(int target, int *argc, char *argv[]) { int num; for(num = target; num < *argc - 1; num++) argv[num] = argv[num+1]; (*argc)--; } #ifdef NO_PDF #define PDFONLY "-psonly" #else #define PDFONLY "-pdfonly" #endif void process_args(int *argc, char *argv[], char **pred, int *pboot_arg, int *p_plot_br_l, int *p_font_size_rank) { int num, taille; for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-h", 2) == 0 ){ char message[1000]; sprintf(message, "Usage: %s [-options] [tree_file_name]\n" "where options are:\n" "-h print out this message\n" #ifdef ADDROOT "-outotu name name of species to use as outgroup for rooting\n" #elif defined(TTY) "-txtw n width of output text (default = 120)\n" "-prefix string string to prefix to all leaf names in output tree\n" #else "-us PDF or PostScript tree file prepared for US Letter paper size\n" #ifndef NO_GUI PDFONLY" no window interface, just write the PDF/PostScript tree plot\n" " to file named as input tree file with .pdf/.ps extension\n" "-red xxxx highlight in red all taxon names containing string xxxx\n" #endif "-pc n number of pages for PDF/PostScript output\n" "-size n font size n used for taxon names\n" "-lengths show branch lengths if they appear in tree file\n" "-boot show bootstrap values if they appear in tree file\n" "-psize size of page for PDF/PostScript expressed as WIDTHxHEIGHT\n" "-notitle don't include title in PDF/PostScript output\n" #endif "\n" "and where tree_file_name is the name of a tree file in the Newick format\n" #ifdef TTY "the output goes to file .txt\n" #elif defined(ADDROOT) "the output goes to stdout\n" #elif defined(NO_GUI) "the output goes to file .pdf or .ps\n" #endif , extract_filename(argv[0]) ); #ifdef MICRO err_message(message); #else fputs(message, stderr); #endif exit(0); } } *pboot_arg = FALSE; *p_plot_br_l = FALSE; for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-us", 3) == 0) { paper_choice = LETTER; remove_arg(num, argc, argv); break; } } for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-size", 5) == 0) { const int maxi = sizeof(list_font_size) / sizeof(int); taille = 12; if(num + 1 < *argc) { sscanf(argv[num + 1], "%d", &taille); remove_arg(num + 1, argc, argv); } remove_arg(num, argc, argv); for(num = 0; num < maxi; num++) if(taille <= list_font_size[num]) break; if(num >= maxi) num = maxi - 1; *p_font_size_rank = num; break; } } for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-pc", 3) == 0) { if(num + 1 < *argc) { sscanf(argv[num + 1], "%d", &page_count); remove_arg(num + 1, argc, argv); } remove_arg(num, argc, argv); break; } } for(num = 1; num < *argc; num++) { if( strncmp(argv[num], PDFONLY, 9) == 0) { pdf_plot_only = TRUE; remove_arg(num, argc, argv); break; } } for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-lengths", 8) == 0) { *p_plot_br_l = TRUE; remove_arg(num, argc, argv); break; } } for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-boot", 5) == 0) { *pboot_arg = TRUE; remove_arg(num, argc, argv); break; } } for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-psize", 6) == 0) { if(num + 1 < *argc) { sscanf(argv[num + 1], "%dx%d", &ps_width, &ps_height); remove_arg(num + 1, argc, argv); } remove_arg(num, argc, argv); break; } } for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-notitle", 8) == 0) { no_title = TRUE; remove_arg(num, argc, argv); break; } } *pred = NULL; #ifndef NO_GUI for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-red", 4) == 0) { if(num + 1 < *argc) { *pred = argv[num+1]; remove_arg(num + 1, argc, argv); } remove_arg(num, argc, argv); break; } } #elif defined(TTY) physx = 120; /* default width of text output */ for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-txtw", 5) == 0) { if(num + 1 < *argc) { int val; sscanf(argv[num+1], "%d", &val); physx = (double)val; remove_arg(num + 1, argc, argv); } remove_arg(num, argc, argv); break; } } for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-prefix", 7) == 0) { if(num + 1 < *argc) { tty_prefix = argv[num+1]; remove_arg(num + 1, argc, argv); } remove_arg(num, argc, argv); break; } } #elif defined(ADDROOT) for(num = 1; num < *argc; num++) { if(strcmp(argv[num], "-outotu") == 0) { if(num + 1 < *argc) { outotu = argv[num+1]; remove_arg(num + 1, argc, argv); } remove_arg(num, argc, argv); break; } } #endif } double length_log_phys(double p) { return p * tek_dx; } double length_phys_log(double p) { return p / tek_dx; } double arrondi_echelle(double x) { /* arrondi x a une valeur 1, 2, 5 pour echelle */ double l, n; int r; static int corresp[] = {1,1,2,2,5,5,5,10,10,10,10,10}; /* 0,1,2,3,4,5,6, 7, 8, 9,10,11 */ l = log10(x); n = floor(l); l = x * pow(10., -n); /* 10. plutot que 10 necessaire pour alpha! */ r = myrint(l); r = corresp[r]; return r * pow(10., n); /* 10. plutot que 10 necessaire pour alpha! */ } void scale_window(double lxmin, double lxmax, double lymin, double lymax, double pxmin, double pxmax, double pymin, double pymax) /* to scale the plot window for logical coords l... in physical coords p... */ { tek_xmin=lxmin; tek_xmax=lxmax; tek_ymin=lymin; tek_ymax=lymax; tek_minx=pxmin; tek_maxx=pxmax; tek_miny=pymin; tek_maxy=pymax; tek_dx = (tek_maxx-tek_minx)/(tek_xmax-tek_xmin < 1e-4 ? 1e-4 : tek_xmax-tek_xmin); tek_dy = (tek_maxy-tek_miny)/(tek_ymax-tek_ymin); } void ch_echelle(double lx, double ly, double *px, double *py) /* conversion coord logique lx,ly en coord physique px,py */ { *px = (lx-tek_xmin)*tek_dx + tek_minx; *py = (ly-tek_ymin)*tek_dy + tek_miny; } void convert_mem_point(void) { int i; if(converted) return; for (i=0; i<=fd_nj_plot->totpoints; i++) { ch_echelle( (fd_nj_plot->points+i)->x, (fd_nj_plot->points+i)->y, &((fd_nj_plot->points+i)->x), &((fd_nj_plot->points+i)->y) ); (fd_nj_plot->points+i)->x += fd_nj_plot->char_height / 6.; } converted = TRUE; } double calc_echelle(double larg) { /* rend taille logique pour echelle optimale */ double log_val, phys_val; phys_val = larg/10; log_val = length_phys_log(phys_val); log_val = arrondi_echelle(log_val); return log_val; } void draw_scale(void) { char ech_name[20]; double phys_w, y, xd, xf, lc; double log_val; log_val = calc_echelle(physx); phys_w = myrint(length_log_phys(log_val)); y = physy - 1.35 * fd_nj_plot->char_height; xf = physx * 0.95; xd = xf - phys_w; sprintf(ech_name, "%.1g", log_val); lc = calc_text_size(ech_name, NULL, NULL); dir_moveto(xd, y); dir_lineto(xf, y); #ifndef TTY dir_moveto(xd, y - fd_nj_plot->char_height/3.); dir_lineto(xd, y + fd_nj_plot->char_height/3.); dir_moveto(xf, y - fd_nj_plot->char_height/3.); dir_lineto(xf, y + fd_nj_plot->char_height/3.); #endif dir_moveto( (xd + xf)/2 - lc/2, y + fd_nj_plot->char_height/6. ); plotstring(ech_name); } #ifndef NO_GUI void scrollcallback(Nlm_BaR b, Nlm_SlatE g, Nlm_Int2 after, Nlm_Int2 before) { fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(b) ); tree_draw_proc(fd_nj_plot->tree_plot); } void zoomcallback(Nlm_SwitcH s, Nlm_Int2 after, Nlm_Int2 before) { char aux[50]; int hide; fd_nj_plot = (FD_nj_plot *)Nlm_GetWindowExtra( Nlm_ParentWindow(s) ); if(after == 1) fd_nj_plot->zoomvalue = 1.; else if(after > before) fd_nj_plot->zoomvalue *= 1.4; else if(after < before) fd_nj_plot->zoomvalue /= 1.4; sprintf(aux, "%d%%", (int)(100. * fd_nj_plot->zoomvalue + 0.5) ); Nlm_SetTitle(fd_nj_plot->zoomprompt, aux); Nlm_InvalObject(fd_nj_plot->zoomprompt); scrollnotu(fd_nj_plot->subtree_notu); hide = (after == 1); Nlm_SetPanelExtra(fd_nj_plot->tree_plot, &hide); tree_draw_proc(fd_nj_plot->tree_plot); } void scrollnotu(int count) { Nlm_BaR obj; int lines; float old; obj = Nlm_GetSlateVScrollBar( (SlatE)fd_nj_plot->tree_plot ); old = Nlm_GetBarValue(obj) / (float)Nlm_GetBarMax(obj); lines = (count + 1) * (1 - 1/fd_nj_plot->zoomvalue) + 0.5; if(lines < 3) lines = 3; Nlm_CorrectBarMax(obj, lines); Nlm_CorrectBarValue(obj, old * lines); Nlm_CorrectBarPage(obj, lines/fd_nj_plot->zoomvalue, lines/fd_nj_plot->zoomvalue); } #endif void do_plot(void) { struct trait *p; int num; double factor, value, m = 1, v = 0, zoom = 1; #ifndef NO_GUI /* size of the tree plot window */ if( ! (file_plot || doing_print) ) { Nlm_RecT ob_rect; Nlm_BaR bar; Nlm_ObjectRect(fd_nj_plot->tree_plot, &ob_rect); bar = Nlm_GetSlateVScrollBar((Nlm_SlatE)fd_nj_plot->tree_plot); v = (double)Nlm_GetBarValue(bar); m = (double)Nlm_GetBarMax(bar); physx = ob_rect.right - ob_rect.left; physy = (ob_rect.bottom - ob_rect.top); zoom = fd_nj_plot->zoomvalue; } #endif factor = 1e99; for(num=0; num<=fd_nj_plot->notu; num++) { if(fd_nj_plot->profs[num] == 0) continue; if(fd_nj_plot->profs[num] <= 0) continue; /* new */ value = (physx - fd_nj_plot->widnames[num] - 2 * fd_nj_plot->ascent) / fd_nj_plot->profs[num]; if(value < factor) factor = value; } physx_min = fd_nj_plot->ascent; physx_corr = maxx * factor + physx_min; if(physx_corr <= physx_min + 1) { physx_corr = physx_min + 1; } physy_corr = physy - 2*fd_nj_plot->char_height; physy_min = fd_nj_plot->char_height; #ifdef TTY physy_corr = physy - 3; physy_min = 0; #endif /* scale_window(0, maxx, 0, maxy, physx_min, physx_corr, physy_min, physy_corr); */ scale_window(0, maxx, ((m-v)/m) * (maxy - maxy/zoom), ((m-v)/m) * (maxy - maxy/zoom) + maxy/zoom, physx_min, physx_corr, physy_min, physy_corr); for(num=0; num<=fd_nj_plot->totnoms; num++) { mydrawstring( (fd_nj_plot->noms+num)->x, (fd_nj_plot->noms+num)->y , (fd_nj_plot->noms+num)->nom, (fd_nj_plot->noms+num)->disp_option ); } for(num=0; num<=fd_nj_plot->tottraits; num++) { p= fd_nj_plot->traits+num; moveto(p->xd,p->yd); lineto(p->xf,p->yf); } if(fd_nj_plot->has_br_length){ /* echelle */ draw_scale(); } convert_mem_point(); } /* end of do_plot */ int calc_text_size(char *text, int *pheight, int *pascent) { int ascent, descent, width; if(file_plot) { int font_size; font_size = list_font_size[fd_nj_plot->font_size_rank]; #ifdef WIN_MAC { static FontInfo macfontinfo; width = TextWidth(text, 0, strlen(text)); GetFontInfo(&macfontinfo); ascent = macfontinfo.ascent; descent = macfontinfo.descent; } #elif defined(TTY) width = strlen(text); ascent = 1; descent = 0; #elif defined(NO_GUI) width = strlen(text) * font_size * postscript_ratio + 0.5; ascent = font_size; descent = 0; #else #ifdef WITH_PDF if(pdf_plot && pdf != NULL) width = PDF_stringwidth(pdf, text, pdf_font, font_size); else #endif /* faire calculer taille en mode ecran et appliquer ratio ecran->postscript */ width = Nlm_TextWidth(text, strlen(text) ) * postscript_ratio + 0.5; ascent = font_size; descent = 0; #endif } #ifndef NO_GUI else { #ifdef WIN_MSWIN HDC picHDC = Nlm_currentHDC; if(doing_copy) { Nlm_currentHDC = Nlm_GetPicWinHDC(); Nlm_SelectFont(fd_nj_plot->current_font); } #endif ascent = Nlm_Ascent(); descent = Nlm_Descent(); width = Nlm_TextWidth(text, strlen(text) ); #ifdef WIN_MSWIN if(doing_copy) Nlm_currentHDC = picHDC; #endif } #endif if(pheight != NULL) *pheight = ascent + descent; if(pascent != NULL) *pascent = ascent; return width; } static int lastmovex, lastmovey; #define bound_int2(i) ( i > INT2_MAX ? INT2_MAX : (i < INT2_MIN ? INT2_MIN : i) ) void plotstring(char *nom) { if(file_plot) { #ifdef WIN_MAC static char copy[255]; int l; l = strlen(nom); *copy = l; memcpy(copy + 1, nom, l + 1); DrawString( (ConstStr255Param) copy); #elif defined(TTY) memcpy(tty_page[tty_y]+tty_x+1, nom, strlen(nom)); #else #ifdef WITH_PDF if(pdf_plot) { PDF_stroke(pdf); PDF_show_xy(pdf, nom, lastmovex, lastmovey); } else #endif fprintf(plotfile,"(%s) show\n",nom); #endif } #ifndef NO_GUI else { #ifdef WIN_MSWIN int y; y = lastmovey - (doing_copy ? fd_nj_plot->ascent : 0) ; y = bound_int2(y); Nlm_PaintStringEx(nom, lastmovex, y ); #else Nlm_PaintString(nom); #endif } #endif } void dir_moveto(double x,double y) /* move to physical coord x,y */ { if(file_plot) { int xi,yi; xi=x; #ifdef WIN_MAC xi += margin; yi = physy - y + margin; MoveTo(xi, yi); #elif defined(TTY) tty_x = x + 0.5; tty_y = y + 0.5; #else yi=y; #ifdef WITH_PDF if(pdf_plot) { PDF_moveto(pdf, xi, yi); lastmovex = xi; lastmovey = yi; } else #endif fprintf(plotfile,"%d %d moveto\n",xi,yi); #endif } #ifndef NO_GUI else { if(doing_print) { lastmovex = myrint(x) + print_rect.left; lastmovey = print_rect.bottom - myrint(y); Nlm_MoveTo(lastmovex, bound_int2(lastmovey) ); } else { Nlm_RecT obrect; ObjectRect(fd_nj_plot->tree_plot, &obrect); lastmovex = myrint(x) + obrect.left; lastmovey = obrect.bottom - myrint(y); if(lastmovey >= INT2_MAX) lastmovey = INT2_MAX - 1; else if(lastmovey < 0) lastmovey = 0; Nlm_MoveTo((Nlm_Int2)lastmovex, (Nlm_Int2)lastmovey ); } } #endif } void dir_lineto(double x,double y) /* draw line from current pos to physical coord x,y */ { int xi,yi; char *p; if(file_plot) { xi=x; #ifdef WIN_MAC xi += margin; yi = physy - y + margin; LineTo(xi, yi); #elif defined(TTY) if(tty_y == (int)(y + 0.5)) { xi = x + 0.5; while(tty_x != xi) { p = tty_page[tty_y] + tty_x; *p = (*p == '|' ? '+' : '-'); if(tty_x < xi) ++tty_x; else --tty_x; } p = tty_page[tty_y] + tty_x; *p = (*p == '|' ? '+' : '-'); } else { yi = y + 0.5; while(tty_y != yi) { p = tty_page[tty_y] + tty_x; *p = (*p == '-' ? '+' : '|'); if(tty_y < yi) ++tty_y; else --tty_y; } p = tty_page[tty_y] + tty_x; *p = (*p == '-' ? '+' : '|'); } #else yi=y; #ifdef WITH_PDF if(pdf_plot) { PDF_lineto(pdf, xi, yi); PDF_stroke(pdf); } else #endif fprintf(plotfile,"%d %d lineto stroke\n",xi,yi); #endif } #ifndef NO_GUI else { if(doing_print) { xi = myrint(x) + print_rect.left; yi = print_rect.bottom - myrint(y) ; yi = bound_int2(yi); Nlm_LineTo( xi, yi ); } else { Nlm_RecT obrect; ObjectRect(fd_nj_plot->tree_plot, &obrect); {int j; j = obrect.bottom - myrint(y); if(j >= INT2_MAX) j = INT2_MAX - 1; else if( j < 0) j = 0; Nlm_LineTo(myrint(x) + obrect.left, (Nlm_Int2)j); } } } #endif } #ifdef WIN_MAC static void closewinproc(Nlm_WindoW w) { Nlm_Remove(Nlm_ParentWindow(w)); } void show_apropos_njplot(Nlm_IteM item) { Nlm_WindoW win; int larg; Nlm_DoC doc; char ligne[100], *p; static char txt[5000]; if(help_file == NULL) return; win = Nlm_FixedWindow( -50, -33, -3, -3, "about Njplot", closewinproc); Nlm_SelectFont(Nlm_programFont); larg = 81 * Nlm_TextWidth("Q", 1); doc = Nlm_DocumentPanel(win, larg, 25 * Nlm_LineHeight() ); rewind(help_file); fgets(ligne, sizeof(ligne), help_file); p = txt; while(fgets(ligne, sizeof(ligne), help_file) != NULL) { if(strncmp(ligne, ">>>", 3) == 0) break; if(strncmp(ligne, "Version:", 8) == 0) sprintf(ligne, "Version: %s\n", NJPLOTVERSION); strcpy(p, ligne); p += strlen(ligne); } Nlm_AppendText(doc, txt, NULL, NULL, Nlm_programFont); Nlm_Break(win); Nlm_DefaultButton(win, "ok", (Nlm_BtnActnProc)closewinproc); Nlm_Show(doc); Nlm_Show(win); } void mac_timer(void) { static FD_nj_plot *current, *previous = NULL; current = (FD_nj_plot *)Nlm_GetWindowExtra(Nlm_FrontWindow()); if(current != previous && current != NULL && current->tag == tag_njplot ) { previous = current; Nlm_SetValue(current->choix_taille, current->font_size_rank); Nlm_SetValue(current->choix_font, current->font_family_rank); Nlm_SetStatus(current->bold_item, strchr(current->font_bold_italic, 'b') != NULL); Nlm_SetStatus(current->italic_item, strchr(current->font_bold_italic, 'i') != NULL); } } void window_callback(IteM item) { Nlm_WindoW w = Nlm_desktopWindow; while(w != NULL) { FD_nj_plot *data = Nlm_GetWindowExtra(w); if(data != NULL && data->tag == tag_njplot && data->win_menu_item == item) { fd_nj_plot = data; Nlm_Select(fd_nj_plot->nj_plot); break; } w = Nlm_GetNext(w); } } void create_win_if_needed(char *fname) { if( (!update_tree_w_data(NULL)) || fd_nj_plot->notu != 0) fd_nj_plot = create_win_nj_plot(); init_tree( fname, NULL); Nlm_Show(fd_nj_plot->nj_plot); Nlm_ObjectRect(fd_nj_plot->nj_plot, &(fd_nj_plot->old_rect)); } int is_macosx(void) { long val; Gestalt (gestaltSystemVersion, &val); return (val >= 0x1000); } int crefpict(char *fname, PicHandle picture) { QDPictRef myqdpict; int err; myqdpict = MyPictToQDPict(picture); if(myqdpict != NULL) err = MyQDPictToPDFfile(myqdpict, fname); else err = TRUE; KillPicture(picture); return err; } void example_tree(IteM unused) { char *p; FILE *in; if(!update_tree_w_data(NULL)) return; if(fd_nj_plot->notu > 0) free_tree(); fd_nj_plot->notu = 0; p = MG_GetBundleResourcesDir(); strcat(p, "/example.phb"); in = fopen(p, "r"); if(in == NULL) { err_message("Sorry, no example available"); return; } fclose(in); init_tree(p, NULL); } void copy_plot(IteM unused) { extern void MyCopyPictToClipboard (PicHandle mypicture); if(!update_tree_w_data(NULL)) return; if(fd_nj_plot->notu == 0) return; doing_copy = TRUE; pict_plot(); MyCopyPictToClipboard (mypicture ); KillPicture(mypicture); file_plot = FALSE; fd_nj_plot->need_runtree = TRUE; doing_copy = FALSE; ArrowCursor(); } void pict_plot(void) { char mess[250]; double currx, curry; int erreur; int macfont; Style mystyle=normal; margin = 30; myrect.top=10; myrect.left=10; myrect.bottom=760 * page_count; myrect.right=500; ClipRect(&myrect); mypicture = OpenPicture(&myrect); PenNormal(); macfont = GetValue(fd_nj_plot->choix_font); if(macfont == courier) macfont=22; else if(macfont == helvetica) macfont=21; else if(macfont == times) macfont=20; else macfont=22; TextFont(macfont); TextSize( list_font_size[fd_nj_plot->font_size_rank] ); if( GetStatus(fd_nj_plot->bold_item) ) mystyle += bold; if( GetStatus(fd_nj_plot->italic_item) ) mystyle += italic; TextFace(mystyle); physx = myrect.right-myrect.left - 2 * margin; physy = myrect.bottom-myrect.top - 2 * margin; WatchCursor(); file_plot = TRUE; fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1; end_br_length = fd_nj_plot->br_length_txt; currx = 0.; maxx = 0.; nexty = -fd_nj_plot->deltay; if(fd_nj_plot->subtree_center == NULL) mem_plot(NULL, fd_nj_plot->racine, currx, &curry); else mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry); do_plot(); file_plot = FALSE; /* pour eviter boucle infernale! */ ClosePicture(); if(doing_copy) return; erreur = crefpict(plotfilename, mypicture); if( !erreur ) sprintf(mess, "Tree plot is now in file %s in PDF format", extract_filename(plotfilename) ); else sprintf(mess, "Error while writing to file %s", extract_filename(plotfilename) ); err_message(mess); fd_nj_plot->need_runtree = TRUE; ArrowCursor(); } #endif #ifdef MICRO #ifdef WIN_MSWIN #define TITLEFONT "Times New Roman,10" #else #define TITLEFONT "Times,10" #endif void print_title(int x, int y, char *text, Nlm_FonT title_font, int p, int totp) { static char ligne[200]; time_t heure; int h; time (&heure); #ifdef WIN_MAC text = mac_fname_to_roman(text); #endif sprintf(ligne, "njplot %s %s", text, ctime(&heure) ); h = strlen(ligne) - 1; ligne[h] = 0; if(totp > 1) sprintf(ligne + h, " Page %d of %d", p, totp); Nlm_Black(); Nlm_SelectFont(title_font); Nlm_PaintStringEx(ligne, x, y); } void print_plot(IteM item) { double currx, curry; Nlm_WindoW w; int h, page, superpos; Nlm_RecT true_print_rect, title_rect; Nlm_FonT title_font; if(!update_tree_w_data(item)) return; if(fd_nj_plot->notu == 0) return; w = Nlm_StartPrinting(); if(w == NULL) return; Nlm_WatchCursor(); doing_print = TRUE; Nlm_PrintingRect(&true_print_rect); title_rect = true_print_rect; title_font = Nlm_ParseFont(TITLEFONT); Nlm_SelectFont(title_font); calc_text_size("Mq", &fd_nj_plot->char_height, &fd_nj_plot->ascent); title_rect.bottom = title_rect.top + fd_nj_plot->ascent - 1; true_print_rect.top += fd_nj_plot->char_height; print_rect.left = true_print_rect.left; print_rect.right = true_print_rect.right; print_rect.top = true_print_rect.top; print_rect.bottom = true_print_rect.bottom; h = print_rect.bottom - print_rect.top + 1; superpos = h / 30; print_rect.bottom = print_rect.top + (page_count - 1) * (h - superpos) + h - 1; fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1; end_br_length = fd_nj_plot->br_length_txt; currx = 0.; maxx = 0.; nexty = -fd_nj_plot->deltay; if(fd_nj_plot->subtree_center == NULL) mem_plot(NULL, fd_nj_plot->racine, currx, &curry); else mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry); for(page = 0; page < page_count; page++) { Nlm_StartPage(); Nlm_ClipPrintingRect( &title_rect); print_title(title_rect.left, title_rect.bottom, fd_nj_plot->tree_name, title_font, page + 1, page_count); Nlm_ClipPrintingRect( &true_print_rect); Nlm_SelectFont(fd_nj_plot->current_font); Nlm_Gray(); Nlm_FrameRect(&true_print_rect); Nlm_Black(); physx = print_rect.right - print_rect.left; physy = print_rect.bottom - print_rect.top; do_plot(); Nlm_EndPage(); print_rect.top -= (h - superpos); print_rect.bottom -= (h - superpos); } Nlm_EndPrinting(w); fd_nj_plot->need_runtree = TRUE; doing_print = FALSE; ArrowCursor(); } #endif #ifdef WIN_MSWIN void copy_plot(IteM item) { double currx, curry; Nlm_WindoW w; Nlm_RecT r; if(!update_tree_w_data(item)) return; if(fd_nj_plot->notu == 0) return; /* dans la picture, les calculs de taille de caractere ne marchent pas! il faut les faire dans le DC de la fenetre */ WatchCursor(); doing_copy = TRUE; Nlm_GetPosition( fd_nj_plot->tree_plot , &r); w = Nlm_StartPicture(&r); fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1; end_br_length = fd_nj_plot->br_length_txt; currx = 0.; maxx = 0.; nexty = -fd_nj_plot->deltay; Nlm_Black(); Nlm_SelectFont(fd_nj_plot->current_font); if(fd_nj_plot->subtree_center == NULL) mem_plot(NULL, fd_nj_plot->racine, currx, &curry); else mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry); do_plot(); Nlm_EndPicture(w); fd_nj_plot->need_runtree = TRUE; doing_copy = FALSE; ArrowCursor(); } #endif char *preptree(char *fname) { int i, c, steparbre, maxarbre, maxlname, v; FILE *njfile; char *arbre, *der_arbre, *finarbre, *tmp; static char message[200]; char *last_bootstrap, *p; if( (njfile=fopen(fname,"r")) == NULL ){ sprintf(message, "Tree file %s not found.", fname); return (message); } /* recherche du debut de la description de l'arbre */ do c=fgetc(njfile); while ( isspace(c) ); /* for fastDNAml format, skip initial [comment] */ if(c == '[') { do c=fgetc(njfile); while (c != ']'); do c=fgetc(njfile); while ( isspace(c) ); } if ( c != '(') { fclose(njfile); goto erreur; } /* lecture de l'arbre par paquets de steparbre caracteres*/ steparbre=1000; maxarbre=steparbre; arbre=check_alloc(maxarbre,1); der_arbre = arbre+maxarbre; *arbre=c; fd_nj_plot->notu=2; i=3; v = 0; finarbre=arbre; while( (c=fgetc(njfile)) != EOF && c != ';') { if( c=='\n' || c=='\r') continue; if(++finarbre >= der_arbre-2) { maxarbre += steparbre; tmp=check_alloc(maxarbre,1); memcpy(tmp,arbre,finarbre-arbre); finarbre=tmp+(finarbre-arbre); free(arbre); arbre=tmp; der_arbre=arbre+maxarbre; } *(finarbre)=c; if(c == ')') fd_nj_plot->notu++; if(c == '(') i++; if(c == ',') v++; } *(finarbre+1)='\0'; fclose(njfile); if(i != fd_nj_plot->notu)goto erreur; finarbre = nextpar(arbre) + 1; /* memorize bootstrap value after last ) */ while(isspace(*finarbre)) finarbre++; if(*finarbre != ';' && *finarbre != 0) { last_bootstrap = strdup(finarbre); p = strchr(last_bootstrap, ';'); if(p != NULL) *p = 0; } else last_bootstrap = NULL; arbre = (char *)realloc(arbre, strlen(arbre) + 4 * v + 5 ); /* worst case add 4 chars for each , */ make_binary_or_unrooted(arbre); fd_nj_plot->long_arbre_parenth = strlen(arbre); fd_nj_plot->notu = v ; /* after this fd_nj_plot->notu = number of OTUs - 1 */ fd_nj_plot->totbranches= -1; /* allocate all memory */ fd_nj_plot->tabtax = (struct noeud **)check_alloc(2*fd_nj_plot->notu +1,sizeof(struct noeud *)); fd_nj_plot->branches = (branche *)check_alloc(fd_nj_plot->notu, sizeof(branche)); fd_nj_plot->tabnames = (char **)check_alloc(2*fd_nj_plot->notu+1, sizeof(char *)); for(i=0; i<2*fd_nj_plot->notu+1; i++) *(fd_nj_plot->tabtax+i)= (struct noeud *)check_alloc(1,s_noeud); fd_nj_plot->noms = (struct nom *)check_alloc(5*fd_nj_plot->notu+1,sizeof(struct nom)); fd_nj_plot->points = (struct mon_point *)check_alloc(4*fd_nj_plot->notu+1,sizeof(struct mon_point)); fd_nj_plot->traits = (struct trait *)check_alloc(3*fd_nj_plot->notu,sizeof(struct trait)); fd_nj_plot->labels = (char **)check_alloc(fd_nj_plot->notu+1, sizeof(char *)); fd_nj_plot->widnames = (int *)check_alloc(fd_nj_plot->notu+1, sizeof(int)); fd_nj_plot->profs = (double *)check_alloc(fd_nj_plot->notu+1, sizeof(double)); fd_nj_plot->br_length_txt = (char *)check_alloc(2*fd_nj_plot->notu,10); loadphylip(arbre, last_bootstrap); free(arbre); maxlname = 0; /* largeur max des noms des feuilles */ if(nextotu != fd_nj_plot->notu) bad_format("Error: incorrect tree file"); #ifdef TTY if(tty_prefix != NULL) { int l, lp, i; char *p; lp = strlen(tty_prefix); for(i=0; i <= fd_nj_plot->notu; i++) { l = strlen(fd_nj_plot->labels[i]) + lp; p = (char *)check_alloc(l + 1, 1); strcpy(p, tty_prefix); strcat(p, fd_nj_plot->labels[i]); free(fd_nj_plot->labels[i]); fd_nj_plot->labels[i] = p; } } #endif for(i = 0; i <= nextotu; i++) { c = strlen(fd_nj_plot->labels[i]); if(c > maxlname) maxlname = c; } for(i = 0; i < 2*fd_nj_plot->notu+1; i++) { fd_nj_plot->tabnames[i] = (char *)check_alloc(maxlname + 2 + 1, 1); /*2=place pour # */ } if(!fd_nj_plot->rooted) { fd_nj_plot->racine = *(fd_nj_plot->tabtax+(++num_noeud)); if(num_noeud >= 2*fd_nj_plot->notu + 1) bad_format("Error: incorrect tree file"); if(fd_nj_plot->has_br_length) { place_midpoint_root(); fd_nj_plot->root_num = -1; } else { /* ancienne version: derniere espece est groupe externe */ fd_nj_plot->racine->v3 = NULL; fd_nj_plot->root_num = fd_nj_plot->notu; } } else { fd_nj_plot->racine = *(fd_nj_plot->tabtax+num_noeud); fd_nj_plot->root_br_l= fd_nj_plot->racine->l1 + fd_nj_plot->racine->l2; fd_nj_plot->root_num = num_noeud; if(!fd_nj_plot->has_br_length) calc_brl_for_lengthless(fd_nj_plot->racine, NULL); /* y a-t-il un bootstrap sur l'une des branches racine ? */ i = get_br_from_bouts(fd_nj_plot->racine, fd_nj_plot->racine->v1); if(i == -1) i = get_br_from_bouts(fd_nj_plot->racine, fd_nj_plot->racine->v2); if(i != -1 && get_br_from_bouts(fd_nj_plot->racine, NULL) == -1) { fd_nj_plot->branches[i].bouta = fd_nj_plot->racine->v1; fd_nj_plot->branches[i].boutb = fd_nj_plot->racine->v2; } } if(fd_nj_plot->notu+1<3) return ("Tree should contain at least 3 elements."); fd_nj_plot->subtree_notu = fd_nj_plot->notu; #ifndef NO_GUI if(!pdf_plot_only) scrollnotu(fd_nj_plot->notu); #endif return NULL; erreur: #ifdef WIN_MAC return ("File or pasted data does not contain correct tree."); #else return ("File does not contain correct tree data."); #endif } /* end of preptree */ char *check_alloc(int nbrelt, int sizelt) { char *retval; if( (retval=(char *)calloc(nbrelt,sizelt)) != NULL ) return retval; err_message("ERROR: Not enough memory."); exit(1); } void loadphylip(char *arbre, char *last_bootstrap) { char *deba,*debb,*debc, *finarbre; struct noeud *p1, *p2, *p3, *p; branche *int_br_g, *int_br_d; fd_nj_plot->has_br_length = 2; fd_nj_plot->has_internal = FALSE; /* ignore all stuff after last closing parenthesis (needed for fastDNAml output) */ finarbre= nextpar(arbre); fd_nj_plot->rooted=0; deba=arbre+1; debb=deba; while(*debb != ',') { if(*debb == 0) bad_format("Incorrect tree file"); if(*debb == '(')debb=nextpar(debb); debb++; } debb++; debc=debb; while(*debc != ',' && debc it has 3 subtrees at its bottommost level */ debc++; } else { /* the tree is rooted */ debc=finarbre+1; fd_nj_plot->rooted=1; /* fd_nj_plot->notu--; //useless now */ } num_noeud=fd_nj_plot->notu; nextotu= -1; p1=unrootedset(deba,debb-2,&int_br_g); p2=unrootedset(debb,debc-2,&int_br_d); p = *(fd_nj_plot->tabtax+(++num_noeud)); if(num_noeud >= 2*fd_nj_plot->notu + 1) bad_format("Error: incorrect tree file"); p->v1=p1; p1->v3=p; p->l1=p1->l3; if(int_br_g!=NULL) { int_br_g->bouta=p; int_br_g->boutb=p1; } p->v2=p2; p2->v3=p; p->l2=p2->l3; if(int_br_d!=NULL) { int_br_d->bouta=p; int_br_d->boutb=p2; } if(!fd_nj_plot->rooted) { p3=unrootedset(debc,finarbre-1,&int_br_g); if(int_br_g!=NULL) { int_br_g->bouta=p; int_br_g->boutb=p3; } p->v3=p3; p3->v3=p; p->l3=p3->l3; } else { p->v3=NULL; /* recherche d'un dernier label interne */ debc=finarbre+1; while(*debc!=0 && *debc!=':' && *debc!='[') debc++; if(debc-finarbre>1) { int l=debc-finarbre-1; fd_nj_plot->has_internal = TRUE; fd_nj_plot->totbranches++; fd_nj_plot->branches[fd_nj_plot->totbranches].br_label=check_alloc(l+1,1); memcpy(fd_nj_plot->branches[fd_nj_plot->totbranches].br_label,finarbre+1,l); fd_nj_plot->branches[fd_nj_plot->totbranches].br_label[l]=0; fd_nj_plot->branches[fd_nj_plot->totbranches].bouta=p1; fd_nj_plot->branches[fd_nj_plot->totbranches].boutb=p2; } } if(fd_nj_plot->rooted && last_bootstrap != NULL) { /* attach last_bootstrap to branch racine <--> NULL */ fd_nj_plot->totbranches++; fd_nj_plot->branches[fd_nj_plot->totbranches].br_label = strdup(last_bootstrap); fd_nj_plot->branches[fd_nj_plot->totbranches].bouta=p; fd_nj_plot->branches[fd_nj_plot->totbranches].boutb=NULL; } if(last_bootstrap != NULL) free(last_bootstrap); } struct noeud *unrootedset(char *deb, char *fin, branche **p_int_br) { struct noeud *p, *pp; char *virg, *ferme; branche *int_br; static int l; static double brlength; *p_int_br=NULL; while(*deb==' ')deb++; while(*fin==' ')fin--; if(*deb != '(') { /* une feuille */ virg = strchr(deb, ':'); if(virg != NULL && virg < fin) { // if(fd_nj_plot->has_br_length == 0) goto problem; sscanf(virg+1, "%le", &brlength); fd_nj_plot->has_br_length=1; } else { // if(fd_nj_plot->has_br_length == 1) goto problem; brlength = 1; fd_nj_plot->has_br_length=0; virg = fin + 1; } virg--; while(*deb==' ' || *deb=='\'')deb++; if( virg-1 >= deb && *virg == '\'' ) virg--; l = virg-deb+1; fd_nj_plot->labels[ ++nextotu] = (char *)check_alloc(l + 1, 1); memcpy(fd_nj_plot->labels[nextotu], deb, l); fd_nj_plot->labels[nextotu][l] = 0; /* if(strchr(fd_nj_plot->labels[nextotu], '(') != NULL || strchr(fd_nj_plot->labels[nextotu], ')') != NULL) { char *tmp = (char *)malloc(strlen(fd_nj_plot->labels[nextotu]) + 60); sprintf(tmp, "Error: parentheses in name: %s", fd_nj_plot->labels[nextotu]); bad_format(tmp); } */ p = *(fd_nj_plot->tabtax + nextotu); p->l3 = brlength; p->v1 = p->v2 = p->v3 = NULL; return p; } /* un noeud */ num_noeud++; if(num_noeud >= 2*fd_nj_plot->notu + 1) bad_format("Error: incorrect tree file"); p = *(fd_nj_plot->tabtax + num_noeud); ferme = nextpar(deb); virg=deb + 1; while(*virg != ',' && virg < fin) { if(*virg == '(') virg=nextpar(virg); virg++; } if(virg>=ferme) bad_format("Error: incorrect tree file"); pp = unrootedset(deb + 1, virg - 1, &int_br); p->v1 = pp; pp->v3 = p; p->l1 = pp->l3; if(int_br != NULL) { int_br->bouta = p; int_br->boutb = pp; } pp = unrootedset(virg + 1, ferme - 1, &int_br); p->v2 = pp; pp->v3 = p; p->l2 = pp->l3; if(int_br != NULL) { int_br->bouta = p; int_br->boutb = pp; } virg = strchr(ferme, ':'); if(virg != NULL && virg < fin) { /* traitement longueur */ // if(fd_nj_plot->has_br_length == 0) goto problem; sscanf(virg+1, "%le", &brlength); fd_nj_plot->has_br_length=1; if(*fin == ']') { /* bootstrap entre [] apres longueurs */ static char *q; q = fin - 1; while(q > virg && *q != '[') q--; if(*q == '[' && fin - q >= 2) { fd_nj_plot->has_internal = TRUE; fd_nj_plot->totbranches++; l = fin - q - 1; fd_nj_plot->branches[fd_nj_plot->totbranches].br_label = check_alloc(l+1,1); memcpy(fd_nj_plot->branches[fd_nj_plot->totbranches].br_label,q+1,l); fd_nj_plot->branches[fd_nj_plot->totbranches].br_label[l]=0; *p_int_br= &fd_nj_plot->branches[fd_nj_plot->totbranches]; } } } else { // if(fd_nj_plot->has_br_length == 1) goto problem; brlength = 1; fd_nj_plot->has_br_length=0; virg = fin + 1; } /* recherche bootstrap (internal label) */ l=virg-ferme-1; if(l>0) { fd_nj_plot->has_internal = TRUE; fd_nj_plot->totbranches++; fd_nj_plot->branches[fd_nj_plot->totbranches].br_label= check_alloc(l+1,1); memcpy(fd_nj_plot->branches[fd_nj_plot->totbranches].br_label,ferme+1,l); fd_nj_plot->branches[fd_nj_plot->totbranches].br_label[l]=0; *p_int_br= &fd_nj_plot->branches[fd_nj_plot->totbranches]; } p->l3 = brlength; return p; problem: err_message("Error: Inconsistent tree file for branch lengths."); exit(1); } char *nextpar(char *pospar) { char *pos; pos=pospar+1; while(*pos != ')') { if(*pos == 0) bad_format("Error: unbalanced parentheses"); if(*pos == '(') pos=nextpar(pos); pos++; } return pos; } void bad_format(char *mess) { err_message(mess); exit(1); } void make_binary_or_unrooted(char *arbre) { char *finarbre, *deba, *debb, *debc; finarbre= nextpar(arbre); *(finarbre + 1) = 0; deba=arbre+1; debb=deba; while(*debb != ',') { if(*debb == 0) bad_format("Incorrect tree file"); if(*debb == '(')debb=nextpar(debb); debb++; } debb++; debc=debb; while(*debc != ',' && debc it has 3 subtrees or more at its bottommost level */ make_binary(arbre , debb, finarbre - 1, TRUE); make_binary(arbre , deba, debb - 2, TRUE); } else make_binary(arbre , deba, finarbre - 1, TRUE); return; } int make_binary(char *arbre, char *debut, char *fin, int go_down) { int virg, l, retval; char *p, *q; p = debut; virg = 0; retval = 0; while(p < fin) { if(*p == ',') virg++; else if(*p == '(') { q = nextpar(p); if(go_down) { l = make_binary(arbre, p+1, q-1, TRUE); fin += l; retval += l; p = q + l; } else p = q; } p++; } if(virg > 1) { /* multifurcation */ /* recherche de la 2eme virgule */ p = debut; l = 0; while(TRUE) { if(*p == ',') { l++; if(l == 2) break; } else if(*p == '(') { p = nextpar(p); } p++; } l = strlen(p); memmove(p + 4, p, l + 1); memmove(debut + 1, debut, p - debut); *debut = '('; memcpy(p + 1, "):0", 3); fin += 4; retval += 4; if(virg > 2) retval += make_binary(arbre, debut, fin, FALSE); } return retval; } void mydrawstring(double x, double y, char *nom, char option) { static double px,py; ch_echelle(x,y,&px,&py); #ifndef TTY if(option == '1') { /* ecrire une chaine en la montant d'un chouia */ py += fd_nj_plot->char_height/6.; } else if(option == 'c' || option == 'r') { /* ecrire une chaine en la centrant vert. sur cette position*/ py -= fd_nj_plot->char_height/3.; px += fd_nj_plot->char_height/6.; } else if(option == 't') { py -= (5./6.) * fd_nj_plot->char_height; } else if(option == 'b') { py += fd_nj_plot->char_height/6.; } #endif dir_moveto(px,py); #ifndef NO_GUI if(option == 'r') Nlm_Red(); #endif plotstring(nom); #ifndef NO_GUI if(option == 'r') Nlm_Black(); #endif } void moveto(double x,double y) /* move from current pos to logical coord x,y */ { static double px,py; ch_echelle(x,y,&px,&py); dir_moveto(px,py); } void lineto(double x,double y) /* draw line from current pos to logical coord x,y */ { static double px,py; ch_echelle(x,y,&px,&py); dir_lineto(px,py); } int calc_brl_for_lengthless(struct noeud *centre, struct noeud *pere) /* Recursively computes branch lengths of a lengthless tree having some branches fixed to 0 to allow multifurcations so that all tips align to the right of the plot. */ { int n1 = 0, n2, depth; volatile double l; if(centre->v1 == NULL && centre->v2 == NULL) return 0;//a leaf //rearrange with centre->v3 towards root if(centre->v1 == pere) { centre->v1 = centre->v3; centre->v3 = pere; l = centre->l3; centre->l3 = centre->l1; centre->l1 = l; } else if(centre->v2 == pere) { centre->v2 = centre->v3; centre->v3 = pere; l = centre->l3; centre->l3 = centre->l2; centre->l2 = l; } n1 = calc_brl_for_lengthless(centre->v1, centre); n2 = calc_brl_for_lengthless(centre->v2, centre); depth = n1; if(centre->l1 != 0) depth++; if(depth < n2) depth = n2; if(centre->l2 != 0 && n2 + 1 > depth) depth++; if(centre->l1 != 0) { centre->l1 = depth - n1; centre->v1->l3 = depth - n1; } else if(depth - n1 > 0) add_value_downstream(centre->v1, depth - n1); if(centre->l2 != 0) { centre->l2 = depth - n2; centre->v2->l3 = depth - n2; } else if(depth - n2 > 0) add_value_downstream(centre->v2, depth - n2); return depth; } void add_value_downstream(struct noeud *centre, int value) { if(centre->l1 != 0) { centre->l1 += value; centre->v1->l3 = centre->l1; } else add_value_downstream(centre->v1, value); if(centre->l2 != 0) { centre->l2 += value; centre->v2->l3 = centre->l1; } else add_value_downstream(centre->v2, value); } void place_midpoint_root(void) /* enraciner l'arbre sans racine en cherchant son centre */ { struct noeud *aux; double laux; current_best_diff = VERY_BIG; if(outotu != NULL) { int i; for(i=0; i <= fd_nj_plot->notu; i++) { if(fd_nj_plot->labels[i] != NULL && strcmp(fd_nj_plot->labels[i], outotu) == 0) break; } if(i > fd_nj_plot->notu) { fprintf(stderr, "Error: outotu %s not found in tree\n", outotu); exit(1); } process_branche(fd_nj_plot->tabtax[i], fd_nj_plot->tabtax[i]->v3, fd_nj_plot->tabtax[i]->l3); } else { current_cote1=current_cote2=NULL; parcourir_branches(*fd_nj_plot->tabtax, NULL); } fd_nj_plot->rooted = TRUE; fd_nj_plot->root_br_l = current_br_length; /* il faut toujours que la racine soit telle que racine->v1->v3=racine */ if (current_cote1->v1 == current_cote2 ) { /* echanger les voisins v1 et v3 de cote1 */ aux=current_cote1->v1; current_cote1->v1=current_cote1->v3; current_cote1->v3=aux; laux=current_cote1->l1; current_cote1->l1=current_cote1->l3; current_cote1->l3=laux; } else if (current_cote1->v2 == current_cote2) { /* echanger les voisins v2 et v3 de cote1 */ aux=current_cote1->v2; current_cote1->v2=current_cote1->v3; current_cote1->v3=aux; laux=current_cote1->l2; current_cote1->l2=current_cote1->l3; current_cote1->l3=laux; } current_cote1->v3 = fd_nj_plot->racine; if (current_cote2->v1 == current_cote1 ) current_cote2->v1 = fd_nj_plot->racine; else if (current_cote2->v2 == current_cote1) current_cote2->v2 = fd_nj_plot->racine; else current_cote2->v3 = fd_nj_plot->racine; fd_nj_plot->racine->v1=current_cote1; fd_nj_plot->racine->v2=current_cote2; fd_nj_plot->racine->v3=NULL; fd_nj_plot->racine->l3=0; /* avoid very unbalanced division of root branch */ if(current_balance > MAX_FRAC) current_balance = MAX_FRAC; else if(current_balance < 1 - MAX_FRAC) current_balance = 1 - MAX_FRAC; fd_nj_plot->racine->l1 = current_br_length * current_balance; fd_nj_plot->racine->l2 = current_br_length - fd_nj_plot->racine->l1; } void parcourir_branches(struct noeud *centre, struct noeud *origine) /* parcourir recursivement toutes les branches de l'arbre sans racine a partir de centre et dans la direction opposee a son voisin origine */ { if(centre==NULL) return; if(centre->v1!=origine) { process_branche(centre,centre->v1,centre->l1); parcourir_branches(centre->v1,centre); } if(centre->v2!=origine) { process_branche(centre,centre->v2,centre->l2); parcourir_branches(centre->v2,centre); } if(centre->v3!=origine) { process_branche(centre,centre->v3,centre->l3); parcourir_branches(centre->v3,centre); } } void process_branche(struct noeud *cote1, struct noeud *cote2, double length) /* calculer la variance des distances racine - feuilles si racine est sur branche cote1 - cote2 et memoriser la meilleure branche dans les variables globales */ { double x ; /* partage de branche par facteur x */ moments m1, m2; double A, B, C; /* variance(x) = A x x + B x + C */ double mini_val; /* meilleure variance pour toutes valeurs de x entre 0 et 1 */ if(cote1 == NULL || cote2 == NULL) return; if( length < 0 ) length = 0; m1 = stat_from_node(cote2, cote1); m2 = stat_from_node(cote1, cote2); A = 4 * m1.N * ( m2.N * length ) * length; B = 4 * length * ( m2.N * m1.somme - m1.N * m2.somme - length * m1.N * m2.N); C = (m1.N + m2.N) * (m1.carres + m2.carres) + m1.N * length * m2.N * length + 2 * m1.N * length * m2.somme - 2 * m2.N * length * m1.somme - (m1. somme + m2.somme) * (m1. somme + m2.somme); if(A < 1e-20) { x = 0.5; mini_val = VERY_BIG * 0.99 ; } else { x = - B / (2 * A); mini_val = C - (B * B) / 4 / A; } if( x < 0 ) { x = 0; mini_val = C; } else if( x > 1) { x = 1; mini_val = A + B + C; } if(mini_val < current_best_diff ) { current_best_diff = mini_val; current_cote1 = cote1; current_cote2 = cote2; current_br_length = length; current_balance = x; } } /* no longer useful */ double get_length_down(struct noeud *pere, struct noeud *racine) /* compute the average length of the tree down a node */ { if(racine == NULL) return 0.0; else { struct noeud *gauche, *droite; double bg,bd,lg,ld; if( racine->v1 == pere ) { gauche =racine->v2; droite = racine->v3; bg = (racine->l2); bd = (racine->l3); } else if( racine->v2 == pere ) { gauche =racine->v1; droite = racine->v3; bg = (racine->l1); bd = (racine->l3); } else { gauche =racine->v1; droite = racine->v2; bg = (racine->l1); bd = (racine->l2); } /* conserver cette ecriture sinon plante sur PC */ lg = ld = 0; if(gauche != NULL) lg = get_length_down(racine,gauche); lg += bg; if(droite != NULL) ld = get_length_down(racine,droite); ld += bd; return ((lg+ld)/2); } } moments stat_from_node(struct noeud *pere, struct noeud *racine) /* compute the moments down a node to all descending tips */ { struct noeud *gauche, *droite; moments m; static moments mtmp; double bg, bd; if( racine->v1 == pere ) { gauche =racine->v2; droite = racine->v3; bg = (racine->l2); bd = (racine->l3); } else if( racine->v2 == pere ) { gauche =racine->v1; droite = racine->v3; bg = (racine->l1); bd = (racine->l3); } else { gauche =racine->v1; droite = racine->v2; bg = (racine->l1); bd = (racine->l2); } if(gauche != NULL) { mtmp = stat_from_node(racine, gauche); m.N = mtmp.N; /* nbre de fils */ m.somme = mtmp.somme + bg * mtmp.N; m.carres = mtmp.carres + 2 * bg * mtmp.somme + mtmp.N * bg * bg; mtmp = stat_from_node(racine, droite); m.N += mtmp.N; /* nbre de fils */ m.somme += mtmp.somme + bd * mtmp.N; m.carres += mtmp.carres + 2 * bd * mtmp.somme + mtmp.N * bd * bd; } else { m.N = 1; m.somme = 0; m.carres = 0; } return m; } void runtree(void) { double currx, curry; int i; struct noeud *p1, *p2; double b1,b2,frac_gauche; if(!fd_nj_plot->rooted) { /* place root at user-chosen place: node # fd_nj_plot->root_num */ fd_nj_plot->rooted = !fd_nj_plot->rooted; p1 = *(fd_nj_plot->tabtax+fd_nj_plot->root_num); p2 = p1->v3; fd_nj_plot->root_br_l = p1->l3; if(fd_nj_plot->has_br_length) { current_best_diff = VERY_BIG; process_branche(p1, p2, fd_nj_plot->root_br_l); } p1->v3 = fd_nj_plot->racine; if (p2->v1 == p1 ) p2->v1 = fd_nj_plot->racine; else if (p2->v2 == p1) p2->v2 = fd_nj_plot->racine; else p2->v3 = fd_nj_plot->racine; fd_nj_plot->racine->v1=p1; fd_nj_plot->racine->v2=p2; fd_nj_plot->racine->v3=NULL; if(fd_nj_plot->has_br_length) { frac_gauche = current_balance; if(frac_gauche>MAX_FRAC) frac_gauche=MAX_FRAC; else if(frac_gauche<1-MAX_FRAC) frac_gauche=1-MAX_FRAC; b1 = frac_gauche*fd_nj_plot->root_br_l; b2 = fd_nj_plot->root_br_l - b1; fd_nj_plot->racine->l1=b1; fd_nj_plot->racine->l2=b2; } else { fd_nj_plot->racine->l1 = p1->l3; if (p2->v1 == fd_nj_plot->racine ) fd_nj_plot->racine->l2 = p2->l1; else if (p2->v2 == fd_nj_plot->racine) fd_nj_plot->racine->l2 = p2->l2; else fd_nj_plot->racine->l2 = p2->l3; calc_brl_for_lengthless(fd_nj_plot->racine, NULL); } } /* initialize leave and node names */ for(i = 0; i <= 2*fd_nj_plot->notu; i++) fd_nj_plot->tabnames[i][0] = 0; if (fd_nj_plot->choix == depl_racine) { for(i=0; i <= 2*fd_nj_plot->notu - 1; i++) { // if(i == fd_nj_plot->root_num) continue;//skip current root if( !fd_nj_plot->has_br_length) { if(fd_nj_plot->tabtax[i]->l3 == 0) continue;//skip internal multifurcation nodes that can't be broken by root } sprintf(fd_nj_plot->tabnames[i], "# "); } } else if(fd_nj_plot->choix == permutation) for(i=fd_nj_plot->notu+1; i<=2*fd_nj_plot->notu; i++) sprintf(fd_nj_plot->tabnames[i],"#"); else if(fd_nj_plot->choix == subtree) for(i=fd_nj_plot->notu+1; i<=2*fd_nj_plot->notu-1; i++) sprintf(fd_nj_plot->tabnames[i],"#"); for(i=0; i<=fd_nj_plot->notu; i++) { int j; j = strlen(fd_nj_plot->tabnames[i]); strcpy(fd_nj_plot->tabnames[i] + j, fd_nj_plot->labels[i]); } #ifndef ADDROOT fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1; end_br_length = fd_nj_plot->br_length_txt; currx = 0.; maxx = 0.; memset(fd_nj_plot->profs, 0, (fd_nj_plot->notu+1)*sizeof(double)); if(fd_nj_plot->subtree_center != NULL) fd_nj_plot->deltay = maxy / fd_nj_plot->subtree_notu; else { fd_nj_plot->deltay = maxy / fd_nj_plot->notu; fd_nj_plot->subtree_notu = fd_nj_plot->notu; } nexty = -fd_nj_plot->deltay; calc_text_size("Mq", &fd_nj_plot->char_height, &fd_nj_plot->ascent); if(fd_nj_plot->subtree_center == NULL) mem_plot(NULL, fd_nj_plot->racine, currx, &curry); else mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry); converted = FALSE; #endif } /* end of runtree */ void mem_plot(struct noeud *pere, struct noeud *centre, double currx, double *curry) /* prepare tree by memorizing all graphic requests */ { int num=0; char *p; struct noeud *gauche, *droite; double bg, bd, bpere; while( *(fd_nj_plot->tabtax+num) != centre) num++; if(pere != NULL && (centre->v1 == NULL || centre->v2 == NULL || centre->v3 == NULL) ) { /* orienter le noeud centre de maniere standard: centre->v3=pere */ if( centre->v1 == pere ) { gauche =centre->v2; droite = centre->v3; bg = centre->l2; bd = centre->l3; bpere = centre->l1; } else if( centre->v2 == pere ) { gauche =centre->v1; droite = centre->v3; bg = centre->l1; bd = centre->l3; bpere = centre->l2; } else { gauche =centre->v1; droite = centre->v2; bg = centre->l1; bd = centre->l2; bpere = centre->l3; } centre->v3=pere; centre->v1=gauche; centre->v2=droite; centre->l3=bpere; centre->l1=bg; centre->l2=bd; /* write taxon name */ nexty += fd_nj_plot->deltay; mem_nom(currx,nexty,fd_nj_plot->tabnames[num],'c'); fd_nj_plot->profs[num] = currx; fd_nj_plot->widnames[num] = calc_text_size(fd_nj_plot->tabnames[num], NULL, NULL); if(fd_nj_plot->choix==depl_racine) mem_point(currx,nexty,num+1); *curry = nexty; } else { double yg, yd, xg, xd; static int doswap; static struct noeud *tmp; /* doswap vrai ssi permutation de 2 descendants necessaire ici */ doswap = (swap != 0 && *(fd_nj_plot->tabtax+swap) == centre); if( centre->v1 == pere ) { if(doswap) { tmp= centre->v2;centre->v2= centre->v3;centre->v3= tmp; bg= centre->l2; centre->l2= centre->l3; centre->l3= bg; } gauche =centre->v2; droite = centre->v3; bg = centre->l2; bd = centre->l3; bpere = centre->l1; } else if( centre->v2 == pere ) { if(doswap) { tmp= centre->v1;centre->v1= centre->v3;centre->v3= tmp; bg= centre->l1; centre->l1= centre->l3; centre->l3= bg; } gauche =centre->v1; droite = centre->v3; bg = centre->l1; bd = centre->l3; bpere = centre->l2; } else { if(doswap) { tmp= centre->v1;centre->v1= centre->v2;centre->v2= tmp; bg= centre->l1; centre->l1= centre->l2; centre->l2= bg; } gauche =centre->v1; droite = centre->v2; bg = centre->l1; bd = centre->l2; bpere = centre->l3; } /* orienter le noeud centre de maniere standard: centre->v3=pere */ centre->v3=pere; centre->v1=gauche; centre->v2=droite; centre->l3=bpere; centre->l1=bg; centre->l2=bd; xg=currx+bg; xd=currx+bd; mem_plot(centre,gauche,xg,&yg); mem_plot(centre,droite,xd,&yd); mem_trait(currx,yg,xg,yg); mem_trait(currx,yd,xd,yd); mem_trait(currx,yg,currx,yd); *curry = (yg+yd)/2; /* write internal fd_nj_plot->labels */ if(fd_nj_plot->choix==show_tree && fd_nj_plot->show_bootstrap) { if(pere != NULL) { /* for all but root node */ if( (p=get_br_label(centre, gauche)) != NULL ) mem_nom(currx,yg,p,'t'); if( (p=get_br_label(centre, droite)) != NULL ) mem_nom(currx,yd,p,'b'); } else {/* for root node */ if( (p=get_br_label(centre, NULL)) != NULL ) { /* if root bootstrap exists */ mem_nom(currx,*curry,p,'c'); if( (p=get_br_label(centre, gauche)) != NULL ) mem_nom(currx,yg,p,'t'); if( (p=get_br_label(centre, droite)) != NULL ) mem_nom(currx,yd,p,'b'); } else {/* if no root bootstrap any bootstrap is to be centered */ if( (p=get_br_label(centre, gauche)) != NULL ) mem_nom(currx,*curry,p,'c'); if( (p=get_br_label(centre, droite)) != NULL ) mem_nom(currx,*curry,p,'c'); if( (p=get_br_label(gauche, droite)) != NULL ) mem_nom(currx,*curry,p,'c'); } } } /* write node number */ mem_nom(currx,*curry,fd_nj_plot->tabnames[num],'c'); mem_point(currx,*curry,num+1); if(fd_nj_plot->plot_br_l && fd_nj_plot->has_br_length) { /* write branch length */ double min_br_l = 0.008; /* minimum branch length displayed */ if(bg>min_br_l) { sprintf(end_br_length,"%.3f",bg); mem_nom(currx+bg/10,yg,end_br_length,'1'); end_br_length += (strlen(end_br_length)+1); } if(bd>min_br_l) { sprintf(end_br_length,"%.3f",bd); mem_nom(currx+bd/10,yd,end_br_length,'1'); end_br_length += (strlen(end_br_length)+1); } } } } /* end of mem_plot */ void mem_point(double x, double y, int number) { ++fd_nj_plot->totpoints; (fd_nj_plot->points+fd_nj_plot->totpoints)->x = x; (fd_nj_plot->points+fd_nj_plot->totpoints)->y = y; (fd_nj_plot->points+fd_nj_plot->totpoints)->number = number; } void mem_nom(double x, double y, char *nom, char option) /* x,y: logical coordinates of beginning of string nom: address of string to be displayed later option: 'c' use for position of center of character height '1' put bottom of characters at y+1 pixel 't' use for position of top of character 'b' use for position of bottom of character */ { if(strlen(nom) != 0) { fd_nj_plot->totnoms++; if(x > maxx) maxx = x; (fd_nj_plot->noms+fd_nj_plot->totnoms)->x = x; (fd_nj_plot->noms+fd_nj_plot->totnoms)->y = y; (fd_nj_plot->noms+fd_nj_plot->totnoms)->nom = nom; (fd_nj_plot->noms+fd_nj_plot->totnoms)->disp_option = option; } } void mem_trait(double xd, double yd, double xf, double yf) { fd_nj_plot->tottraits++; if(xd>maxx) maxx=xd; if(xf>maxx) maxx=xf; (fd_nj_plot->traits+fd_nj_plot->tottraits)->xd = xd; (fd_nj_plot->traits+fd_nj_plot->tottraits)->yd = yd; (fd_nj_plot->traits+fd_nj_plot->tottraits)->xf = xf; (fd_nj_plot->traits+fd_nj_plot->tottraits)->yf = yf; } char *get_br_label(struct noeud *a, struct noeud *b) { int i; for(i=0; i<=fd_nj_plot->totbranches; i++) { if(fd_nj_plot->branches[i].bouta==a && fd_nj_plot->branches[i].boutb==b) return fd_nj_plot->branches[i].br_label; if(fd_nj_plot->branches[i].boutb==a && fd_nj_plot->branches[i].bouta==b) return fd_nj_plot->branches[i].br_label; } return NULL; } int get_br_from_bouts(struct noeud *a, struct noeud *b) { int i; for(i=0; i<=fd_nj_plot->totbranches; i++) { if(fd_nj_plot->branches[i].bouta==a && fd_nj_plot->branches[i].boutb==b) return i; if(fd_nj_plot->branches[i].boutb==a && fd_nj_plot->branches[i].bouta==b) return i; } return -1; } void free_tree(void) { int i; if(fd_nj_plot->notu == 0) return; /* de-allocate all memory */ for(i=0; i<2*fd_nj_plot->notu+1; i++) free(fd_nj_plot->tabtax[i]); free(fd_nj_plot->tabtax); for(i=0; inotu; i++) if(fd_nj_plot->branches[i].br_label != NULL) free(fd_nj_plot->branches[i].br_label); free(fd_nj_plot->branches); for(i = 0; i < 2 * fd_nj_plot->notu + 1; i++) free(fd_nj_plot->tabnames[i]); free(fd_nj_plot->tabnames); free(fd_nj_plot->widnames); free(fd_nj_plot->noms); free(fd_nj_plot->points); free(fd_nj_plot->traits); free(fd_nj_plot->profs); for(i = 0; i < fd_nj_plot->notu + 1; i++) free(fd_nj_plot->labels[i]); free(fd_nj_plot->labels); free(fd_nj_plot->br_length_txt); if(fd_nj_plot->tree_name != NULL) free(fd_nj_plot->tree_name); } /* ecriture d'un arbre non racine au format phylip, multifurcations allowed */ char *ecrit_arbre_parenth_unrooted(struct noeud *root) { struct noeud *t1, *t2, *t3; char *p1, *p2, *p3, *p, *bootstrap; int l; float l1, l2, l3; t1 = root->v1->v1; t2 = root->v1->v2; t3 = root->v2; l1 = root->v1->l1; l2 = root->v1->l2; if(t1 == NULL) { t1 = root->v2->v1; t2 = root->v2->v2; t3 = root->v1; l1 = root->v2->l1; l2 = root->v2->l2; } l3 = root->l1 + root->l2; bootstrap = get_br_label(root->v1, root->v2); if(bootstrap == NULL) bootstrap = ""; p1 = ecrit_arbre_parenth(t1); *(p1 + strlen(p1) - 1) = 0; p2 = ecrit_arbre_parenth(t2); *(p2 + strlen(p2) - 1) = 0; p3 = ecrit_arbre_parenth(t3); *(p3 + strlen(p3) - 1) = 0; l = strlen(p1) + strlen(p2)+ strlen(p3) + 150; p = (char *)check_alloc(l, 1); if(fd_nj_plot->has_br_length) sprintf(p, "(%s:%.5f,%s:%.5f,%s%s:%.5f);", p1, l1, p2, l2, p3, bootstrap, l3); else sprintf(p, "(%s,%s,%s%s);", p1, p2, p3, bootstrap); free(p1); free(p2); free(p3); return p; } /* ecriture d'un arbre racine au format phylip, multifurcations allowed */ char *ecrit_arbre_parenth(struct noeud *root) { char *arbre, *fin, *p; int l, maxarbre = 2 * fd_nj_plot->long_arbre_parenth + 1000; arbre=check_alloc( maxarbre+20,1); fin=recur_ecrit_arbre(root,arbre,arbre+maxarbre-1); /* ecriture du dernier label interne */ if( fin != NULL && (p=get_br_label(root->v1,root->v2)) != NULL ) { l=strlen(p); if(fin+l>=arbre+maxarbre) fin= NULL; else { memcpy(fin+1,p,l); fin+=l; } } if(fin == NULL) { free(arbre); return NULL; } strcpy(fin+1,";"); return arbre; } char *recur_ecrit_arbre(struct noeud *centre, char *arbre, char *finarbre) { int num, l; char *p, *q; if(centre->v1==NULL && centre->v2==NULL) { num=0; while( *(fd_nj_plot->tabtax+num) != centre) num++; l=strlen(fd_nj_plot->tabnames[num]); if(arbre+l>=finarbre) return NULL; memcpy(arbre,fd_nj_plot->tabnames[num],l); arbre += l-1; } else { *arbre='('; p = arbre; arbre=recur_ecrit_arbre(centre->v1,arbre+1,finarbre); if(arbre==NULL) return NULL; if(fd_nj_plot->has_br_length) { if(arbre+10>=finarbre) return NULL; sprintf(++arbre,":%.5f",centre->l1); while(*arbre!=0) arbre++; } else arbre++; *arbre=','; arbre=recur_ecrit_arbre(centre->v2,arbre+1,finarbre); if(arbre==NULL) return NULL; if(fd_nj_plot->has_br_length) { if(arbre+10>=finarbre) return NULL; sprintf(++arbre,":%.5f",centre->l2); while(*arbre!=0) arbre++; } else arbre++; *arbre=')'; /* ecriture des fd_nj_plot->labels internes */ if( (q=get_br_label(centre,centre->v3)) != NULL && (fd_nj_plot->has_br_length || (centre->l3 != 0) ) ) { l=strlen(q); if(arbre+l>=finarbre) return NULL; memcpy(arbre+1,q,l); arbre+=l; } else if(centre->v3 != NULL && (!fd_nj_plot->has_br_length) && (centre->l3 == 0) ) {//multibranches processed here memmove(p, p + 1, arbre - p); arbre -= 2; } } return arbre; } void removeroot(void) { struct noeud *p1, *p2; p1=fd_nj_plot->racine->v1; p2=fd_nj_plot->racine->v2; if(p1->v1 == fd_nj_plot->racine ) {p1->v1 = p2; p1->l1 = fd_nj_plot->root_br_l;} else if (p1->v2 == fd_nj_plot->racine) {p1->v2 = p2; p1->l2 = fd_nj_plot->root_br_l;} else {p1->v3 = p2; p1->l3 = fd_nj_plot->root_br_l;} if(p2->v1 == fd_nj_plot->racine ) {p2->v1 = p1; p2->l1 = fd_nj_plot->root_br_l;} else if (p2->v2 == fd_nj_plot->racine) {p2->v2 = p1; p2->l2 = fd_nj_plot->root_br_l;} else {p2->v3 = p1; p2->l3 = fd_nj_plot->root_br_l;} fd_nj_plot->rooted = 0; } int calc_n_desc(struct noeud *pere) { if(pere->v1 == NULL) return 1; else return calc_n_desc(pere->v1) + calc_n_desc(pere->v2); } void postscript_plot(void) { double currx, curry; int page, erreur = FALSE, offset; int paper_h, sheets_h, recouvre, font_size; const int a4_h = 750, letter_h = 700; time_t heure; float screen_w, ps_w; static int first = TRUE; const char alphabet[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; /* partie dessinable 500(ps_width) x a4_h decalee de 50 x 50 par rapport a coin inferieur gauche du papier cadre exterieur de 10 sur les 4 cotes, correspond aussi a zone de clip */ if(fd_nj_plot->notu == 0) return; if(paper_choice == A4) { paper_h = a4_h; } else { paper_h = letter_h; } if(ps_height != 0) paper_h = ps_height; #ifndef NO_GUI Nlm_WatchCursor(); #endif file_plot = TRUE; font_size = list_font_size[fd_nj_plot->font_size_rank]; if(first) { first = FALSE; #ifndef NO_GUI #ifdef WIN_MSWIN Nlm_SelectFont( Nlm_ParseFont( "Courier New,12" ) ); #else Nlm_SelectFont( Nlm_ParseFont( "Courier,12" ) ); #endif screen_w = Nlm_TextWidth(alphabet, 26);/*taille sur ecran*/ ps_w = 12 * 0.60 * 26; /*taille en postscript pour courier,12*/ postscript_ratio = ps_w / screen_w ; Nlm_SelectFont(fd_nj_plot->current_font);/*retour a police courante pour ecran */ #endif } /* recouvre = paper_h / 30; */ recouvre = 0; sheets_h = (paper_h - recouvre) * page_count + recouvre; offset = paper_h - recouvre; physx = ps_width; physy = sheets_h; plotfile=fopen(plotfilename,"w"); if(plotfile == NULL) { char tmp[300]; sprintf(tmp, "Error opening %s for writing\n", plotfilename); #ifndef NO_GUI err_message(tmp); #else fputs(tmp, stderr); #endif exit(1); } fprintf(plotfile,"%%!PS-Adobe-1.0\n" "%%%%DocumentFonts: Times-Roman %s\n" "%%%%Creator: njplot\n" "%%%%Pages: %d\n" "%%%%Title: %s\n" "%%%%BeginFeature: *PageSize \n" "%s\n" "%%%%EndFeature\n" "%%%%EndComments\n", current_ps_font, page_count, fd_nj_plot->tree_name, paper_choice == A4 ? "a4" : "letter" ); fprintf(plotfile, "/setpacking where {true setpacking} if\n" "1 setlinecap 1 setlinejoin 1 setlinewidth 0 setgray\n" "/basefont /%s findfont %d scalefont def\n", current_ps_font, font_size); fprintf(plotfile,"/titlefont /Times-Roman findfont 12 scalefont def\n"); fprintf(plotfile, "/setclip {40 40 moveto %d 40 lineto %d %d lineto 40 %d " "lineto closepath clip newpath} def\n", ps_width + 60, ps_width + 60, paper_h+60, paper_h+60); time(&heure); fprintf(plotfile, "/title {titlefont setfont\n" "40 %d moveto (%s %s) show ( Page ) show show ( of %d) show\n" "} def\n", paper_h+65, extract_filename(fd_nj_plot->tree_name), ctime(&heure), page_count); fprintf(plotfile,"%%%%EndProlog\n"); fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1; end_br_length = fd_nj_plot->br_length_txt; currx = 0.; maxx = 0.; nexty = -fd_nj_plot->deltay; if(fd_nj_plot->subtree_center == NULL) mem_plot(NULL, fd_nj_plot->racine, currx, &curry); else mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry); for(page = 0; page < page_count ; page++) { fprintf(plotfile,"%%%%Page: ? %d\n", page+1); if( ! no_title) fprintf(plotfile,"(%d) title ", page+1); fprintf(plotfile,"setclip\n"); fprintf(plotfile,"0 %d translate\n", - (page_count - page - 1) * offset); fprintf(plotfile,"basefont setfont\n"); fprintf(plotfile,"50 50 translate\n"); fprintf(plotfile,"0.7 setgray -10 -10 moveto %d -10 lineto %d %d lineto " "-10 %d lineto closepath stroke 0 setgray \n", ps_width + 10, ps_width + 10, sheets_h+10, sheets_h+10); do_plot(); fprintf(plotfile,"showpage\n"); } fprintf(plotfile, "%%%%Trailer\n"); if(ferror(plotfile)) erreur = TRUE; if(fclose(plotfile) != 0) erreur = TRUE; fd_nj_plot->need_runtree = TRUE; file_plot = FALSE; #ifndef NO_GUI ArrowCursor(); if(!pdf_plot_only ) { char mess[250]; if(!erreur ) { sprintf(mess, "Tree plot is now in file %s in Postscript format", extract_filename(plotfilename) ); } else { sprintf(mess, "Error while writing to file %s", extract_filename(plotfilename) ); } err_message(mess); } #endif } #ifdef WITH_PDF void plot_to_pdf(void) { int t_font, font_size; char *encoding; double currx, curry; int page, offset; double paper_h; int sheets_h, recouvre; const int a4_h = 750, letter_h = 700; time_t heure; /* partie dessinable 500(ps_width) x a4_h decalee de 50 x 50 par rapport a coin inferieur gauche du papier cadre exterieur de 10 sur les 4 cotes, correspond aussi a zone de clip */ char bigline[500]; #ifdef WIN_MAC encoding = "macroman"; #else encoding = "iso8859-1"; #endif if(fd_nj_plot->notu == 0) return; pdf = PDF_new(); if(pdf == NULL) return; if( PDF_begin_document(pdf, plotfilename, 0, "compatibility=1.3") == -1) { PDF_delete(pdf); char tmp[300]; sprintf(tmp, "Error opening %s for writing\n", plotfilename); #ifndef NO_GUI err_message(tmp); #else fputs(tmp, stderr); #endif return; } PDF_TRY(pdf) { PDF_set_info(pdf, "Title", fd_nj_plot->tree_name ); PDF_set_info(pdf, "Creator", "njplot"); t_font = PDF_load_font(pdf, "Times-Roman", 0, encoding, ""); pdf_font = PDF_load_font(pdf, current_ps_font, 0, encoding, ""); font_size = list_font_size[fd_nj_plot->font_size_rank]; if(paper_choice == A4) { paper_h = a4_h; } else /* LETTER */ { paper_h = letter_h; } if(ps_height != 0) paper_h = ps_height; #ifndef NO_GUI Nlm_WatchCursor(); #endif pdf_plot = TRUE; file_plot = TRUE; /* recouvre = paper_h / 30; */ recouvre = 0; sheets_h = (paper_h - recouvre) * page_count + recouvre; offset = paper_h - recouvre; physx = ps_width; physy = sheets_h; time(&heure); fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1; end_br_length = fd_nj_plot->br_length_txt; currx = 0.; maxx = 0.; nexty = -fd_nj_plot->deltay; if(fd_nj_plot->subtree_center == NULL) mem_plot(NULL, fd_nj_plot->racine, currx, &curry); else mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry); for(page = 0; page < page_count ; page++) { PDF_begin_page_ext(pdf, paper_choice == A4 ? a4_width : letter_width, paper_choice == A4 ? a4_height : letter_height, ""); if( ! no_title) { PDF_setfont(pdf, t_font, 12); sprintf(bigline, "%s %s Page %d of %d", extract_filename(fd_nj_plot->tree_name), ctime(&heure), page+1, page_count); PDF_show_xy(pdf, bigline, 40, paper_h+65); } PDF_setlinewidth(pdf, 1); PDF_moveto(pdf, 40, 40); PDF_lineto(pdf, ps_width + 60, 40); PDF_lineto(pdf, ps_width + 60, paper_h+60); PDF_lineto(pdf, 40, paper_h+60); PDF_closepath(pdf); PDF_clip(pdf); PDF_translate(pdf, 0, - (page_count - page - 1) * offset); PDF_setfont(pdf, pdf_font, font_size); PDF_translate(pdf, 50, 50); PDF_setcolor(pdf, "stroke", "gray", 0.7, 0,0,0); PDF_moveto(pdf, -10, -10); PDF_lineto(pdf, ps_width + 10, -10); PDF_lineto(pdf, ps_width + 10, sheets_h+10); PDF_lineto(pdf, -10, sheets_h+10); PDF_closepath_stroke(pdf); PDF_setcolor(pdf, "stroke", "gray", 0, 0,0,0); do_plot(); PDF_end_page_ext(pdf, ""); } PDF_end_document(pdf, ""); PDF_delete(pdf); } /* end of PDF_TRY */ PDF_CATCH(pdf) { sprintf(bigline, "Error while writing pdf file: [%d] %s: %s", PDF_get_errnum(pdf), PDF_get_apiname(pdf), PDF_get_errmsg(pdf) ); err_message(bigline); PDF_delete(pdf); return; } fd_nj_plot->need_runtree = TRUE; file_plot = FALSE; #ifndef NO_GUI Nlm_ArrowCursor(); if(!pdf_plot_only ) { char mess[250]; sprintf(mess, "Tree plot is now in file %s in PDF format", extract_filename(plotfilename) ); err_message(mess); } #endif } #endif void tty_plot(void) { double currx, curry; int h, erreur = FALSE; char *p; if(fd_nj_plot->notu == 0) return; file_plot = TRUE; /* physx was set in process_args */ physy = 2*(fd_nj_plot->notu + 1) + 4; tty_page = (char **)malloc(physy*sizeof(char *)); for(h=0; h < physy; h++) { tty_page[h] = (char *)malloc(physx + 1); memset(tty_page[h], ' ', physx); tty_page[h][(int)physx] = 0; } fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1; end_br_length = fd_nj_plot->br_length_txt; currx = 0.; maxx = 0.; nexty = -fd_nj_plot->deltay; if(fd_nj_plot->subtree_center == NULL) mem_plot(NULL, fd_nj_plot->racine, currx, &curry); else mem_plot(fd_nj_plot->subtree_ascend, fd_nj_plot->subtree_center, currx, &curry); do_plot(); for(h=0; h < physy; h++) { p = tty_page[h] + strlen(tty_page[h]) - 1; while(p > tty_page[h] && *p == ' ') *(p--) = 0; } plotfile=fopen(plotfilename, "w"); for(h=1; h <= physy; h++) { fprintf(plotfile, "%s\n", tty_page[(int)physy - h]); } if(ferror(plotfile)) erreur = TRUE; if(fclose(plotfile) != 0) erreur = TRUE; fd_nj_plot->need_runtree = TRUE; file_plot = FALSE; } void majuscules(char *p) { while(*p != 0) {*p = toupper(*p); p++;} } #ifdef WIN_MAC #if TARGET_RT_MAC_MACHO #define DIR_DELIM '/' #else #define DIR_DELIM ':' #endif #elif defined(WIN_MSWIN) #define DIR_DELIM '\\' #else #define DIR_DELIM '/' #endif char *extract_filename(char *name) { char *p; while( ( p = strchr(name, DIR_DELIM) ) != NULL) name = p + 1; return name; } #ifdef WIN_MOTIF #include static void Nlm_GetFontData (Nlm_FonT f, Nlm_FontData * fdata) { Nlm_FntPtr fp; if (f != NULL && fdata != NULL) { fp = (Nlm_FntPtr) Nlm_HandLock (f); *fdata = *fp; Nlm_HandUnlock (f); } } void set_systemfont(char *fname) { XFontStruct *font; XmFontListEntry entry; Nlm_FontData fontdata; extern XmFontList Nlm_XfontList; Nlm_systemFont = Nlm_ParseFont(fname); Nlm_GetFontData(Nlm_systemFont, &fontdata); font= (XFontStruct *)fontdata.handle; entry = XmFontListEntryCreate(XmFONTLIST_DEFAULT_TAG, XmFONT_IS_FONT, (XtPointer)font); Nlm_XfontList = XmFontListAppendEntry(NULL, entry); Nlm_SelectFont(Nlm_systemFont); Nlm_stdLineHeight=Nlm_LineHeight(); Nlm_stdFontHeight=Nlm_FontHeight(); Nlm_stdAscent=Nlm_Ascent(); Nlm_stdDescent=Nlm_Descent(); Nlm_stdLeading=Nlm_Leading(); Nlm_stdCharWidth = Nlm_MaxCharWidth (); } #endif njplot-2.4/unrooted-vib.c0000644000002300003250000011775211245233251014125 0ustar mgouybge#ifdef WIN_MAC #include /* must be before or it does not compile */ #endif #include #include #include #include #if defined(WIN_MSWIN) || defined (WIN_MAC) #define MICRO #endif #ifdef WIN_MAC #ifndef M_PI #define M_PI 3.14159265358979323846 /* pi */ #endif #if TARGET_RT_MAC_MACHO #define DIR_DELIM '/' #else #define DIR_DELIM ':' #endif #define myWaitAndProcessNextEvent Nlm_ProcessAnEvent extern int Nlm_textScrapFull; #elif defined(WIN_MSWIN) #define HDC void * extern HDC Nlm_currentHDC; extern HDC Nlm_GetPicWinHDC ( void ); char *get_prog_dir(void); #define M_PI pi #define DIR_DELIM '\\' extern const double pi; #define myWaitAndProcessNextEvent Nlm_ProcessAnEvent #define tempnam _tempnam #include //temporaire passage CW8 int __getche(void) { return getche(); } #else /* unix */ #include #define DIR_DELIM '/' #undef Boolean #include void set_systemfont(char *systemfont); extern Nlm_CharPtr Nlm_XrmGetResource(const Nlm_Char PNTR _resource); extern XtAppContext Nlm_appContext; void myWaitAndProcessNextEvent (void) { XEvent event; if( XtAppPending(Nlm_appContext) & XtIMXEvent ) { Nlm_ProcessAnEvent(); } else { /* wait until next event and catch it */ XtAppNextEvent (Nlm_appContext, &event); XtDispatchEvent (&event); } } #endif #ifndef M_PI #define M_PI 3.14159265358979323846 /* pi */ #endif /* typedefs */ typedef enum { NO_HIT, LEFT_HIT, RIGHT_HIT, TOP_HIT, BOTTOM_HIT } hit; enum {times = 1, helvetica, courier}; enum { font_tiny = 1, font_small, font_normal, font_medium, font_large, font_bold, font_italic }; typedef enum { A4 = 1, LETTER } paper_item; typedef struct { int x, y; } point; typedef struct _cp_point { double x, y, r, angle; } cp_point; typedef struct _bignoeud { struct _bignoeud *v1, *v2, *v3; double l1, l2, l3; cp_point position; char *nom; } bignoeud; struct noeud { double l1,l2,l3; struct noeud *v1,*v2,*v3; char *nom; }; typedef struct _branche { cp_point debut, fin; int color; char *nom; } branche; typedef struct _plot_data { int x, y, w, h; int ps_plot; int lstyle, lcol, lsize; int comp_phys_bounds; } plot_data; typedef struct { Nlm_WindoW unrooted; Nlm_IteM open_button; Nlm_MenU tree_font_menu; Nlm_MenU paper_menu; Nlm_IteM save_plot_button; Nlm_IteM AgainItem; Nlm_ChoicE choix_font, choix_taille; Nlm_IteM bold_item, italic_item; Nlm_IteM exit_button; Nlm_PaneL tree_plot; char *tree_name; } FD_unrooted; /* prototypes of included functions */ int direct_ps_plot(void); FD_unrooted *create_win_unrooted(void); void open_callback(Nlm_IteM ob); void win_resize_proc(Nlm_WindoW); void prepare_fonts(void); void change_panel_size(Nlm_PaneL panel, int change_x, int change_y); void err_message(char *text); void place_midpoint_root(void); char *extract_filename(char *fname); void save_plot_callback(Nlm_IteM ob); void font_callback(Nlm_ChoicE choix); void paper_callback(Nlm_ChoicE ob); void exit_callback(Nlm_IteM ob); void tree_draw_proc(Nlm_PaneL panel); void set_tree_w_title(Nlm_WindoW w, char *file, int tips); void init_tree(char *titre); void debut_arbre(void); void my_draw_line(int dx, int dy, int fx, int fy, int col, int ps, int h); void my_draw_text(int align, int x, int y, int col, int size, int style, char *chaine, int ps, int h, int ascent); hit draw_line(branche *br, plot_data *ob, int doit, int char_width, int char_height, int descend, int ascent); hit draw_name_angle(cp_point *phys_pos, char *nom, plot_data *ob, double angle, int doit, int char_width, int char_height, int descend, int color, int ascent); hit draw_letter(point *position, char lettre, plot_data *ob, int doit, int char_width, int color, int ascent); void draw_scale(plot_data *ob, int char_height, int ascent); int my_get_char_height(int *ascend, int *descend); int my_get_string_width(char *nom); char *check_alloc(int nbrelt, int sizelt); void majuscules(char *p); void search_callback(Nlm_IteM item); void reset_callback(Nlm_IteM item); void string_callback(Nlm_ButtoN item); void process_keys(Nlm_Char key); void clear_tree(Nlm_IteM unused); void paste_tree(Nlm_IteM unused); #ifdef MICRO void copy_callback(Nlm_IteM); int print_title(int x, int y, char *text); void print_plot(Nlm_IteM); #endif #ifdef WIN_MAC int crefpict(char *, PicHandle ); extern void add_apropos(char *progname, Nlm_ActnProc my_show_apropos); extern void show_apropos_unrooted(Nlm_IteM item); extern char *mac_fname_to_roman(char *); #else void process_args(int *argc, char *argv[]); void remove_arg(int target, int *argc, char *argv[]); #endif #ifdef WIN_MAC extern int MG_GetInputFName(char *fname, int maxl); extern int MG_GetOutputFName(char *fname, int maxl, char *dfault); extern QDPictRef MyPictToQDPict(PicHandle mypicture); extern int MyQDPictToPDFfile (QDPictRef picture, char *fname); #elif defined(WIN_MSWIN) extern int MG_GetInputFName(char *fname, int maxl); extern int MG_GetOutputFName(char *fname, int maxl, char *dfault); #else #define MG_GetOutputFName Nlm_GetOutputFileName #define MG_GetInputFName(a,b) Nlm_GetInputFileName(a, b, NULL, NULL) #endif /* external functions */ double arrondi_echelle(double x); double calc_echelle(int larg); bignoeud *cre_new_tree(struct noeud *debut, struct noeud *parent, bignoeud *bigparent); void remove_big_root(bignoeud *bigracine); double calc_dist_centre_feuilles(bignoeud *debut, bignoeud *parent); double proc_null_neg_branches(bignoeud *debut, bignoeud *parent); int set_angles_noeuds(bignoeud *debut, bignoeud *parent, double delta, double *p_current_angle, double rayon); void calc_cartesienne( cp_point *p); void calc_polaire( cp_point *p); cp_point calc_point_direction( cp_point *depart, cp_point *direction, double longueur); branche *calc_position_noeuds(bignoeud *debut, bignoeud *parent, branche *curr_branche); void mem_line(cp_point *debut, cp_point *fin, bignoeud *noeud_term, branche *br); void draw_tree(plot_data *ob, branche *branches, int comp_phys_bounds); void log_to_phys(cp_point *log_pos, cp_point *phys_pos); double length_log_phys(double p); double length_phys_log(double p); char *preptree(char *fname); void free_tree(void); int myrint(double val); /* globals */ FD_unrooted *fd_unrooted; Nlm_FonT current_font; char current_ps_font[40]; #ifdef WIN_MSWIN int current_font_size_rank = font_small; #else int current_font_size_rank = font_normal; #endif int list_font_size[] = { 0, 8, 10, 12, 14, 18 }; #ifdef WIN_MSWIN char list_font_name[4][40] = {"", "Times New Roman", "Lucida Sans", "Courier New"}; #else char list_font_name[4][15] = {"", "Times", "Helvetica", "Courier"}; #endif paper_item paper_choice = A4; char fname[200]; plot_data plot_aux_data; branche *branches; double log_min_x, log_min_y, log_max_x, log_max_y, mini_br_length; int phys_min_x, phys_min_y, phys_max_x, phys_max_y; int doing_copy = FALSE; int doing_print = FALSE; Nlm_RecT print_rect; int ps_plot_only = FALSE; FILE *plotfile; #ifdef WIN_MAC PicHandle mypicture; int margin; #endif /* external variables */ extern int notu, has_br_length; extern struct noeud *racine; int argc; char **argv; Nlm_Int2 Nlm_Main(void) { Nlm_RecT *p_rect; *fname = 0; #ifndef WIN_MAC argc = Nlm_GetArgc(); argv = Nlm_GetArgv(); process_args(&argc, argv); if(argc>=2) { strcpy(fname,argv[1]); } else { *fname=0; } #endif if(ps_plot_only) { if ( *fname != 0 ) exit( direct_ps_plot() ); else exit(1); } Nlm_WatchCursor(); #ifdef WIN_MOTIF {char *font; font = Nlm_XrmGetResource("systemfont"); if(font != NULL) set_systemfont(font); } #endif fd_unrooted = create_win_unrooted(); prepare_fonts(); fd_unrooted->tree_name = fname; /* show the first form */ if(*fname != 0) debut_arbre(); set_tree_w_title(fd_unrooted->unrooted, (*fname == 0 ? "unrooted" : fname), notu ); Nlm_Show(fd_unrooted->unrooted); p_rect = (Nlm_RecT *)Nlm_GetWindowExtra(fd_unrooted->unrooted); Nlm_ObjectRect(fd_unrooted->unrooted, p_rect); Nlm_ArrowCursor(); Nlm_ProcessEvents(); return 0; } int direct_ps_plot(void) { /* valeurs initiales des extr physiques des lignes du graphique */ phys_max_x = 500; phys_max_y = 750; phys_min_x = 0; phys_min_y = 0; debut_arbre(); strcpy(current_ps_font, "Times-Roman"); plot_aux_data.comp_phys_bounds = TRUE; save_plot_callback(NULL); return 0; } FD_unrooted *create_win_unrooted(void) { Nlm_WindoW win; Nlm_MenU menu; Nlm_ChoicE choix_paper; Nlm_WindoW place_menu; FD_unrooted *fdui = (FD_unrooted *) calloc(1, sizeof(FD_unrooted)); static Nlm_RecT winrect; int width, height; #ifdef WIN_MAC add_apropos("unrooted", show_apropos_unrooted); #endif Nlm_KeyboardView(process_keys); fdui->unrooted = win = Nlm_DocumentWindow(-50, -33, -3, -3, "Unrooted", (Nlm_WndActnProc) exit_callback, win_resize_proc); #ifdef WIN_MAC place_menu = NULL; #else place_menu = win; #endif #ifdef WIN_MAC #define OPEN_LABEL "Open O" #define SAVE_PLOT_LABEL "Save Plot S" #define PRINT_LABEL "Print P" #define FIND_LABEL "Find F" #define AGAIN_LABEL "Again A" #define RESET_LABEL "Reset R" #define COPY_LABEL "Copy C" #define PASTE_LABEL "Paste V" #else #define OPEN_LABEL "Open ^O" #define SAVE_PLOT_LABEL "Save Plot ^S" #define PRINT_LABEL "Print ^P" #define QUIT_LABEL "Quit ^Q" #define FIND_LABEL "Find ^F" #define AGAIN_LABEL "Again ^A" #define RESET_LABEL "Reset ^R" #define COPY_LABEL "Copy ^C" #define PASTE_LABEL "Paste ^V" #endif menu = Nlm_PulldownMenu(place_menu, "File"); fdui->open_button = Nlm_CommandItem(menu, OPEN_LABEL, open_callback); fdui->save_plot_button = Nlm_CommandItem(menu, SAVE_PLOT_LABEL, save_plot_callback); #ifdef MICRO Nlm_CommandItem(menu, PRINT_LABEL, print_plot); #endif #ifndef WIN_MAC Nlm_CommandItem(menu, QUIT_LABEL, exit_callback); #endif Nlm_Advance(place_menu); menu = Nlm_PulldownMenu(place_menu, "Edit"); #if defined(WIN_MAC) || defined(WIN_MSWIN) #endif Nlm_CommandItem(menu, "Clear", clear_tree); #ifdef MICRO Nlm_CommandItem(menu, COPY_LABEL, copy_callback); #endif Nlm_CommandItem(menu, PASTE_LABEL, paste_tree); Nlm_SeparatorItem(menu); Nlm_CommandItem(menu, FIND_LABEL, search_callback); fdui->AgainItem = Nlm_CommandItem(menu, AGAIN_LABEL, search_callback); Nlm_CommandItem(menu, RESET_LABEL, reset_callback); Nlm_Disable(fdui->AgainItem); Nlm_Advance(place_menu); fdui->tree_font_menu = Nlm_PulldownMenu(place_menu, "Font"); fdui->choix_font = Nlm_ChoiceGroup(fdui->tree_font_menu, font_callback); Nlm_ChoiceItem(fdui->choix_font, list_font_name[1]); Nlm_ChoiceItem(fdui->choix_font, list_font_name[2]); Nlm_ChoiceItem(fdui->choix_font, list_font_name[3]); Nlm_SetValue(fdui->choix_font, times); Nlm_SeparatorItem(fdui->tree_font_menu); fdui->choix_taille = Nlm_ChoiceGroup(fdui->tree_font_menu, font_callback); Nlm_ChoiceItem(fdui->choix_taille, "8"); Nlm_ChoiceItem(fdui->choix_taille, "10"); Nlm_ChoiceItem(fdui->choix_taille, "12"); Nlm_ChoiceItem(fdui->choix_taille, "14"); Nlm_ChoiceItem(fdui->choix_taille, "18"); Nlm_SetValue(fdui->choix_taille, current_font_size_rank); Nlm_SeparatorItem(fdui->tree_font_menu); fdui->bold_item = Nlm_StatusItem(fdui->tree_font_menu, "Bold", (Nlm_ItmActnProc) font_callback); fdui->italic_item = Nlm_StatusItem(fdui->tree_font_menu, "Italic", (Nlm_ItmActnProc) font_callback); Nlm_SetStatus(fdui->bold_item, FALSE); Nlm_SetStatus(fdui->italic_item, FALSE); Nlm_Advance(place_menu); fdui->paper_menu = Nlm_PulldownMenu(place_menu, "Paper"); choix_paper = Nlm_ChoiceGroup(fdui->paper_menu, paper_callback); Nlm_ChoiceItem(choix_paper, "A4"); Nlm_ChoiceItem(choix_paper, "US letter"); if(paper_choice == A4) Nlm_SetValue(choix_paper, 1); else Nlm_SetValue(choix_paper, 2); Nlm_Break(win); #ifdef WIN_MOTIF /* bug in LessTif : resize does not work if nothing except panel */ { Nlm_Handle obj; Nlm_PoinT position; Nlm_GetNextPosition(win, &position); obj = Nlm_PushButton(win,"void",NULL); Nlm_Hide(obj); Nlm_SetNextPosition(win, position); } #endif #if defined(unix) || defined(WIN_MSWIN) width = height = 510; #else width = height = 450; #endif fdui->tree_plot = Nlm_AutonomousPanel(win, width, height, tree_draw_proc, NULL, NULL, 0, NULL, NULL); winrect.left = -1; Nlm_SetWindowExtra(win, &winrect, NULL); return fdui; } void win_resize_proc(Nlm_WindoW win) { Nlm_RecT *old_rect, rect; int change_x, change_y, old_height, new_height; old_rect = (Nlm_RecT *)Nlm_GetWindowExtra(win); if(old_rect->left == -1) return; Nlm_ObjectRect(win, &rect); old_height = old_rect->bottom - old_rect->top; new_height = rect.bottom - rect.top; change_y = (new_height - old_height); old_height = old_rect->right - old_rect->left; new_height = rect.right - rect.left; change_x = (new_height - old_height); if(change_x != 0 || change_y != 0) { change_panel_size(fd_unrooted->tree_plot, change_x, change_y); *old_rect = rect; } } void change_panel_size(Nlm_PaneL panel, int change_x, int change_y) { Nlm_RecT r, r_group; Nlm_GrouP group; Nlm_Boolean in_group; static int recursive = FALSE; Nlm_GetPosition(panel, &r); #ifdef WIN_MOTIF if(recursive) return; recursive = TRUE; group = Nlm_Parent(panel); in_group = (group != Nlm_ParentWindow(panel)); if(in_group) { Nlm_GetPosition(group, &r_group); Nlm_Hide(group); } else Nlm_Hide(panel); #endif r.bottom += change_y; r.right += change_x; Nlm_SetPosition(panel, &r); #ifdef WIN_MOTIF if(in_group) { r_group.bottom += change_y; r_group.right += change_x; Nlm_SetPosition( group, &r_group); Nlm_Show(group); } else Nlm_Show(panel); recursive = FALSE; #endif } void font_callback(Nlm_ChoicE choix) { prepare_fonts(); plot_aux_data.comp_phys_bounds = TRUE; tree_draw_proc(fd_unrooted->tree_plot); } void prepare_fonts(void) { Nlm_Boolean use_bold, use_italic; Nlm_Int2 font_num; char font_full_name[40]; /* prepare vibrant font */ use_bold = Nlm_GetStatus(fd_unrooted->bold_item); use_italic = Nlm_GetStatus(fd_unrooted->italic_item); font_num = Nlm_GetValue(fd_unrooted->choix_font); current_font_size_rank = Nlm_GetValue(fd_unrooted->choix_taille); sprintf(font_full_name, "%s,%d", list_font_name[font_num], list_font_size[current_font_size_rank]); if(use_bold || use_italic) strcat(font_full_name, ","); if(use_bold) strcat(font_full_name, "b"); if(use_italic) strcat(font_full_name, "i"); current_font = Nlm_ParseFont(font_full_name); /* prepare postscript name of font */ strcpy(current_ps_font, list_font_name[font_num]); current_ps_font[0] = toupper(current_ps_font[0]); if( use_bold ) strcat(current_ps_font,"-Bold"); else if( use_italic ) { if(font_num == times) strcat(current_ps_font,"-Italic"); else strcat(current_ps_font,"-Oblique"); } else if(font_num == times) strcat(current_ps_font,"-Roman"); } #ifndef WIN_MAC void remove_arg(int target, int *argc, char *argv[]) { int num; for(num = target; num < *argc - 1; num++) argv[num] = argv[num+1]; (*argc)--; } void process_args(int *argc, char *argv[]) { int num, taille; for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-h", 2) ==0 ){ fprintf(stderr,"Usage: unrooted [options] [tree_file_name]\n" "where options are:\n" "-h print out this message\n" "-psonly no window interface, just write the postscript tree file\n" "-us postcript tree file prepared for US Letter paper size\n" "-size n font size n used for taxon names\n" "\n" "and where tree_file_name is the name of a tree file using nested parentheses\n"); exit(0); } } for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-us", 3) == 0) { paper_choice = LETTER; remove_arg(num, argc, argv); break; } } for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-psonly", 7) == 0) { ps_plot_only = TRUE; remove_arg(num, argc, argv); break; } } for(num = 1; num < *argc; num++) { if( strncmp(argv[num], "-size", 5) == 0) { taille = 12; if(num + 1 < *argc) { sscanf(argv[num + 1], "%d", &taille); remove_arg(num + 1, argc, argv); } remove_arg(num, argc, argv); for(num = 0; num < 5; num++) if(taille <= list_font_size[num]) break; current_font_size_rank = num; break; } } } #endif void open_callback(Nlm_IteM ob) { Nlm_Boolean reponse; char *p; reponse = MG_GetInputFName(fname, sizeof(fname) ); if(!reponse) { tree_draw_proc(fd_unrooted->tree_plot); return; } Nlm_WatchCursor(); if(notu != 0) free_tree(); notu = 0; debut_arbre(); plot_aux_data.comp_phys_bounds = TRUE; set_tree_w_title(fd_unrooted->unrooted, fname, notu); tree_draw_proc(fd_unrooted->tree_plot); } void set_tree_w_title(Nlm_WindoW w, char *file, int tips) { char tmp[200]; file = extract_filename(file); #ifdef WIN_MAC file = mac_fname_to_roman(file); #endif if(tips != 0) sprintf(tmp, "%s (%d tips)", file, tips + 1); Nlm_SetTitle(w, (tips == 0 ? "unrooted" : tmp ) ); } void paper_callback(Nlm_ChoicE ob) { paper_choice = (paper_item) Nlm_GetValue(ob); } void exit_callback(Nlm_IteM ob) { exit(0); } void tree_draw_proc(Nlm_PaneL panel) { Nlm_RecT ob_rect; Nlm_Int2 width, height; static Nlm_Int2 previous_h = 0, previous_w = 0; if(doing_print) ob_rect = print_rect; else { Nlm_Select(panel); Nlm_ObjectRect(panel, &ob_rect); } #ifdef WIN_MOTIF ob_rect.bottom -= 3; #endif Nlm_Black(); Nlm_EraseRect(&ob_rect); Nlm_FrameRect(&ob_rect); if(notu == 0) return; width = ob_rect.right - ob_rect.left + 1; height = ob_rect.bottom - ob_rect.top + 1; if( width != previous_w || height != previous_h ) { /* si on a redimensionne la fenetre ou la 1ere fois */ previous_w = width; previous_h = height; plot_aux_data.comp_phys_bounds = TRUE; plot_aux_data.x = ob_rect.left; plot_aux_data.y = ob_rect.top; plot_aux_data.w = width; plot_aux_data.h = height; tree_draw_proc(panel); return; } Nlm_SelectFont(current_font); if(!doing_print) Nlm_ClipRect(&ob_rect); if( plot_aux_data.comp_phys_bounds ) { /* valeurs initiales des extr physiques des lignes du graphique */ phys_max_x = ob_rect.right; phys_max_y = ob_rect.bottom; phys_min_x = ob_rect.left; phys_min_y = ob_rect.top; } plot_aux_data.x = ob_rect.left; plot_aux_data.y = ob_rect.top; plot_aux_data.w = width; plot_aux_data.h = height; Nlm_WatchCursor(); draw_tree(&plot_aux_data, branches, plot_aux_data.comp_phys_bounds); Nlm_ArrowCursor(); if(!doing_print) Nlm_ResetClip(); plot_aux_data.comp_phys_bounds = FALSE; } /* fenetre message d'alerte. Operation Select dans la boucle des evenements qui ramene toujours la fenetre au premier plan. Lent, mais interessant. */ static void alert_ok_action(Nlm_ButtoN bouton) { Nlm_Boolean *alert_done; alert_done = (Nlm_Boolean *)Nlm_GetWindowExtra(Nlm_Parent(bouton)); *alert_done = TRUE; } void err_message(char *texte) { Nlm_WindoW alwin; Nlm_Boolean alert_done; #ifdef WIN_MAC alwin = Nlm_FixedWindow(-50,-50,-5,-5,"MESSAGE",NULL); // Bug: ModalWindow crashes when return key hit #else alwin = Nlm_ModalWindow(-50,-50,-5,-5,NULL); #endif Nlm_StaticPrompt(alwin,texte,0,0,Nlm_programFont,'l'); Nlm_Break(alwin); Nlm_DefaultButton(alwin,"ok",alert_ok_action); Nlm_Show(alwin); alert_done=FALSE; Nlm_SetWindowExtra(alwin, &alert_done, NULL); Nlm_ArrowCursor(); while(! alert_done) { #ifdef WIN_MAC if(! Nlm_InFront(alwin) ) Nlm_Select(alwin); // to emulate modal window on mac #endif myWaitAndProcessNextEvent(); } Nlm_Remove(alwin); } char *extract_filename(char *name) { char *p; while( ( p = strchr(name, DIR_DELIM) ) != NULL) name = p + 1; return name; } #ifdef WIN_MAC int crefpict(char *fname, PicHandle picture) { QDPictRef myqdpict; int err; myqdpict = MyPictToQDPict(picture); if(myqdpict != NULL) err = MyQDPictToPDFfile(myqdpict, fname); else err = TRUE; KillPicture(picture); return err; } void copy_callback(Nlm_IteM unused) { extern void MyCopyPictToClipboard (PicHandle mypicture); if(notu == 0) return; doing_copy = TRUE; save_plot_callback(NULL); MyCopyPictToClipboard (mypicture ); KillPicture(mypicture); doing_copy = FALSE; } #endif #ifdef WIN_MSWIN void copy_callback(Nlm_IteM unused) { Nlm_RecT r; Nlm_WindoW w; if(notu == 0) return; /* dans la picture, les calculs de taille de caractere ne marchent pas! il faut les faire dans le DC de la fenetre */ doing_copy = TRUE; Nlm_GetPosition( fd_unrooted->tree_plot , &r); w = Nlm_StartPicture(&r); tree_draw_proc(fd_unrooted->tree_plot); Nlm_EndPicture(w); doing_copy = FALSE; } #endif void paste_tree(Nlm_IteM unused) { char *buff; FILE *tmp; char *tmpfname; char pasted_title[] = "pasted tree"; if(notu != 0) { err_message("Do \"Edit:clear\" before pasting tree data"); return; } #ifdef WIN_MAC Nlm_textScrapFull = FALSE; /* arrange un bug de Nlm_ClipboardHasString */ #endif if( ! Nlm_ClipboardHasString() ) { err_message("No text describing tree present in clipboard"); return; } buff = Nlm_ClipboardToString(); tmpfname = tempnam(NULL, "unrootedtemp_"); tmp = fopen(tmpfname,"w"); fwrite(buff, 1, strlen(buff), tmp); fclose(tmp); strcpy(fname, tmpfname); debut_arbre(); remove(tmpfname); if(notu > 0) { set_tree_w_title(fd_unrooted->unrooted, pasted_title, notu); strcpy(fname, pasted_title); plot_aux_data.comp_phys_bounds = TRUE; tree_draw_proc(fd_unrooted->tree_plot); } else fname[0] = 0; } void save_plot_callback(Nlm_IteM ob) { const int a4_h = 750, letter_h = 700; int paper_h, font_size; char *sp, *p1, message[100]; char plotfilename[200]; int myw, myh, myx, myy; #ifdef WIN_MAC int macfont; Style mystyle=normal; Rect myrect; #else time_t heure; #endif if(notu==0)return; myw = plot_aux_data.w; myh = plot_aux_data.h; myx = plot_aux_data.x; myy = plot_aux_data.y; if(!doing_copy) { strcpy(plotfilename,fname); sp = strchr(plotfilename,'.'); if(sp == NULL) sp = plotfilename + strlen(plotfilename); #ifdef WIN_MAC strcpy(sp,".pdf"); #else strcpy(sp,".ps"); #endif p1 = extract_filename(plotfilename); if(!ps_plot_only) { if( !MG_GetOutputFName(plotfilename, sizeof(plotfilename), p1) ) return; } } #ifdef WIN_MAC margin = 30; myrect.top=10; myrect.left=10; myrect.bottom=760; myrect.right=500; ClipRect(&myrect); mypicture = OpenPicture(&myrect); PenNormal(); macfont = Nlm_GetValue(fd_unrooted->choix_font); if(macfont == courier) macfont=22; else if(macfont == helvetica) macfont=21; else if(macfont == times) macfont=20; else macfont=22; TextFont(macfont); TextSize( list_font_size[current_font_size_rank] ); if( Nlm_GetStatus(fd_unrooted->bold_item) ) mystyle += bold; if( Nlm_GetStatus(fd_unrooted->italic_item) ) mystyle += italic; TextFace(mystyle); plot_aux_data.w = myrect.right-myrect.left - 2 * margin; plot_aux_data.h = myrect.bottom-myrect.top - 2 * margin; #else font_size = list_font_size[current_font_size_rank]; plotfile = fopen(plotfilename,"w"); if(plotfile == NULL) { return; } if(paper_choice == A4) paper_h = a4_h; else paper_h = letter_h; plot_aux_data.h = paper_h; plot_aux_data.w = 500; plot_aux_data.x = plot_aux_data.y = 0; fprintf(plotfile,"%%!\n1 setlinecap 1 setlinejoin 1 setlinewidth 0 setgray\n"); fprintf(plotfile,"/basefont /%s findfont %d scalefont def\n", current_ps_font, font_size); fprintf(plotfile,"/titlefont /Times-Roman findfont 12 scalefont def\n"); fprintf(plotfile,"50 50 translate\n"); fprintf(plotfile,"-10 -10 moveto 510 -10 lineto 510 %d lineto -10 %d lineto \ -10 -10 lineto stroke\n", paper_h+10, paper_h+10); time(&heure); fprintf(plotfile,"titlefont setfont\n"); fprintf(plotfile, "0 %d moveto (%s %s) show\n", paper_h+15, fname, ctime(&heure)); fprintf(plotfile,"basefont setfont\n"); #endif plot_aux_data.ps_plot = TRUE; Nlm_WatchCursor(); draw_tree(&plot_aux_data, branches, TRUE); Nlm_ArrowCursor(); plot_aux_data.w = myw; plot_aux_data.h = myh; plot_aux_data.x = myx; plot_aux_data.y = myy; plot_aux_data.ps_plot = FALSE; #ifdef WIN_MAC ClosePicture(); if( !doing_copy ) if( crefpict(plotfilename, mypicture) ) { sprintf(message, "Problem writing PDF file %s", plotfilename); err_message(message); } #else fprintf(plotfile,"showpage\n"); fclose(plotfile); if(ps_plot_only) return; sprintf(message, "The tree is now in file %s " "in Postscript format", plotfilename); err_message(message); #endif plot_aux_data.comp_phys_bounds = TRUE; if( !doing_copy ) tree_draw_proc(fd_unrooted->tree_plot); } void create_win_if_needed(char *titre) { strcpy(fname, titre); debut_arbre(); set_tree_w_title(fd_unrooted->unrooted, titre, notu); tree_draw_proc(fd_unrooted->tree_plot); } void debut_arbre(void) { bignoeud *centre, *bigracine; char *pname; int tot; double delta, current_angle, width, height; branche *fin_branche, *br; double radius; /* read tree file */ if( (pname=preptree(fname)) != NULL ) { char mess[150]; strcpy(mess, pname); strcat(mess, fname); err_message(mess); notu = 0; Nlm_UseWindow(fd_unrooted->unrooted); return; } bigracine = cre_new_tree(racine, NULL, NULL); if(!has_br_length) bigracine->l2 = 0; centre = bigracine->v1; /* changer de centre si c'est une feuille */ tot=0; if(centre->v1 == NULL) tot++; if(centre->v2 == NULL) tot++; if(centre->v3 == NULL) tot++; if(tot>= 2) centre = bigracine->v2; remove_big_root(bigracine); radius = calc_dist_centre_feuilles(centre, NULL); /* on va remplacer les branches nulles par des branches 100 fois plus courtes que la plus courte de l'arbre */ mini_br_length = proc_null_neg_branches(centre, NULL); mini_br_length /= 100; delta = 2*M_PI / (notu+1); current_angle = 0; set_angles_noeuds(centre, NULL, delta, ¤t_angle, radius); centre->position.r = 0; centre->position.angle = 0; calc_cartesienne(&(centre->position)); branches = (branche *)check_alloc(2*(notu+1)-3, sizeof(branche)); fin_branche = calc_position_noeuds(centre, NULL, branches); /* calcul extremites du graphique des branches */ log_min_x = log_max_x = branches->debut.x; log_min_y = log_max_y = branches->debut.y; for(br = branches; br < fin_branche; br++) { if(br->debut.x < log_min_x) log_min_x = br->debut.x; if(br->debut.x > log_max_x) log_max_x = br->debut.x; if(br->fin.x < log_min_x) log_min_x = br->fin.x; if(br->fin.x > log_max_x) log_max_x = br->fin.x; if(br->debut.y < log_min_y) log_min_y = br->debut.y; if(br->debut.y > log_max_y) log_max_y = br->debut.y; if(br->fin.y < log_min_y) log_min_y = br->fin.y; if(br->fin.y > log_max_y) log_max_y = br->fin.y; } width = log_max_x - log_min_x; height = log_max_y - log_min_y; if( width > height ) { log_min_y -= (width - height)/2; log_max_y += (width - height)/2; } else if( height > width ) { log_min_x -= (height - width)/2; log_max_x += (height - width)/2; } } void my_draw_line(int dx, int dy, int fx, int fy, int col, int ps, int h) { if(ps) { #ifdef WIN_MAC MoveTo(dx + margin, dy + margin); LineTo(fx + margin, fy + margin); #else fprintf(plotfile, "%d %d moveto ", dx, h - dy); fprintf(plotfile, "%d %d lineto stroke\n", fx, h - fy); #endif } else { Nlm_MoveTo(dx, dy); Nlm_LineTo(fx, fy); } } void my_draw_text(int align, int x, int y, int color, int size, int style, char *chaine, int ps, int h, int ascent) { int w; if( align == ALIGN_CENTER) w = my_get_string_width(chaine)/2; else w = 0; if( ps ) { #ifdef WIN_MAC static char copy[255]; int l; MoveTo(x + margin - w, y + margin); l = strlen(chaine); *copy = l; memcpy(copy + 1, chaine, l + 1); DrawString( (ConstStr255Param) copy); #else fprintf(plotfile, "%d %d moveto ", x - w, h - y); fprintf(plotfile,"(%s) show\n",chaine); #endif } else { if(color) Nlm_Red(); #ifdef WIN_MSWIN Nlm_PaintStringEx(chaine, x-w, (doing_copy ? y-ascent : y) ); #else Nlm_MoveTo(x - w, y); Nlm_PaintString(chaine); #endif if(color) Nlm_Black(); } } hit draw_line(branche *br, plot_data *ob, int doit, int char_width, int char_height, int descend, int ascent) { double h, w; double angle; cp_point phys_debut, phys_fin; hit result; log_to_phys(&br->debut, &phys_debut); log_to_phys(&br->fin, &phys_fin); w = phys_fin.x - phys_debut.x; h = phys_fin.y - phys_debut.y; if( doit ) { my_draw_line(phys_debut.x + ob->x, phys_debut.y + ob->y, phys_fin.x + ob->x, phys_fin.y + ob->y, ob->lcol, ob->ps_plot, ob->h); } if(br->nom != NULL) { /* calcule de l'angle tel que vu sur le dessin: il faut utiliser -h car les coord en y sont calculees avec 0 en haut aussi mettre angle dans [0 , 2*pi[ */ angle = atan( (-h) / w ); if( w < 0 ) angle = M_PI + angle; if(angle < 0) angle += 2*M_PI; result = draw_name_angle(&phys_fin, br->nom, ob, angle, doit, char_width, char_height, descend, br->color, ascent); if( result != NO_HIT ) return result; } return NO_HIT; } hit draw_name_angle(cp_point *phys_pos, char *nom, plot_data *ob, double angle, int doit, int char_width, int char_height, int descend, int color, int ascent) { double x, y, x_delta, y_delta; point new_position; int stepx; hit result; static char lettre[2] = "A"; #ifdef WIN_MAC if(doit && ob->ps_plot) PicComment(140, 0, nil); /* pour grouper les caract d'un nom */ #endif x = phys_pos->x; y = phys_pos->y; if((angle>= 0 && angle <= M_PI/4) || (angle >= 7*M_PI/4 && angle <= 2*M_PI)) { stepx = TRUE; } else if((angle > M_PI/4 && angle < M_PI/2) || (angle > 3*M_PI/2 && angle < 7*M_PI/4)) { stepx = FALSE; } else if((angle >= M_PI/2 && angle <= 3*M_PI/4) || (angle >= 5*M_PI/4 && angle <= 3*M_PI/2)) { stepx = FALSE; y_delta = char_height; y_delta -= descend; y_delta *= ( (int) strlen(nom) ); if(angle >= M_PI/2 && angle <= 3*M_PI/4) y -= y_delta; else y += y_delta; x_delta = y_delta / fabs( tan(angle) ); x -= x_delta; angle -= M_PI; if(angle < 0) angle += 2*M_PI; } else { stepx = TRUE; x_delta = my_get_string_width(nom); y_delta = x_delta * tan(angle); x -= x_delta; y += y_delta; angle -= M_PI; if(angle < 0) angle += 2*M_PI; } do { new_position.x = x + 0.5; new_position.y = y + 0.5; result = draw_letter(&new_position, *nom, ob, doit, char_width, color, ascent); if( result != NO_HIT ) return result; if(stepx) { lettre[0] = nom[0]; x_delta = my_get_string_width(lettre); x += x_delta; y_delta = x_delta * tan(angle); y -= y_delta; } else { y_delta = char_height; y_delta -= descend; x_delta = y_delta / fabs( tan(angle) ); x += x_delta; if(angle <= M_PI/2) y -= y_delta; else y += y_delta; } nom++; } while(*nom != 0); #ifdef WIN_MAC if(doit && ob->ps_plot) PicComment(141, 0, nil); /* fin du groupe */ #endif return NO_HIT; } hit draw_letter(point *position, char lettre, plot_data *ob, int doit, int char_width, int color, int ascent) { static char chaine[2] = " "; double maxx; if(ob->ps_plot) { maxx = ob->w; } else { maxx = ob->w - char_width; } /* clipping */ if( position->x <= 0 ) return LEFT_HIT; if( position->x >= maxx ) return RIGHT_HIT; if( position->y - ascent < 0 ) return TOP_HIT; if( position->y >= ob->h ) return BOTTOM_HIT; chaine[0] = lettre; if(doit && lettre != ' ') my_draw_text(ALIGN_LEFT, position->x + ob->x, position->y + ob->y, color, ob->lsize, ob->lstyle, chaine, ob->ps_plot, ob->h, ascent); return NO_HIT; } void draw_scale(plot_data *ob, int charheight, int ascent) { char ech_name[20]; int phys_w, y, xd, xf; double log_val; log_val = calc_echelle(ob->w); phys_w = myrint(length_log_phys(log_val)); y = 1.5 * charheight; xf = ob->w * 0.97; xd = xf - phys_w; my_draw_line(xd + ob->x, y + ob->y, xf + ob->x, y + ob->y, ob->lcol, ob->ps_plot, ob->h); sprintf(ech_name, "%.1g", log_val); my_draw_text(ALIGN_CENTER, (xd + xf)/2 + ob->x, y - charheight/3 + ob->y, ob->lcol, ob->lsize, ob->lstyle, ech_name, ob->ps_plot, ob->h, ascent); my_draw_line(xd + ob->x, y - charheight/3 + ob->y, xd + ob->x, y + charheight/3 + ob->y, ob->lcol, ob->ps_plot, ob->h); my_draw_line(xf + ob->x, y - charheight/3 + ob->y, xf + ob->x, y + charheight/3 + ob->y, ob->lcol, ob->ps_plot, ob->h); } int my_get_char_height(int *ascend, int *descend) { if(plot_aux_data.ps_plot) { #ifdef WIN_MAC static FontInfo myinfo; GetFontInfo(&myinfo); *ascend = myinfo.ascent; *descend = myinfo.descent; #else int font_size; font_size = list_font_size[current_font_size_rank]; *ascend = 0.80 * font_size; *descend = font_size - *ascend; #endif } else { #ifdef WIN_MSWIN HDC picHDC = Nlm_currentHDC; if(doing_copy) { Nlm_currentHDC = Nlm_GetPicWinHDC(); Nlm_SelectFont(current_font); } #endif *ascend = Nlm_Ascent(); *descend = Nlm_Descent(); #ifdef WIN_MSWIN if(doing_copy) Nlm_currentHDC = picHDC; #endif } return *ascend + *descend ; } int my_get_string_width(char *nom) { int w; if(plot_aux_data.ps_plot) { #ifdef WIN_MAC static char nom255[256]; w = strlen(nom); memcpy(nom255+1, nom, w); nom255[0] = w; w = StringWidth( (ConstStr255Param) nom255); #else w = list_font_size[current_font_size_rank]; w = w * 0.61 * (int)strlen(nom); #endif } else { #ifdef WIN_MSWIN HDC picHDC = Nlm_currentHDC; if(doing_copy) { Nlm_currentHDC = Nlm_GetPicWinHDC(); Nlm_SelectFont(current_font); } #endif w = Nlm_TextWidth(nom, strlen(nom)) ; #ifdef WIN_MSWIN if(doing_copy) Nlm_currentHDC = picHDC; #endif } return w; } char *check_alloc(int nbrelt, int sizelt) { char *retval; if( (retval = calloc(nbrelt,sizelt)) != NULL ) return retval; err_message("ERROR: not enough memory."); } void process_keys(Nlm_Char key) { #ifdef WIN_MAC /* combinaison command-lettre */ #define test_key(a) Nlm_cmmdKey && Nlm_currentKey == a #else /* combinaison control-lettre */ #define test_key(a) key == a - 96 #endif if( test_key('q') ) exit(0); else if( test_key('o') ) open_callback(fd_unrooted->open_button); else if( test_key('s') ) save_plot_callback(fd_unrooted->save_plot_button); #ifdef MICRO else if( test_key('c') ) copy_callback(NULL); else if( test_key('p') ) print_plot(NULL); #endif else if( test_key('v') ) paste_tree(NULL); else if( test_key('f') ) search_callback(NULL); else if( test_key('a') ) { if(Nlm_Enabled(fd_unrooted->AgainItem) ) search_callback(fd_unrooted->AgainItem); } else if( test_key('r') ) reset_callback(NULL); return; } void string_callback(Nlm_ButtoN item) { Nlm_Boolean *pdone; pdone = (Nlm_Boolean *)Nlm_GetWindowExtra( Nlm_ParentWindow(item) ); *pdone = TRUE; } void majuscules(char *p) { while(*p != 0) {*p = toupper(*p); p++;} } void search_callback(Nlm_IteM item) { static Nlm_WindoW win; static Nlm_Boolean search_done; static Nlm_TexT select_box; static char select[100]; char aux[100]; int num, trouve, totnoms; static int first = TRUE; if(item != fd_unrooted->AgainItem) { if(first) { win = Nlm_FixedWindow(-50,-50,-5,-5,"Name searched:",NULL); select_box=Nlm_DialogText(win,"",15,NULL); Nlm_Advance(win); Nlm_DefaultButton(win,"ok",string_callback); Nlm_SetWindowExtra(win, &search_done, NULL); first = FALSE; } Nlm_Show(win); Nlm_Select(win); Nlm_Select(select_box); search_done=FALSE; while(! search_done) { myWaitAndProcessNextEvent(); } Nlm_GetTitle(select_box, select, sizeof(select)); majuscules(select); Nlm_Hide(win); Nlm_Enable(fd_unrooted->AgainItem); Nlm_Select(fd_unrooted->unrooted); Nlm_FlushEvents(); } if(strlen(select) == 0) return; trouve = FALSE; totnoms = 2 * (notu + 1) - 3; for(num = 0; num < totnoms; num++) { if(branches[num].nom == NULL) continue; strcpy(aux, branches[num].nom); majuscules(aux); if(strstr( aux, select) != NULL) { trouve = TRUE; branches[num].color = TRUE; } } if(trouve) { tree_draw_proc(fd_unrooted->tree_plot); } } void reset_callback(Nlm_IteM item) { int num; for(num = 0; num < 2 * (notu + 1) - 3; num++) branches[num].color = FALSE; tree_draw_proc(fd_unrooted->tree_plot); } void clear_tree(Nlm_IteM unused) { if(notu != 0) free_tree(); notu = 0; Nlm_SetTitle(fd_unrooted->unrooted, "unrooted"); tree_draw_proc(fd_unrooted->tree_plot); } #ifdef MICRO int print_title(int x, int y, char *text) { static char ligne[200]; time_t heure; int h, ascent, descent; time (&heure); #ifdef WIN_MAC text = mac_fname_to_roman(text); #endif sprintf(ligne, "unrooted %s %s", text, ctime(&heure) ); h = strlen(ligne); ligne[h - 1] = 0; h = my_get_char_height(&ascent, &descent); Nlm_PaintStringEx(ligne, x, y + ascent); return h; } void print_plot(Nlm_IteM unused) { Nlm_WindoW w; int h; if(notu == 0) return; w = Nlm_StartPrinting(); if(w == NULL) return; doing_print = TRUE; Nlm_PrintingRect(&print_rect); Nlm_StartPage(); Nlm_ClipPrintingRect( &print_rect); Nlm_SelectFont(current_font); h = print_title(print_rect.left, print_rect.top, fname); print_rect.top += h; plot_aux_data.comp_phys_bounds = TRUE; tree_draw_proc(fd_unrooted->tree_plot); Nlm_EndPage(); Nlm_EndPrinting(w); doing_print = FALSE; } #endif #ifdef WIN_MOTIF #include static void Nlm_GetFontData (Nlm_FonT f, Nlm_FontData * fdata) { Nlm_FntPtr fp; if (f != NULL && fdata != NULL) { fp = (Nlm_FntPtr) Nlm_HandLock (f); *fdata = *fp; Nlm_HandUnlock (f); } } void set_systemfont(char *fname) { XFontStruct *font; XmFontListEntry entry; Nlm_FontData fontdata; extern XmFontList Nlm_XfontList; Nlm_systemFont = Nlm_ParseFont(fname); Nlm_GetFontData(Nlm_systemFont, &fontdata); font= (XFontStruct *)fontdata.handle; entry = XmFontListEntryCreate(XmFONTLIST_DEFAULT_TAG, XmFONT_IS_FONT, (XtPointer)font); Nlm_XfontList = XmFontListAppendEntry(NULL, entry); Nlm_SelectFont(Nlm_systemFont); Nlm_stdLineHeight=Nlm_LineHeight(); Nlm_stdFontHeight=Nlm_FontHeight(); Nlm_stdAscent=Nlm_Ascent(); Nlm_stdDescent=Nlm_Descent(); Nlm_stdLeading=Nlm_Leading(); Nlm_stdCharWidth = Nlm_MaxCharWidth (); } #endif njplot-2.4/preptree.c0000644000002300003250000007152710426665211013342 0ustar mgouybge#include #include #include #include #ifndef FALSE #define FALSE 0 #define TRUE (!FALSE) #endif #ifndef M_PI #define M_PI 3.14159265358979323846 /* pi */ #endif #ifndef M_PI_2 #define M_PI_2 (M_PI/2) #endif /* typedefs */ typedef struct { unsigned int left : 1; unsigned int right : 1; unsigned int top : 1; unsigned int bottom : 1; } hits_field; struct noeud { double l1,l2,l3; struct noeud *v1,*v2,*v3; char *nom; } **tabtax; typedef struct { /* une branche definie par ses deux extremites */ struct noeud *bouta; struct noeud *boutb; char *br_label; } branche_noeud; typedef struct _cp_point { double x, y, r, angle; } cp_point; typedef struct _branche { cp_point debut, fin; int color; char *nom; } branche; typedef struct _bignoeud { struct _bignoeud *v1, *v2, *v3; double l1, l2, l3; cp_point position; char *nom; } bignoeud; typedef struct _plot_data { int x, y, w, h; int ps_plot; int lstyle, lcol, lsize; int comp_phys_bounds; } plot_data; typedef enum { NO_HIT, LEFT_HIT, RIGHT_HIT, TOP_HIT, BOTTOM_HIT } hit; #define s_noeud sizeof(struct noeud) char *preptree(char *fname); void make_binary_or_unrooted(char *arbre); int make_binary(char *arbre, char *debut, char *fin, int go_down); void loadphylip(char *arbre); struct noeud *unrootedset(char *arbre, char *deb, char *fin, branche_noeud **p_int_br); char *nextpar(char *text, char *pospar); void free_tree(void); double tree_bal(struct noeud *centre, struct noeud *p1, struct noeud *p2); void get_next_br(struct noeud *pere, struct noeud *fils, double **abdown, double **abup, struct noeud **f1, struct noeud **f2); void place_midpoint_root(void); void parcourir_branches(struct noeud *centre, struct noeud *origine); void process_branche(struct noeud *cote1, struct noeud *cote2, double length); double get_length_down(struct noeud *pere, struct noeud *racine); double arrondi_echelle(double x); double calc_echelle(int larg); int myrint(double val); bignoeud *cre_new_tree(struct noeud *debut, struct noeud *parent, bignoeud *bigparent); void remove_big_root(bignoeud *bigracine); double calc_dist_centre_feuilles(bignoeud *debut, bignoeud *parent); double proc_null_neg_branches(bignoeud *debut, bignoeud *parent); int set_angles_noeuds(bignoeud *debut, bignoeud *parent, double delta, double *p_current_angle, double rayon); void calc_cartesienne( cp_point *p); void calc_polaire( cp_point *p); cp_point calc_point_direction( cp_point *depart, cp_point *direction, double longueur); branche *calc_position_noeuds(bignoeud *debut, bignoeud *parent, branche *curr_branche); void mem_line(cp_point *debut, cp_point *fin, bignoeud *noeud_term, branche *br); void draw_tree(plot_data *ob, branche *branches, int comp_phys_bounds); int chg_phys(plot_data *ob, hits_field hits, int char_height); void log_to_phys(cp_point *log_pos, cp_point *phys_pos); double length_log_phys(double p); double length_phys_log(double p); /* external functions */ char *check_alloc(int nbrelt, int sizelt); void err_message(char *text); hit draw_line(branche *br, plot_data *ob, int doit, int char_width, int char_height, int descend, int ascent); int my_get_char_height(int *ascend, int *descend); int my_get_string_width(char *nom); void draw_scale(plot_data *ob, int char_height, int ascent); /* globals */ struct noeud *racine; double root_br_l; int has_br_length = 0, notu, totbranches, num_noeud, rooted, nextotu; static branche_noeud *branches; /* variables globales pour memoriser la meilleure branche: celle qui partage l'arbre en 2 parties les plus egales possibles en prof moyenne */ static double current_best_diff, current_br_length, current_balance; static struct noeud *current_cote1=NULL, *current_cote2=NULL; /* externals */ extern int phys_min_x, phys_min_y, phys_max_x, phys_max_y; extern double log_min_x, log_min_y, log_max_x, log_max_y, mini_br_length; char *preptree(char *fname) { int i, c, v, steparbre, maxarbre; FILE *njfile; char *arbre, *der_arbre, *finarbre, *tmp; if( (njfile=fopen(fname,"r")) == NULL )return ("Tree file not found."); /* recherche du debut de la description de l'arbre */ do c=fgetc(njfile); while (c == '\n' || c == '\r' || c == ' ' ); /* for fastDNAml format, skip initial [comment] */ if(c == '[') { do c=fgetc(njfile); while (c != ']'); do c=fgetc(njfile); while (c == '\n' || c == '\r' || c == ' ' ); } if ( c != '(') goto erreur; /* lecture de l'arbre par paquets de steparbre caracteres*/ steparbre=1000; maxarbre=steparbre; arbre=check_alloc(maxarbre,1); der_arbre = arbre+maxarbre; *arbre=c; notu=2; i=3; v = 0; finarbre=arbre; while( (c=fgetc(njfile)) != EOF && c != ';') { if( /* c==' ' || */ c=='\n' || c=='\r') continue; if(++finarbre >= der_arbre-2) { maxarbre += steparbre; tmp=check_alloc(maxarbre,1); memcpy(tmp,arbre,finarbre-arbre); finarbre=tmp+(finarbre-arbre); free(arbre); arbre=tmp; der_arbre=arbre+maxarbre; } *(finarbre)=c; if(c==')')notu++; if(c=='(')i++; if(c == ',') v++; } *(finarbre+1)='\0'; fclose(njfile); if(i!=notu)goto erreur; arbre = (char *)realloc(arbre, strlen(arbre) + 4 * v + 5 ); /* worst case add 4 chars for each , */ make_binary_or_unrooted(arbre); /* notu--; */ notu = v ; /* after this notu = number of OTUs - 1 */ totbranches= -1; /* allocate all memory */ tabtax = (struct noeud **)check_alloc(2*notu +1,sizeof(struct noeud *)); if(notu > 2) branches = (branche_noeud *)check_alloc(notu-2, sizeof(branche_noeud)); for(i=0; i<2*notu+1; i++) *(tabtax+i)= (struct noeud *)check_alloc(1,s_noeud); loadphylip(arbre); free(arbre); if(notu == 0) goto erreur; if(!rooted) { racine = *(tabtax+(++num_noeud)); if(num_noeud >= 2*notu + 1) return("Error: incorrect tree file"); if(has_br_length) { place_midpoint_root(); } else { struct noeud *centre = *(tabtax + num_noeud - 1); racine->v1 = centre->v1; racine->v2 = centre; racine->v3 = NULL; centre->v1 = racine; if(racine->v1->v1 == centre) racine->v1->v1 = racine; else if(racine->v1->v2 == centre) racine->v1->v2 = racine; else racine->v1->v3 = racine; } } else { racine = *(tabtax+num_noeud); root_br_l= racine->l1 + racine->l2; if(!has_br_length) tree_bal(racine,racine->v1,racine->v2); } if(notu+1<3) return ("Tree should contain at least 3 elements."); return (NULL); erreur: return ("Not a valid tree file: "); } /* end of preptree */ void make_binary_or_unrooted(char *arbre) { char *finarbre, *deba, *debb, *debc; finarbre= nextpar(arbre,arbre); *(finarbre + 1) = 0; deba=arbre+1; debb=deba; while(*debb != ',') { if(*debb == 0) { err_message("Incorrect tree file"); exit(1); } if(*debb == '(')debb=nextpar(debb,debb); debb++; } debb++; debc=debb; while(*debc != ',' && debc it has 3 subtrees or more at its bottommost level */ make_binary(arbre , debb, finarbre - 1, TRUE); make_binary(arbre , deba, debb - 2, TRUE); } else make_binary(arbre , deba, finarbre - 1, TRUE); return; } int make_binary(char *arbre, char *debut, char *fin, int go_down) { int virg, l, retval; char *p, *q; p = debut; virg = 0; retval = 0; while(p < fin) { if(*p == ',') virg++; else if(*p == '(') { q = nextpar(p,p); if(go_down) { l = make_binary(arbre, p+1, q-1, TRUE); fin += l; retval += l; p = q + l; } else p = q; } p++; } if(virg > 1) { /* multifurcation */ /* make sure tree has branch lengths */ if( memchr(debut, ':', fin - debut + 1) == NULL) { err_message("Cannot process multibranched tree without branch lengths"); exit(1); } /* recherche de la 2eme virgule */ p = debut; l = 0; while(TRUE) { if(*p == ',') { l++; if(l == 2) break; } else if(*p == '(') { p = nextpar(p,p); } p++; } l = strlen(p); memmove(p + 4, p, l + 1); memmove(debut + 1, debut, p - debut); *debut = '('; memcpy(p + 1, "):0", 3); fin += 4; retval += 4; if(virg > 2) retval += make_binary(arbre, debut, fin, FALSE); } return retval; } void loadphylip(char *arbre) { char *deba,*debb,*debc, *finarbre; struct noeud *p1, *p2, *p3, *p; branche_noeud *int_br_g, *int_br_d; int i; has_br_length=2; /* ignore all stuff after last closing parenthesis (needed for fastDNAml output) */ finarbre= nextpar(arbre,arbre); rooted=0; deba=arbre+1; debb=deba; while(*debb != ',') { if(*debb == '(')debb=nextpar(arbre,debb); debb++; } debb++; debc=debb; while(*debc != ',' && debc it has 3 subtrees at its bottommost level */ debc++; } else { /* the tree is rooted */ debc=finarbre+1; rooted=1; /* notu--; //useless now */ } num_noeud=notu; nextotu= -1; p1=unrootedset(arbre,deba,debb-2,&int_br_g); if(p1 != NULL) p2=unrootedset(arbre,debb,debc-2,&int_br_d); if(p1 == NULL || p2 == NULL || num_noeud + 1 >= 2*notu + 1) { notu = 0; return; } p = *(tabtax+(++num_noeud)); if(!has_br_length) { p1->l3 = 0.5*p1->l3; p2->l3 = 0.5*p2->l3; } p->v1=p1; p1->v3=p; p->l1=p1->l3; if(int_br_g!=NULL) { int_br_g->bouta=p; int_br_g->boutb=p1; } p->v2=p2; p2->v3=p; p->l2=p2->l3; if(int_br_d!=NULL) { int_br_d->bouta=p; int_br_d->boutb=p2; } if(!rooted) { p3=unrootedset(arbre,debc,finarbre-1,&int_br_g); if(p3 == NULL ) { notu = 0; return; } if(int_br_g!=NULL) { int_br_g->bouta=p; int_br_g->boutb=p3; } p->v3=p3; p3->v3=p; p->l3=p3->l3; } else { p->v3=NULL; /* recherche d'un dernier label interne */ debc=finarbre+1; while(*debc!=0 && *debc!=':' && *debc!='[') debc++; if(debc-finarbre>1) { int l=debc-finarbre-1; totbranches++; branches[totbranches].br_label=check_alloc(l+1,1); memcpy(branches[totbranches].br_label,finarbre+1,l); branches[totbranches].br_label[l]=0; branches[totbranches].bouta=p1; branches[totbranches].boutb=p2; } } } struct noeud *unrootedset(char *arbre, char *deb, char *fin, branche_noeud **p_int_br) { struct noeud *p; char *virg; int l; branche_noeud *int_br_g, *int_br_d; *p_int_br=NULL; while(*deb==' ' || *deb=='\'')deb++; while(*fin==' ')fin--; virg=deb; while(*virg != ',' && virg < fin) { if(*virg == '(') virg=nextpar(arbre,virg); virg++; } if(virg>fin) virg=deb; if(*virg == ',') { struct noeud *p1,*p2; p1=unrootedset(arbre,deb,virg-1,&int_br_g); if(p1 == NULL) return NULL; p2=unrootedset(arbre,virg+1,fin,&int_br_d); if(p2 == NULL) return NULL; if(num_noeud + 1 >= 2*notu + 1) return NULL; p = *(tabtax+(++num_noeud)); p->v1=p1; p1->v3=p; p->l1=p1->l3; if(int_br_g!=NULL) { int_br_g->bouta=p; int_br_g->boutb=p1; } p->v2=p2; p2->v3=p; p->l2=p2->l3; if(int_br_d!=NULL) { int_br_d->bouta=p; int_br_d->boutb=p2; } } else { double brlength; virg=deb; while(*virg != ':' && virg < fin) { if(*virg=='(')virg=nextpar(arbre,virg); virg++; } if(virg>fin) virg=deb; if(*virg == ':') { if(has_br_length == 0) goto problem; sscanf(virg+1,"%le",&brlength); virg--; has_br_length=1; } else { if(has_br_length == 1) goto problem; brlength=1; has_br_length=0; } if(*deb == '(') { char *fpar; branche_noeud *prov; fpar=nextpar(arbre,deb)-1; p=unrootedset(arbre,deb+1,fpar,&prov); if(p == NULL) return NULL; /* recherche internal label */ l=virg-fpar-1; if(l>0) { totbranches++; branches[totbranches].br_label= check_alloc(l+1,1); memcpy(branches[totbranches].br_label,fpar+2,l); branches[totbranches].br_label[l]=0; *p_int_br= &branches[totbranches]; } } else { size_t n; if( virg-1>=deb && *virg=='\'' )virg--; n=virg-deb+1; ++nextotu; p= *(tabtax+nextotu); p->nom = (char *)check_alloc(n+1,1); memcpy(p->nom, deb, n); p->nom[n] = 0; p->v1=p->v2=p->v3=NULL; } p->l3=brlength; } return p; problem: err_message("Error: Inconsistent tree file for branch lengths."); } char *nextpar(char *text, char *pospar) { char *pos; pos=pospar+1; while(*pos != ')') { if(*pos == '(') pos=nextpar(text,pos); pos++; } return pos; } void free_tree(void) { int i; if(notu == 0) return; /* de-allocate all memory */ for(i=0; i<2*notu+1; i++) { if(tabtax[i]->nom != NULL) free(tabtax[i]->nom); free(tabtax[i]); } free(tabtax); for(i=0; ipd) pd=pg; else pg=pd; *abup1 = *abdown1 = pg-lg; *abup2 = *abdown2 = pd-ld; return (pg); } void get_next_br(struct noeud *pere, struct noeud *fils, double **abdown, double **abup, struct noeud **f1, struct noeud **f2) /* pour une branche pere->fils donnee, calculer dans *f1, *f2 les deux autres voisins de fils et dans *abdown et *abup les adresses des longeurs de la branche pere->fils dans les deux sens */ { if(pere->v1==fils) *abdown= &(pere->l1); else if(pere->v2==fils) *abdown=&(pere->l2); else *abdown=&(pere->l3); if(fils->v1==pere) { *abup=&(fils->l1); *f1=fils->v2; *f2=fils->v3; } else if(fils->v2==pere) { *abup=&(fils->l2); *f1=fils->v1; *f2=fils->v3; } else { *abup=&(fils->l3); *f1=fils->v1; *f2=fils->v2; } } void place_midpoint_root(void) /* enraciner l'arbre sans racine en cherchant son centre */ { struct noeud *aux; double laux; current_best_diff= 9.e99; current_cote1=current_cote2=NULL; parcourir_branches(*tabtax,NULL); rooted = TRUE; root_br_l = current_br_length; /* il faut toujours que la racine soit telle que racine->v1->v3=racine */ if (current_cote1->v1 == current_cote2 ) { /* echanger les voisins v1 et v3 de cote1 */ aux=current_cote1->v1; current_cote1->v1=current_cote1->v3; current_cote1->v3=aux; laux=current_cote1->l1; current_cote1->l1=current_cote1->l3; current_cote1->l3=laux; } else if (current_cote1->v2 == current_cote2) { /* echanger les voisins v2 et v3 de cote1 */ aux=current_cote1->v2; current_cote1->v2=current_cote1->v3; current_cote1->v3=aux; laux=current_cote1->l2; current_cote1->l2=current_cote1->l3; current_cote1->l3=laux; } current_cote1->v3 = racine; if (current_cote2->v1 == current_cote1 ) current_cote2->v1 = racine; else if (current_cote2->v2 == current_cote1) current_cote2->v2 = racine; else current_cote2->v3 = racine; racine->v1=current_cote1; racine->v2=current_cote2; racine->v3=NULL; racine->l3=0; racine->l1=current_br_length*current_balance; racine->l2=current_br_length - racine->l1; } void parcourir_branches(struct noeud *centre, struct noeud *origine) /* parcourir recursivement toutes les branches de l'arbre sans racine a partir de centre et dans la direction opposee a son voisin origine */ { if(centre==NULL) return; if(centre->v1!=origine) { process_branche(centre,centre->v1,centre->l1); parcourir_branches(centre->v1,centre); } if(centre->v2!=origine) { process_branche(centre,centre->v2,centre->l2); parcourir_branches(centre->v2,centre); } if(centre->v3!=origine) { process_branche(centre,centre->v3,centre->l3); parcourir_branches(centre->v3,centre); } } void process_branche(struct noeud *cote1, struct noeud *cote2, double length) /* calculer la prof moyenne des 2 cotes de la branche cote1<-->cote2 de longueur length et memoriser la meilleure branche dans les variables globales */ { double b1, b2, x, dist_root_side1, dist_root_side2, diff_betw_sides; if(cote1==NULL || cote2==NULL) return; b1=get_length_down(cote2,cote1); b2=get_length_down(cote1,cote2); if( fabs(length) > 1.e-5 ) x=(b2-b1+length)/(2*length); else x=0; if(x<0) x=0; if(x>1) x=1; dist_root_side1=length*x+b1; dist_root_side2=length*(1-x)+b2; diff_betw_sides=fabs(dist_root_side1-dist_root_side2); if(diff_betw_sides < current_best_diff ) { current_best_diff=diff_betw_sides; current_cote1=cote1; current_cote2=cote2; current_br_length=length; current_balance=x; } } double get_length_down(struct noeud *pere, struct noeud *racine) /* compute the average length of the tree down a node */ { if(racine == NULL) return 0.0; else { struct noeud *gauche, *droite; double bg,bd,lg,ld; if( racine->v1 == pere ) { gauche =racine->v2; droite = racine->v3; bg = (racine->l2); bd = (racine->l3); } else if( racine->v2 == pere ) { gauche =racine->v1; droite = racine->v3; bg = (racine->l1); bd = (racine->l3); } else { gauche =racine->v1; droite = racine->v2; bg = (racine->l1); bd = (racine->l2); } /* conserver cette ecriture sinon plante sur PC */ lg = ld = 0; if(gauche != NULL) lg = get_length_down(racine,gauche); lg += bg; if(droite != NULL) ld = get_length_down(racine,droite); ld += bd; return ((lg+ld)/2); } } bignoeud *cre_new_tree(struct noeud *debut, struct noeud *parent, bignoeud *bigparent) { bignoeud *nouveau; size_t l; if(debut == NULL) return NULL; nouveau = (bignoeud *)check_alloc(1, sizeof(bignoeud) ); if(debut->v1 == parent) { nouveau->v1 = bigparent; nouveau->v2 = cre_new_tree(debut->v2, debut, nouveau); nouveau->v3 = cre_new_tree(debut->v3, debut, nouveau); } else if(debut->v2 == parent) { nouveau->v2 = bigparent; nouveau->v1 = cre_new_tree(debut->v1, debut, nouveau); nouveau->v3 = cre_new_tree(debut->v3, debut, nouveau); } else { nouveau->v3 = bigparent; nouveau->v1 = cre_new_tree(debut->v1, debut, nouveau); nouveau->v2 = cre_new_tree(debut->v2, debut, nouveau); } if(has_br_length) { nouveau->l1 = debut->l1; nouveau->l2 = debut->l2; nouveau->l3 = debut->l3; } else { if(nouveau->v1 != NULL) nouveau->l1 = 1; if(nouveau->v2 != NULL) nouveau->l2 = 1; if(nouveau->v3 != NULL) nouveau->l3 = 1; } if(debut->nom != NULL) { /*ajouter espace en tete du nom pour plus joli dessin*/ l = strlen(debut->nom); nouveau->nom = (char *)check_alloc(l+2, 1); nouveau->nom[0] = ' '; memcpy(nouveau->nom + 1, debut->nom, l+1); free(debut->nom); debut->nom = nouveau->nom; } return nouveau; } void remove_big_root(bignoeud *bigracine) { bignoeud *p1, *p2; double root_br_l; p1=bigracine->v1; p2=bigracine->v2; root_br_l = bigracine->l1 + bigracine->l2; if(p1->v1 == bigracine ) {p1->v1 = p2; p1->l1 = root_br_l;} else if (p1->v2 == bigracine) {p1->v2 = p2; p1->l2 = root_br_l;} else {p1->v3 = p2; p1->l3 = root_br_l;} if(p2->v1 == bigracine ) {p2->v1 = p1; p2->l1 = root_br_l;} else if (p2->v2 == bigracine) {p2->v2 = p1; p2->l2 = root_br_l;} else {p2->v3 = p1; p2->l3 = root_br_l;} } double calc_dist_centre_feuilles(bignoeud *debut, bignoeud *parent) { double valeur, current; if(debut == NULL) return 0; valeur = 0; /* !!!!! conserver cette ecriture sinon plante sur PC !!!!!! */ if(debut->v1 != parent) { current = calc_dist_centre_feuilles(debut->v1, debut); current += debut->l1; if(current > valeur) valeur = current; } if(debut->v2 != parent) { current = calc_dist_centre_feuilles(debut->v2, debut); current += debut->l2; if(current > valeur) valeur = current; } if(debut->v3 != parent) { current = calc_dist_centre_feuilles(debut->v3, debut); current += debut->l3; if(current > valeur) valeur = current; } return valeur; } double proc_null_neg_branches(bignoeud *debut, bignoeud *parent) /* mettre branches negatives a 0 !attention dans un seul sens! retourner la + petite branche non nulle */ { double valeur, current; if(debut == NULL) return 0; valeur = 1e50; if(debut->v1 != parent) { if(debut->l1 < 0) debut->l1 = 0; current = debut->l1; if(current < valeur && current > 0) valeur = current; current = proc_null_neg_branches(debut->v1, debut); if(current < valeur && current > 0) valeur = current; } if(debut->v2 != parent) { if(debut->l2 < 0) debut->l2 = 0; current = debut->l2; if(current < valeur && current > 0) valeur = current; current = proc_null_neg_branches(debut->v2, debut); if(current < valeur && current > 0) valeur = current; } if(debut->v3 != parent) { if(debut->l3 < 0) debut->l3 = 0; current = debut->l3; if(current < valeur && current > 0) valeur = current; current = proc_null_neg_branches(debut->v3, debut); if(current < valeur && current > 0) valeur = current; } return valeur; } int set_angles_noeuds(bignoeud *debut, bignoeud *parent, double delta, double *p_current_angle, double rayon) { int feuille = FALSE; int poids, poids1, poids2; double angle1 = -1, angle2 = -1; static int totfeuilles=0; char *nom; if(debut == NULL) return 0; if(debut->v1 != parent) { poids = set_angles_noeuds(debut->v1, debut, delta, p_current_angle, rayon); if(debut->v1 == NULL) feuille = TRUE; else if (parent != NULL) { angle1 = debut->v1->position.angle; poids1 = poids; } } if(debut->v2 != parent) { poids = set_angles_noeuds(debut->v2, debut, delta, p_current_angle, rayon); if(debut->v2 == NULL) feuille = TRUE; else if (parent != NULL) { if ( angle1 == -1 ) { angle1 = debut->v2->position.angle; poids1 = poids; } else { angle2 = debut->v2->position.angle; poids2 = poids; } } } if(debut->v3 != parent) { poids = set_angles_noeuds(debut->v3, debut, delta, p_current_angle, rayon); if(debut->v3 == NULL) feuille = TRUE; else if (parent != NULL) { angle2 = debut->v3->position.angle; poids2 = poids; } } if( feuille ) { totfeuilles++; debut->position.angle = *p_current_angle; *p_current_angle += delta; poids = 1; } else if(parent != NULL) { /* faire angle moyen modulo 2.pi */ debut->position.angle = (poids1*angle1 + poids2*angle2)/(poids1+poids2); poids = poids1 + poids2; if( angle1 > angle2 ) debut->position.angle -= M_PI; } debut->position.r = rayon; calc_cartesienne(&(debut->position)); return poids; } void calc_cartesienne( cp_point *p) { p->x = p->r * cos(p->angle); p->y = p->r * sin(p->angle); return; } void calc_polaire( cp_point *p) { p->r = sqrt(p->x * p->x + p->y * p->y); if( p->x == 0 ) { if( p->y == 0) p->angle = 0; else if (p->y > 0) p->angle = M_PI_2; else p->angle = 3*M_PI_2; } else if (p->x > 0) { p->angle = atan( p->y / p->x ); if( p->angle < 0 ) p->angle += 2*M_PI; } else { p->angle = M_PI - atan( p->y / p->x ); } return; } cp_point calc_point_direction( cp_point *depart, cp_point *direction, double longueur) { static cp_point retour; double lac, eps, tmp1, tmp2; tmp1 = direction->x - depart->x; tmp2 = direction->y - depart->y; lac = sqrt( tmp1*tmp1 + tmp2*tmp2 ); /* on remplace les branches nulles par des branches tres courtes pour que le calcul de l'angle en double soit bon mais que le dessin en entier soit le meme */ if(longueur == 0) longueur = mini_br_length; eps = longueur / lac; retour.x = depart->x + eps * tmp1; retour.y = depart->y + eps * tmp2; calc_polaire(&retour); return retour; } branche *calc_position_noeuds(bignoeud *debut, bignoeud *parent, branche *curr_branche) { if(debut->v1 != parent && debut->v1 != NULL ) { debut->v1->position = calc_point_direction( &(debut->position), &(debut->v1->position), debut->l1); curr_branche = calc_position_noeuds(debut->v1, debut, curr_branche); mem_line(&debut->position, &debut->v1->position, debut->v1, curr_branche); curr_branche++; } if(debut->v2 != parent && debut->v2 != NULL ) { debut->v2->position = calc_point_direction( &(debut->position), &(debut->v2->position), debut->l2); curr_branche = calc_position_noeuds(debut->v2, debut, curr_branche); mem_line(&debut->position, &debut->v2->position, debut->v2, curr_branche); curr_branche++; } if(debut->v3 != parent && debut->v3 != NULL ) { debut->v3->position = calc_point_direction( &(debut->position), &(debut->v3->position), debut->l3); curr_branche = calc_position_noeuds(debut->v3, debut, curr_branche); mem_line(&debut->position, &debut->v3->position, debut->v3, curr_branche); curr_branche++; } return curr_branche; } void mem_line(cp_point *debut, cp_point *fin, bignoeud *noeud_term, branche *br) { br->debut = *debut; br->fin = *fin; br->nom = noeud_term->nom; } void draw_tree(plot_data *ob, branche *branches, int comp_phys_bounds) { int char_width, char_height, num, dernier, encore = FALSE, ascend, descend; hit result; hits_field hits; char_width = my_get_string_width("M"); char_height = my_get_char_height(&ascend, &descend); dernier = 2*(notu+1)-3; if( comp_phys_bounds ) { /* rendre dimensions carrees */ if (phys_max_x - phys_min_x > phys_max_y - phys_min_y) phys_max_x = phys_min_x + (phys_max_y - phys_min_y); else if(phys_max_y - phys_min_y > phys_max_x - phys_min_x) phys_max_y = phys_min_y + (phys_max_x - phys_min_x); do { hits.left = hits.right = hits.top = hits.bottom = 0; for(num = 0; num < dernier; num++) { result = draw_line(branches+num, ob, FALSE, char_width, char_height, descend, ascend); if(result == LEFT_HIT) hits.left = 1; else if(result == RIGHT_HIT) hits.right = 1; else if(result == TOP_HIT) hits.top = 1; else if(result == BOTTOM_HIT) hits.bottom = 1; } encore = chg_phys(ob, hits, char_height); } while (encore); for(num = 0; num < dernier; num++) branches[num].color = FALSE; } for(num=0; num< dernier; num++) { draw_line(branches+num, ob, TRUE, char_width, char_height, descend, ascend); } if(has_br_length) draw_scale(ob, char_height, ascend); } int chg_phys(plot_data *ob, hits_field hits, int char_height) { int encore = FALSE; const float delta = 0.05; int value; static int lr = 0, tb = 0, oldvaluex = 0, oldvaluey = 0; if(hits.left == 1 && hits.right == 0) { if(oldvaluex == 0) value = (phys_max_x - phys_min_x) * delta; else value = oldvaluex; if(value < 2) value = 2; if(lr == 2) { /* alternance left/right */ if(oldvaluex <= 2) { hits.right = 1; return chg_phys(ob, hits, char_height); } value = oldvaluex/2; } lr = 1; oldvaluex = value; phys_min_x += value; phys_max_x += value; if(phys_max_x <= phys_min_x) { phys_max_x = phys_min_x + 1; return FALSE; } encore = TRUE; } else if(hits.left == 0 && hits.right == 1) { if(oldvaluex == 0) value = (phys_max_x - phys_min_x) * delta; else value = oldvaluex; if(value < 2) value = 2; if(lr == 1) { /* alternance left/right */ if(oldvaluex <= 2) { hits.left = 1; return chg_phys(ob, hits, char_height); } value = oldvaluex/2; } lr = 2; oldvaluex = value; phys_max_x -= value; phys_min_x -= value; if(phys_max_x <= phys_min_x) { phys_max_x = phys_min_x + 1; return FALSE; } encore = TRUE; } else if(hits.left == 1 && hits.right == 1) { lr = tb = 0; oldvaluex = 0; value = (phys_max_x - phys_min_x) * delta / 2; if(value < 2) value = 2; phys_min_x += value; phys_max_x -= value; if(phys_max_x <= phys_min_x) { phys_max_x = phys_min_x + 1; return FALSE; } encore = TRUE; phys_max_y = phys_min_y + (phys_max_x - phys_min_x); } if(hits.top == 0 && hits.bottom == 1) { if(oldvaluey == 0) value = (phys_max_y - phys_min_y) * delta; else value = oldvaluey; if(value < 2) value = 2; if(tb == 2) { if(oldvaluey <= 2) { hits.top = 1; return chg_phys(ob, hits, char_height); } value = oldvaluey/2; } tb = 1; oldvaluey = value; phys_max_y -= value; phys_min_y -= value; if(phys_max_y <= phys_min_y) { phys_max_y = phys_min_y + 1; return FALSE; } encore = TRUE; } else if(hits.top == 1 && hits.bottom == 0) { if(oldvaluey == 0) value = (phys_max_y - phys_min_y) * delta; else value = oldvaluey; if(value < 2) value = 2; if(tb == 1) { if(oldvaluey <= 2) { hits.bottom = 1; return chg_phys(ob, hits, char_height); } value = oldvaluey/2; } tb = 2; oldvaluey = value; phys_min_y += value; phys_max_y += value; if(phys_max_y <= phys_min_y) { phys_max_y = phys_min_y + 1; return FALSE; } encore = TRUE; } else if(hits.top == 1 && hits.bottom == 1) { value = (phys_max_y - phys_min_y) * delta/2; if(value < 2) value = 2; lr = tb = 0; oldvaluey = 0; phys_min_y += value; phys_max_y -= value; if(phys_max_y <= phys_min_y) { phys_max_y = phys_min_y + 1; return FALSE; } encore = TRUE; phys_max_x = phys_min_x + (phys_max_y - phys_min_y); } return encore; } void log_to_phys(cp_point *log_pos, cp_point *phys_pos) { double factorx, factory; factorx = (phys_max_x - phys_min_x) / (log_max_x - log_min_x); factory = (phys_max_y - phys_min_y) / (log_max_y - log_min_y); phys_pos->x = factorx * ( log_pos->x - log_min_x ) + phys_min_x; phys_pos->y = factory * ( log_pos->y - log_min_y ) + phys_min_y; } double length_log_phys(double p) { double factor; factor = (phys_max_x - phys_min_x) / (log_max_x - log_min_x); return p * factor; } double length_phys_log(double p) { double factor; factor = (phys_max_x - phys_min_x) / (log_max_x - log_min_x); return p / factor; } double arrondi_echelle(double x) { /* arrondi x a une valeur 1, 2, 5 pour echelle */ double l, n; int r; static int corresp[] = {1,1,2,2,5,5,5,10,10,10,10,10}; /* 0,1,2,3,4,5,6, 7, 8, 9,10,11 */ l = log10(x); n = floor(l); l = x * pow(10, -n); r = myrint(l); r = corresp[r]; return r * pow(10, n); } double calc_echelle(int larg) { /* rend taille logique pour echelle optimale */ double log_val, phys_val; phys_val = larg/10; log_val = length_phys_log(phys_val); log_val = arrondi_echelle(log_val); return log_val; } int myrint(double val) { if(val >= 0) return (int)(val + 0.5); else return (int)(val - 0.5); } njplot-2.4/njplot.help0000644000002300003250000000534610713122032013510 0ustar mgouybge>>>About njplot Version: ?? Written by M. Gouy (mgouy@biomserv.univ-lyon1.fr). Phylogenetic trees read from Newick formatted files can be displayed, re-rooted, saved, and plotted to PDF or PostScript files. Input trees can be with/without branch lengths, with/without bootstrap values, rooted or unrooted. Binary as well as multibranched trees are accepted. njplot is available at http://pbil.univ-lyon1.fr/software/njplot.html for MAC, PC under MS-Windows and several unix platforms. njplot uses the Vibrant library by J. Kans. Some versions of njplot use the PDFLib Lite library (http://www.pdflib.com) under the "Open Source Developer Exemption" of the PDFlib Lite License Agreement. >>>Menu File Open: To read a tree file in the Newick format (i.e., the file format used for trees by Clustal, PHYLIP and other programs). Save as PDF/PostScript: To save the tree plot in PDF/PostScript format. Save rooted/unrooted tree: To save the tree in a file with/without its current rooting. Print: [Mac & Windows ONLY] it does print your tree. >>>Menu Edit Copy: [Mac & Windows ONLY] Copies the current tree plot to the Clipboard so that the plot can be pasted to another application. Paste: If the clipboard contains a parenthesized tree, this tree will be plotted. Clear: Clears the current plot so that new tree data can be pasted. Find: To search for a taxon in tree and display it in red. Enter a (partial) name, case is not significant. Again: Redisplay in red names matching the string entered in a previous Find operation. >>>Menu Font Allows to change the font face and size used to display tree labels. >>>Menu Paper Allows to set the paper size used by the "Save as PDF" item of menu "File". Pagecount (x): sets the number of pages used by "Save as PDF". >>>Operations Full tree: Normal tree display of entire tree New outgroup: Allows to re-root the tree. The tree becomes displayed with added # signs. Clicking on any # will set descending taxa as an outgroup to remaining taxa. Swap nodes: Allows to change the display order of taxa. The tree becomes displayed with added # signs. Clicking on any # will swap corresponding taxa. Subtree: Allows to zoom on part of the tree. The tree becomes displayed with added # signs. Clicking on any # will limit display to descending taxa. Select "Full tree" to go back to full tree display. >>>Display Branch lengths: If the tree contains branch lengths, they will be displayed. For readability, very short lengths are not displayed. Bootstrap values: If the tree contains bootstrap values, they will be displayed. >>>Subtree up When a subtree is being displayed, allows to add one more node towards the root in the displayed tree part. njplot-2.4/example.phb0000644000002300003250000000215410703201756013462 0ustar mgouybge(((((((Prorocentrum:0.0536, Tetrahymena:0.0721)45:0.0038, ((Oryza:0.0135, (Lycopersicon:0.0046, Citrus:0.0060)84:0.0025)100:0.0414, Saccharomyces:0.0494)55:0.0051)87:0.0102, (((Homo:0.0009, Mus:0.0019)100:0.0065, Xenopus:0.0093)100:0.0448, (Drosophila:0.0863, Caenorhabditis:0.0843)51:0.0029)66:0.0070)73:0.0062, Dictyostelium:0.1226)92:0.0132, Crithidia:0.1403)65:0.0095, Physarum:0.1347):0.1191, ((((Rhodobacter:0.1032, (Pseudomonas:0.0468, (Escherichia:0.0399, Ruminobacter:0.0553)81:0.0103)100:0.0325)100:0.0301, (Leptospira:0.0932, (((Micrococcus:0.0380, Streptomyces:0.0478)100:0.0654, Pirellula:0.1269)27:0.0014, ((Anacystis:0.0490, EuglenaCP:0.1184)100:0.0341, (BacillusSubt:0.0262, BacillusStea:0.0184)100:0.0504)86:0.0148)33:0.0013)70:0.0073)93:0.0161, Thermus:0.1043)100:0.1052, (((Desulfurococcus:0.0412, Sulfolobus:0.0710)97:0.0145, Thermoproteus:0.0880)100:0.0521, ((Methanococcus:0.0927, Methanobacterium:0.1006)99:0.0282, (Thermoplasma:0.1526, (HalobacteriumH:0.0515, (Halococcus:0.0543, HalobacteriumM:0.0532)50:0.0030)100:0.1324)39:0.0027)72:0.0118)96:0.0130)100:0.0634); 0.0118)96:0.0130)100:0.0634); njplot-2.4/multi.phb0000644000002300003250000000070010115076703013153 0ustar mgouybge[ lh=-14278.640123 ] ( CarMV:3.39196, (RHDV:0.47444,FCV:0.51180)82:1.25237, ((RTSV:0.63519, PYFV:0.55541)85:0.27247,(CPMV:0.36886,ToRSV:0.63500)84:0.25338)79:0.41898, (PV:0.29108,HRV:0.30594)74:1.49385,(SbV:0.80644,IFV:1.10565)62:0.23162, ((BQCV:0.38541,HiPV:0.35087)97:0.62997,(DCV:0.23060,CrPV:0.18902) 56:0.42244,ABPV:0.49656,TSV:0.62703,RhPV:1.03466)55:0.44393,(TEV:0.60499, BaYMV:0.49954)55:1.32670,HaRNAV:1.29712,PnPV:2.06493,APV:2.12968 ); njplot-2.4/bigtree.phb0000644000002300003250000003224610702712651013455 0ustar mgouybge((((((((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01, ( (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01) :0.01, (((((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01, ( (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01) :0.01) :0.01, ((((((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01, ( (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01) :0.01, (((((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01, ( (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01):0.01):0.01) :0.01, (((((((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01, ( (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01) :0.01, (((((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01, ( (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01) :0.01) :0.01, ((((((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01, ( (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01) :0.01, (((((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01, ( (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919) :0.1, (((GlnRS[Ec]:0.22184,GlnRS[Sc]:0.22033)40:0.17723,(GluRS[Ec]:0.25282,(GluRS[Rm]:0.24251,(GluRS[Bst]:0.13448,GluRS[Bsu]:0.11723)99:0.07382)610:0.02439)1000:0.09412):0.06060,(((TrpRS[Ec]:0.16684,(TrpRS[Bst]:0.10637,TrpRS[Bsu]:0.10451)970:0.05425)10:0.10491,TrpRS[Scm]:0.25223)20:0.14764,(((TyrRS[Bst]:0.14456,TyrRS[Ec]:0.14116)30:0.15731,TyrRS[Ncm]:0.29167)991:0.06216,TyrRS[Bsu]:0.35621)992:0.05942):0.01919):0.01):0.01):0.01):0.01) :0.01); njplot-2.4/README0000644000002300003250000000361310703114576012220 0ustar mgouybgeNJPLOT is a phylogenetic tree drawing program that handles Newick tree files, that is files describing trees by the nested parentheses method (e.g. PHYLIP-built trees). Features: A graphical interface allows to re-root a tree anywhere and to swap branches. Bootstrap values are displayed next to internal branches. Branch lengths can be optionally displayed. Tree plots can be printed or saved to a PostScript file. Program unrooted draws trees in an unrooted, circular form. Program newicktops uses no GUI and converts a Newick file into a postscript document. Usage: newicktops newick-file-name or newicktops -h (to see program options) The result goes to file newick-file-name.ps Program newicktotxt uses no GUI and converts a Newick file into a pure text file where the tree is drawn with | and - characters. Usage: newicktotxt newick-file-name or newicktotxt -h (to see program options) The result goes to file newick-file-name.txt Program add_root reads a Newick tree file and roots it with the midpoint method, that is at the point that minimizes the root-to-leaves variance. It does no change if the input tree is already rooted. Usage: add_root newick-file-name The result goes to stdout. Please quote: Perriere, G. & Gouy, M. (1996) WWW-Query: an on-line retrieval system for biological sequence banks. Biochimie 78:364-369. when publishing after njplot use. __________________________________________________________________________ | Manolo Gouy | | Laboratoire de biometrie, genetique et biologie des populations | | UMR CNRS 5558 | E-MAIL : mgouy@biomserv.univ-lyon1.fr | | Universite C. Bernard - Lyon 1 | Tel : +33 4-72-43-12-87 | | 69622 Villeurbanne, France | Fax : +33 4-78-89-27-19 | |_________________________________|________________________________________| njplot-2.4/njplot.10000644000002300003250000000457310703350550012730 0ustar mgouybge.TH NJPLOT 1 "April 10, 2001" .SH NAME njplot \- A phylogenetic tree drawing program for biologists newicktops \- draw phylogenetic trees into PostScript file .SH SYNOPSIS .B njplot .RI [ options ] " tree_file" .P .B newicktops .RI [ options ] " tree_file" .P .B newicktotxt .RI [ options ] " tree_file" .SH DESCRIPTION This manual page documents briefly the .B njplot command. .P The .B newicktops command does exactly the same but needs no X11 display. The output is rendered into a PostScript file. .P The .B newicktotxt command does exactly the same as .B newicktops but the output is rendered into a text file. .P This manual page was rewritten for the Debian GNU/Linux distribution because the original program does not have a manual page. .PP \fBnjplot\fP is a tree drawing program able to draw any binary or multi-branched tree expressed in the standard phylogenetic tree format (e.g., the format used by the PHYLIP package). NJplot is especially convenient for rooting the unrooted trees obtained from parsimony, distance or maximum likelihood tree-building methods. .P Any rooting of the unrooted tree can be interactively specified using the mouse. NJplot also allows zooming, branch swapping, display of bootstrap scores and saving in the PostScript format. NJplot can therefore be used as a graphical extension of any package of phylogenetic program which employs the standard tree format for storing trees (i.e., with most such packages). .SH OPTIONS There are only the following options which only work in an x-terminal-emulator, but not in console mode: .TP .B \-h Prints out brief help. .TP .B \-us Postscript tree file prepared for US Letter paper size. .TP .B \-psonly No window interface, just write the PostScript tree file. .TP .B \-size n Font size n used for taxon names. .TP .B \-pc n number of pages for PostScript output. .TP .B \-psize widthxheight size of PostScript page expressed as WIDTHxHEIGHT. .TP .B \-lengths Show branch lengths if they appear in tree file. .TP .B \-boot Show bootstrap values if they appear in tree file. .TP .B \-notitle Don't include title in PostScript output. .SH SEE ALSO .BR unrooted (1). .br .SH Word-Wide-Web: http://pbil.univ-lyon1.fr/software/njplot.html .SH AUTHOR: .I Manolo Gouy .br e-mail: mgouy@biomserv.univ-lyon1.fr .PP This manual page was written by Dr. Guenter Bechly , for the Debian GNU/Linux system (but may be used by others). njplot-2.4/unrooted.10000644000002300003250000000207710703201400013243 0ustar mgouybge.TH UNROOTED 1 "April 10, 2001" .SH NAME unrooted \- A phylogenetic tree drawing program for biologists .SH SYNOPSIS .B unrooted .RI [ options ] " tree_file" .SH DESCRIPTION This manual page documents briefly the .B unrooted command. This manual page was rewritten for the Debian GNU/Linux distribution because the original program does not have a manual page. .PP \fBunrooted\fP is part of the \fBnjplot\fP tree drawing software package. .SH OPTIONS There are only the following options which only work in an x-terminal-emulator, but not in console mode: .TP .B \-h Prints out brief help. .TP .B \-psonly No window interface, just write the PostScript tree file. .TP .B \-us Postscript tree file prepared for US Letter paper size. .TP .B \-size n Font size n used for taxon names. .SH SEE ALSO .BR njplot (1). .br .SH Word-Wide-Web: http://pbil.univ-lyon1.fr/software/njplot.html .SH AUTHOR: .I Manolo Gouy .br e-mail: mgouy@biomserv.univ-lyon1.fr .PP This manual page was written by Dr. Guenter Bechly , for the Debian GNU/Linux system (but may be used by others). njplot-2.4/makefile0000644000002300003250000000176011701011343013024 0ustar mgouybge#uncomment and locally adapt next line to fix the full helpfile path name HELPFILENAME = -DHELPFILENAME=\"/usr/share/njplot/njplot.help\" #comment out next line and uncomment next 2 to use the PDFLib Lite library NO_PDF = -DNO_PDF #PDF = ../PDFlibLite/libs/pdflib #PDFLIB = -L$(PDF) -lpdf # c compiler and linker CC = gcc # Vibrant top directory VIBRANT = /usr/include/ncbi OBJECTS = njplot-vib.o OBJUNROOTED = unrooted-vib.o preptree.o CFLAGS = -c -DWIN_MOTIF -Dunix -I$(VIBRANT) $(HELPFILENAME) $(NO_PDF) all: njplot unrooted newicktops newicktotxt njplot : $(OBJECTS) $(CC) -o njplot $(OBJECTS) \ -lvibrant -lncbi -lXm -lXt unrooted : $(OBJUNROOTED) $(CC) -o unrooted $(OBJUNROOTED) \ -lvibrant -lncbi -lXm -lXt newicktops: njplot-vib.c $(CC) -DNO_GUI -DNO_PDF -o $@ njplot-vib.c -lm newicktotxt: njplot-vib.c $(CC) -DTTY -o $@ njplot-vib.c -lm .c.o : $(CC) $(CFLAGS) $? clean: rm -f *.o distclean: clean rm -f njplot unrooted newicktops newicktotxt njplot-2.4/njplot.html0000644000002300003250000001126311701012430013515 0ustar mgouybge NJplot

NJplot

NEW: NJplot plots trees in PDF and PostScript formats (not for MacOS).
NEW: NJplot allows to open several tree windows.
NEW: NJplot can draw multibranched trees with or without branch lengths.

NJplot is a tree drawing program able to draw any phylogenetic tree expressed in the Newick phylogenetic tree format (e.g., the format used by the PHYLIP package). NJplot is especially convenient for rooting the unrooted trees obtained from parsimony, distance or maximum likelihood tree-building methods.

A screen shot of the main window of njplot is available here.

Use of NJPlot

Any rooting of the unrooted tree can be interactively specified using the mouse. NJplot also allows zooming, branch swapping, display of bootstrap scores and printing in the PDF format. NJplot can therefore be used as a graphical extension of any package of phylogenetic programs which employs the standard tree format for storing trees (i.e., with most such packages).

Download NJplot

Executables and full source code can be downloaded through our FTP server. You may also use the following table to directly access the version corresponding to your computer:

MacOS X
MacOS (8,9)

Linux on PC
in case of font problem
Use without X11 display: newicktopdf

MS Windows

Sun-Solaris

HP Alpha

The Mac and Windows versions are self-extracting archives which include an example file, help information, and the unrooted program that draws unrooted trees. The Windows version is for any MS Windows version except 3.*.

For unix versions, get also an example tree file and the on-line help file.

Note for unix/linux users: In case of problem with default fonts, the font used by menus and buttons can be changed through the resource mechanism:
- add to your $HOME/.Xdefaults file the single line
Vibrant.systemfont : Helvetica,14,b
and activate the change by running command xrdb -merge $HOME/.Xdefaults
- you may change the font name (times, courier, fixed) and size.
- For that change to apply systemwide, create a file named Vibrant and containing the above line in directory /usr/X11R6/lib/X11/app-defaults or in a directory pointed to by environment variable XAPPLRESDIR.

Use as a helper application

NJplot can be used as a standalone application or as a helper application when using the World Wide Web. In this case, prospective users must configure their WWW browser in a way to make it able to recognize the MIME-type associated to the data read by NJplot: chemical/njplot.

Reference

If you use NJplot in a published work, please cite the following reference:
Perrière, G. and Gouy, M. (1996) WWW-Query: An on-line retrieval system for biological sequence banks. Biochimie, 78, 364-369.

If you have problems or comments...

Back to PBIL home page
njplot-2.4/njplot.gif0000644000002300003250000005702411701012430013323 0ustar mgouybgeGIF89aja1{scJ){sZ9){ֽε){sskJ޽R޵ޭޥ1ޜޜBބskcccΌ{΄9{!cRRR{s!RJJBB9sֵν{k1)skεc)!!kcsBcZZ91)省祥!!ZƜ眽ޜs!kkJ)19֔R甔k1k)!!B猔֌J{sZR9!BRJ1ZZRB{{{1{{{{{{ss{11{1s)ssBs)ss{sRsRRsBBs99s!!kkkkkkBkk{k{{ksskkkkccccksckcc!cZZZZ9ZZ1Z{ZsZZZZcZ11RRRRR!R{RcsRZRRZR)1Js)JZJZsJZkJZZJRJRZJBBJ19BBBkBkBZ9BJZBBBB{B9999!9s99c9Jc9BJ9BB9B99199))1s1BR19J1111)11!)Z))R)Bc)19)11))!{!B!!!!1!B1k)9!)kZB)!kZ,jaH*\ȰÇ#JHŋ3jȱǏ C8ɓ(S\ɲ˗0cʜI͛8sɳϟ@ JN*MtӦPJJuժXju׮` KvٲhϪMv۶pʍKw]\K> RL#lr/Uˆ+6̸bǍ>9d˕_֜0ϔAc͙ШG.׬aM{ĝqݚlߵVlȓ+_μУK`эe+~č'ԊWI M=O^M^?_%(h_M?h 3aT# U!La<RđT#:h$(n#c`Z#M"vBBI@f %VCjeXr^9dnyUIg8%^xrj6A&D<ČZ%@Iy!i@@p""TL J{*ʙ% O&r梛nZj&Z*?VhZk, [,F:2,BJk':R z*jhs1R_)4:ܐ?Đ%Yqo;NphkMxR)Lj7՚R)񴸎¥d ڔbS)[RC6Y<:}ްK 2-gZҺ;aRSL6 Hp6Fy۟\w]bߋWG12OtLL)=q 5 !"9C57?G%-W/Ӿ.n R AJϭOpo^59X.ZݹL 2X% MhT>bc0x uqX:DM`g㐇lcQ2:@ b O@УL'YO Lѝ!Pd "aҸ1)WZF lt1@dRH,FRJZLjHIje6og F '.XH1(RD~gbtqR:F:g΍Uyp?ITE+XVϜt(=)7Px$@MrC7Ҥi\! )+Ѱ+R,-˒䏠xY3/>= G jbI{Q  @YeG(&9$HE:2af* )L*Տƴ CJխNE%jW Vj_Yֳk-U:WUu]W5m(;vAkeоuTGf/%c۪#く^W De+$6z͓hESڡ) z"Sqb$0rPz f"٫挮t})gh<}p :~:8e5Y-*!Fn1ap:0a|Ā^cCE%x m*F:xdfEkΡ̚Z۶ !yt^˥th[%uO<IrREKvԦ$+LT( */٧ )@#%26+o3,:v3>~4< x r/ ֺi +AѹW9Zh^4}A3fEvoVM-R1ʣ^׾6-b|꺴S6bvgrjM /SkԒ ٳKq)% 9.QnR"B92UɭŪ7^1,K&WI¯}, n[u||uquKX^렿*49ɃROSU@5MiNГ8mj$'e)4396U#j{jNu9K}Uաny>s t9 jPδxpZ=1| ]Cu|z uƮnw1>C̻KFy?~w}azk^oo{{/|ܭ| ЏO}+8ϾkO~/~7돿OϿ|4p?P  Np##р8XxX)9` 0#  ~4b*,؂.HR 3tr'7SjW/rOwg.wr 7Pj7; v'x4iz(qk(xxix©vřiy).U 42 wÕys&wĉyiYɚy)Y)v/H `P"P"0%P (zB @ Z:Dΐ \$\ yw+ڢ)z4Fy0Zآp׈)wp7Sxyx? é/)GPꀞrJjճ4$+x˳|+ 7z{Gyz+Kz ڀ&"h`44s; ZqPĠ9 2 eDI% ;裃^  U:~.;2k;{"۷۽Ջ{CۼQ l>3 JΠv Q$@$еQ` 2z0 P˭?K!!0L-p@zp m߈z~M}m7.ɋ8ي-Y| 㘝Y1W'1q/-a7CO.+I1׉ٻDs/H<#3+ pHyA`p!A8ՕEMHM^}އ:z O ߒ.Lz//Zqpp)PP 0R\_ _N݁5pLp c@~8އ݉N+FA~~}]Zm}q=6J~ ~^p׸-V/پDHڝ23O%_2~.mY /PLov~`MO@dMP5{ h`-Atq$90z?Roun߁/qoދ/s/ڝ*Im{K@FDXa/pŠ .`b΢ iϽ@Cd&$ Dr0Ddq g+- Jg+HDEIrA)uF*q-4/ U,?,2r_${qH N!o<< sPA_Db!W ,TOBSRBIdM@EPH-"/K STTPM]$BL5TP[a-?-}QQaySP .SL@SX [ Te \`UZ^A5V`%j^|w_~7C8_4`Ʒ| VX_-a>b|'c;c9aGWN9C}Yyfy```g{gzh6hVzivizjjzkk{l6lV{msfm{nn:oo|p&pW|qo|q3|s;py\=7tSW}n{r'9vqa/}u~xmw䗯u畗w⫷z=ݕG{O{W}w}~~/|;G& d @w˝h n|!Q#LZ#GB0j"Ta }fBЅ3ajXC P;!iC2标YT1ey&j>O3똝&wK;)] Xh 3ךaUWEggUJ񞃑!B< PNl^? fZ|::x`/;?!lWY%_cG{2:id"ǫ.:_tBXBsL`.];LAIʳ'gů!R(R@o o?L>?밷!ȽÆbx&x6ÿ@>n_#C`13{)ˆbӼC <)("$|Mثꤓ8:3[d1 `BBb.r#r+;`Cx=?;;9#C:+ BC<¤c:S`.;0;YhZN>!X`˫hBvؙĶ3Nj94" A#,W;s)C9L,(*uD"%"!"(B7pƂ32;'$'4b#V|;!8Oa ;xž0{AI=DAA]{]-U)h[A/ FopG&6ˣjS5bIH6be3M.zcRp)bBeV6IxHd(bj[AlȆLؾt6o*tA^x!@N(b$2bLi4YlA=&4=*[-׊-:8?<4C5v/ZIJ#-S?S@ TAE: ,TDMTEYTG}8=THTJFTL3TMTO!u QOB=UUe!yRS]UTUZ=KU A"]EZU _TNUBVJbŚ ʠf; *hAVoVp}IhBl%mV Uumg-m=שy UmQݝ }]gUkׂeV}դS}VfUmJR1Q؍յظOB=Yش1ϸ+Y!ٚYYYYY ZHQv}bY!"2?yY\;ZIYbq!@kt,۳M[][m[}[۲ '@-!- @BR[ۆ̞ h~M\~5'@=۳قp[0CB\Z]5'Pϻ ١٥Bp]op\r-ςгѽF+@]u(m̰!]:݀% 7ߴ]-} *؂18z}ZĹ`v@sO):@'` @r'㛈-)@ėhd2{`7-7z7&,L&ޚi$_ q}\e&^>80^0e:EQ{'aQ{#D y3c}-6߼?+ +za&6 }mkBx*#P7 {HL'~,N Zr]X0ݳZO; \x +H9@8X] 1F 7Bύ ؀^Ƽ+C6 *@^a_=ӌىؚ-*Z І/;c;b1u˷gyvf/ gԄ?{H7Mu`BB`Kc2g&c/4ׂe0 #4 s@#v '@xUx"3r:eBQp5feLfpp 0#jplV뭆j؀%@Ȃ(]l`'6aJ5_y1 "}7mPClP K4K͆l֢P3jy0g8T0h&^xa_7LJb&xe $b-_JD)^E7S U4WyףϸΕ+;&+1&dp6c^7>n~R >d^a k+J97"pBz膝pb84$q;CtT@KH؉˲Tpc41c ߩ+Fl5!/۫b:\˫;Nyi-Uf  ~[Vkd:Vtfۑz0$X 8kdš&n ӰbB̵l?/xl&9T z1\fM}_&&4 @#NR*{$8z8`d([pco&t0OcRF0y*6x`b-F6g32*x04l3\5##Rwov0{$B<`7}$|"3ɳL2̚!g^rТGt +V.5زgӮm/`#iYH֩S ]^rҧS'9fDZ/\`I#z[r-͞ӏ<] n? 0 db jN6T5 ӞtN6LXal֠{"]v B_16ްA 9$~BĒB H$ih RJpM#N:)QN9'Ryz/{V9'NIgtʙ}i)yB7晍:/8飕6b3ny^#RnpRƚ*zʪkj:,b*,qlGe-fۚZkm6{.FR.;/{//o0b{0 7 ;hzJ0[kq{1!pn#|r2-C1 0|3Df3=34E}4ұ4M;tYU[}5Yk5]{5a=6eѺ+C6mMڒL.}7y [2R{ >8ym0^8;^h[~9ʑ )vc9腣.{ 0:eH[̺ ?ڜ];Q.xQNh;{1?_>'o7,K??_f;^ٟY<x&%h3"U:.yk ۴u" mw +laL|B宊࣌Fg!J?eP?LG<1 ,cR:o)m!]QW䱋]C% D0F Ba𲞚w􏔥SOBGI,+ #삌 dJQ_ \d&A^EiJ&VxE`o,h9ˤfeLIs2|hbl7 J7p ,U)WL,4(H "Y}}gC0M::+*hbl.#((Sw@`W= z˩OStS+@8Ѡ5f'z |S9G~.M)%USQ5N|PWZ9וshZMnr}HqQ啯54HD63K[ŽT\)aW@U(1kF%n]:ONs2ٿB JbhfL!3X*g \(P\vs9Q{/Y뜌J’\`Aqu._Al'8Ƃs-~S췶H٥g,Z.. 2ܝ]7F6V/xL4 D#FUvZw =֏&>q6b-Ùkh_ cněOxfLXXع:.\2{4qؾJI?9~h(2>]Meg7>a@;`,V0MgnpuVxsZ}kP, pU; S .*qxhq{CƓV d)/yC*x#oڵ;20czCCs+mLrt.kLEXy. \Nө֮ d;Jm1?is?2dAє,vGE;u$I6t;7d⍝Ȩ+(᝷Mt Z1 Qi&$z׸fFyp g)i~;s ?HF ȿ3b}DO Ǜd2u4}Qh`ٳN/_O(qōm_@xdE]:NY1VdZԝ%eSkT%CR9]ځۥ `)T^-ٝeU]` ͋h5eS9ݱ9 V c9-MS]!SU @,hSM[zTi[^uW!!UR18 AX[I!%cXJbT3Ŕa"TbޅlFQ 0uB̚ viF/ /#.=F<@_\2]=YYab6v0BVŎU 9^6Tۘg}ܣ0 = c.p|m ApFdA*R R\3^)#dJ $Fڠ`,ՒVegeB6Cnk<1E!TV;)^ke!td<<$%t l`SpW1JQ7$PjYcѐ :[JQ|#z1bzVCvkYifXm(R J)态iUA_Q&09e*m~ 0^ m"og'"q68nLo:'uޙ%'sܼP ~eneL'lL/gvfv\B%MR eC_URJf訧*#fe^j.]- T:klUmvTTnͬ4aV֡4yaqѐ'mbNѡ#%eYrb(~zABuk $pS{B[*",*[h1>B&VU[U]xj瀮(  zϘS[#uhf>)bz{N Ml D= "&,iIojjkBlҬoo^'玧뢯nܾ/)֯Zcr]/+Fe/Yo Nԥe"0 l`BN !m,0!i* [5&^4+( #Ywq0xB+kݰ-60e0+ idkxؙWASm/(W.?֪^[ˢ^p]1f wUq1;v8hأncͱv0Cp@NPZ2jD&j]fQvfS2_/)Or) R̝bE.iC&2[1)'Ş2d"ƫ9CE4kpai/î^Vˬ7 7?qoǵ3ހ6t?T8M[sS>_,cx6bxsUCTP%A\$*%X]8(vL7[0-(Zʁzye3WO~8e%`*ȊK<gUiЦ nOfE[~k0{{$f"+-^-Ӵ^u9:rxhcp+i{ ?-]{%omٴ{rX$3-/H2CA rU_ɘUjqڙ1+[uW]atTWH6m9zɑ]u{̲?Pw0!EaTl+IxM ܞvV0OV@Wco&82mH,)ysJ!c:6Y`#.J mmt}!MJ $:E`֨_uE=DE!J-&Bwۥi&[#pKVZ:$C0[I^9ƺ><͑tZ#b F.vDRE\#(IY-x}$ IRm{,wg%`QH~yGPƒ{JXI SN#2"`2L&0iHkw(f3 \Q! 95Iәb8WDRb#'Ϥ!}PyLvƎ! U 4(BJiP'B^{颵5@Z\1 Ή>.|(~̃ 3IΓtVAgWuv\ ǴAVMal T4D]!SNyғ9gԦLS:JS`eYIVB5VM+w%17P+q\k+R 7Xua9t|JTv>,?!M k(Iu94XvL$~< ]\W !bZHy?ypIhȣnV"ږ [fU Ao3E^)Ds^-lg@eW 4QAzցmK^TEhhlÌ/ AZԎ6XOL\}xJRXq}Z5+)j`|c]id%7 &5΀1"2[DV|bN.c, !6k֣^EB&.\]LV5%7BH¡EZ +ϰl&`gR&sՒ`Co~t;{+Fx hjzbE]/Af_1KQ7 L ٰԢ?XMԞ̲o;֢ OUs;WI>kW2@sh@ŭƄox*>K~a>Zpt6oy_^mߊtKsUMP fbcnOț5ZP~}3qqꢟJF-iy2}vy} ]2&:~YNk˳Ymӻ\tM=f'J}=Zf8_7h{LVBǻ"9\EYQ^Tq zx MqmAXͪ?a^lo}{эQ]i\`M ߗd,`>.|RT_I()=ldchUzAY{_l`ܧO#ϜD>X9(9:?jQ FLR(E-xvAO'cۆ2dF<6PeS™R0]'e`-,K*lqum$&jJdo"<,[ W}Km"04 ?- -.ċ ިvHOjbzPx Gp33)fe$ ^Px0;qHl_$Q:*W$L J`n[Avǂl OȆHLFJHcE ]Kb|x:*O PG1xRG 6QE!nӑzXDQ&Q-iq7Q ~ +Ü}p& W/"w `EVF@ѱ$K$b# ~+DLl!m!IͰ>^Px@0p dD/(gB )Ujqlghj ZRXdjR(*ˊl!paNRV!,!30͙2""dLbx0̒*-%-2:sT(o2%疍K sH1q$1FdȞV-uJ'N88d҄ 5453'F%2Ff3'3?S\:,xJ6E3 hgQPz: >0'ΎAtLM@G1A9mtBz8A3' C".#V2E6BCA@ 7  T$H?-}b UQb!1jt9aEcEr*0"/2Nn +=_z6CTGSMAMT)L[<%M,GJ IsAPO3rMF;?&XC-(4T!'a͂ꎌJTTQQʈC'k )0P*GپL,JaL Iv 4x^!O5VtLôV,X.XI;u,S3XΒuZ=DJmr28bL0HJ+ZW=TZs"AtT>:HbFozp[/]mӲzKYl$ 'o 5 6xn&].&p`e"ve)vb73H7QnJZ#0#MgZ4&eF"4Tx|e ,ҷJy:Kt9}'yȺb_lC^l?v2G< =G/SnfǮŎb oi;p,S!+Th{uk3{b6GhU IĔ64auruM7Si'tJn.7fkF[մvh; uVDvnD4Ll^7vxUpw au9tay1hhkxxUϣǤ)d]uy]y+k'"~XJdeE1"6^ &[h"Bg_ 9YW;(P4z1QmjsIEm$@_Tf"nS!<'Y',X0EU K$v?}n}'PWo;ͅ937"ꯄ[ G%XmmqwK8A¬'1xxx`gN;=7U!"Cy- I" 'I,/C wQ$oD/]X%"IzRiZpg'T@`CW;"N4{>Öo4B b&dvqφ.Vͳ#@ 9=B? 挸OR X , 9_5’ YH$"FY'=Ñ65aɢ^hFn ^-2̸LΨ+ +:톰,O:yl(]zl:c#g"0o5A|&e/J x鏗ovA#ڥg "YT`YIo F.Z%:l}":FQ H&8^;"|ݓh:sf +<Ψh;;[aC;+Y'ί~g0W ED$5jfx(=Iqhu@A[=c ޑp&ɞ!WK❩fu%c-Q=D"|w8|ga.\\b~[:9MG>x=_WCop1O4zt\H>[LJн̷U"Ga#|W6p0>l,!#wA深FH$op>dܰ] 2At:ޞ< >dO%j;\ڟ>u4q\% REVI3O#pqM0~ͭK_0D~-m-)?Y;aq:Ja%`'DzūYD߽}׾"JYգ\2dB~* gA4aT{QnBd]9הY_G ԐxIf)2)9)gYXiךdA8nёvF'8)裖.ztg^X@ڸ饪H"8X骲'"OT|j|J`dSU52:kصJ>{#qv"Y`zЎTJn%iِTW&n ܠ!l1ߐD,Hbh8tmo*ZY |2ˎJɑ:1gyS-NI_@V`V 7_-+\Nundo90k+5YTвo+)wmaihq½-gPN@]cC~i]6E$VChEB77ȹH0RfǓ>3fN{ΧO&b]hy4^b>6zX!c#+dD>Z@Celh(.eOooAMc.Jg[=޷BH1,Z oC#JH=%)񈮣doDEKO,QC!"8X˜ʮ *c8;A cV9%EsY1FGq2Yɟwf4812 S=HƱguӿ} hJe(.+,OYՁ()Qc/!6pi[ZU2xpQ6$ <t&gϬ`-YtHj: x=9H!?tN~s eYЄ*')|B Q qZE/ьjtG? Ґt$-IOJɑ0,m\Ҙʴ(+Mo:t3,VN`-2QxլlXOD mk Z@5ؠ]Au0a1 ĒyEj^WJ6AI!v^-8:i)VaJ7{>qŬZ vkk'PU-\b55sv4h# ;njplot-2.4/helpers.html0000644000002300003250000000377411701012430013661 0ustar mgouybge Helper applications

Helper applications for Hovergen


The version of Hovergen accessible through WWW-Query uses two helper applications that allow to visualize and to handle the alignments and the phylogenic trees provided with this database. These applications are SeaView (for the alignments) and NJplot (for the phylogenic trees).

The procedure to set up these two applications is the following:

  1. Download the binaries corresponding to your platform.

  2. Configure your Web browser in a way to make it able to recognize two new MIME-types: chemical/mase and chemical/njplot. For instance, if you use a UNIX machine, modify the .mailcap file of your home directory by adding the following lines:
            chemical/mase; seaview -save clustal  %s
            chemical/njplot; njplot %s
    
  3. Then, when you will click on the hypertext links labelled ALN or TREE, you will access respectively the protein alignment and the tree of the corresponding gene family in Hovergen.

Seaview allows you to edit the alignment and to save it on your disk. Njplot allows you to root the tree and to swap the nodes. You can also save the tree on your local disk in PostScript format in a way to print it on a compatible printer.

Note that if you do not want to install these applications on your computer or if the binary corresponding to your platform is not available, you can still click on the ALN and TREE links. In this case the corresponding data will be send as text files to your Web browser.


If you have problems or comments...

Back to PBIL home page