1 /*
2  *  pretty.c
3  *  migrate-n
4  *
5  *  Created by Peter Beerli on 7/25/05.
6  *  Copyright 2005-2013 Peter Beerli. All rights reserved.
7 
8  Permission is hereby granted, free of charge, to any person obtaining
9  a copy of this software and associated documentation files (the
10  "Software"), to deal in the Software without restriction, including
11  without limitation the rights to use, copy, modify, merge, publish,
12  distribute, sublicense, and/or sell copies of the Software, and to
13  permit persons to whom the Software is furnished to do so, subject
14  to the following conditions:
15 
16  The above copyright notice and this permission notice shall be
17  included in all copies or substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
23  ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
24  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 
27  *
28  */
29 #ifdef PRETTY
30 #include "pretty.h"
31 #include "data.h"
32 #include "options.h"
33 #include "migevents.h"
34 #include "menu.h"
35 #include "bayes.h"
36 
37 #include <stdarg.h>
38 
39 #define LINESTRETCH 15
40 #define NOT_PERCENTILES FALSE
41 #define PERCENTILES TRUE
42 #define SQUARE 0
43 #define DIAMOND 1
44 
45 #ifndef A4PAPER
46 #define LETTERADJUST 50
47 #else
48 #define LETTERADJUST 0
49 #endif
50 
51 
52 extern pdf_doc doc;
53 extern pdf_page page;
54 extern pdf_contents canvas;
55 extern int page_counter;
56 extern char pdf_pagetitle[LINESIZE+1];
57 extern char pdf_time[LINESIZE+1];
58 extern float page_height;
59 extern float left_margin;
60 extern int numcpu;
61 pdf_contents firstcanvas;
62 float timestampy;
63 void pdf_printf_right(float x, float y, char string[],...);
64 int pdf_print_header(char *title);
65 void pdf_print_contents_at(float x, float y, char *title);
66 void pdf_draw_line(float xs, float ys, float xe, float ye);
67 void pdf_migrate_logo(float x, float y, float stretch);
68 void pdf_migrate_logo_lines(float x, float y, float stretch);
69 void pdf_print_time(float startx, float *pageheight, char text[]);
70 boolean  pdf_advance(float *page_height);
71 void pdf_print_seqdata (float *page_height, float margin, world_fmt * world, data_fmt * data, option_fmt * options);
72 void pdf_printf_next(float x, float *y, char string[], ...);
73 void pdf_printf_ralign(float rx, float y, char string[], ...);
74 void pdf_printf(float x, float y, char align, char string[], ...);
75 void pdf_print_tableline(float *page_height, float *width, char *fmt, ...);
76 void pdf_print_result_param (float *lx, float *page_height,  MYREAL *param, long numpop, long pop,
77                              boolean usem);
78 void pdf_table(float left_margin, float *page_height, int cols, int rows, char **buffer, char *position, int col_overflow, float separator);
79 
80 long nice_element(MYREAL param, char *element, MYREAL lower, MYREAL mid, MYREAL upper,
81                   int low_mid_digits, int mid_upper_digits, char delimiter);
82 void pdf_linedotplot(long n, float *x, float *y, float dotcolor[], float linecolor[], MYREAL linethickness, float * page_height, float width, float height, boolean has_dots, boolean has_line);
83 
84 void pdf_print_symbol(float lx, float *page_height, long fontsize, char pos, char *symbolstring);
85 
86 void pdf_print_citation(float *page_height, char type[],world_fmt *world);
87 void pdf_print_section_title(float *page_width, float * page_height, char *title);
88 float pdf_print_line_element(float lx, float ly, float offset, char *title);
89 float pdf_print_line_element2(float lx, float ly, float offset, float value, int fmt1, int fmt2);
90 void symbol_Theta(float lx, float ly, int size, long subscript);
91 #ifndef HAVE_STRSEP
92 /*-
93 * Copyright (c) 1990, 1993
94  *      The Regents of the University of California.  All rights reserved.
95  *
96  * Redistribution and use in source and binary forms, with or without
97  * modification, are permitted provided that the following conditions
98  * are met:
99  * 1. Redistributions of source code must retain the above copyright
100  *    notice, this list of conditions and the following disclaimer.
101  * 2. Redistributions in binary form must reproduce the above copyright
102  *    notice, this list of conditions and the following disclaimer in the
103  *    documentation and/or other materials provided with the distribution.
104  * 3. All advertising materials mentioning features or use of this software
105  *    must display the following acknowledgement:
106  *      This product includes software developed by the University of
107  *      California, Berkeley and its contributors.
108  * 4. Neither the name of the University nor the names of its contributors
109  *    may be used to endorse or promote products derived from this software
110  *    without specific prior written permission.
111  *
112  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
113  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
114  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
115  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
116  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
117  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
118             * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
119  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
120  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
121  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
122  * SUCH DAMAGE.
123  */
124 
125 // #include "config.h"
126 
127 // #include <sys/types.h>
128 
129 // #include <string.h>
130 // #include <stdio.h>
131 
132 // #ifndef HAVE_STRSEP
133 char *strsep(char **, const char *);
134 // #endif
135 
136 // #if defined(LIBC_SCCS) && !defined(lint)
137 // static char sccsid[] = "@(#)strsep.c    8.1 (Berkeley) 6/4/93";
138 // #endif /* LIBC_SCCS and not lint */
139 // #ifndef lint
140 // static const char rcsid[] =
141 //   "$FreeBSD: src/lib/libc/string/strsep.c,v 1.2.12.1 2001/07/09 23:30:07 obrien Exp $";
142 // #endif
143 
144 /*
145  * Get next token from string *stringp, where tokens are possibly-empty
146  * strings separated by characters from delim.
147  *
148  * Writes NULs into the string at *stringp to end tokens.
149  * delim need not remain constant from call to call.
150  * On return, *stringp points past the last NUL written (if there might
151                                                          * be further tokens), or is NULL (if there are definitely no more tokens).
152  *
153  * If *stringp is NULL, strsep returns NULL.
154  */
155 char *
strsep(register char ** stringp,register const char * delim)156 strsep(register char **stringp, register const char *delim)
157 {
158     register char *s;
159     register const char *spanp;
160     register int c, sc;
161     char *tok;
162 
163     if ((s = *stringp) == NULL)
164         return (NULL);
165     for (tok = s;;) {
166         c = *s++;
167         spanp = delim;
168         do {
169             if ((sc = *spanp++) == c) {
170                 if (c == 0)
171                     s = NULL;
172                 else
173                     s[-1] = 0;
174                 *stringp = s;
175                 return (tok);
176             }
177         } while (sc != 0);
178     }
179     /* NOTREACHED */
180 }
181 #endif
182 
183 ///
184 /// returns the quantile at prob1 or prob2, if the value at prob2 is smaller than
185 /// the value at prob1 then the value at prob1 is return otherwise the value at prob2.
186 /// We assume range1< range2
quantiler(float * values,float prob1,float prob2,long range1,long range2)187 float quantiler(float *values, float prob1, float prob2, long range1, long range2)
188 {
189   float *temp;
190   MYREAL a,b;
191   if (range2==0)
192     return 0.0f;
193   temp = (float *) calloc(range2+1,sizeof(float));
194   memcpy(temp, values,sizeof(float)*range2);
195   qsort ((void *) temp, range2, sizeof (float), floatcmp);
196   a = temp[((long) (range1 * prob1))];
197   b = temp[((long) ((range2-1) * prob2))];
198   myfree(temp);
199   return (float) (a<b ? b : a);
200 }
201 
symbol_Theta(float lx,float ly,int size,long subscript)202 void symbol_Theta(float lx, float ly, int size, long subscript)
203 {
204     char *thetatitle = "Q";
205     char tempstring[100];
206     int subsize =  (int) (0.75 * size);
207     float lxdelta = lx + (float) 0.8 * size;
208     float lydelta = ly - (float) 0.5 * subsize ;
209     if(subscript >= 0)
210       sprintf(tempstring,"%li",subscript);
211     else
212       sprintf(tempstring," ");
213     pdf_contents_set_font_and_size(canvas, "Symbol", (float) size);
214     pdf_print_contents_at(lx,ly,thetatitle);
215     pdf_contents_set_font_and_size(canvas, "Symbol", (float) subsize);
216     pdf_print_contents_at(lxdelta,lydelta,tempstring);
217     // backt to default
218     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
219 }
220 
symbol_R(float lx,float ly,int size,long subscript)221 void symbol_R(float lx, float ly, int size, long subscript)
222 {
223     char *thetatitle = "R";
224     char tempstring[100];
225     int subsize =  (int) (0.75 * size);
226     float lxdelta = lx + (float) 0.8 * size;
227     float lydelta = ly - (float) 0.5 * subsize ;
228     if(subscript > -1)
229         sprintf(tempstring,"%li",subscript);
230     else
231       {
232 	if(subscript < -1)
233 	  sprintf(tempstring,"combined");
234 	else
235 	  sprintf(tempstring," ");
236       }
237     pdf_contents_set_font_and_size(canvas, "Helvetica", size);
238     pdf_print_contents_at(lx,ly,thetatitle);
239     if(subscript < -1)
240       pdf_contents_set_font_and_size(canvas, "Helvetica", subsize);
241     else
242       pdf_contents_set_font_and_size(canvas, "Symbol", subsize);
243     pdf_print_contents_at(lxdelta,lydelta,tempstring);
244     // backt to default
245     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
246 }
247 
symbol_M(float lx,float ly,int size,long subscript1,long subscript2,boolean usem)248 void symbol_M(float lx, float ly, int size, long subscript1, long subscript2, boolean usem)
249 {
250     char *migt1 = "M";
251     char *migt2 = "xNm";
252     char *migtitle = usem ? migt1 : migt2;
253     int msub = usem ?  size/2 : size+ size/2;
254     char tempstring[100];
255     int subsize =  (int) (0.75 * size);
256     float lxdelta = lx + (float) 0.8 * size + msub;
257     float lydelta = ly - (float) 0.5 * subsize ;
258     sprintf(tempstring,"%li->%li",subscript1,subscript2);
259     pdf_contents_set_font_and_size(canvas, "Helvetica", size);
260     pdf_print_contents_at(lx,ly,migtitle);
261     pdf_contents_set_font_and_size(canvas, "Symbol", subsize);
262     pdf_print_contents_at(lxdelta,lydelta,tempstring);
263     // backt to default
264     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
265 }
266 
symbol_Hexp(float lx,float ly,int size)267 void symbol_Hexp(float lx, float ly, int size)
268 {
269     char *title = "H";
270     char tempstring[100];
271     int subsize =  (int) (0.75 * size);
272     float lxdelta = lx + (float) 0.8 * size;
273     float lydelta = ly - (float) 0.5 * subsize ;
274     sprintf(tempstring,"exp");
275     pdf_contents_set_font_and_size(canvas, "Helvetica", (float) size);
276     pdf_print_contents_at(lx,ly,title);
277     pdf_contents_set_font_and_size(canvas, "Helvetica", (float) subsize);
278     pdf_print_contents_at(lxdelta,lydelta,tempstring);
279     // backt to default
280     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
281 }
282 
283 ///
284 /// Draw a simple line from x0,y0 to x0/y0, this function does not change
285 /// thickness or line type
pdf_draw_line(float xs,float ys,float xe,float ye)286 void pdf_draw_line(float xs, float ys, float xe, float ye)
287 {
288     pdf_contents_move_to(canvas, xs, ys);
289     pdf_contents_line_to(canvas, xe, ye);
290     pdf_contents_stroke(canvas);
291 }
292 
293 ///
294 /// draw a rectangle [from haru examples]
draw_rect(pdf_contents canvas,float x,float y,const char * label)295 void draw_rect(pdf_contents canvas, float x, float y, const char* label)
296 {
297     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
298     pdf_contents_begin_text(canvas);
299     pdf_contents_move_text_pos(canvas, x, y - 10.);
300     pdf_contents_show_text(canvas, label);
301     pdf_contents_end_text(canvas);
302 
303     pdf_contents_rectangle(canvas, x, y - 40., 220., 25.);
304 }
305 
306 ///
307 /// when there are fewer than need_pixels create a new page and
308 /// and push page_height down so that the need_pixel object will fit.
pdf_page_advance_or_not(float * page_height,float need_pixels)309 float pdf_page_advance_or_not(float *page_height, float need_pixels)
310 {
311     boolean new_page = FALSE;
312     if(*page_height < need_pixels)
313       {
314         pdf_new_page("");
315         *page_height = (float) pdf_contents_get_height(canvas);
316         *page_height -= 55. + LINESTRETCH;
317         new_page = TRUE;
318       }
319     return new_page;
320 }
321 
322 ///
323 /// advance a line and check whether we are at the end of the page, if yes then add a new page
pdf_advance(float * page_height)324 boolean pdf_advance(float *page_height)
325 {
326     *page_height -= LINESTRETCH;
327     return (boolean) pdf_page_advance_or_not(page_height, 55.);
328 }
329 ///
330 /// advance a half-line and check whether we are at the end of the page, if yes then add a new page
pdf_advance_half(float * page_height)331 boolean pdf_advance_half(float *page_height)
332 {
333     *page_height -= LINESTRETCH/2.;
334     return (boolean) pdf_page_advance_or_not(page_height, 55.);
335 }
336 
337 #define HORIZONTAL 0
338 #define VERTICAL   1
339 ///
340 /// plot a single tick with label at location x/y.
341 /// \param xs  x coordinate in true paper coordinates (points)
342 /// \param xy  y coordinate in true paper coordinates (points)
343 /// \param orientation either HORIZONTAL or VERTICAL, on HORIZONTAL=0 is checked
344 /// \param ticklength length of a the tick to draw
345 /// \param value this is a float value to put into the label
346 /// \param digits number of decimal digits
pdf_draw_tick(float xs,float ys,int orientation,float ticklength,float value,int digits)347 void   pdf_draw_tick(float xs, float ys, int orientation, float ticklength, float value, int digits)
348 {
349     float w;
350     float h;
351     float tl = ticklength;
352     char *title;
353     title = (char *) mycalloc(100,sizeof(char));
354     sprintf(title,"%.*f",digits, value);
355     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
356     h = (float) pdf_contents_get_font_size(canvas);
357     if(orientation==HORIZONTAL)
358       {
359         pdf_print_contents_at(xs-w/2, ys-tl-h, title);
360         pdf_draw_line(xs,ys, xs , ys - tl);
361       }
362     else
363       {
364         pdf_print_contents_at(xs-tl-w-2, ys-h/2+2, title);
365         pdf_draw_line(xs,ys, xs-tl , ys);
366       }
367     myfree(title);
368 }
369 
370 ///
371 /// find pretty values for tick labels
372 /// using heuristics
prettytick(float mi,float ma,long ticks,float * nmi,float * nma,float * newdelta,int * digits)373 float prettytick(float mi, float ma, long ticks,
374 		 float *nmi, float *nma, float * newdelta, int * digits)
375 {
376   float newvalue = 0;
377   float dist = (ma - mi)/ticks;
378   float multiplier[5];
379   long  lmi = (long) floor(log10(dist));
380   float scale  = (float) pow(10.,lmi);
381   long i=0;
382   multiplier[0] = 1.;
383   multiplier[1] = 2.;
384   multiplier[2] = 2.5;
385   multiplier[3] = 5.;
386   multiplier[4] = 10.;
387   if(lmi<3)
388     *digits = labs(lmi);
389   else
390     *digits = 0;
391   dist /= scale;
392   if(dist < 1.)
393     dist *= 10.;
394   else
395     dist /= 10.;
396   if(dist >= 10.)
397     dist /= 10.;
398   else
399     dist *= 10.;
400   i = 0;
401   while(i < 5 && dist > multiplier[i])
402     {
403       i++;
404     }
405   *newdelta = scale * multiplier[i];
406   *nmi = (float) ceil(mi/(*newdelta) - 0.05) * (*newdelta);
407 
408   return newvalue;
409 }
410 
411 ///
412 /// create a vertical or horizontal axis
413 /// \param up is either HORIZONTAL=1 or VERTICAL
414 /// \param xmin  real start value
415 /// \param xmax  real end value
416 /// \param ticks number of ticks
417 /// \param lx    x paper coordinate to start axis
418 /// \param ly    y paper coordinate to start axis
419 /// \param length  length on paper in paper coordinate system
pdf_create_axes(int up,float xmin,float xmax,long ticks,float lx,float ly,float length)420 void  pdf_create_axes(int up, float xmin, float xmax, long ticks, float lx, float ly, float length)
421 {
422     long i;
423     int digits = 3;
424     float value = 0.0;
425     float plotdelta = length/ticks;
426     float realdelta = (xmax - xmin)/ticks;
427     float newxmin;
428     float newxmax;
429     float newrealdelta;
430     float newlx;
431     float newly;
432     // pretty printing of labels
433     // find pretty tickmarks
434     prettytick(xmin,xmax, ticks, &newxmin, &newxmax, &newrealdelta,&digits);
435     //
436     if(up!=HORIZONTAL)
437       {
438 	//xcode newlx = lx;
439 	newly = ly + (newxmin-xmin)/(xmax-xmin) * length;
440 	plotdelta *= newrealdelta/realdelta;
441         pdf_draw_line(lx,ly, lx ,ly + length);
442         for(i=0; i<ticks; i++)
443           {
444             value = newxmin+i*newrealdelta;
445 	    if(value>xmax)
446 	      break;
447             pdf_draw_tick(lx, newly+i*plotdelta, VERTICAL, 3, value, digits);
448             }
449           }
450     else
451       {
452         pdf_draw_line(lx,ly, lx + length, ly);
453 	newly = ly;
454 	newlx = lx + (newxmin-xmin)/(xmax-xmin) * length;;
455 	plotdelta *= newrealdelta/realdelta;
456 
457         for(i=0; i<ticks; i++)
458           {
459             value = newxmin+i*newrealdelta;
460 	    if(value>xmax)
461 	      break;
462             pdf_draw_tick(newlx + i*plotdelta,
463                           newly, HORIZONTAL, 3, value, digits);
464           }
465       }
466 }
467 
468 ///
469 /// plot a dot of the shape i (currently i = square or diamond) at position
470 /// xs and ys in RGB color is a float vector of 3 values
pdf_print_dot(float xs,float ys,float width,int shape,float color[])471 void pdf_print_dot(float xs, float ys, float width, int shape, float color[])
472 {
473   float w = (float) (width / 2.);
474     float red = color[0];
475     float green = color[1];
476     float blue = color[2];
477     pdf_contents_set_rgb_fill(canvas, PdfRGBColor(red, green, blue));
478     switch(shape)
479       {
480         case SQUARE:
481             pdf_contents_move_to(canvas, xs-w, ys-w);
482             pdf_contents_line_to(canvas, xs+w, ys-w);
483             pdf_contents_line_to(canvas, xs+w, ys+w);
484             pdf_contents_line_to(canvas, xs-w, ys+w);
485             pdf_contents_line_to(canvas, xs-w, ys-w);
486             break;
487         case DIAMOND:
488         default:
489             pdf_contents_move_to(canvas, xs, ys + w);
490             pdf_contents_line_to(canvas, xs+w, ys);
491             pdf_contents_line_to(canvas, xs, ys-w);
492             pdf_contents_line_to(canvas, xs-w, ys);
493             pdf_contents_line_to(canvas, xs, ys + w);
494             break;
495       }
496     pdf_contents_fill(canvas);
497     pdf_contents_set_rgb_fill(canvas, PdfRGBColor(0, 0, 0));
498 }
499 
findmoments(float * vals,long n,float * p01,long * pos01,float * p99,long * pos99,float * mm,long * posmm)500 void findmoments(float *vals, long n, float *p01, long *pos01, float *p99, long *pos99, float *mm, long *posmm)
501 {
502     long i;
503     float val;
504     float total = 0. ;
505     *mm = - (float) (LONG_MAX);
506     *p01 = 0.;
507     *p99 = 0.;
508     *pos01 = 0;
509     *pos99 = 0;
510     *posmm = 0;
511     for(i=0;i<n; i++)
512       {
513         val = (float) vals[i];
514         total += val;
515         if( *mm < val)
516           {
517             *mm = val;
518             *posmm = i;
519           }
520       }
521     val = 0.;
522     for(i=0;i<n; i++)
523       {
524         val += (float) vals[i]/total;
525         if(val < 0.01)
526           {
527             //	    if(*p01  < (float) vals[i])
528             //  {
529             *p01 = (float) vals[i];
530             *pos01 = i;
531             //  }
532           }
533         if(val <= 0.99)
534           {
535             //	    if(*p99 < (float) vals[i])
536             //  {
537             *p99 = (float) vals[i];
538             *pos99 = i;
539             //   }
540           }
541       }
542 }
543 
544 ///
545 /// finds outliers in vals and retunrs some specified quantiles and the position of these
546 /// values in the vals vector.
findoutliers(float * vals,long n,float * p01,long * pos01,float * p99,long * pos99,float * mm,long * posmm)547 void findoutliers(float *vals, long n,
548                   float *p01, long *pos01,
549                   float *p99, long *pos99,
550                   float *mm, long *posmm)
551 {
552     long i;
553     float * temp;
554     if(n==0)
555       {
556         warning("findoutliers(): The number of values to check for the histogram is zero\n");
557         return;
558       }
559     temp = (float *) mycalloc((n+1),sizeof(float));
560     memcpy(temp,vals,n*sizeof(float));
561     qsort(temp, n, sizeof(float), floatcmp);
562 
563     *mm = (float) temp[n-1];
564     *p01 = (float) temp[(long)(n * 0.01)];
565     *p99 = (float)temp[(long)(n * 0.99)];
566     *pos01 = 0;
567     *pos99 = 0;
568     *posmm = 0;
569     for(i=0;i<n; i++)
570       {
571         if(vals[i] <= *p01)
572           {
573             *pos01 = i;
574           }
575         if(vals[i] < *p99)
576           {
577             *pos99 = i;
578           }
579 
580         if(vals[i] < *mm)
581           {
582             *posmm = i;
583           }
584 
585       }
586     myfree(temp);
587 }
588 
589 ///
590 /// only for fractions 0..1
findminmax_freq_only(float * vals,long n,float * p00,long * pos00,float * p100,long * pos100)591 void findminmax_freq_only(float *vals, long n, float *p00, long *pos00, float *p100, long *pos100)
592 {
593     long i;
594     float val;
595     float total = 0. ;
596     *p00 = 0.;
597     *p100 = 0.;
598     *pos00 = 0;
599     *pos100 = 0;
600     for(i=0;i<n; i++)
601       {
602         val = (float) vals[i];
603         total += val;
604       }
605     val = 0.;
606     for(i=0;i<n; i++)
607       {
608         val += (float) vals[i]/total;
609         if(val < 0.000001)
610           {
611             *p00 = (float) vals[i];
612             *pos00 = i;
613           }
614         if(val < 0.999999)
615           {
616             *p100 = (float) vals[i];
617             *pos100 = i;
618           }
619       }
620 }
621 
622 ///
623 /// create a histogram from bincounts at a specific location and width and height
624 /// If binmax is -9999 then the maximum is reset to the 99% percentile.
625 /// If binmax is -999 then the maximum is reset to the 100% percentile
626 /// if nofreq is TRUE then the y axes is treated literally and not scaled
pdf_histogram(float * binvals,char * set50,char * set95,long bins,float bindelta,float binmin,float binmax,float lx,float ly,float width,float height,boolean nofreq,MYREAL * priors)627 void pdf_histogram(float *binvals, char *set50, char *set95, long bins, float bindelta, float binmin, float binmax, float lx, float ly, float width, float height, boolean nofreq, MYREAL *priors)
628 {
629     long i;
630     float total=0.0f;
631     float binvalsmax=0.0f;
632     float priorsmax=0.0f;
633     long binvalspos;
634     float p99=0.0f;
635     long pos99;
636     float p100=0.0f;
637     long pos100;
638     float p00=0.0f;
639     long pos00;
640     float p01=0.0f;
641     long pos01;
642     float x = 0.;
643     float delta = width / bins;
644     long numbins = bins;
645 
646     float red[3]={0.99f,0.f,0.f};
647     float sumval=0.0;
648     float sumprior=0.0;
649     if(nofreq)
650       {
651         findoutliers(binvals,bins,&p01,&pos01, &p99,
652                      &pos99, &binvalsmax, &binvalspos);
653       }
654     else
655         findmoments(binvals,bins,&p01,&pos01, &p99,
656                     &pos99, &binvalsmax, &binvalspos);
657     //fprintf(stdout,"p01=%f, pos01=%li, p99=%f, pos99=%li, binvalsmax=%f, binvalspos=%li\n",p01,pos01, p99,
658     //	    pos99, binvalsmax, binvalspos);
659     total = 0. ;
660     if(priors == NULL)
661       {
662 	for(i=0;i<bins;i++)
663 	  {
664 	    total += (float) binvals[i];
665 	  }
666       }
667     else
668       {
669 	priorsmax=-HUGE;
670 	for(i=0;i<bins;i++)
671 	  {
672 	    if (priors[i]>priorsmax)
673 	      priorsmax = priors[i];
674 	    total += (float) binvals[i];
675 	  }
676 	priorsmax = priorsmax/binvalsmax;
677       }
678     if(binmax < -9000)
679       {
680         binmax = binmin + pos99 * bindelta;
681         delta = width/pos99;
682         numbins = pos99;
683       }
684     else
685       {
686         if(binmax < -900)
687           {
688             findminmax_freq_only(binvals,bins,&p00,&pos00, &p100,
689                        &pos100);
690             binmax = binmin + pos100 * bindelta;
691             delta = width/pos100;
692             numbins = pos100;
693           }
694       }
695     if(nofreq)
696         pdf_create_axes(VERTICAL, 0, p99, 5, lx, ly, height);
697     else
698         pdf_create_axes(VERTICAL, 0, binvalsmax, 5, lx, ly, height);
699     pdf_create_axes(HORIZONTAL, binmin , binmax, 5, lx, ly, width);
700     pdf_contents_set_line_width(canvas, delta);
701 
702     x = (float) (delta/1.95);
703     for(i=0;i<numbins;i++)
704       {
705         if(set50[i] == '1')
706             pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0.1, 0.1, 0.1));
707         else
708           {
709             if(set95[i] == '1')
710                 pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0.4, 0.4, 0.4));
711             else
712                 pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0.8, 0.8, 0.8));
713           }
714         if(nofreq)
715           {
716             if(binvals[i]/p99 > 1.0)
717               {
718                 pdf_draw_line(lx+x,ly+0,lx+x,ly + height);
719                 pdf_print_dot(lx+x, ly + height - 3.0, 3, SQUARE, red);
720               }
721             else
722                 pdf_draw_line(lx+x,ly+0,lx+x,ly + binvals[i]/p99 * height);
723           }
724         else
725 	  pdf_draw_line(lx+x,ly+0,lx+x,ly + binvals[i]/binvalsmax * height);
726         //fprintf(stderr,"%f %f %f\n",lx+x,ly+ binvals[i]/binvalsmax * height, binvals[i]);
727 	if(priors !=NULL)
728 	  {
729 #ifdef DEBUG
730 	    if (FALSE)
731 	      printf("pretty.c:730: %f %f %f %f %f %f %f %f\n", x, priors[i], binvals[i], height, priorsmax,
732 		     binvalsmax , binvals[i]/binvalsmax * height , priors[i]/binvalsmax * height);
733 #endif
734 	    if (i>0)
735 	      {
736 		if(i<numbins-1)
737 		  {
738 		    sumprior += (((float) priors[i]/binvalsmax) * height) * delta ;
739 		    sumval += (((float) binvals[i]/binvalsmax) * height) * delta ;
740 		  }
741 		else
742 		  {
743 		    sumprior += (((float) priors[i]/binvalsmax) * height) * delta/2.0 ;
744 		    sumval += (((float) binvals[i]/binvalsmax) * height) * delta/2.0 ;
745 		  }
746 	      }
747 	    else
748 	      {
749 		sumprior += (((float) priors[i]/binvalsmax) * height) * delta/2.0 ;
750 		sumval += (((float) binvals[i]/binvalsmax) * height) * delta/2.0 ;
751 	      }
752 	    pdf_print_dot(lx+x, ly + (((float) priors[i]/binvalsmax) * height) , 1, SQUARE, red);
753 	  }
754 	else
755 	  {
756 	    if (i>0)
757 	      {
758 		if(i<numbins-1)
759 		  {
760 		    sumval += (((float) binvals[i]/binvalsmax) * height) * delta ;
761 		  }
762 		else
763 		  {
764 		    sumval += (((float) binvals[i]/binvalsmax) * height) * delta/2.0 ;
765 		  }
766 	      }
767 	    else
768 	      {
769 		sumval += (((float) binvals[i]/binvalsmax) * height) * delta/2.0 ;
770 	      }
771 	  }
772         x += delta;
773       }
774     //printf ("###########>>>>>>>> %f %f\n", sumval, sumprior);
775     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
776     pdf_contents_set_line_width(canvas, 1);
777 }
778 
779 ///
780 /// create a histogram from bincounts at a specific location and width and height using *std as +-std dev
781 /// If binmax is -9999 then the maximum y-value printed is reset to the 99% percentile.
782 /// If binmax is -999 then the maximum y-value printed is reset to the 100% percentile
783 /// if nofreq is TRUE then the y axes is treated literally and are not scaled
784 /// world is needed for the skyline plots so that we can plot the dots for
785 /// the data points onto the graph.
pdf_histogram_plus(float * binvals,MYREAL * std,char * set50,char * set95,long bins,float bindelta,float binmin,float binmax,float lx,float ly,float width,float height,MYREAL valmax,boolean nofreq,world_fmt * world,float * confidence,long topop)786 void pdf_histogram_plus(float *binvals, MYREAL *std,
787                         char *set50, char *set95,
788                         long bins, float bindelta, float binmin, float binmax,
789                         float lx, float ly, float width, float height,
790                         MYREAL valmax, boolean nofreq, world_fmt * world, float * confidence, long topop)
791 {
792     long locus;
793     long ind;
794     long pop;
795     float ratio;
796     float xcoord;
797     float averagerate=0.;
798     long i;
799     long nbmin;
800     float total=0.0f;
801     float binvalsmax=0.0f;
802     long binvalspos;
803     float p99=0.0f;
804     long pos99= -1;
805     float p100=0.0f;
806     long pos100= -1;
807     float p00=0.0f;
808     long pos00= -1;
809     float p01=0.0f;
810     long pos01= -1;
811     float x = 0.0f;
812     float delta = width / bins;
813     long numbins = bins;
814     //long grouping = 0;
815     float r;
816     float vold=0.;
817     float xold;
818     float *upper;
819     float *lower;
820     MYREAL l;
821     MYREAL v;
822     MYREAL u;
823     //    long k;
824     float blue[3]={0.,0.,0.99};
825     float red[3]={0.99,0.,0.};
826 
827     upper = (float*) mycalloc(numbins,sizeof(float));
828     lower = (float*) mycalloc(numbins,sizeof(float));
829     // setting lower and upper to the mean values;
830     memcpy(upper, binvals,numbins * sizeof(float));
831     memcpy(lower, binvals,numbins * sizeof(float));
832 
833     for(i=0; i< numbins; i++)
834       {
835         upper[i] += fabs(std[i]);
836         lower[i] -= fabs(std[i]);
837         if(lower[i] < 0.0)
838             lower[i] = 0.0;
839       }
840     if(nofreq)
841       {
842         findoutliers(binvals,bins,&p01,&pos01, &p99,
843                      &pos99, &binvalsmax, &binvalspos);
844       }
845     else
846         findmoments(upper,bins,&p01,&pos01, &p99,
847                     &pos99, &binvalsmax, &binvalspos);
848     // fprintf(stdout,"p01=%f, pos01=%li, p99=%f, pos99=%li, binvalsmax=%f, binvalspos=%li\n",p01,pos01, p99,
849     //	    pos99, binvalsmax, binvalspos);
850     total = 0. ;
851     for(i=0;i<bins;i++)
852       {
853         total += (float) upper[i];
854       }
855 
856     if(binmax < -9000)
857       {
858         //find the 99% percentile of the upper limit to show the whole skyline
859         //the closeup should not use this setting because it may be dominated by
860         //few spikes
861         findoutliers(upper,bins,&p01,&pos01, &p99,
862                      &pos99, &binvalsmax, &binvalspos);
863 	if (pos99 <= 0)
864 	  {
865 	    binmax = binmin;
866 	    delta=0.0;
867 	    numbins = 0;
868 	  }
869 	else
870 	  {
871 	    binmax = binmin + pos99 * bindelta;
872 	    delta = width/pos99;
873 	    numbins = pos99;
874 	  }
875       }
876     else
877       {
878         if(binmax < -900)
879           {
880             findminmax_freq_only(upper,bins,&p00,&pos00, &p100,
881                        &pos100);
882 	    if(pos100 <=0 )
883 	      {
884 		binmax=binmin;
885 		delta=0.0;
886 		numbins=0;
887 	      }
888 	      else
889 	      {
890 		binmax = binmin + pos100 * bindelta;
891 		delta = width/pos100;
892 		numbins = pos100;
893 	      }
894 	  }
895       }
896     if(valmax < binvalsmax)
897       {
898 	binvalsmax = valmax;
899       }
900     if(nofreq)
901       {
902         //	if(p99 > 5000.)
903         //  p99 = 5000.;
904         if(binvalsmax < p99)
905             p99 = binvalsmax;
906 
907         pdf_create_axes(VERTICAL, 0, p99, 5, lx, ly, height);
908       }
909     else
910       {
911         pdf_create_axes(VERTICAL, 0, binvalsmax/total, 5, lx, ly, height);
912       }
913     pdf_create_axes(HORIZONTAL, binmin , binmax, 6, lx, ly, width);
914     if(world->options->has_datefile)
915       {
916         ratio = width / (binmax - binmin);
917         for(locus = 0; locus < world->loci; locus++)
918           {
919 	    if(world->bayes->mu)
920 	      averagerate += world->options->meanmu[locus] * world->bayes->histogram[locus].modes[world->numpop2+world->locus];
921 	    else
922 	      averagerate += world->options->meanmu[locus];
923 	  }
924 	averagerate /= world->loci;
925 	pop = topop;
926 	//	for(pop=0; pop < world->numpop; pop++)
927 	//  {
928 	if(world->data->numind != NULL)
929 	  {
930 	    for(ind = 0; ind < world->data->numind[pop][0]; ind++)
931 	      {
932 		xcoord = world->data->sampledates[pop][0][ind].date
933 		  * world->options->generation_year
934 		  * averagerate;
935 		pdf_print_dot(lx+(xcoord * ratio), ly-3.0, 3.0, DIAMOND, blue);
936 	      }
937 	  }
938 	    //  }
939       }
940 
941 
942     //    x = delta/1.95;
943     x = delta/2.0;
944 
945     xold = x;
946     if(nofreq)
947       {
948 	nbmin = (long) MAX(2.,((double) numbins)/50.);//I need a better algorithm! MAX(2.,((double) numbins)/200.);
949 	bayes_smooth(lower,numbins,nbmin, TRUE);
950 	bayes_smooth(binvals,numbins, nbmin, TRUE);
951 	bayes_smooth(upper,numbins, nbmin, TRUE);
952 	//warning("\nNO SMOOTHING for plotting!\n");
953 	vold = binvals[0];
954       }
955     for(i=0;i<numbins;i++)
956       {
957         if(set50[i] == '1')
958             pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0.1, 0.1, 0.1));
959         else
960           {
961             if(set95[i] == '1')
962                 pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0.4, 0.4, 0.4));
963             else
964                 pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0.8, 0.8, 0.8));
965           }
966         if(nofreq)
967           {
968 	    l = lower[i];
969 	    u = upper[i];
970 	    v = binvals[i];
971 	    if(confidence !=NULL && confidence[i]>=1.0)
972 	      {
973 		xold = x;
974 		vold = v;
975 		x += delta;
976 		continue;
977 	      }
978 	    pdf_contents_set_line_width(canvas, delta);
979             if(u/p99 > 1.0)
980               {
981                 if(l/p99 < (1.0 + SMALLEPSILON))
982                   {
983                     pdf_draw_line(lx+x,ly + ((float) l)/p99 * height,
984                                   lx+x,ly + height);
985                   }
986                 pdf_print_dot(lx+x, ly + height, 3, SQUARE, red);
987               }
988             else
989               {
990                 pdf_draw_line(lx+x,ly + ((float) l)/p99 * height,
991                               lx+x,ly + ((float) u)/p99 * height);
992               }
993             pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0.2, 0.2, 0.2));
994 
995             if(((float) v)/p99 < (1.0 + SMALLEPSILON))
996               {
997 		//                pdf_draw_line(lx+x,ly + ((float) v)/p99 * height-1.0F,
998                 //              lx+x,ly + ((float) v)/p99 * height+1.0F);
999 		pdf_contents_set_line_width(canvas, 1.0);
1000                 pdf_draw_line(lx+xold,ly + ((float) vold)/p99 * height,
1001                               lx+x,ly + ((float) v)/p99 * height);
1002 		vold  = v;
1003 		xold = x;
1004               }
1005 	    else
1006 	      {
1007 		if(vold<p99)
1008 		  {
1009 		    pdf_contents_set_line_width(canvas, 1.0);
1010 		    pdf_draw_line(lx+xold,ly + ((float) vold)/p99 * height,
1011 				  lx+x,ly + height);
1012 		  }
1013 		vold  = p99;
1014 		xold = x;
1015 	      }
1016           }
1017         else
1018           {
1019             pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0.8, 0.8, 0.8));
1020             pdf_contents_set_line_width(canvas, delta);
1021             pdf_draw_line(lx+x,ly+0,lx+x,ly + ((float) binvals[i])/binvalsmax * height);
1022             pdf_contents_set_line_width(canvas, delta/3);
1023             pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0.5, 0.5, 0.5));
1024             pdf_draw_line(lx+x,ly+((float) binvals[i])/binvalsmax * height,
1025                           lx+x,ly + ((float) upper[i])/binvalsmax * height);
1026             pdf_draw_line(lx+x,ly+((float) lower[i])/binvalsmax * height,
1027                           lx+x,ly + ((float) binvals[i])/binvalsmax * height);
1028           }
1029         //fprintf(stderr,"%f %f %f\n",lx+x,ly+ binvals[i]/binvalsmax * height, binvals[i]);
1030         if(confidence != NULL)
1031           {
1032             r = confidence[i];
1033 	    if(r>1.0 && r < 0.0)
1034 	      continue;
1035             pdf_contents_set_line_width(canvas, delta);
1036             pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(r,r,r));
1037             pdf_draw_line(lx+x,ly + height+5.0F,
1038                           lx+x,ly + height+10.0F);
1039             //	    pdf_print_dot(lx+x, ly + height + 5, 3, SQUARE, red);
1040           }
1041         x += delta;
1042       }
1043     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
1044     pdf_contents_set_line_width(canvas, 1);
1045     myfree(lower);
1046     myfree(upper);
1047 }
1048 
pdf_master_init(world_fmt * world,option_fmt * options,data_fmt * data)1049 void pdf_master_init(world_fmt *world, option_fmt *options, data_fmt *data)
1050 {
1051         ////////////////////////////////////
1052         pdf_init();
1053         // add first page
1054         pdf_new_page(options->title);
1055         pdf_master_title(options->title,  &page_height, &left_margin);
1056         pdf_print_options(world, options, data, &page_height, &left_margin);
1057 	if(options->datatype!='g')
1058 	  {
1059 	    pdf_print_data_summary(world, options, data,  &page_height, &left_margin);
1060 	    pdf_print_data (world, options, data, &page_height, &left_margin);
1061 	    if(options->murates_fromdata)
1062 	      pdf_print_mutationrate_weights(options->mu_rates, options->segregs, options->wattersons, world->loci);
1063 	  }
1064         ////////////////////////////////////
1065 }
1066 
1067 
pdf_init()1068 int pdf_init()
1069 {
1070     pdf_type1_fontdef font1_def;
1071     pdf_type1_fontdef font2_def;
1072     pdf_type1_fontdef font3_def;
1073     pdf_type1_fontdef font4_def;
1074 
1075     /* Create a new PDF document. */
1076     doc = pdf_doc_new();
1077     pdf_doc_new_doc(doc);
1078 
1079     /* Add Helvetica Font. */
1080     font1_def = pdf_create_type1_fontdef(PDF_FONT_HELVETICA);
1081     pdf_doc_add_type1font(doc, font1_def, NULL, NULL);
1082     /* Add Helvetica-Oblique Font. */
1083     font2_def = pdf_create_type1_fontdef(PDF_FONT_HELVETICA_OBLIQUE);
1084     pdf_doc_add_type1font(doc, font2_def, NULL, NULL);
1085     /* Add Symbol Font. */
1086     font3_def = pdf_create_type1_fontdef(PDF_FONT_SYMBOL);
1087     pdf_doc_add_type1font(doc, font3_def, NULL, NULL);
1088     /* Add Courier Font. */
1089     font4_def = pdf_create_type1_fontdef(PDF_FONT_COURIRE);
1090     pdf_doc_add_type1font(doc, font4_def, NULL, NULL);
1091     return 0;
1092 }
1093 
1094 ///
1095 /// generate a new PDF page with a border rectangle and with page numbers and
1096 /// title in top right corner and impressum at bottom left
pdf_new_page(char * title)1097 int pdf_new_page(char *title)
1098 {
1099     char stemp[LINESIZE];
1100     if(strlen(title)>1)
1101         strncpy(pdf_pagetitle,title,80);
1102     /* Add a page to the document. */
1103     page = pdf_doc_add_page(doc);
1104     page_counter += 1;
1105     /* Get the canvas object of the page. */
1106     canvas = pdf_page_get_canvas(page);
1107 
1108     /*Set current font to "Helvetica" and set the size to 10. */
1109     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1110 
1111     pdf_contents_set_line_width(canvas, 1);
1112     /* draw page rectangle 50pt from border*/
1113     pdf_contents_rectangle(canvas, 50, 50,
1114                            pdf_contents_get_width(canvas) - 100,
1115                            pdf_contents_get_height(canvas) - 110);
1116     pdf_contents_stroke(canvas);
1117     /* print the title of the analysis*/
1118     pdf_print_header(pdf_pagetitle);
1119     /* print the impressum at the bottome*/
1120     sprintf(stemp,"Migrate %s: (http://popgen.sc.fsu.edu) [program run on %s]",MIGRATEVERSION, pdf_time);
1121     pdf_contents_set_font_and_size(canvas, "Helvetica", 6);
1122     pdf_print_contents_at(50, 42, stemp);
1123     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1124     return 0;
1125 }
1126 
1127 
1128 
pdf_print_mutationrate_weights(MYREAL * murates,long * segregs,MYREAL * wattersons,long loci)1129 void pdf_print_mutationrate_weights(MYREAL *murates, long *segregs, MYREAL *wattersons, long loci)
1130 {
1131   float offset[]={55.,150.,280.,380.};
1132   float page_width;
1133   float page_height;
1134   float left_margin=55.0;
1135   char title[]="Relative mutation rate among loci estimated from the data";
1136   long locus;
1137   //long row;
1138   //long rows = loci+2;
1139   //long cols = 4;
1140   float lx = left_margin;
1141   float ly;
1142   char st[100];
1143   float mumean=0.0;
1144   float segregmean=0.0;
1145   float wamean=0.0;
1146   pdf_print_section_title(&page_width, &page_height, title);
1147   ly  = page_height;
1148   pdf_print_line_element(lx, ly, offset[0], "Locus");
1149   pdf_print_line_element(lx, ly, offset[1]-10.0, "Relative");
1150   if(wattersons!=NULL)
1151     {
1152       pdf_print_line_element(lx, ly, offset[2]-7.0, "Watterson's");
1153       symbol_Theta(lx+offset[2],ly ,11, -1);
1154       pdf_print_line_element(lx, ly, offset[3]+10.0, "Segregating");
1155     }
1156   else
1157     {
1158       pdf_print_line_element(lx, ly, offset[2], "Number of alleles");
1159     }
1160   pdf_advance(&page_height);
1161   ly = page_height;
1162   pdf_print_line_element(lx, ly, offset[1], "mutation rate");
1163   if(wattersons!=NULL)
1164     {
1165       pdf_print_line_element(lx, ly, offset[2], "(per site)");
1166       pdf_print_line_element(lx, ly, offset[3], "sites");
1167     }
1168   pdf_advance(&page_height);
1169   ly = page_height;
1170   pdf_draw_line(50, page_height, page_width-50, page_height);
1171   pdf_advance(&page_height);
1172   for (locus=0; locus < loci; locus++)
1173     {
1174       pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1175       sprintf(st,"%5li",locus+1);
1176       pdf_print_line_element(lx, page_height, offset[0], st);
1177       pdf_print_line_element2(lx, page_height, offset[1], murates[locus],5,5);
1178       mumean += (murates[locus] - mumean)/(locus+1);
1179       if(wattersons != NULL)
1180 	{
1181 	  pdf_print_line_element2(lx, page_height, offset[2], wattersons[locus],2,8);
1182 	  sprintf(st,"%6li",segregs[locus]);
1183 	  pdf_print_line_element(lx, page_height, offset[3], st);
1184 	  wamean += (wattersons[locus] - wamean)/(locus+1);
1185 	  segregmean += (segregs[locus] - segregmean)/(locus+1);
1186 	}
1187       else
1188 	{
1189 	  sprintf(st,"%6li",segregs[locus]);
1190 	  pdf_print_line_element(lx, page_height, offset[2], st);
1191 	  segregmean += (segregs[locus] - segregmean)/(locus+1);
1192 	}
1193       pdf_advance(&page_height);
1194     }
1195   sprintf(st,"%6s","All");
1196   pdf_print_line_element(lx, page_height, offset[0], st);
1197   pdf_print_line_element2(lx, page_height, offset[1], mumean,5,5);
1198   if (wattersons!=NULL)
1199     {
1200       pdf_print_line_element2(lx, page_height, offset[2], wamean,2,8);
1201       pdf_print_line_element2(lx, page_height, offset[3], segregmean,5,1);
1202     }
1203   else
1204     pdf_print_line_element2(lx, page_height, offset[2], segregmean,5,1);
1205 }
1206 
1207 ///
1208 /// start a new page and print the section title on top of page
pdf_print_section_title(float * page_width,float * page_height,char * title)1209 void pdf_print_section_title(float *page_width, float * page_height, char *title)
1210 {
1211     float w;
1212     // setup new page and title
1213     pdf_new_page("");
1214     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 18);
1215     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
1216     *page_height = pdf_contents_get_height(canvas) - 75.;
1217     *page_width = pdf_contents_get_width(canvas);
1218     *page_height -= 20.;
1219     pdf_print_contents_at((*page_width - w)/2., *page_height, title);
1220     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
1221     *page_height -= 20.;
1222     pdf_draw_line(50, *page_height, *page_width-50., *page_height);
1223     *page_height -= 20.;
1224     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1225 }
1226 
1227 ///
1228 /// print title on every page with page number
pdf_print_header(char * title)1229 int pdf_print_header(char *title)
1230 {
1231     float w;
1232     float page_height;
1233     float page_width;
1234     char *fulltitle;
1235 
1236     fulltitle = (char*) mycalloc(255,sizeof(char));
1237     /* Print the title of the page (with positioning center). */
1238     sprintf(fulltitle,"%s -- %i",title, page_counter);
1239     //printf("%s\n",fulltitle);
1240     w = (float) pdf_contents_get_text_width(canvas, fulltitle, NULL, NULL);
1241     /* Start to print text. */
1242     pdf_contents_begin_text(canvas);
1243     /* Move the position of the text to center */
1244     page_height = pdf_contents_get_height(canvas);
1245     page_width = pdf_contents_get_width(canvas);
1246     pdf_contents_move_text_pos(canvas, (page_width - w - 50),
1247                                page_height - 50);
1248 
1249     /* Print title with pagenumber to rightadjusted */
1250     pdf_contents_show_text(canvas, fulltitle);
1251     /* Finish to print text. */
1252     pdf_contents_end_text(canvas);
1253 
1254     myfree(fulltitle);
1255 
1256     return 0;
1257 }
1258 
pdf_print_contents_at(float x,float y,char * title)1259 void pdf_print_contents_at(float x, float y, char *title)
1260 {
1261     pdf_contents_begin_text(canvas);
1262     pdf_contents_move_text_pos(canvas, x, y);
1263     pdf_contents_show_text(canvas, title);
1264     pdf_contents_end_text(canvas);
1265     //fprintf(stderr,"(%f, %f) %s\n",x,y,title);
1266 }
1267 
1268 ///
1269 /// print first title page
pdf_master_title(char * title,float * orig_page_height,float * left_margin)1270 int pdf_master_title(char *title, float *orig_page_height, float *left_margin)
1271 {
1272 #ifdef MPI
1273     int cpus;
1274 #endif
1275     float w;
1276     float page_height;
1277     float page_width;
1278     char newtitle[LINESIZE];
1279 
1280     get_time (pdf_time, "%H:%M:%S");
1281 
1282     /* Move the position of the text to center */
1283 
1284     page_height = pdf_contents_get_height(canvas);
1285     page_width = pdf_contents_get_width(canvas);
1286     /* Print the title of the page (with positioning center). */
1287     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 24);
1288 
1289     MYSNPRINTF(newtitle,(long) (page_width-110)/10, "%s",title);
1290     w = (float) pdf_contents_get_text_width(canvas, newtitle, NULL, NULL);
1291     *left_margin = 55;
1292     /* Start to print text. */
1293     pdf_contents_begin_text(canvas);
1294     /* Print title centered */
1295     page_height -= 100;
1296     pdf_print_contents_at((page_width - w)/2, page_height, newtitle);
1297     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
1298     page_height -= 26;
1299     pdf_draw_line(50, page_height, page_width-50, page_height);
1300     pdf_contents_set_font_and_size(canvas, "Helvetica", 12);
1301     page_height -= 24;
1302     pdf_print_contents_at(55, page_height, "MIGRATION RATE AND POPULATION SIZE ESTIMATION");
1303     pdf_advance(&page_height);
1304     pdf_print_contents_at(55, page_height, "using the coalescent and maximum likelihood or Bayesian inference");
1305     pdf_advance(&page_height);
1306     pdf_printf(55, page_height, 'L', "Migrate-n version %s [%s]",MIGRATEVERSION, MIGRATESUBVERSION);
1307 #ifdef BEAGLE
1308     pdf_advance(&page_height);
1309     pdf_printf(55, page_height, 'L',"  Compiled for GPU or other acceleration methods\n");
1310 #endif
1311 #ifdef MPI
1312     pdf_advance(&page_height);
1313     pdf_printf(55, page_height, 'L', "  Compiled for a PARALLEL COMPUTER ARCHITECTURE\n");
1314     pdf_advance(&page_height);
1315     cpus = numcpu - 1;
1316     pdf_printf(55, page_height, 'L', "  One master and %i compute nodes are available.\n", cpus);
1317 #endif
1318 #ifdef THREAD
1319     pdf_advance(&page_height);
1320     pdf_printf(55, page_height, 'L',"  Compiled for a SYMMETRIC MULTIPROCESSORS\n");
1321 #endif
1322 #ifdef GRANDCENTRAL
1323     pdf_advance(&page_height);
1324     pdf_printf(55, page_height, 'L',"  Compiled for a SYMMETRIC MULTIPROCESSORS\n");
1325 #endif
1326 #ifdef ALTIVEC
1327     pdf_advance(&page_height);
1328     pdf_printf(55, page_height,  'L',"  ALTIVEC enabled\n");
1329 #endif
1330 #ifdef FAST_EXP
1331     pdf_advance(&page_height);
1332     pdf_printf(55, page_height,  'L',"  Fast approximation to Exp() and Log() used\n");
1333 #endif
1334     pdf_advance(&page_height);
1335     pdf_print_time(55, &page_height, "Program started at ");
1336     firstcanvas = canvas;
1337     timestampy = page_height;
1338     // here the end time stamp will be printed at the very end the run
1339     pdf_advance(&page_height);
1340     pdf_draw_line(50, page_height, page_width-50, page_height);
1341     // print migrate logo
1342     pdf_contents_set_line_width(canvas, 1);
1343     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
1344     pdf_contents_set_rgb_fill(canvas, PdfRGBColor(0.99, 0, 0));
1345     pdf_migrate_logo(-1410, -1435 - LETTERADJUST, 100.0);
1346     pdf_contents_set_rgb_fill(canvas, PdfRGBColor(0, 0.1, 0.9));
1347     pdf_migrate_logo(-1374, -1435  - LETTERADJUST, 100.0);
1348     pdf_contents_set_line_width(canvas, 4);
1349     pdf_migrate_logo_lines(-1410, -1435 - LETTERADJUST, 100.0);
1350     *orig_page_height = page_height - 3*LINESTRETCH;
1351     return 0;
1352 }
1353 
pdf_write_file(option_fmt * options)1354 int pdf_write_file(option_fmt *options)
1355 {
1356     pdf_doc_write_to_file(doc, options->pdfoutfilename);
1357     return 0;
1358 }
1359 
1360 ///
1361 /// print elements of Bayesian table for character variables
pdf_print_line_element(float lx,float ly,float offset,char * title)1362 float pdf_print_line_element(float lx, float ly, float offset, char *title)
1363 {
1364     float w=0;
1365     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
1366     if(offset>=0)
1367         pdf_print_contents_at(lx+offset-w, ly, title);
1368     else
1369         pdf_print_contents_at(lx-offset, ly, title);
1370     return w;
1371 }
1372 
1373 ///
1374 /// print elements of Bayesian table for float variables
pdf_print_line_element2(float lx,float ly,float offset,float value,int fmt1,int fmt2)1375 float pdf_print_line_element2(float lx, float ly, float offset, float value, int fmt1, int fmt2)
1376 {
1377     float w=0;
1378     char title[100];
1379     sprintf(title,"%*.*f",fmt1,fmt2,value);
1380     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
1381     if(offset>=0)
1382         pdf_print_contents_at(lx+offset-w, ly, title);
1383     else
1384         pdf_print_contents_at(lx-offset, ly, title);
1385     return w;
1386 }
1387 
1388 
pdf_print_line_theta(float lx,float ly,float offset,long j)1389 void pdf_print_line_theta(float lx, float ly, float offset, long j)
1390 {
1391     char tempstring[100];
1392     char * thetatitle="Q";
1393     if(j < 0)
1394         sprintf(tempstring," ");
1395     else
1396         sprintf(tempstring,"%li",j+1);
1397     pdf_contents_set_font_and_size(canvas, "Symbol", 11);
1398     pdf_print_contents_at(lx-offset,ly,thetatitle);
1399     pdf_contents_set_font_and_size(canvas, "Symbol", 8);
1400     pdf_print_contents_at(lx-offset+10,ly-4,tempstring);
1401     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1402 }
1403 
1404 /// print rate line
pdf_print_line_rate(float lx,float ly,float offset,long j,long exponent)1405 void pdf_print_line_rate(float lx, float ly, float offset, long j, long exponent)
1406 {
1407     char tempstring[100];
1408     char * rtitle="m";
1409     if(j < 0)
1410         sprintf(tempstring," ");
1411     else
1412         sprintf(tempstring,"%li",j+1);
1413     pdf_contents_set_font_and_size(canvas, "Symbol", 10);
1414     pdf_print_contents_at(lx-offset,ly,rtitle); // print mu
1415     pdf_contents_set_font_and_size(canvas, "Symbol", 8);
1416     pdf_print_contents_at(lx-offset+10,ly-4,tempstring);//print locus number as subscript
1417 
1418     pdf_contents_set_font_and_size(canvas, "Symbol", 10);
1419     sprintf(tempstring,"[10");
1420     pdf_print_contents_at(lx-offset+13,ly,tempstring); //print the scale should look like this [x10-5]
1421     pdf_contents_set_font_and_size(canvas, "Symbol", 8);
1422     sprintf(tempstring,"%li",exponent);
1423     pdf_print_contents_at(lx-offset+26,ly+4,tempstring); // print the exponent as superscript
1424     pdf_contents_set_font_and_size(canvas, "Symbol", 10);
1425     sprintf(tempstring,"]");
1426     pdf_print_contents_at(lx-offset+35,ly,tempstring);
1427 
1428     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1429 }
1430 
1431 ///
1432 /// pretty print the M values
pdf_print_line_mig(char * migtitle,float lx,float page_height,float offset,long frompop,long topop)1433 void  pdf_print_line_mig(char *migtitle, float lx, float page_height, float offset, long frompop, long topop)
1434 {
1435     float w;
1436     char tostring[100];
1437     char tempstring[100];
1438     if(topop < 0)
1439         sprintf(tostring,"+");
1440     else
1441         sprintf(tostring,"%li",topop+1);
1442     sprintf(tempstring,"%li->%s",frompop+1,tostring);
1443     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1444     pdf_print_contents_at(lx-offset, page_height,migtitle);
1445     w = (float) pdf_contents_get_text_width(canvas, migtitle, NULL, NULL);
1446     pdf_contents_set_font_and_size(canvas, "Helvetica", 8);
1447     pdf_print_contents_at(lx-offset+w,page_height-4,tempstring);
1448     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1449 }
1450 
1451 
1452 ///
1453 /// Print Bayesian table header
1454 /// and report the width of the text in the headerline
pdf_print_bayestableheader(float page_height,float left_margin,float right_margin,float * offset)1455 void pdf_print_bayestableheader(float page_height, float left_margin, float right_margin, float *offset)
1456 {
1457     float lx = left_margin;
1458     float ly = page_height;
1459 
1460     pdf_print_line_element(lx, ly, offset[0], "Locus");
1461     pdf_print_line_element(lx, ly, offset[1], "Parameter");
1462     pdf_print_line_element(lx, ly, offset[2], "2.5%");
1463     pdf_print_line_element(lx, ly, offset[3], "25.0%");
1464     pdf_print_line_element(lx, ly, offset[4], "Mode");
1465     pdf_print_line_element(lx, ly, offset[5], "75.0%");
1466     pdf_print_line_element(lx, ly, offset[6], "97.5%");
1467     pdf_print_line_element(lx, ly, offset[7], "Median");
1468     pdf_print_line_element(lx, ly, offset[8], "Mean");
1469 }
1470 
1471 // Parameter        2.5%%      25.0%%   median    75.0%%   97.5%%     mode     mean\n"
1472 
1473 ///
1474 /// print Bayesian table
pdf_print_bayestable(world_fmt * world)1475 void pdf_print_bayestable(world_fmt *world)
1476 {
1477     int fmt1;
1478     int fmt2;
1479     double mu;
1480     long lmu;
1481     double meanmu;
1482     long j0, j;
1483     long l;
1484     long size = world->numpop2 + (world->bayes->mu);
1485     float lx;
1486     float *offset;
1487     bayes_fmt * bayes = world->bayes;
1488     bayeshistogram_fmt * hist;
1489 
1490     float page_height = pdf_contents_get_height(canvas);
1491     float page_width = pdf_contents_get_width(canvas);
1492 
1493     float left_margin = 60;
1494     float right_margin = page_width - 60;
1495 
1496     //    float w;
1497 
1498     char st[100];
1499     char title[100] = "Bayesian Analysis: Posterior distribution table";
1500     long frompop;
1501     long topop;
1502     long locus;
1503     long lozi = world->loci > 1 ? world->loci : 0;
1504 
1505     //column to to right-align the table columns
1506     offset = (float *) mycalloc(9,sizeof(float));
1507     offset[0] = -1; //left align
1508     offset[1] = -40;
1509     offset[2] = 135;
1510     offset[3] = 191;
1511     offset[4] = 247;
1512     offset[5] = 303;
1513     offset[6] = 359;
1514     offset[7] = 415;
1515     offset[8] = 471;
1516     pdf_print_section_title(&page_width, &page_height, title);
1517     //page_height -= 126;
1518     lx = left_margin;
1519     page_height -= 20;
1520     pdf_draw_line(left_margin, page_height, right_margin, page_height);
1521     pdf_advance(&page_height);
1522     pdf_print_bayestableheader(page_height, left_margin, right_margin, offset);
1523     pdf_advance(&page_height);
1524     pdf_draw_line(left_margin, page_height, right_margin, page_height);
1525     pdf_advance(&page_height);
1526     for(locus=0; locus <= lozi; locus++)
1527       {
1528 	if(!world->data->skiploci[locus])
1529 	  {
1530 	    mu = 1.0; //used to adjust values for rate estimates for others this is 1.
1531 	    hist = &bayes->histogram[locus];
1532 	    if(locus == world->loci)
1533 	      strcpy(st,"  All ");
1534 	    else
1535 	      sprintf(st,"%5li ",locus + 1);
1536 
1537 	    for(j0=0; j0< size; j0++)
1538 	      {
1539 		if(j0 < world->numpop2)
1540 		  {
1541 		    //if(strchr("0c", world->options->custm2[j]))
1542 		    //  continue;
1543 		    if(world->bayes->map[j0][1] == INVALID)
1544 		      continue;
1545 		  }
1546 		j = world->bayes->map[j0][1];
1547 		pdf_print_line_element(lx, page_height, offset[0], st);
1548 		if(j < world->numpop)
1549 		  {
1550 		    pdf_print_line_theta(lx, page_height, offset[1], j0);
1551 		    fmt1 = 8;
1552 		    fmt2 = 5;
1553 		  }
1554 		else
1555 		  {
1556 		    if(j >= world->numpop2)
1557 		      {
1558 			// rate modifier used
1559 			if(locus==lozi && lozi>1)
1560 			  {
1561 			    meanmu = 0.;
1562 			    for(l=0;l<world->loci;l++)
1563 			      {
1564 				meanmu += world->options->meanmu[l];
1565 			      }
1566 			    meanmu /= world->loci;
1567 			    lmu = (long) floor( log10(hist->modes[j] * meanmu));
1568 			    mu = meanmu * pow(10. , -lmu);
1569 			  }
1570 			else
1571 			  {
1572 			    lmu = (long) floor( log10(hist->modes[j]*world->options->meanmu[locus]));
1573 			    mu = world->options->meanmu[locus] * pow(10. , -lmu);
1574 			  }
1575 			pdf_print_line_rate(lx, page_height, offset[1], -1, lmu);
1576 			fmt1 = 8;
1577 			fmt2 = 5;
1578 		      }
1579 		    else
1580 		      {
1581 			m2mm(j0,world->numpop,&frompop, &topop);
1582 			if(world->options->usem)
1583 			  {
1584 			    pdf_print_line_mig("M", lx, page_height, offset[1], frompop, topop);
1585 			    fmt1 = 8;
1586 			    if (strchr (SEQUENCETYPES, world->options->datatype))
1587 			      fmt2 = 1;
1588 			    else
1589 			      fmt2 = 3;
1590 			  }
1591 			else
1592 			  {
1593 			    pdf_print_line_mig("xNm", lx, page_height, offset[1], frompop, topop);
1594 			    fmt1 = 8;
1595 			    fmt2 = 5;
1596 			  }
1597 		      }
1598 		  }
1599 		// reset the to helvetica from symbol or small helvetica
1600 		pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1601 		pdf_print_line_element2(lx, page_height, offset[2], mu * hist->cred95l[j],fmt1,fmt2);
1602 		pdf_print_line_element2(lx, page_height, offset[3], mu * hist->cred50l[j],fmt1,fmt2);
1603 		pdf_print_line_element2(lx, page_height, offset[4], mu * hist->modes[j],fmt1,fmt2);
1604 		pdf_print_line_element2(lx, page_height, offset[5], mu * hist->cred50u[j],fmt1,fmt2);
1605 		pdf_print_line_element2(lx, page_height, offset[6], mu * hist->cred95u[j],fmt1,fmt2);
1606 		pdf_print_line_element2(lx, page_height, offset[7], mu * hist->medians[j],fmt1,fmt2);
1607 		pdf_print_line_element2(lx, page_height, offset[8], mu * hist->means[j],fmt1,fmt2);
1608 		page_height -= LINESTRETCH;
1609 		if(page_height < 55)
1610 		  {
1611 		    pdf_new_page("");
1612 		    page_height = pdf_contents_get_height(canvas);
1613 		    page_width = pdf_contents_get_width(canvas);
1614 		    page_height -= 50;
1615 		    lx = left_margin;
1616 		    page_height -= 20;
1617 		    pdf_draw_line(left_margin, page_height, right_margin, page_height);
1618 		    page_height -= 20;
1619 		    pdf_print_bayestableheader(page_height, left_margin, right_margin, offset);
1620 		    page_height -= 20;
1621 		    pdf_draw_line(left_margin, page_height, right_margin, page_height);
1622 		    pdf_advance(&page_height);
1623 		  }
1624 	      }
1625 	    pdf_draw_line(left_margin, page_height, right_margin, page_height);
1626 	    pdf_advance(&page_height);
1627 	  } // only when loci contains info
1628       } // over all loci
1629     myfree(offset);
1630     pdf_print_citation(&page_height,"Bayesian inference", world);
1631 }
1632 
1633 
1634 ///
1635 /// print out the acceptance ratios for all the different Bayesian updates
1636 void
pdf_bayes_print_accept(world_fmt * world)1637 pdf_bayes_print_accept(world_fmt *world)
1638 {
1639     char title[LINESIZE];
1640     float w;
1641     float left_margin = 55;
1642     float page_width;
1643     long j0,j=0;             //used to loop over all parameters
1644     long topop    =0;   // indicator into the parameter vector, specifying originating population
1645     long frompop  =0;   // receiving population
1646     char *stempo;       // string variable holding print-string
1647     char *stemp;        // pointer to string, seems to be need to don't get MYREAL free warnings
1648     long trials   =0;   //
1649     long tc = world->numpop2 + (world->bayes->mu * world->loci); //position of genealogy accept rates
1650     bayes_fmt *bayes = world->bayes;
1651 
1652     stempo = (char *) mycalloc(LINESIZE,sizeof(char));
1653     stemp = stempo;
1654 
1655     sprintf(title,"Acceptance ratios for all parameters and the genealogies");
1656     pdf_new_page("");
1657     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
1658     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
1659 
1660     /* Start to print text. */
1661     page_height = pdf_contents_get_height(canvas);
1662     page_width = pdf_contents_get_width(canvas);
1663     pdf_print_contents_at((page_width - w)/2, page_height - 100, title);
1664     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
1665     page_height -= 126;
1666     pdf_draw_line(50, page_height, page_width-50, page_height);
1667     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1668 
1669     pdf_advance(&page_height);
1670     pdf_advance(&page_height);
1671 
1672 // This needs more attention but will need more stuff to safe
1673     if(world->options->datatype == 'g')
1674       {
1675 	    pdf_print_contents_at(left_margin, page_height, "not available with datatype=Genealogy");
1676 	    pdf_advance(&page_height);
1677 	    myfree(stempo);
1678 	    return;
1679       }
1680 
1681     pdf_print_contents_at(left_margin, page_height, "Parameter");
1682     pdf_print_contents_at(250, page_height, "Accepted changes");
1683     pdf_print_contents_at(450, page_height, "Ratio");
1684     pdf_advance(&page_height);
1685     pdf_draw_line(50, page_height, page_width-50, page_height);
1686     pdf_advance(&page_height);
1687     // population sizes
1688     for(j0=0; j0 < world->numpop; j0++)
1689       {
1690         if(!strchr("c", bayes->custm2[j0]))
1691           {
1692             j = world->bayes->map[j0][1];
1693             if((trials=world->trials_archive[j])>0)
1694               {
1695                 symbol_Theta(left_margin, page_height, 12, j0+1);
1696                 pdf_printf(250, page_height, 'L', "%8li/%-8li",world->accept_archive[j],trials);
1697                 pdf_printf(450, page_height, 'L', "%8.5f", (MYREAL) world->accept_archive[j]/trials);
1698                 pdf_advance(&page_height);
1699               }
1700           }
1701       }
1702     // migration rates
1703     for(j0=world->numpop; j0 < world->numpop2; j0++)
1704       {
1705         if(!strchr("0c", bayes->custm2[j0]))
1706           {
1707             j = world->bayes->map[j0][1];
1708             if((trials=world->trials_archive[j])>0)
1709               {
1710                 m2mm (j0, world->numpop, &frompop, &topop);
1711                 symbol_M(left_margin, page_height, 12, frompop+1, topop+1, world->options->usem);
1712                 pdf_printf(250, page_height, 'L', "%8li/%-8li",world->accept_archive[j],trials);
1713                 pdf_printf(450, page_height, 'L', "%8.5f", (MYREAL) world->accept_archive[j]/trials);
1714                 pdf_advance(&page_height);
1715                 memset(stemp,0,sizeof(char)*(LINESIZE-1));
1716               }
1717           }
1718       }
1719     // accepted rate of mutation rate changes
1720     if(bayes->mu)
1721       {
1722         if((trials=world->trials_archive[j0])>0)
1723           {
1724 	    for(j=world->numpop2; j < world->numpop2 + world->loci;j++)
1725 	      {
1726 		symbol_R(left_margin, page_height, 12, j+1-world->numpop2);
1727 		pdf_printf(250, page_height, 'L', "%8li/%-8li",world->accept_archive[j0],trials);
1728 		pdf_printf(450, page_height, 'L', "%8.5f", (MYREAL) world->accept_archive[j0]/trials);
1729 		pdf_advance(&page_height);
1730 	      }
1731 	  }
1732       }
1733     // accepted trees
1734     if((trials=world->trials_archive[tc])>0)
1735       {
1736         pdf_printf(left_margin, page_height,'L', "Genealogies");
1737         pdf_printf(250, page_height, 'L', "%8li/%-8li", world->accept_archive[tc], trials);
1738         pdf_printf(450, page_height, 'L', "%8.5f", (MYREAL) world->accept_archive[tc]/ trials);
1739         pdf_advance(&page_height);
1740       }
1741     myfree(stempo);
1742 }
1743 
1744 ///
1745 /// print out the autocorrelation in replicates and the effective sample size
1746 void
pdf_bayes_print_ess(world_fmt * world)1747 pdf_bayes_print_ess(world_fmt *world)
1748 {
1749     char title[LINESIZE];
1750     float w;
1751     float left_margin = 55;
1752     float page_width;
1753     long j0,j=0;             //used to loop over all parameters
1754     long topop    =0;   // indicator into the parameter vector, specifying originating population
1755     long frompop  =0;   // receiving population
1756     char *stempo;       // string variable holding print-string
1757     char *stemp;        // pointer to string, seems to be need to don't get MYREAL free warnings
1758     bayes_fmt *bayes = world->bayes;
1759     stempo = (char *) mycalloc(LINESIZE,sizeof(char));
1760     stemp = stempo;
1761 
1762     sprintf(title,"MCMC-Autocorrelation and Effective MCMC Sample Size");
1763     pdf_new_page("");
1764     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
1765     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
1766 
1767     /* Start to print text. */
1768     page_height = pdf_contents_get_height(canvas);
1769     page_width = pdf_contents_get_width(canvas);
1770     pdf_print_contents_at((page_width - w)/2, page_height - 100, title);
1771     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
1772     page_height -= 126;
1773     pdf_draw_line(50, page_height, page_width-50, page_height);
1774     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1775 
1776     pdf_advance(&page_height);
1777     pdf_advance(&page_height);
1778 
1779     pdf_print_contents_at(left_margin, page_height, "Parameter");
1780     pdf_print_contents_at(250, page_height, "Autocorrelation");
1781     pdf_print_contents_at(450, page_height, "Effective Sampe Size");
1782     pdf_advance(&page_height);
1783     pdf_draw_line(50, page_height, page_width-50, page_height);
1784     pdf_advance(&page_height);
1785     if(world->options->bayes_infer)
1786       {
1787 	// population sizes
1788 	for(j0=0; j0 < world->numpop; j0++)
1789 	  {
1790 	    if(!strchr("c", world->options->custm2[j0]))
1791 	      {
1792 		j = world->bayes->map[j0][1];
1793 		symbol_Theta(left_margin, page_height, 12, j0+1);
1794 		pdf_printf(250, page_height, 'L', "%5.5f",world->auto_archive[j]);
1795 		pdf_printf(450, page_height, 'L', "%10.2f", world->ess_archive[j]);
1796 		pdf_advance(&page_height);
1797 	      }
1798 	  }
1799 	// migration rates
1800 	for(j0=world->numpop; j0 < world->numpop2; j0++)
1801 	  {
1802 	    if(!strchr("0c", bayes->custm2[j0]))
1803 	      {
1804 		j = world->bayes->map[j0][1];
1805 		m2mm (j0, world->numpop, &frompop, &topop);
1806 		symbol_M(left_margin, page_height, 12, frompop+1, topop+1, world->options->usem);
1807 		pdf_printf(250, page_height, 'L', "%5.5f",world->auto_archive[j]);
1808 		pdf_printf(450, page_height, 'L', "%10.2f", world->ess_archive[j]);
1809 		pdf_advance(&page_height);
1810 		memset(stemp,0,sizeof(char)*(LINESIZE-1));
1811 	      }
1812 	  }
1813       }
1814     j = world->numpop2; //adjusting j to fit
1815     // accepted rate of mutation rate changes
1816     if(world->bayes->mu)
1817       {
1818 	for(j=world->numpop2; j < world->numpop2 + world->loci;j++)
1819 	  {
1820 	    symbol_R(left_margin, page_height, 12, j+1-world->numpop2);
1821 	    pdf_printf(250, page_height, 'L', "%5.5f",world->auto_archive[j]);
1822 	    pdf_printf(450, page_height, 'L', "%10.2f", world->ess_archive[j]);
1823 	    pdf_advance(&page_height);
1824 	  }
1825       }
1826     // likelihood of trees
1827     pdf_print_contents_at(left_margin, page_height,"Ln[Prob(D|G)]");
1828     pdf_printf(250, page_height, 'L', "%5.5f",world->auto_archive[j]);
1829     pdf_printf(450, page_height, 'L', "%10.2f", world->ess_archive[j]);
1830 	    pdf_advance(&page_height);
1831 
1832     myfree(stempo);
1833 }
1834 
1835 
1836 ///
1837 /// print out marginal likelihood calculated from thermodynamic integration, harmonic and arithmetic mean.
pdf_bayes_factor_header(world_fmt * world,option_fmt * options)1838 void pdf_bayes_factor_header(world_fmt *world, option_fmt *options)
1839 {
1840     char title[LINESIZE];
1841     float w;
1842     float left_margin = 55;
1843     float page_width;
1844     sprintf(title,"Log-Probability of the data given the model (marginal likelihood)");
1845     pdf_new_page("");
1846     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
1847     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
1848 
1849     /* Start to print text. */
1850     page_height = pdf_contents_get_height(canvas);
1851     page_width = pdf_contents_get_width(canvas);
1852     pdf_print_contents_at((page_width - w)/2, page_height - 100, title);
1853     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
1854     page_height -= 126;
1855     pdf_draw_line(50, page_height, page_width-50, page_height);
1856     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
1857 
1858     pdf_advance(&page_height);
1859     pdf_advance(&page_height);
1860     pdf_printf(left_margin, page_height, 'L', "Use this value for Bayes factor calculations:");
1861     pdf_advance(&page_height);
1862     pdf_printf(left_margin, page_height,'L', "BF = Exp[ ln(Prob(D | thisModel) - ln( Prob( D | otherModel)");
1863     pdf_advance(&page_height);
1864     pdf_printf(left_margin, page_height,'L', "or as LBF = 2 (ln(Prob(D | thisModel) - ln( Prob( D | otherModel))");
1865     pdf_advance(&page_height);
1866     pdf_printf(left_margin, page_height,'L', "shows the support for thisModel]");
1867     pdf_advance(&page_height);
1868     pdf_advance(&page_height);
1869     pdf_draw_line(50, page_height, page_width-50, page_height);
1870     pdf_advance(&page_height);
1871 }
1872 
1873 
pdf_bayes_factor_rawscores_header(world_fmt * world,option_fmt * options)1874 void pdf_bayes_factor_rawscores_header(world_fmt *world, option_fmt *options)
1875 {
1876     float left_margin = 55;
1877     float page_width;
1878     page_width = pdf_contents_get_width(canvas);
1879     pdf_advance(&page_height);
1880     pdf_draw_line(50, page_height, page_width-50, page_height);
1881     pdf_advance(&page_height);
1882     pdf_print_contents_at(left_margin, page_height, "Locus");
1883     pdf_print_contents_at(100, page_height, "Raw thermodynamic score(1a)");
1884     pdf_print_contents_at(250, page_height, "Bezier approximation score(1b)");
1885     pdf_print_contents_at(460, page_height, "Harmonic mean(2)");
1886     pdf_advance(&page_height);
1887     pdf_draw_line(50, page_height, page_width-50, page_height);
1888     pdf_advance(&page_height);
1889 }
1890 
pdf_bayes_factor_rawscores(long locus,MYREAL rawtermo,MYREAL beziertermo,MYREAL harmo)1891 void pdf_bayes_factor_rawscores(long locus, MYREAL rawtermo, MYREAL beziertermo, MYREAL harmo)
1892 {
1893   float page_width;
1894   page_width = pdf_contents_get_width(canvas);
1895   if(locus<0)
1896     {
1897       pdf_draw_line(50, page_height,  page_width-50, page_height);
1898       pdf_advance(&page_height);
1899       pdf_printf_right(left_margin+20, page_height,"All  ");
1900     }
1901   else
1902     pdf_printf_right(left_margin+20, page_height,"%5li", locus+1);
1903   pdf_printf_right(200, page_height,"   %20.2f", rawtermo);
1904   pdf_printf_right(360, page_height,"   %20.2f", beziertermo);
1905   pdf_printf_right(520, page_height,"   %20.2f", harmo);
1906   pdf_advance(&page_height);
1907 }
1908 
pdf_bayes_factor_rawscores_harmo(long locus,MYREAL harmo)1909 void pdf_bayes_factor_rawscores_harmo(long locus, MYREAL harmo)
1910 {
1911   float page_width;
1912   page_width = pdf_contents_get_width(canvas);
1913   if(locus < 0)
1914     {
1915       pdf_draw_line(50, page_height, page_width-50, page_height);
1916       pdf_advance(&page_height);
1917       pdf_printf_right(left_margin+20, page_height,"All  ");
1918     }
1919   else
1920     pdf_printf(left_margin, page_height,'R',"%5li", locus+1);
1921   pdf_draw_line(140, page_height, 150, page_height);
1922   pdf_draw_line(280, page_height, 290, page_height);
1923   pdf_printf_right(520, page_height,"   %20.2f", harmo);
1924   pdf_advance(&page_height);
1925 }
1926 
1927 ///
1928 /// print out marginal likelihood calculated from thermodynamic integration, harmonic and arithmetic mean.
1929 void
pdf_bayes_factor(world_fmt * world,MYREAL tsum,MYREAL tsum2,MYREAL hsum,MYREAL asum,long maxreplicate,MYREAL scaling_factor)1930 pdf_bayes_factor(world_fmt *world,  MYREAL tsum, MYREAL tsum2, MYREAL hsum, MYREAL asum, long maxreplicate, MYREAL scaling_factor)
1931 {
1932     float left_margin = 55;
1933     float page_width;
1934     page_width = pdf_contents_get_width(canvas);
1935     pdf_advance(&page_height);
1936     if(world->loci<=1)
1937       {
1938 	pdf_draw_line(50, page_height, page_width-50, page_height);
1939 	pdf_advance(&page_height);
1940 	pdf_print_contents_at(left_margin, page_height, "Method");
1941 	pdf_print_contents_at(250, page_height, "ln(Prob(D|Model))");
1942 	pdf_print_contents_at(450, page_height, "Notes");
1943 	pdf_advance(&page_height);
1944 	pdf_advance(&page_height);
1945 	pdf_draw_line(50, page_height, page_width-50, page_height);
1946 	pdf_advance(&page_height);
1947 	pdf_print_contents_at(left_margin, page_height, "Thermodynamic integration");
1948 	if(world->options->heating)
1949 	  {
1950 	    pdf_printf(250, page_height,'L',"%f", tsum);
1951 	    pdf_printf(480, page_height,'L',"%s", "(1a)");
1952 	    pdf_print_contents_at(left_margin, page_height, "");
1953 	    pdf_advance(&page_height);
1954 	    pdf_printf(250, page_height,'L',"%f", tsum2);
1955 	    pdf_printf(480, page_height,'L',"%s", "(1b)");
1956 	  }
1957 	else
1958 	  {
1959 	    pdf_printf(250, page_height,'L',"(not estimated [no heating])");
1960 	    pdf_printf(480, page_height,'L',"%s", "(1)");
1961 	  }
1962 	pdf_advance(&page_height);
1963 	pdf_print_contents_at(left_margin, page_height, "Harmonic mean");
1964 	pdf_printf(250, page_height,'L',"%f", hsum);
1965 	pdf_printf(480, page_height,'L',"%s", "(2)");
1966 	pdf_advance(&page_height);
1967 	//pdf_print_contents_at(left_margin, page_height, "Arithmetic mean");
1968 	//pdf_printf(250, page_height,'L',"%f", asum);
1969 	//pdf_printf(480, page_height,'L',"%s", "(3)");
1970 	//pdf_advance(&page_height);
1971 	pdf_draw_line(50, page_height, page_width-50, page_height);
1972 	pdf_advance(&page_height);
1973       }
1974     pdf_printf(left_margin, page_height,'L',"(1a, 1b and 2) are approximations to the marginal likelihood, make sure that the program run long enough!");
1975     pdf_advance(&page_height);
1976     pdf_printf(left_margin, page_height,'L',"(1a, 1b) and (2) should give similar results, in principle.");
1977     pdf_advance(&page_height);
1978     pdf_printf(left_margin, page_height,'L',"But (2) is overestimating the likelihood, it is presented for historical reasons and should not be used");
1979     pdf_advance(&page_height);
1980     pdf_printf(left_margin, page_height,'L',"(1a, 1b) needs heating with chains that span a temperature range of 1.0 to at least 100,000.");
1981     pdf_advance(&page_height);
1982     pdf_printf(left_margin, page_height,'L',"(1b) is using a Bezier-curve to get better approximations for runs with low number of heated chains");
1983     pdf_advance(&page_height);
1984     switch(world->options->adaptiveheat)
1985       {
1986       case STANDARD:
1987         pdf_printf(left_margin, page_height,'L',"%s","Adaptive heating was ON, therefore the values of (1) may be incorrect),");
1988         pdf_advance(&page_height);
1989 	break;
1990       case BOUNDED:
1991         pdf_printf(left_margin, page_height,'L',"%s","Adaptive heating with bounds was ON, therefore the values of (1) may be incorrect),");
1992         pdf_advance(&page_height);
1993 	break;
1994       }
1995     if(world->loci>1)
1996       {
1997 	pdf_printf(left_margin, page_height,'L',"[Scaling factor = %f", scaling_factor);
1998       }
1999     pdf_advance(&page_height);
2000     pdf_print_citation(&page_height, "Marginal likelihood", world);
2001 }
2002 
pdf_burnin_stops(world_fmt * world,long maxreplicate)2003 void pdf_burnin_stops(world_fmt *world, long maxreplicate)
2004 {
2005     long z;
2006     float w;
2007     char title[LINESIZE];
2008     float left_margin = 55;
2009     float page_width;
2010     sprintf(title,"Stop of burnin-in phase due to convergence");
2011     pdf_new_page("");
2012     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
2013     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
2014 
2015     /* Start to print text. */
2016     page_height = pdf_contents_get_height(canvas);
2017     page_width = pdf_contents_get_width(canvas);
2018     pdf_print_contents_at((page_width - w)/2, page_height - 100, title);
2019     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
2020     page_height -= 126;
2021     pdf_draw_line(50, page_height, page_width-50, page_height);
2022     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
2023 
2024     pdf_advance(&page_height);
2025     pdf_advance(&page_height);
2026     pdf_print_contents_at(left_margin, page_height, "Locus");
2027     pdf_print_contents_at(120, page_height, "Replicate");
2028     pdf_print_contents_at(210, page_height, "Steps");
2029     pdf_print_contents_at(310, page_height, "Variance ratio (new/old variance)");
2030     pdf_advance(&page_height);
2031     pdf_advance(&page_height);
2032     pdf_draw_line(50, page_height, page_width-50, page_height);
2033     pdf_advance(&page_height);
2034     for(z=0; z < world->loci * maxreplicate; z++)
2035       {
2036         pdf_printf(left_margin, page_height,'L',"%5li", world->burnin_stops[z].locus);
2037         pdf_printf(120, page_height,'L',"%10li",world->burnin_stops[z].replicate);
2038         pdf_printf(200, page_height,'L',"%10li", world->burnin_stops[z].stopstep);
2039         pdf_printf(310, page_height,'L',"%f", world->burnin_stops[z].variance/world->burnin_stops[z].oldvariance);
2040         pdf_printf(390, page_height,'L',"(%f/%f)",world->burnin_stops[z].variance,
2041                    world->burnin_stops[z].oldvariance);
2042         pdf_advance(&page_height);
2043       }
2044     pdf_advance(&page_height);
2045     pdf_advance(&page_height);
2046 }
2047 
pdf_print_stored_warnings(world_fmt * world)2048 void pdf_print_stored_warnings(world_fmt *world)
2049 {
2050   float w;
2051   char title[LINESIZE];
2052   float left_margin = 55;
2053   float page_width;
2054   char *buffer;
2055   char *b;
2056   char *tmp;
2057   long i=0;
2058   long z=0;
2059   char *section;
2060   char paragraph[] = "This section reports potential problems with your run, but such reporting is often not very accurate. Whith many parameters in a multilocus analysi\
2061 s, it is very common that some parameters for some loci will not be very informative, triggering suggestions (for example to increase the prior ran\
2062 ge) that are not sensible. This suggestion tool will improve with time, therefore do not blindly follow its suggestions. If some parameters are fla\
2063 gged, inspect the tables carefully and judge wether an action is required. For example, if you run a Bayesian inference with sequence data, for mac\
2064 roscopic species there is rarely the need to increase the prior for Theta beyond 0.1; but if you use microsatellites it is rather common that your \
2065 prior distribution for Theta should have a range from 0.0 to 100 or more. With many populations (>3) it is also very common that some migration rou\
2066 tes are estimated poorly because the data contains little or no information for that route. Increasing the range will not help in such situations, \
2067 reducing number of parameters may help in such situations.\0";
2068   section = (char *) mycalloc(LINESIZE,sizeof(char));
2069   sprintf(title,"Potential Problems");
2070   pdf_new_page("");
2071   pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
2072   w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
2073 
2074   /* Start to print text. */
2075   page_height = pdf_contents_get_height(canvas);
2076   page_width = pdf_contents_get_width(canvas);
2077   pdf_print_contents_at((page_width - w)/2, page_height - 100, title);
2078   pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
2079   page_height -= 126;
2080   pdf_draw_line(50, page_height, page_width-50, page_height);
2081   pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
2082 
2083   pdf_advance(&page_height);
2084   pdf_advance(&page_height);
2085   w = 0;
2086   while(paragraph[i]!='\0')
2087     {
2088       section[z]=paragraph[i];
2089       section[z+1] = '\0';
2090       z++;
2091       i++;
2092       w = (float) pdf_contents_get_text_width(canvas, section, NULL, NULL);
2093       if(w >= page_width-110)
2094 	{
2095 	  while(section[z-1]!=' ')
2096 	    {
2097 	      z--;
2098 	      i--;
2099 	    }
2100 	  section[z]='\0';
2101 	  pdf_printf_next(left_margin, &page_height,section);
2102 	  section[0]='\0';
2103 	  z=0;
2104 	}
2105     }
2106   pdf_printf_next(left_margin, &page_height,section);
2107   pdf_advance(&page_height);
2108   pdf_advance(&page_height);
2109   if(world->warningsize > 0)
2110     {
2111       buffer = (char *) mycalloc(strlen(world->warning)+1,sizeof(char));
2112       sprintf(buffer,"%s",world->warning);
2113       b = buffer;
2114       tmp = strsep(&buffer,"\n");
2115       while(tmp!=NULL)
2116 	{
2117 	  pdf_printf(left_margin, page_height,'L',"%s",tmp);
2118 	  pdf_advance(&page_height);
2119 	  tmp = strsep(&buffer,"\n");
2120 	}
2121       myfree(b);
2122     }
2123   else
2124     {
2125       pdf_printf(left_margin, page_height,'L',"No warning was recorded during the run");
2126     }
2127   myfree(section);
2128 }
2129 
2130 
2131 
2132 
2133 /* DEBUG TODO ready to remove this function?*/
2134 #if 0
2135 ///
2136 /// plot migration time histograms, assumes that the ascii_printer has already filled the
2137 /// plotfield table when used with boolean PRECALC (=True)
2138 void
2139 pdf_mig_histogram(histogram_fmt ** histogram,
2140                   plotfield_fmt ** plotfield, long loci, long numparams,
2141                   long bins, long *sum, MYREAL ***migtable,  boolean precalc, world_fmt *world)
2142 {
2143     float left_margin = 55;
2144     //float page_height;
2145     float page_width;
2146     float lx;
2147     float ly;
2148     float ph;
2149 
2150     long loc, i, j, z, zz;
2151     long frompop;
2152     long topop;
2153 
2154     float biggest = 0.;
2155     float *binning;
2156     float *binvec;
2157     float tempmin = MYREAL_MAX;
2158     float tempmax = -MYREAL_MAX;
2159     float begin = MYREAL_MAX;
2160     float end = -MYREAL_MAX;
2161     float delta;
2162 
2163     MYREAL mtime;
2164     char *set50;
2165     char *set95;
2166     long weight;
2167     char title[LINESIZE];
2168     float w;
2169     long bin;
2170     MYREAL *temp;
2171     temp = (MYREAL *) mymalloc(sizeof(MYREAL) * bins);
2172     if (loci > 1)
2173         sprintf(title,"Migration event histogram over all loci");
2174     else
2175         sprintf(title,"Migration event histogram");
2176 
2177     // add a new page so that we can print at least four histograms
2178     pdf_new_page("");
2179     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
2180     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
2181 
2182     /* Start to print text. */
2183     page_height = pdf_contents_get_height(canvas);
2184     page_width = pdf_contents_get_width(canvas);
2185     pdf_print_contents_at((page_width - w)/2, page_height - 100, title);
2186     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
2187     page_height -= 126;
2188     pdf_draw_line(50, page_height, page_width-50, page_height);
2189     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
2190     // first histogram position
2191     page_height -= 150;
2192     lx = 100;
2193     ly = page_height;
2194 
2195     set50 = (char *) mycalloc(bins+1, sizeof(char));
2196     set95 = (char *) mycalloc(bins+1, sizeof(char));
2197     memset (set50, '0', bins * sizeof(char));
2198     memset (set95, '0', bins * sizeof(char));
2199 
2200     binning = (float *) mycalloc (bins+1, sizeof (float));
2201     binvec = (float *) mycalloc (bins+1, sizeof (float));
2202 
2203     for (loc = 0; loc < loci; loc++)
2204       {
2205         for (i = (world->options->mighist_all ? 0 : world->numpop); i < numparams; i++)
2206           {
2207             if (migtable[loc][i][2] == NOAVERAGE)
2208               {
2209                 plotfield[loc][i].print = FALSE;
2210                 continue;
2211               }
2212             minmax (&histogram[loc][i], &tempmin, &tempmax);
2213             if (tempmin < begin)
2214                 begin = tempmin;
2215             if (tempmax > end)
2216                 end = tempmax;
2217           }
2218       }
2219     delta = (end - begin) / bins;
2220     binning[0] = begin + 0.5 * delta;
2221     for (i = 1; i < bins; i++)
2222         binning[i] = delta + binning[i - 1];
2223     if(!precalc)
2224       {
2225         for (loc = 0; loc < loci; loc++)
2226           {
2227 
2228             for (i = (world->options->mighist_all ? 0 : world->numpop); i < numparams; i++)
2229               {
2230                 if (migtable[loc][i][2] == NOAVERAGE)
2231                     continue;
2232                 memset (binvec, 0, sizeof (float) * (bins+1));
2233                 for (j = 0; j < histogram[loc][i].count; j++)
2234                   {
2235                     mtime = histogram[loc][i].time[j];
2236                     weight = histogram[loc][i].weight[j];
2237                     z = 0;
2238                     while (mtime > binning[z] && z < bins)
2239                         z++;
2240                     binvec[z] += weight;
2241                   }
2242                 biggest = 0.;
2243                 for (j = 0; j < bins; j++)
2244                   {
2245                     plotfield[loc][i].y[j] = (long) binvec[j];
2246                     plotfield[loc][i].yfreq[j] = binvec[j] = binvec[j] / sum[loc];
2247                     if (biggest < binvec[j])
2248                         biggest = binvec[j];
2249                   }
2250                 for (j = 0; j < bins; j++)
2251                   {
2252                     for (zz = 0;
2253                          zz <
2254                          (long) (binvec[j] * plotfield[loc][i].ysize / biggest);
2255                          zz++)
2256                         plotfield[loc][i].data[j][zz] = '+';
2257                     plotfield[loc][i].data[j][zz] = '\0';
2258                   }
2259               }
2260           }
2261       }
2262     // plot only overall loci
2263     // keep code that would allow to print everything
2264     for (loc = loci-1; loc < loci; loc++)
2265       {
2266         if (loc == (loci - 1))
2267           {
2268 
2269             //            if (loci > 1)
2270             //     pdf_printf_next(left_margin, &page_height,"Over all loci");
2271             //else
2272             //   pdf_printf_next(left_margin, &page_height,"Locus %li\n",loc + 1);
2273           }
2274         else
2275             pdf_printf_next(left_margin, &page_height,"Locus %li\n",loc + 1);
2276 
2277         for (i0 = (world->options->mighist_all ? 0 : world->numpop); i0 < numparams; i0++)
2278           {
2279             if (plotfield[loc][i0].print)
2280               {
2281                 i = world->bayes->map[i0][1];
2282                 m2mm(i0, world->numpop, &frompop, &topop);
2283                 if(frompop==topop)
2284                   {
2285                     pdf_print_contents_at(lx-30,ly+125,"Freq. for ");
2286                     symbol_Theta(lx+12, ly+125,12,frompop+1);
2287                     pdf_print_contents_at(lx+90,ly-25, "Time [scaled by mutation rate / site / generation]");
2288                   }
2289                 else
2290                   {
2291                     pdf_print_contents_at(lx-30,ly+125,"Freq. for ");
2292                     symbol_M(lx+12, ly+125, 12, frompop+1, topop+1, world->options->usem);
2293                     pdf_print_contents_at(lx+90,ly-25, "Time [scaled by mutation rate / site / generation]");
2294                   }
2295                 pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
2296                 // TODO convert all results and helper-functions to float
2297                 // as we certainly do not print out higher precision than that
2298                 // currentl only plotfield is compliant but pdf_histogram is written
2299                 // the MYREAL that in oter parts of the program needs to be double
2300                 //
2301                 for(bin=0;bin< bins; bin++)
2302                     temp[bin] = (MYREAL) plotfield[loc][i].yfreq[bin];
2303                 //
2304                 pdf_histogram( temp, set50, set95, bins, delta,
2305                               0., -999, lx, ly, page_width - 55 - lx, 116, FALSE);
2306                 page_height -= 160;
2307                 if(i < (numparams-1))
2308                   {
2309                     pdf_page_advance_or_not(&page_height, 50);
2310                     ph = pdf_contents_get_height(canvas) - 55 - LINESTRETCH;
2311                     if(page_height >= ph)
2312                         page_height -= 150;
2313                     ly = page_height;
2314                   }
2315               }
2316           }
2317       }
2318     myfree(binning);
2319     myfree(binvec);
2320     myfree(set50);
2321     myfree(set95);
2322     myfree(temp);
2323 }
2324 
2325 ///
2326 /// print the table header
2327 void pdf_print_mighist_table_header(float lx, const float *offset, const float *roffset,
2328                                     float *page_height, float left_margin, float right_margin)
2329 {
2330     float *ly = page_height;
2331     pdf_draw_line(left_margin, *page_height, right_margin, *page_height);
2332     pdf_advance(page_height);
2333     pdf_print_line_element(lx, *ly, offset[0], "Population");
2334     pdf_print_line_element(lx, *ly, offset[2], "Time");
2335     pdf_print_line_element(lx, *ly, offset[5], "Frequency");
2336     pdf_advance(page_height);
2337     pdf_draw_line(offset[2], *ly, lx+roffset[4], *page_height);
2338     pdf_advance(page_height);
2339     pdf_print_line_element(lx, *ly, offset[0], "From");
2340     pdf_print_line_element(lx, *ly, offset[1], "To");
2341     pdf_print_line_element(lx, *ly, offset[2], "Average");
2342     pdf_print_line_element(lx, *ly, offset[3], "Median");
2343     pdf_print_line_element(lx, *ly, offset[4], "SE");
2344     pdf_advance(page_height);
2345 }
2346 
2347 void
2348 pdf_print_mighist_table (world_fmt * world, MYREAL ***migtable,
2349                          long *total)
2350 {
2351     boolean first=TRUE;
2352     float lx;
2353     float *ly;
2354     float page_height;
2355     float page_width;
2356     //  float w;
2357     float left_margin = 55;
2358     float ph;
2359     float right_margin = pdf_contents_get_width(canvas) - 55;
2360     const     float offset[] = {-1, -40, 135, 191, 247, 303, 359, 415, 471};
2361     const     float roffset[] = {5, 50, 135, 191, 247, 303, 359, 415, 471};
2362     long loc, p1;
2363     long loci1 = world->loci == 1 ? 1 : world->loci + 1;
2364     char title[LINESIZE];
2365     sprintf (title, "Summary of %s events",
2366              world->options->mighist_all ? "coalescence and migration" : "migration");
2367     pdf_print_section_title(&page_width, &page_height, title);
2368     //page_height -= 126;
2369     lx = 55;
2370     page_height -= 20;
2371     //    pdf_draw_line(left_margin, page_height, right_margin, page_height);
2372     pdf_advance(&page_height);
2373     ly = &page_height;
2374     for (loc = 0; loc < world->loci; loc++)
2375         total[world->loci] += total[loc];
2376     first = TRUE;
2377     for (loc = 0; loc < loci1; loc++)
2378       {    /* Each locus + Summary */
2379 
2380         if (loc != world->loci)
2381             sprintf(title, "Locus %li", loc + 1);
2382         else
2383             sprintf(title, "Over all loci");
2384 
2385         pdf_print_contents_at(lx,page_height,title);
2386         pdf_advance(&page_height);
2387 
2388         // table header
2389         if(first)
2390           {
2391             pdf_print_mighist_table_header(lx, offset, roffset,
2392                                            &page_height, left_margin, right_margin);
2393             first=FALSE;
2394           }
2395         else
2396           {
2397             ph = pdf_contents_get_height(canvas) - 55 - LINESTRETCH;
2398             if(page_height >= ph)
2399               {
2400                 pdf_print_mighist_table_header(lx, offset, roffset,
2401                                                &page_height, left_margin, right_margin);
2402               }
2403           }
2404 
2405         for (p1 = (world->options->mighist_all ? 0 : world->numpop); p1 < world->numpop2; p1++)
2406           {
2407             ph = pdf_contents_get_height(canvas) - 55 - LINESTRETCH;
2408             if(page_height >= ph)
2409               {
2410                 pdf_print_mighist_table_header(lx, offset, roffset,
2411                                                &page_height, left_margin, right_margin);
2412               }
2413             if (migtable[loc][p1][2] == NOAVERAGE)
2414               {
2415                 continue;
2416                 //                pdf_printf(lx, ly, 'L',"%4li %4li    No migration event encountered\n",
2417                 //           (long) migtable[loc][p1][0] + 1,
2418                 //           (long) migtable[loc][p1][1] + 1);
2419               }
2420             else
2421               {
2422                 pdf_printf(lx + roffset[0], *ly,'L', "%4li", (long) migtable[loc][p1][0] + 1);
2423                 pdf_printf(lx + roffset[1], *ly,'L', "%4li", (long) migtable[loc][p1][1] + 1);
2424                 pdf_printf_ralign(lx + roffset[2], *ly,"%3.5f",migtable[loc][p1][2]);
2425                 pdf_printf_ralign(lx + roffset[3], *ly,"%3.5f",migtable[loc][p1][3]);
2426                 pdf_printf_ralign(lx + roffset[4], *ly,"%3.5f",migtable[loc][p1][4]);
2427                 pdf_printf_ralign(lx + roffset[5], *ly,"%3.5f",migtable[loc][p1][5] / total[loc]);
2428               }
2429             pdf_advance(&page_height);
2430           }
2431         //        pdf_draw_line(left_margin+offset[2], page_height, left_margin+offset[4], page_height);
2432         pdf_advance(&page_height);
2433         pdf_advance(&page_height);
2434       }
2435 pdf_advance(&page_height);
2436 }
2437 
2438 void
2439 pdf_print_event_table (world_fmt * world, float *migtable)
2440 {
2441     boolean first=TRUE;
2442     float lx;
2443     float *ly;
2444     float page_height;
2445     float page_width;
2446     //  float w;
2447     float left_margin = 55;
2448     float ph;
2449     float right_margin = pdf_contents_get_width(canvas) - 55;
2450     const     float offset[] = {-1, -40, 135, 191, 247, 303, 359, 415, 471};
2451     const     float roffset[] = {5, 50, 135, 191, 247, 303, 359, 415, 471};
2452     long loc, p1;
2453     long loci1 = world->loci == 1 ? 1 : world->loci + 1;
2454     char title[LINESIZE];
2455     long frompop;
2456     long topop;
2457     long migwidth = loci1 * world->numpop2;
2458     sprintf (title, "Summary of %s events",
2459              world->options->mighist_all ? "coalescence and migration" : "migration");
2460     pdf_print_section_title(&page_width, &page_height, title);
2461     //page_height -= 126;
2462     lx = 55;
2463     page_height -= 20;
2464     //    pdf_draw_line(left_margin, page_height, right_margin, page_height);
2465     pdf_advance(&page_height);
2466     ly = &page_height;
2467     first = TRUE;
2468     for (loc = 0; loc < loci1; loc++)
2469       {    /* Each locus + Summary */
2470 
2471         if (loc != world->loci)
2472             sprintf(title, "Locus %li", loc + 1);
2473         else
2474             sprintf(title, "Over all loci");
2475 
2476         pdf_print_contents_at(lx,page_height,title);
2477         pdf_advance(&page_height);
2478 
2479         // table header
2480         if(first)
2481           {
2482             pdf_print_mighist_table_header(lx, offset, roffset,
2483                                            &page_height, left_margin, right_margin);
2484             first=FALSE;
2485           }
2486         else
2487           {
2488             ph = pdf_contents_get_height(canvas) - 55 - LINESTRETCH;
2489             if(page_height >= ph)
2490               {
2491                 pdf_print_mighist_table_header(lx, offset, roffset,
2492                                                &page_height, left_margin, right_margin);
2493               }
2494           }
2495 
2496         for (p1 = (world->options->mighist_all ? 0 : world->numpop); p1 < world->numpop2; p1++)
2497           {
2498             ph = pdf_contents_get_height(canvas) - 55 - LINESTRETCH;
2499             if(page_height >= ph)
2500               {
2501                 pdf_print_mighist_table_header(lx, offset, roffset,
2502                                                &page_height, left_margin, right_margin);
2503               }
2504             m2mm(p1,world->numpop,&frompop,&topop);
2505             pdf_printf(lx + roffset[0], *ly,'L', "%4li", frompop + 1);
2506             pdf_printf(lx + roffset[1], *ly,'L', "%4li", topop + 1);
2507             pdf_printf_ralign(lx + roffset[2], *ly,"%3.5f", migtable[loc * loci1 + p1]);
2508             pdf_printf_ralign(lx + roffset[3], *ly,"%3.5f",migtable[migwidth + loc * loci1 + p1]);
2509             pdf_printf_ralign(lx + roffset[4], *ly,"%3.5f",migtable[2*migwidth + loc * loci1 + p1]);
2510             pdf_printf_ralign(lx + roffset[5], *ly,"%3.5f",migtable[3*migwidth + loc * loci1 + p1]);
2511             pdf_advance(&page_height);
2512           }
2513         //        pdf_draw_line(left_margin+offset[2], page_height, left_margin+offset[4], page_height);
2514         pdf_advance(&page_height);
2515         pdf_advance(&page_height);
2516       }
2517     pdf_advance(&page_height);
2518 }
2519 #endif
2520 /* END DEBUG TODO ready to remove this function?*/
2521 
2522 
2523 ///
2524 /// fill and stroke bezier curve
pdf_fill_stroke(float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4)2525 void pdf_fill_stroke(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
2526 {
2527     pdf_contents_move_to(canvas, x1, y1);
2528     pdf_contents_curve_to(canvas, x2, y2, x3, y3, x4, y4);
2529     pdf_contents_fill_stroke(canvas);
2530 }
2531 
2532 ///
2533 /// plot migrate logo
pdf_migrate_logo(float x,float y,float stretch)2534 void pdf_migrate_logo(float x, float y, float stretch)
2535 {
2536     pdf_contents_move_to(canvas, x + stretch * 18.705982, y + stretch * 21.16717);
2537     pdf_contents_curve_to(canvas, x + stretch * 18.705982,
2538                           y + stretch * 21.234596, x + stretch * 18.779981,y + stretch * 21.289254,
2539                           x + stretch * 18.871266, y + stretch * 21.289254);
2540     pdf_contents_curve_to(canvas, x + stretch * 18.962551,
2541                           y + stretch * 21.289254, x + stretch * 19.03655, y + stretch * 21.234596,
2542                           x + stretch * 19.03655, y + stretch * 21.167171);
2543     pdf_contents_curve_to(canvas, x + stretch * 19.03655,
2544                           y + stretch *  21.099745, x + stretch * 18.962551, y + stretch * 21.045087,
2545                           x + stretch * 18.871266, y + stretch * 21.045087);
2546     pdf_contents_curve_to(canvas, x + stretch * 18.779981,
2547                           y + stretch * 21.045087, x + stretch * 18.705982, y + stretch * 21.099745,
2548                           x + stretch * 18.705982, y + stretch * 21.167171);
2549     pdf_contents_fill_stroke(canvas);
2550 }
2551 
pdf_migrate_logo_lines(float x,float y,float stretch)2552 void pdf_migrate_logo_lines(float x, float y, float stretch)
2553 {
2554     pdf_contents_move_to(canvas, x + stretch * 18.773599, y + stretch * 21.177612);
2555     pdf_contents_line_to(canvas, x + stretch * 18.773599, y + stretch * 20.997156);
2556     pdf_contents_line_to(canvas, x + stretch * 18.882535, y + stretch * 20.997156);
2557     pdf_contents_line_to(canvas, x + stretch * 18.882861, y + stretch * 21.177612);
2558     pdf_contents_stroke(canvas);
2559     pdf_contents_move_to(canvas, x + stretch * 18.979539,  y + stretch * 21.177612);
2560     pdf_contents_line_to(canvas, x + stretch * 18.980202,  y + stretch * 20.948318);
2561     pdf_contents_line_to(canvas, x + stretch * 19.104166,  y + stretch * 20.948318);
2562     pdf_contents_line_to(canvas, x + stretch * 19.10341 ,  y + stretch * 21.177612);
2563     pdf_contents_stroke(canvas);
2564     pdf_contents_move_to(canvas, x + stretch * 19.213683,  y + stretch * 21.177612);
2565     pdf_contents_line_to(canvas, x + stretch * 19.213103,  y + stretch * 20.891974);
2566     pdf_contents_line_to(canvas, x + stretch * 19.045865,  y + stretch * 20.891974);
2567     pdf_contents_line_to(canvas, x + stretch * 19.045865,  y + stretch * 20.948318);
2568     pdf_contents_stroke(canvas);
2569     pdf_contents_move_to(canvas, x + stretch * 19.318285,   y + stretch * 21.177612);
2570     pdf_contents_line_to(canvas, x + stretch * 19.318285,   y + stretch * 20.809329);
2571     pdf_contents_line_to(canvas, x + stretch * 19.132266,   y + stretch * 20.809329);
2572     pdf_contents_line_to(canvas, x + stretch * 19.132521,   y + stretch * 20.890561);
2573     pdf_contents_stroke(canvas);
2574     pdf_contents_move_to(canvas, x + stretch * 19.228543,  y + stretch * 20.645554);
2575     pdf_contents_line_to(canvas, x + stretch * 19.229199,  y + stretch * 20.808985);
2576     pdf_contents_stroke(canvas);
2577     pdf_contents_move_to(canvas, x + stretch * 18.829904,  y + stretch * 20.647076);
2578     pdf_contents_line_to(canvas, x + stretch * 18.829904,  y + stretch * 20.996422);
2579     pdf_contents_stroke(canvas);
2580 
2581 }
2582 
2583 ///
2584 /// print time stamp in pdf
pdf_print_time(float startx,float * pageheight,char text[])2585 void pdf_print_time(float startx, float *pageheight, char text[])
2586 {
2587     char nowstr[LINESIZE];
2588     get_time(nowstr, "  %c");
2589     if (nowstr[0] != '\0')
2590         pdf_printf(startx, *pageheight, 'L',"%s %s", text, nowstr);
2591     pdf_advance(pageheight);
2592 }
2593 
2594 ///
2595 /// prints time stamp for end of run needs pretty.c-global variables firstcanvas and timestampy/// to successfully print timestamp, compare to call of pdf_print_time() function.
pdf_print_end_time(float * page_height)2596 void pdf_print_end_time(float *page_height)
2597 {
2598     pdf_contents thiscanvas = firstcanvas;
2599     char nowstr[LINESIZE];
2600     char *title;
2601     title = (char *) mycalloc(LINESIZE,sizeof(char));
2602 
2603     get_time(nowstr, "  %c");
2604     sprintf(title,"Program finished at %s", nowstr);
2605 
2606     if (nowstr[0] != '\0')
2607       {
2608         pdf_contents_set_font_and_size(thiscanvas, "Helvetica", 12);
2609         pdf_contents_begin_text(thiscanvas);
2610         pdf_contents_move_text_pos(thiscanvas, 55., timestampy);
2611         pdf_contents_show_text(thiscanvas, title);
2612         pdf_contents_end_text(thiscanvas);
2613       }
2614     myfree(title);
2615 }
2616 
2617 ///
2618 /// add a new page and set the master title
pdf_title(char * title,float * page_height,float page_width)2619 void pdf_title(char *title, float *page_height, float page_width)
2620 {
2621     float w;
2622     pdf_new_page("");
2623     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
2624     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
2625     pdf_print_contents_at((page_width - w)/2, *page_height - 100, title);
2626     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
2627     pdf_draw_line(50, *page_height - 126, page_width-50, *page_height - 126);
2628     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
2629     *page_height -= 126.0f;
2630 }
2631 
find_posterior_min_max(float * minval,float * maxval,long start,long stop,bayes_fmt * bayes,long locus)2632 void find_posterior_min_max(float *minval, float *maxval, long start, long stop, bayes_fmt *bayes, long locus)
2633 {
2634     long j, pa0,pa;
2635     long numbins  = 0;
2636     long *bins = bayes->histogram[locus].bins;
2637     float *results = bayes->histogram[locus].results;
2638     MYREAL *mini = bayes->histogram[locus].minima;
2639     MYREAL *maxi = bayes->histogram[locus].maxima;
2640     float p01, p99, mm;
2641     float val;
2642     long pos01, pos99, posmm;
2643     // set all parameter print maxima to the same value for theta and M
2644     *minval  = __FLT_MAX__;
2645     *maxval  = 0.;
2646     for(pa=0;pa < start; pa++)
2647         numbins += bins[pa];
2648     for(pa0=start; pa0 < stop; pa0++)
2649       {
2650         // if custom migration matrix is set to zero
2651         // continue
2652         //if(strchr("0c",bayes->custm2[pa]))
2653         //continue;
2654         if(bayes->map[pa0][1] == INVALID)
2655             continue;
2656         else
2657             pa = bayes->map[pa0][1];
2658         for(j=0;j < pa; j++)
2659             numbins += bins[j];
2660         findmoments(&results[numbins],bins[pa],&p01,&pos01,&p99,&pos99,&mm,&posmm);
2661         if(mini[pa] < *minval)
2662             *minval = mini[pa];
2663         val = pos99 * (maxi[pa]-mini[pa])/bins[pa];
2664         if(val> *maxval)
2665             *maxval = val;
2666         //      numbins += bins[pa];
2667       }
2668 }
2669 
2670 ///
2671 /// plot posterior distribution, returns page_height
pdf_loci_histogram(world_fmt * world)2672 float pdf_loci_histogram(world_fmt *world)
2673 {
2674     bayes_fmt * bayes  = world->bayes;
2675 
2676     long locus         = world->loci > 1 ? world->loci : 0;
2677     long numparam      = world->numpop2 + (world->bayes->mu);
2678     long z             = 0;
2679     long numbins       = 0;
2680     long numbinsall    = 0;
2681     long p99bins       = 0;
2682     long *bins         = bayes->histogram[locus].bins;
2683     long frompop;
2684     long topop;
2685     long pa0, pa=0;
2686     long rpa;
2687     //long j;
2688 
2689     float thetamin     = 0;
2690     float migmin       = 0;
2691     float ratemin      = 0;
2692     float thetamax     = 0;
2693     float migmax       = 0;
2694     float ratemax      = 0;
2695     float page_height  = pdf_contents_get_height(canvas);
2696     float page_width   = pdf_contents_get_width(canvas);
2697     float lx;
2698     float ly;
2699 
2700     char *set50        = bayes->histogram[locus].set50;
2701     char *set95        = bayes->histogram[locus].set95;
2702     char title[100]    = "Bayesian Analysis: Posterior distribution over all loci";
2703 
2704     float delta;
2705     float *results    = bayes->histogram[locus].results;
2706     MYREAL *mini       = bayes->histogram[locus].minima;
2707     MYREAL *maxi       = bayes->histogram[locus].maxima;
2708 
2709     // set the title of the section
2710     pdf_title(title, &page_height, page_width);
2711 
2712     switch(bayes->prettyhist)
2713       {
2714         case PRETTY_MAX:
2715         case PRETTY_P99:
2716         case PRETTY_P100:
2717             break;
2718         default:
2719             find_posterior_min_max(&thetamin, &thetamax, 0, world->numpop, bayes, locus);
2720             find_posterior_min_max(&migmin, &migmax, world->numpop, world->numpop2, bayes, locus);
2721             if(bayes->mu)
2722                 find_posterior_min_max(&ratemin, &ratemax, world->numpop2, numparam, bayes, locus);
2723       }
2724 
2725     lx = 100;
2726     ly = page_height - 190;
2727     numbinsall = 0;
2728     for(pa0=0; pa0 < numparam; pa0++)
2729       {
2730         if(bayes->map[pa0][1] == INVALID)
2731           {
2732             continue;
2733           }
2734         else
2735           {
2736             pa = bayes->map[pa0][1];
2737           }
2738 
2739 	if(pa < pa0)
2740 	  continue; // does not print multiple copies for 'm' and 's'
2741 
2742 	if(pa0>=world->numpop2)
2743 	  {
2744 	    rpa=world->numpop2;
2745 	    pa = pa0;
2746 	  }
2747 	else
2748 	  {
2749 	    rpa=pa;
2750 	  }
2751 	numbinsall += bins[rpa];
2752 	numbins = numbinsall - bins[rpa];
2753         //for(j=0; j < pa; j++)
2754         //  {
2755         //    numbins += bins[j];
2756         //  }
2757         if(pa0<world->numpop2)
2758           {
2759             m2mm(pa0, world->numpop, &frompop, &topop);
2760             if(frompop==topop)
2761               {
2762                 pdf_print_contents_at(lx-30,ly+125, "Freq");
2763                 symbol_Theta(lx+80, ly-25, 12, frompop+1);
2764               }
2765             else
2766               {
2767                 pdf_print_contents_at(lx-30,ly+125, "Freq");
2768                 symbol_M(lx+80, ly-25, 12, frompop+1, topop+1, world->options->usem);
2769               }
2770           }
2771         else
2772           {
2773             pdf_print_contents_at(lx-30,ly+125, "Freq");
2774             symbol_R(lx+80, ly-25, 12, -2);
2775           }
2776         delta = (maxi[rpa] - mini[rpa])/bins[rpa];
2777         switch(bayes->prettyhist)
2778           {
2779             case PRETTY_MAX:
2780 	      pdf_histogram( &results[numbins],&set50[numbins], &set95[numbins],
2781                               bins[pa],(float) delta, (float) mini[rpa], (float) maxi[rpa],lx,ly,187,116, FALSE, &world->bayes->priors[numbins]);
2782                 break;
2783             case PRETTY_P99:
2784 	      pdf_histogram( &results[numbins],&set50[numbins], &set95[numbins],
2785                               bins[rpa],(float) delta, (float) mini[rpa], -9999,lx,ly,187,116, FALSE, &world->bayes->priors[numbins]);
2786                 break;
2787             case PRETTY_P99MAX:
2788                 if(pa < world->numpop)
2789                   {
2790                     p99bins = (long)((thetamax-thetamin)/(float)delta);
2791                     pdf_histogram( &results[numbins],&set50[numbins], &set95[numbins],
2792                                   p99bins,(float) delta, thetamin, thetamax,
2793                                   lx,ly,187,116, FALSE, &world->bayes->priors[numbins]);
2794                   }
2795                 else
2796                   {
2797                     if(pa >= world->numpop2)
2798                       {
2799                         p99bins = (long) ((ratemax - ratemin)/(float)delta);
2800                         pdf_histogram( &results[numbins],&set50[numbins], &set95[numbins],
2801                                       p99bins,(float) delta, ratemin, ratemax,
2802                                       lx,ly,187,116, FALSE, &world->bayes->priors[numbins]);
2803                       }
2804                     else
2805                       {
2806                         p99bins = (long) ((migmax - migmin)/(float)delta);
2807                         pdf_histogram( &results[numbins],&set50[numbins], &set95[numbins],
2808                                       p99bins,(float) delta, migmin, migmax,
2809                                       lx,ly,187,116, FALSE, &world->bayes->priors[numbins]);
2810                       }
2811                   }
2812                 break;
2813             case PRETTY_P100:
2814             default:
2815 	      pdf_histogram( &results[numbins],&set50[numbins], &set95[numbins],
2816 			     bins[rpa],(float) delta, (float) mini[rpa], -999,lx,ly,187,116, FALSE, &world->bayes->priors[numbins]);
2817                 break;
2818 
2819           }
2820         if(z++ % 2 == 0 && world->numpop > 1)
2821 	      {
2822             lx = 350;
2823             ly = page_height - 190;
2824 	      }
2825 	    else
2826 	      {
2827             lx = 100;
2828             page_height -= 180;
2829             if(page_height-50 < 180)
2830               {
2831                 pdf_new_page("");
2832                 page_height = pdf_contents_get_height(canvas) - 10 ;
2833               }
2834             ly = page_height - 190;
2835 	      }
2836         //numbins += bins[pa];
2837       }
2838     return page_height;
2839 }
2840 
2841 ///
2842 /// prints right-adjusted text, based on margin-width x and stay on the line
pdf_printf_right(float x,float y,char string[],...)2843 void pdf_printf_right(float x, float y, char string[],...)
2844 {
2845     //    float     page_width = pdf_contents_get_width(canvas);
2846     float w;
2847     char message[LINESIZE];
2848 	char fp[LINESIZE];
2849 	va_list args;
2850     va_start (args, string);
2851     vsprintf (message, string, args);
2852     va_end (args);
2853     sprintf(fp,"%s",message);
2854     w = (float) pdf_contents_get_text_width(canvas, fp, NULL, NULL);
2855     pdf_print_contents_at(/*page_width-*/x-w, y, fp);
2856 }
2857 
2858 
2859 ///
2860 /// prints right-adjusted text, based on margin-width x and jumps to next line
pdf_printf_right_next(float x,float * y,char string[],...)2861 void pdf_printf_right_next(float x, float *y, char string[],...)
2862 {
2863     float page_width = pdf_contents_get_width(canvas);
2864     float w;
2865     char message[LINESIZE];
2866     char fp[LINESIZE];
2867     va_list args;
2868     va_start (args, string);
2869     vsprintf (message, string, args);
2870     va_end (args);
2871     sprintf(fp,"%s",message);
2872     w = (float) pdf_contents_get_text_width(canvas, fp, NULL, NULL);
2873     pdf_print_contents_at(page_width-x-w, *y, fp);
2874     pdf_advance(y);
2875 }
2876 
2877 ///
2878 /// prints right-aligned mutable text. Like vprintf
pdf_printf_ralign(float rx,float y,char string[],...)2879 void pdf_printf_ralign(float rx, float y, char string[], ...)
2880 {
2881     float w;
2882     char message[LINESIZE];
2883 	char fp[LINESIZE];
2884 	va_list args;
2885     va_start (args, string);
2886     vsprintf (message, string, args);
2887     va_end (args);
2888 	sprintf(fp,"%s",message);
2889     w = (float) pdf_contents_get_text_width(canvas, fp, NULL, NULL);
2890     pdf_print_contents_at(rx-w, y, fp);
2891 }
2892 
2893 
2894 
2895 ///
2896 /// Prints aligned text mutable text; like vprintf.
2897 /// The align parameter defines the alignment of the coordinate
2898 /// when align = 'L' it is left aligned, 'C' center aligned, and 'R' rightaligned
pdf_printf(float x,float y,char align,char string[],...)2899 void pdf_printf(float x, float y, char align, char string[], ...)
2900 {
2901 
2902     char message[LINESIZE];
2903     char fp[LINESIZE];
2904     float w;
2905     va_list args;
2906 
2907     va_start (args, string);
2908     vsprintf (message, string, args);
2909     va_end (args);
2910 
2911     sprintf(fp,"%s",message);
2912 
2913     w = (float) pdf_contents_get_text_width(canvas, fp, NULL, NULL);
2914     switch(align)
2915       {
2916         case 'C':
2917             w /= 2. ;
2918             break;
2919         case 'R':
2920             break;
2921         case 'L':
2922         default:
2923             w = 0.;
2924             break;
2925       }
2926     pdf_print_contents_at(x+w, y, fp);
2927 }
2928 
2929 
2930 ///
2931 /// prints mutable text and advances to next line.
pdf_printf_next(float x,float * y,char string[],...)2932 void pdf_printf_next(float x, float *y, char string[], ...)
2933 {
2934     char message[LINESIZE];
2935 	char fp[LINESIZE];
2936 	va_list args;
2937     va_start (args, string);
2938     vsprintf (message, string, args);
2939     va_end (args);
2940 	sprintf(fp,"%s",message);
2941     pdf_print_contents_at(x, *y, fp);
2942     pdf_advance(y);
2943 }
2944 
2945 ///
2946 /// prints mutable text at x,y and changes x and y when reaching end of line
pdf_printf_cell(float * x,float * y,float width,char string[],...)2947 void pdf_printf_cell(float *x, float *y, float width, char string[], ...)
2948 {
2949     char message[LINESIZE];
2950     char fp[LINESIZE];
2951     float w;
2952     //double ww;
2953     va_list args;
2954 
2955     va_start (args, string);
2956     vsprintf (message, string, args);
2957     va_end (args);
2958     sprintf(fp,"%s",message);
2959     //  pdf_contents_get_char_widths(canvas, fp, &ww);
2960     //w = (float) ww;
2961     w = (float) pdf_contents_get_text_width(canvas, fp, NULL, NULL);
2962     if((w + *x) >=  width)
2963       {
2964         *x = 55;
2965         pdf_advance(y);
2966       }
2967     pdf_print_contents_at(*x, *y, fp);
2968     *x += w+5;
2969 }
2970 
pdf_print_connection_table(float * page_height,world_fmt * world,option_fmt * options,data_fmt * data)2971 void    pdf_print_connection_table (float * page_height, world_fmt * world, option_fmt *options, data_fmt * data)
2972 {
2973     const float offset = 20;
2974     long i;
2975     long j;
2976     long z;
2977     float right_margin = pdf_contents_get_width(canvas) - 2*55 - offset;
2978     float left_margin = 55;
2979     float left_margin2 = 60;
2980     float lx = left_margin + 105;
2981     pdf_advance(page_height);
2982     pdf_printf_next(left_margin, page_height,"Connection type matrix:");
2983     pdf_printf_next (left_margin2, page_height, "where m = average (average over a group of Thetas or M,");
2984     pdf_printf_next (left_margin2, page_height, "s = symmetric M, S = symmetric 4Nm,\n 0 = zero, and not estimated,");
2985     pdf_printf_next (left_margin2, page_height, "* = free to vary, Thetas are on diagonal\n");
2986     pdf_advance(page_height);
2987     pdf_printf (left_margin, *page_height, 'L', "Population");
2988     for (i = 0; i < data->numpop; i++)
2989       {
2990         pdf_printf (lx, *page_height, 'L', "%3li", options->newpops[i]);
2991         lx += offset;
2992         if(lx > right_margin)
2993           {
2994             lx = left_margin + 110;
2995             pdf_advance(page_height);
2996           }
2997       }
2998     //xcode lx = left_margin + 110;
2999     for (i = 0; i < data->numpop; i++)
3000       {
3001         lx = left_margin + 110;
3002         pdf_advance(page_height);
3003         pdf_printf (left_margin, *page_height, 'L', "%3li %-15.15s",options->newpops[i],  data->popnames[i]);
3004         for (j = 0; j < data->numpop; j++)
3005           {
3006             z = mm2m(options->newpops[j]-1,options->newpops[i]-1,world->numpop);
3007             pdf_printf(lx, *page_height, 'L', " %c", world->options->custm2[z]);
3008             lx += offset;
3009             if(lx > right_margin)
3010               {
3011                 lx = left_margin + 90;
3012                 pdf_advance(page_height);
3013               }
3014           }
3015 
3016       }
3017     pdf_advance(page_height);
3018     pdf_advance(page_height);
3019 }
3020 
3021 
3022 ///
3023 /// prints order of parameters for PDF output file
pdf_print_param_order(float * page_height,world_fmt * world)3024 void pdf_print_param_order(float *page_height, world_fmt *world)
3025 {
3026   float left_margin = 60;
3027 
3028   long pa;
3029   long pa0;
3030   long numpop = world->numpop;
3031   long numpop2 = world->numpop2;
3032   long frompop, topop;
3033   long frompop2, topop2;
3034   char *custm2 = world->options->custm2;
3035   boolean usem = world->options->usem;
3036   bayes_fmt *bayes = world->bayes;
3037   long numparam = world->numpop2 + world->bayes->mu;
3038   pdf_advance(page_height);
3039   pdf_printf_next(left_margin, page_height,"Order of parameters:");
3040   //  fprintf(bayesfile,"# Parameter-number Parameter\n");
3041   for(pa0=0;pa0<numparam;pa0++)
3042     {
3043       if(bayes->map[pa0][1] != INVALID)
3044 	{
3045 	  if(pa0 == bayes->map[pa0][1])
3046 	    pa = pa0;
3047 	  else
3048 	    pa = bayes->map[pa0][1];
3049 
3050 	  if(pa0 < numpop)
3051 	    {
3052 	      if((pa0 == pa) && (custm2[pa0] == '*'))
3053 		{
3054 		  pdf_printf(left_margin, *page_height,'L',"%4li ",pa0+1);
3055 		  symbol_Theta(left_margin+80, *page_height,12,pa0+1);
3056 		  pdf_printf(left_margin+230, *page_height,'L',"<displayed>");
3057 		}
3058 	      else
3059 		{
3060 		  pdf_printf(left_margin, *page_height,'L',"%4li ",pa0+1);
3061 		  symbol_Theta(left_margin+80, *page_height,12,pa0+1);
3062 		  pdf_printf(left_margin+120, *page_height,'L'," = ");
3063 		  symbol_Theta(left_margin+150, *page_height,12,pa+1);
3064 		  pdf_printf(left_margin+190, *page_height,'L',"[%c]",custm2[pa0]);
3065 		  if(pa==pa0)
3066 		    pdf_printf(left_margin+230, *page_height,'L',"<displayed>");
3067 		}
3068 	    }
3069 	  else
3070 	    {
3071 	      // do we estimate mutation rate changes?
3072 	      if(pa0 >= numpop2)
3073 		{
3074 		  pdf_printf(left_margin, *page_height,'L',"%4li ",pa0+1);
3075 		  pdf_printf(left_margin+80, *page_height,'L', "Rate");
3076 		  pdf_printf(left_margin+230, *page_height,'L',"<displayed>");
3077 		}
3078 	      else
3079 		{
3080 		  m2mm(pa0,numpop,&frompop,&topop);
3081 		  if((pa0==pa) && (custm2[pa0]=='*'))
3082 		    {
3083 		      if(usem)
3084 			{
3085 			  pdf_printf(left_margin, *page_height,'L',"%4li ",pa0+1);
3086 			  symbol_M(left_margin+80, *page_height,12,frompop+1,topop+1,TRUE);
3087 			  pdf_printf(left_margin+230, *page_height,'L',"<displayed>");
3088 			}
3089 		      else
3090 			{
3091 			  pdf_printf(left_margin, *page_height,'L',"%4li ",pa0+1);
3092 			  symbol_M(left_margin+80, *page_height,12,frompop+1,topop+1,FALSE);
3093 			  pdf_printf(left_margin+120, *page_height,'L'," = ");
3094 			  symbol_Theta(left_margin+150, *page_height,12,topop+1);
3095 			  symbol_M(left_margin+190, *page_height,12,frompop+1,topop+1,TRUE);
3096 			  pdf_printf(left_margin+230, *page_height,'L',"<displayed>");
3097 			}
3098 		    }
3099 		  else
3100 		    {
3101 		      m2mm(pa,numpop,&frompop2,&topop2);
3102 		      if(usem)
3103 			{
3104 			  pdf_printf(left_margin, *page_height,'L',"%4li ",pa0+1);
3105 			  symbol_M(left_margin+80, *page_height,12,frompop+1,topop+1,TRUE);
3106 			  pdf_printf(left_margin+120, *page_height,'L'," = ");
3107 			  symbol_M(left_margin+150, *page_height,12,frompop2+1,topop2+1,TRUE);
3108 			  pdf_printf(left_margin+190, *page_height,'L',"[%c]",custm2[pa0]);
3109 			  if(pa==pa0)
3110 			    pdf_printf(left_margin+230, *page_height,'L',"<displayed>");
3111 			}
3112 		      else
3113 			{
3114 			  symbol_M(left_margin+80, *page_height,12,frompop+1,topop+1,FALSE);
3115 			  pdf_printf(left_margin+120, *page_height,'L'," = ");
3116 			  symbol_Theta(left_margin+150, *page_height,12,topop+1);
3117 			  symbol_M(left_margin+190, *page_height,12,frompop+1,topop+1,TRUE);
3118 			  pdf_printf(left_margin+240, *page_height,'L'," = ");
3119 			  symbol_M(left_margin+290, *page_height,12,frompop2+1,topop2+1,FALSE);
3120 			  pdf_printf(left_margin+330, *page_height,'L'," = ");
3121 			  symbol_Theta(left_margin+350, *page_height,12,topop2+1);
3122 			  symbol_M(left_margin+390, *page_height,12,frompop2+1,topop2+1,TRUE);
3123 			  pdf_printf(left_margin+430, *page_height,'L',"[%c]",custm2[pa0]);
3124 			  if(pa==pa0)
3125 			    pdf_printf(left_margin+460, *page_height,'L',"<displayed>");
3126 
3127 			}
3128 		    }
3129 		}
3130 	    }
3131 	  pdf_advance(page_height);
3132 	}
3133     }
3134   pdf_advance(page_height);
3135   pdf_advance(page_height);
3136 }
3137 
3138 
3139 
pdf_print_distance_table(float * page_height,world_fmt * world,option_fmt * options,data_fmt * data)3140 void    pdf_print_distance_table (float * page_height, world_fmt * world, option_fmt * options, data_fmt * data)
3141 {
3142     const float offset = 60;
3143     long i;
3144     long j;
3145     float right_margin = pdf_contents_get_width(canvas) - 2*55 - offset;
3146     float left_margin = 55;
3147     float lx=left_margin + 80;
3148 
3149     if(!options->geo)
3150         return;
3151 
3152     pdf_advance(page_height);
3153     pdf_printf_next(left_margin, page_height, "Distance among populations:");
3154     pdf_advance(page_height);
3155     pdf_printf (left_margin, *page_height, 'L', "Population");
3156     for (i = 0; i < data->numpop; i++)
3157       {
3158         pdf_printf (lx, *page_height, 'L', "%3li", options->newpops[i]);
3159         lx += offset;
3160         if(lx > right_margin)
3161           {
3162             lx = left_margin + 80;
3163             pdf_advance(page_height);
3164           }
3165       }
3166     for (i = 0; i < data->numpop; i++)
3167       {
3168         lx = left_margin + 80;
3169         pdf_advance(page_height);
3170         pdf_printf (left_margin, *page_height, 'L', "%3li %-15.15s",options->newpops[i],  data->popnames[i]);
3171         for (j = 0; j < data->numpop; j++)
3172           {
3173             pdf_printf(lx, *page_height, 'L', " %10.4f ", data->ogeo[j][i]);
3174             lx += offset;
3175             if(lx > right_margin)
3176               {
3177                 lx = left_margin + 80;
3178                 pdf_advance(page_height);
3179               }
3180           }
3181       }
3182     pdf_advance(page_height);
3183     pdf_advance(page_height);
3184 }
3185 
3186 
3187 
pdf_print_options(world_fmt * world,option_fmt * options,data_fmt * data,float * orig_page_height,float * orig_left_margin)3188 void pdf_print_options(world_fmt * world, option_fmt *options, data_fmt * data, float *orig_page_height, float *orig_left_margin)
3189 {
3190 
3191     float page_width;
3192     float page_height = *orig_page_height;
3193     float left_margin = *orig_left_margin;
3194     float right_margin = 300. ;
3195     float w;
3196     float width[7]={0, 100, 160, 240, 320, 400, 480};
3197     float width2[2]={0, 240};
3198     char *title = "Options";
3199     long i, j, tt, ii;
3200     char mytext[LINESIZE];
3201     char mytext1[LINESIZE];
3202     char mytext2[LINESIZE];
3203     char mytext3[LINESIZE];
3204     char mytext4[LINESIZE];
3205     char seedgen[LINESIZE], spacer[LINESIZE];
3206     char paramtgen[LINESIZE], parammgen[LINESIZE];
3207     boolean inheritance_table = FALSE;
3208     //xcode page_width = pdf_contents_get_width(canvas) - 120;
3209 
3210     if (options->datatype != 'g')
3211       {
3212         switch ((short) options->autoseed)
3213           {
3214             case AUTO:
3215                 strcpy (seedgen, "with internal timer");
3216                 strcpy (spacer, "  ");
3217                 break;
3218             case NOAUTOSELF:
3219                 strcpy (seedgen, "from parmfile");
3220                 strcpy (spacer, "      ");
3221                 break;
3222             case NOAUTO:
3223                 strcpy (seedgen, "from seedfile");
3224                 strcpy (spacer, "      ");
3225                 break;
3226             default:
3227                 strcpy (seedgen, "ERROR");
3228                 strcpy (spacer, " ");
3229                 break;
3230           }
3231         switch (options->thetaguess)
3232           {
3233             case OWN:
3234                 strcpy (paramtgen, "from guessed values");
3235                 break;
3236             case FST:
3237                 strcpy (paramtgen, "from the FST-calculation");
3238                 break;
3239             case NRANDOMESTIMATE:
3240                 strcpy (paramtgen, "RANDOM start value from N(mean,std)");
3241                 break;
3242             case URANDOMESTIMATE:
3243                 strcpy (paramtgen, "RANDOM start value from U(min,msx)");
3244                 break;
3245             default:
3246                 strcpy (paramtgen, "ERROR");
3247                 break;
3248           }
3249         switch (options->migrguess)
3250           {
3251             case OWN:
3252                 strcpy (parammgen, "from guessed values");
3253                 break;
3254             case FST:
3255                 strcpy (parammgen, "from the FST-calculation");
3256                 break;
3257             case NRANDOMESTIMATE:
3258                 strcpy (parammgen, "RANDOM start value from N(mean,std)");
3259                 break;
3260             case URANDOMESTIMATE:
3261                 strcpy (parammgen, "RANDOM start value from U(min,max)");
3262                 break;
3263             default:
3264                 strcpy (parammgen, "ERROR");
3265                 break;
3266           }
3267       }
3268     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 18);
3269     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
3270     page_width = pdf_contents_get_width(canvas);
3271     right_margin = page_width - 55;
3272     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
3273     pdf_contents_set_rgb_fill(canvas, PdfRGBColor(0, 0, 0));
3274     pdf_contents_set_line_width(canvas, 1);
3275     pdf_print_contents_at((page_width - w)/2, page_height, title);
3276     page_height -= 20;
3277     pdf_draw_line(50, page_height, page_width-50, page_height);
3278     page_height -= 20;
3279     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
3280 
3281     switch (options->datatype)
3282       {
3283         case 'a':
3284             pdf_print_contents_at(left_margin, page_height,"Datatype:");
3285             pdf_printf_right_next(left_margin, &page_height,"Allelic data");
3286             pdf_print_contents_at(left_margin, page_height,"Missing data:");
3287             pdf_printf_right_next(left_margin, &page_height,"%s\n",options->include_unknown ? "included" : "not included");
3288             break;
3289         case 'b':
3290             pdf_print_contents_at(left_margin, page_height,"Datatype:");
3291             pdf_printf_right_next(left_margin, &page_height,"Microsatellite data [Brownian motion]\n");
3292             pdf_print_contents_at(left_margin, page_height,"Missing data:");
3293             pdf_printf_right_next(left_margin, &page_height,"%s\n",options->include_unknown ? "included" : "not included");
3294             break;
3295         case 'm':
3296             pdf_print_contents_at(left_margin, page_height,"Datatype:");
3297 	    if(options->msat_option == SINGLESTEP)
3298 	      pdf_printf_right_next(left_margin, &page_height,"Microsatellite data [Singlestep model]\n");
3299 	    else
3300 	      pdf_printf_right_next(left_margin, &page_height,"Microsatellite data [Multistep model (Tune=%f, P_increase=%f)]\n",
3301 							       options->msat_tuning[0], options->msat_tuning[1]);
3302             pdf_print_contents_at(left_margin, page_height,"Missing data:");
3303             pdf_printf_right_next(left_margin, &page_height,"%s\n",options->include_unknown ? "included" : "not included");
3304             break;
3305         case 's':
3306             pdf_print_contents_at(left_margin, page_height,"Datatype:");
3307             pdf_printf_right_next(left_margin, &page_height,"DNA sequence data\n");
3308             break;
3309         case 'n':
3310             pdf_print_contents_at(left_margin, page_height,"Datatype:");
3311             pdf_printf_right_next(left_margin, &page_height,"Single nucleotide polymorphism data\n");
3312             break;
3313         case 'h':
3314             pdf_print_contents_at(left_margin, page_height,"Datatype:");
3315             pdf_printf_right_next(left_margin, &page_height,"Single nucleotide polymorphism data(Hapmap formatting)\n");
3316             break;
3317         case 'u':
3318             pdf_print_contents_at(left_margin, page_height,"Datatype:");
3319             pdf_printf_right_next(left_margin, &page_height,"Single nucleotide polymorphism data (PANEL)\n");
3320             break;
3321         case 'f':
3322             pdf_print_contents_at(left_margin, page_height,"Datatype:");
3323             pdf_printf_right_next(left_margin, &page_height,"Ancestral state method\n");
3324             break;
3325         case 'g':
3326             pdf_print_contents_at(left_margin, page_height,"Datatype:");
3327             pdf_printf_right_next(left_margin, &page_height,"Genealogy summary of an older run\n");
3328             break;
3329       }
3330 
3331     pdf_advance(&page_height);
3332     pdf_print_contents_at(left_margin, page_height,"Inheritance scalers in use for Thetas:");
3333     pdf_advance(&page_height);
3334     //left_margin += pdf_contents_get_text_width(canvas, "Inheritance scalers in use for Thetas: ", NULL, NULL);
3335     for(i=0;i<data->loci;i++)
3336       {
3337 	if(options->inheritance_scalars[i]<1.0 || options->inheritance_scalars[i]>1.0)
3338 	  {
3339 	    inheritance_table = TRUE;
3340 	    break;
3341 	  }
3342       }
3343     if (inheritance_table)
3344       {
3345 	for(i=0;i<data->loci;i++)
3346 	  {
3347 	    if(i<options->inheritance_scalars_numalloc)
3348 	      pdf_printf_cell(&left_margin, &page_height, page_width-55.0, "%2.2f", options->inheritance_scalars[i]);
3349 	    else
3350 	      pdf_printf_cell(&left_margin, &page_height, page_width-55.0, "%2.2f", options->inheritance_scalars[options->inheritance_scalars_numalloc-1]);
3351 	  }
3352       }
3353     else
3354       {
3355 	pdf_print_contents_at(left_margin, page_height,"All loci use an inheritance scaler of 1.0");
3356       }
3357     pdf_advance(&page_height);
3358     left_margin = *orig_left_margin ;
3359     pdf_print_contents_at(left_margin, page_height,"[The locus with a scaler of 1.0 used as reference]");
3360     pdf_advance(&page_height);
3361 
3362 
3363     if(options->randomsubset > 0)
3364       {
3365         pdf_advance(&page_height);
3366 	pdf_print_contents_at(left_margin, page_height,"Data set was subsampled: used a random sample of size:");
3367 	if (options->randomsubsetseed > 0)
3368 	  pdf_printf_right_next(left_margin, &page_height,"%5li and seed %8li", options->randomsubset,options->randomsubsetseed);
3369 	else
3370 	  pdf_printf_right_next(left_margin, &page_height,"%5li", options->randomsubset);
3371         pdf_advance(&page_height);
3372       }
3373 
3374     if (options->datatype != 'g')
3375       {
3376         pdf_print_contents_at(left_margin, page_height,"Random number seed:");
3377         pdf_printf_right_next(left_margin, &page_height,"(%s)%s%20li", seedgen, " ",
3378                               options->saveseed);
3379         pdf_printf_next(left_margin, &page_height,"Start parameters:");
3380         pdf_advance(&page_height);
3381         pdf_print_contents_at(left_margin, page_height,"Theta values were generated");
3382         pdf_printf_right_next(left_margin, &page_height," %s", paramtgen);
3383         if (options->thetaguess == OWN)
3384           {
3385             //xcode ii = 0;
3386             left_margin += 10;
3387             pdf_print_contents_at(left_margin, page_height,"Theta = ");
3388             left_margin += pdf_contents_get_text_width(canvas, "Theta = ", NULL, NULL);
3389             for (i = 0; i < options->numthetag; i++)
3390               {
3391                 pdf_printf_cell(&left_margin, &page_height, page_width-55.0, "%.5f", options->thetag[i]);
3392               }
3393           }
3394 
3395         left_margin = *orig_left_margin ;
3396         pdf_advance(&page_height);
3397 
3398         if(options->usem)
3399             pdf_print_contents_at(left_margin, page_height,"M values were generated");
3400         else
3401             pdf_print_contents_at(left_margin, page_height,"xNm values were generated");
3402 
3403         pdf_printf_right_next(left_margin, &page_height," %s", parammgen);
3404 
3405         left_margin = *orig_left_margin + 10;
3406         if (options->migrguess == OWN)
3407           {
3408             tt = 0;
3409             if (options->usem)
3410                 pdf_print_contents_at(left_margin, page_height,"M-matrix:");
3411             else
3412                 pdf_print_contents_at(left_margin, page_height,"xNm-matrix:");
3413             pdf_advance(&page_height);
3414             if (options->nummg == 1)
3415               {
3416                 pdf_printf_cell(&left_margin, &page_height, page_width-55.0,
3417                                 "%5.2f [all are the same]", options->mg[tt]);//xcode replaced tt++ with tt
3418               }
3419             else
3420               {
3421                 for (i = 0; i < world->numpop; i++)
3422                   {
3423                    //xcode  ii = 0;
3424                     for (j = 0; j < world->numpop; j++)
3425                       {
3426                         if (i != j)
3427                           {
3428                             pdf_printf_cell(&left_margin, &page_height, page_width-55.0,
3429                                             " %5.*f, ",options->usem ? 1 : 5, options->mg[tt++]);
3430                           }
3431                         else
3432                           {
3433                             pdf_printf_cell(&left_margin,
3434                                             &page_height, page_width-55.0, "   -   ");
3435                           }
3436                       }
3437                     left_margin = *orig_left_margin;
3438                     pdf_advance(&page_height);
3439                   }
3440                 left_margin = *orig_left_margin;
3441                 pdf_advance(&page_height);
3442               }
3443           }
3444       }
3445     pdf_print_connection_table (&page_height, world, options, data);
3446     pdf_print_distance_table (&page_height, world, options, data);
3447     pdf_print_param_order(&page_height, world);
3448     left_margin = *orig_left_margin;
3449     if (options->gamma)
3450       {
3451         pdf_print_contents_at(left_margin, page_height,"Mutation rate among loci:");
3452         pdf_printf_right_next(left_margin, &page_height,"from a Gamma distribution\n");
3453         pdf_printf_right_next(left_margin, &page_height,"Initial scale parameter alpha = %f\n",
3454                               options->alphavalue);
3455         if (options->custm[world->numpop2] == 'c')
3456           {
3457             pdf_printf_next(left_margin + 300, &page_height,"and is constant [will not be estimated]\n");
3458           }
3459       }
3460     else
3461       {
3462         if(options->bayesmurates)
3463           {
3464             pdf_printf_right_next(left_margin, &page_height,"Mutation rate is estimated %s", world->loci > 1 ?
3465                                   "for all loci" : "");
3466           }
3467         else
3468           {
3469             pdf_print_contents_at(left_margin, page_height,"Mutation rate among loci:");
3470             if (options->murates && world->loci > 1)
3471               {
3472                 if(options->murates_fromdata)
3473                     pdf_printf_right_next(left_margin, &page_height,"Varying ([crudely] estimated from data)");
3474                 else
3475                     pdf_printf_right_next(left_margin, &page_height,"Varying (user input)");
3476                 pdf_print_contents_at(left_margin + 10, page_height,"Rates per locus: ");
3477                 ii=0;
3478                 for (i = 0; i < world->loci-1; i++)
3479                   {
3480                     sprintf(mytext,"%.5f, ", options->mu_rates[i]);
3481                     if (i % 6 == 5)
3482                       {
3483                         ii=0;
3484                         pdf_advance(&page_height);
3485                         pdf_print_contents_at(left_margin + 100 + ii * 60, page_height,mytext);
3486                       }
3487                     else
3488                       {
3489                         pdf_print_contents_at(left_margin + 100 + ii * 60, page_height,mytext);
3490                       }
3491                     ii++;
3492                   }
3493                 if(i % 6 == 5)
3494                   {
3495                     ii=0;
3496                     pdf_advance(&page_height);
3497                   }
3498                 pdf_printf_next(left_margin + 100 + ii * 60, &page_height,"%.5f", options->mu_rates[i]);
3499               }
3500             else
3501                 pdf_printf_right_next(left_margin, &page_height,"Mutation rate is constant %s", world->loci > 1 ?
3502                                       "for all loci" : "");
3503           }
3504       }
3505 #ifdef UEP
3506     if (options->uep)
3507       {
3508         pdf_printf_next(left_margin, &page_height,"0/1 polymorphism analysis, with 0/1 data in file:");
3509         pdf_printf_right_next(left_margin, &page_height,"%s\n", options->uepfilename);
3510         pdf_printf_right_next(left_margin, &page_height,"with forward mutation rate %f*mu\n",
3511                               options->uepmu);
3512         pdf_printf_right_next(left_margin, &page_height,"with back mutation rate %f*mu\n",
3513                               options->uepnu);
3514         pdf_printf_right_next(left_margin, &page_height,"with base frequencies \"0\"=%f and \"1\"=%f\n",
3515                               options->uepfreq0,options->uepfreq1);
3516       }
3517 #endif
3518     pdf_advance(&page_height);
3519 
3520     if(options->bayes_infer)
3521       {
3522         pdf_print_contents_at(left_margin, page_height,"Analysis strategy:");
3523         pdf_printf_right_next(left_margin, &page_height,"Bayesian inference");
3524         pdf_advance(&page_height);
3525 
3526         pdf_print_contents_at(left_margin, page_height,"Proposal distributions for parameter");
3527         pdf_advance(&page_height);
3528         pdf_print_tableline(&page_height, width2, "%s %s", "Parameter", "Proposal");
3529         pdf_advance(&page_height);
3530         pdf_print_tableline(&page_height, width2, "%s %s", "Theta",
3531                             is_proposaltype(options->slice_sampling[THETAPRIOR]));
3532         pdf_advance(&page_height);
3533         pdf_print_tableline(&page_height, width2, "%s %s", options->usem ? "M" : "xNm",
3534                             is_proposaltype(options->slice_sampling[MIGPRIOR]));
3535         pdf_advance(&page_height);
3536         if(options->bayesmurates)
3537           {
3538             pdf_print_tableline(&page_height, width2, "%s %s", "Rate",
3539                                 is_proposaltype(options->slice_sampling[RATEPRIOR]));
3540             pdf_advance(&page_height);
3541           }
3542         pdf_advance(&page_height);
3543 
3544         pdf_print_contents_at(left_margin, page_height,"Prior distribution for parameter");
3545         pdf_advance(&page_height);
3546         pdf_print_tableline(&page_height, width, "%s %s %s %s %s %s %s", "Parameter", "Prior", "Minimum",  "Mean*",  "Maximum", "Delta", "Bins");
3547         pdf_advance(&page_height);
3548         pdf_print_tableline(&page_height, width, "%s %s %s %s %s %s %s", "Theta",
3549                             is_priortype(options->bayesprior[THETAPRIOR]),
3550                             show_priormin(mytext1, options->bayespriortheta,options->bayesprior[THETAPRIOR]),
3551                             show_priormean(mytext2, options->bayespriortheta,options->bayesprior[THETAPRIOR]),
3552                             show_priormax(mytext3, options->bayespriortheta,options->bayesprior[THETAPRIOR]),
3553                             show_priordelta(mytext4,options->bayespriortheta,options->bayesprior[THETAPRIOR]),
3554                             show_priorbins(mytext, options->bayespriortheta,options->bayesprior[THETAPRIOR]));
3555         pdf_advance(&page_height);
3556 
3557         pdf_print_tableline(&page_height, width, "%s %s %s %s %s %s %s", options->usem ? "M" : "xNm",
3558                             is_priortype(options->bayesprior[MIGPRIOR]),
3559                             show_priormin(mytext1, options->bayespriorm,options->bayesprior[MIGPRIOR]),
3560                             show_priormean(mytext2, options->bayespriorm,options->bayesprior[MIGPRIOR]),
3561                             show_priormax(mytext3, options->bayespriorm,options->bayesprior[MIGPRIOR]),
3562                             show_priordelta(mytext4, options->bayespriorm,options->bayesprior[MIGPRIOR]),
3563                             show_priorbins(mytext, options->bayespriorm,options->bayesprior[MIGPRIOR]));
3564         pdf_advance(&page_height);
3565         if(options->bayesmurates)
3566           {
3567             pdf_print_tableline(&page_height, width, "%s %s %s %s %s %s %s", "Rate modif.",
3568                                 is_priortype(options->bayesprior[RATEPRIOR]),
3569 				show_priormin(mytext1, options->bayespriorrate,options->bayesprior[RATEPRIOR]),
3570 				show_priormean(mytext2, options->bayespriorrate,options->bayesprior[RATEPRIOR]),
3571 				show_priormax(mytext3, options->bayespriorrate,options->bayesprior[RATEPRIOR]),
3572 				show_priordelta(mytext4, options->bayespriorrate,options->bayesprior[RATEPRIOR]),
3573 				show_priorbins(mytext, options->bayespriorrate,options->bayesprior[RATEPRIOR]));
3574             pdf_advance(&page_height);
3575           }
3576         pdf_advance(&page_height);
3577       }
3578     else
3579       {
3580         pdf_print_contents_at(left_margin, page_height,"Analysis strategy is");
3581         pdf_printf_right_next(left_margin, &page_height,"Maximum likelihood");
3582       }
3583 
3584     pdf_advance(&page_height);
3585 
3586     if (options->datatype != 'g')
3587       {
3588         pdf_print_contents_at(left_margin, page_height,"Markov chain settings:");
3589         if(!options->bayes_infer)
3590             pdf_print_contents_at(left_margin + 300, page_height,"Short chain");
3591         pdf_printf_right_next(left_margin, &page_height, "Long chain");
3592         pdf_print_contents_at(left_margin, page_height,"Number of chains");
3593         if(!options->bayes_infer)
3594             pdf_printf_ralign(left_margin + 340, page_height,"%20li", options->schains);
3595         pdf_printf_right_next(left_margin+10, &page_height,"%20li", options->lchains);
3596 
3597         pdf_print_contents_at(left_margin + 10, page_height,"Recorded steps [a]");
3598         if(!options->bayes_infer)
3599             pdf_printf_ralign(left_margin + 340, page_height,"%20li", options->ssteps);
3600         pdf_printf_right_next(left_margin + 10, &page_height,"%20li", options->lsteps);
3601 
3602         pdf_print_contents_at(left_margin + 10, page_height,"Increment (record every x step [b]");
3603         if(!options->bayes_infer)
3604             pdf_printf_ralign(left_margin + 340, page_height,"%20li", options->sincrement);
3605         pdf_printf_right_next(left_margin+10, &page_height,"%20li", options->lincrement);
3606         if(options->bayes_infer)
3607           {
3608             pdf_print_contents_at(left_margin + 10, page_height,"Number of concurrent chains (replicates) [c]");
3609             pdf_printf_ralign(left_margin + 340, page_height," ");
3610             pdf_printf_right_next(left_margin + 10, &page_height,"%20li", options->replicate ?
3611                                   options->replicatenum : 1);
3612             pdf_print_contents_at(left_margin + 10, page_height,"Visited (sampled) parameter values [a*b*c]");
3613             // pdf_printf_ralign(left_margin + 340, page_height,"%20li",
3614             //                  options->ssteps * options->sincrement*(options->replicate ? options->replicatenum : 1));
3615             pdf_printf_right_next(left_margin + 10, &page_height,"%20li", options->lsteps * options->lincrement*(options->replicate ? options->replicatenum : 1));
3616           }
3617         else
3618           {
3619             pdf_print_contents_at(left_margin + 10, page_height,"Visited (sampled) genealogies [a*b]");
3620             pdf_printf_ralign(left_margin + 340, page_height,"%20li", options->ssteps * options->sincrement);
3621             pdf_printf_right_next(left_margin + 10, &page_height,"%20li", options->lsteps * options->lincrement);
3622 
3623           }
3624         if (options->burn_in > 0)
3625           {
3626             pdf_print_contents_at(left_margin + 10, page_height,"Number of discard trees per chain (burn-in)");
3627             if(!options->bayes_infer)
3628 	      pdf_printf(left_margin + 320, page_height,'L', "%c%li",  options->burnin_autostop, (long) options->burn_in);
3629             else
3630 	      pdf_printf_right_next(left_margin + 10, &page_height,"%c%li", options->burnin_autostop, (long) options->burn_in);
3631           }
3632         if (options->movingsteps)
3633           {
3634             pdf_print_contents_at(left_margin + 10, page_height,"Forcing percentage of new genealogies");
3635              //    pdf_printf(left_margin + 360, page_height,"%5.2f",   (MYREAL) options->acceptfreq);
3636             pdf_printf_right_next(left_margin + 10, &page_height,"%5.2f",   (MYREAL) options->acceptfreq);
3637           }
3638         if (options->lcepsilon < LONGCHAINEPSILON)
3639           {
3640             pdf_print_contents_at(left_margin + 10, page_height,"Forcing parameter-likelihood improvement");
3641             //    pdf_printf(left_margin + 360, page_height,"%20.5f",   (MYREAL) options->lcepsilon);
3642             pdf_printf_right_next(left_margin + 10, &page_height,"%20.5f",   (MYREAL) options->lcepsilon);
3643           }
3644 
3645         pdf_advance(&page_height);
3646 
3647         if(options->replicate && !options->bayes_infer)
3648             pdf_printf_next(left_margin, &page_height,"Multiple Markov chains:");
3649         else
3650           {
3651             if(options->heating > 0)
3652                 pdf_printf_next(left_margin, &page_height,"Multiple Markov chains:");
3653           }
3654         if (options->replicate && !options->bayes_infer)
3655           {
3656             pdf_print_contents_at(left_margin + 10, page_height,"Averaging over replicates");
3657             if (options->replicatenum == 0)
3658                 pdf_printf_right_next(left_margin, &page_height,"Long chains only");
3659             else
3660                 pdf_printf_right_next(left_margin, &page_height,"Over indepedent %li replicates", options->replicatenum);
3661           }
3662 
3663         if (options->heating > 0)
3664           {
3665             pdf_printf(left_margin+10, page_height,'L', "%s heating scheme", options->adaptiveheat!=NOTADAPTIVE ? ( options->adaptiveheat==STANDARD ? "Adaptive_standard" : "Bounded_adaptive") : "Static");
3666             pdf_printf_right_next(left_margin, &page_height, "%li chains with %s temperatures",
3667                                   options->heated_chains, options->adaptiveheat!=NOTADAPTIVE ? "start values" : "" );
3668             for (i = options->heated_chains - 1; i >= 0; i--)
3669                 pdf_printf_right(right_margin - i * 50, page_height,"%5.2f ", options->heat[i]);
3670             pdf_advance(&page_height);
3671 
3672             pdf_printf_right_next(left_margin, &page_height,"Swapping interval is %li\n",
3673                                   options->heating_interval);
3674           }
3675       }
3676 
3677     pdf_advance(&page_height);
3678     pdf_printf_next(left_margin, &page_height,"Print options:\n");
3679     if (options->datatype != 'g')
3680       {
3681         pdf_print_contents_at(left_margin + 10, page_height,"Data file:");
3682         pdf_printf_right_next(left_margin, &page_height,"%s", options->infilename);
3683         pdf_print_contents_at(left_margin + 10, page_height,"Output file:");
3684         pdf_printf_right_next(left_margin, &page_height,"%s", options->outfilename);
3685         if(options->writesum)
3686           {
3687             pdf_print_contents_at(left_margin + 10, page_height,"Summary of genealogies for further run:");
3688             pdf_printf_right_next(left_margin, &page_height,"%s", options->sumfilename);
3689           }
3690         if(options->writelog)
3691           {
3692             pdf_print_contents_at(left_margin + 10, page_height,"Log file:");
3693             pdf_printf_right_next(left_margin, &page_height,"%s", options->logfilename);
3694           }
3695 
3696         if(options->bayes_infer)
3697           {
3698             pdf_print_contents_at(left_margin + 10, page_height,"Posterior distribution raw histogram file:");
3699             pdf_printf_right_next(left_margin, &page_height,"%s\n", options->bayesfilename);
3700           }
3701 
3702         pdf_print_contents_at(left_margin + 10, page_height,"Print data:");
3703         pdf_printf_right_next(left_margin, &page_height,"%45.45s", options->printdata ? "Yes" : "No");
3704 
3705         pdf_printf(left_margin + 10, page_height,'L', "Print genealogies [only some for some data type]:");
3706         switch (options->treeprint)
3707           {
3708             case _NONE:
3709                 pdf_printf_right_next(left_margin, &page_height,"None");
3710                 break;
3711             case ALL:
3712                 pdf_printf_right_next(left_margin, &page_height,"Yes, all");
3713                 break;
3714             case LASTCHAIN:
3715                 pdf_printf_right_next(left_margin, &page_height,"Yes, only those in last chain");
3716                 break;
3717             case BEST:
3718                 pdf_printf_right_next(left_margin, &page_height,"Yes, only the best");
3719                 break;
3720           }
3721         if (options->mighist)
3722           {
3723             pdf_print_contents_at(left_margin + 10, page_height,"Histogram of the frequency of migration events");
3724             pdf_printf_right_next(left_margin, &page_height,"%s", options->mighistfilename);
3725           }
3726       }
3727     else
3728       {
3729         pdf_print_contents_at(left_margin + 10, page_height,"Data file:");
3730         pdf_printf_right_next(left_margin, &page_height,"%s", options->infilename);
3731         pdf_print_contents_at(left_margin + 10, page_height,"Output file:");
3732         pdf_printf_right_next(left_margin, &page_height,"%s", options->outfilename);
3733       }
3734     if(!options->bayes_infer)
3735       {
3736         pdf_print_contents_at(left_margin + 10, page_height,"Plot log(likelihood) surface:");
3737         if (options->plot)
3738           {
3739             switch (options->plotmethod)
3740               {
3741                 case PLOTALL:
3742                     sprintf (mytext, "Yes, to outfile and %s", options->mathfilename);
3743                     break;
3744                 default:
3745                     strcpy (mytext, "Yes, to outfile");
3746                     break;
3747               }
3748             pdf_printf_right_next(left_margin, &page_height,"%s\n", mytext);
3749             pdf_printf_right_next(left_margin, &page_height,
3750                                   "Parameter: %s, Scale: %s, Intervals: %li\n",
3751                                   options->plotvar == PLOT4NM ? "{Theta, 4Nm}" : "{Theta, M}",
3752                                   options->plotscale == PLOTSCALELOG ? "Log10" : "Standard",
3753                                   options->plotintervals);
3754             pdf_printf_right_next(left_margin, &page_height,"Ranges: X-%5.5s: %f - %f\n",
3755                                   options->plotvar == PLOT4NM ? "4Nm" : "M",
3756                                   options->plotrange[0], options->plotrange[1]);
3757             pdf_printf_right_next(left_margin, &page_height,"Ranges: Y-%5.5s: %f - %f\n", "Theta",
3758                                   options->plotrange[2], options->plotrange[3]);
3759           }
3760         else
3761           {
3762             pdf_printf_right_next(left_margin, &page_height,"No");
3763           }
3764         switch (options->profile)
3765           {
3766             case _NONE:
3767                 strcpy (mytext, "No");
3768                 break;
3769             case ALL:
3770                 strcpy (mytext, "Yes, tables and summary");
3771                 break;
3772             case TABLES:
3773                 strcpy (mytext, "Yes, tables");
3774                 break;
3775             case SUMMARY:
3776                 strcpy (mytext, "Yes, summary");
3777                 break;
3778           }
3779         pdf_printf(left_margin+10, page_height,'L', "Profile likelihood:");
3780         pdf_printf_right_next(left_margin, &page_height,"%s", mytext);
3781 
3782         if (options->profile != _NONE)
3783           {
3784             switch (options->profilemethod)
3785               {
3786                 case 'p':
3787                     pdf_printf_right_next(left_margin, &page_height,"Percentile method\n");
3788                     break;
3789                 case 'q':
3790                     pdf_printf_right_next(left_margin, &page_height,"Quick method\n");
3791                     break;
3792                 case 'f':
3793                     pdf_printf_right_next(left_margin, &page_height,"Fast method\n");
3794                     break;
3795                 case 'd':
3796                     pdf_printf_right_next(left_margin, &page_height,"Discrete method\n");
3797                     break;
3798                 case 's':
3799                     pdf_printf_right_next(left_margin, &page_height,"Spline method\n");
3800                     break;
3801                 default:
3802                     pdf_printf_right_next(left_margin, &page_height,"UNKOWN method????\n");
3803                     break;
3804               }
3805             pdf_printf_right_next(left_margin, &page_height,"with df=%li and for Theta and %s",
3806                                   options->df, options->profileparamtype ? "M=m/mu" : "4Nm");
3807           }
3808       }
3809     *orig_page_height = page_height;
3810     *orig_left_margin = left_margin;
3811 }
3812 
3813 
pdf_print_data_summary(world_fmt * world,option_fmt * options,data_fmt * data,float * orig_page_height,float * orig_left_margin)3814 void pdf_print_data_summary(world_fmt * world, option_fmt *options, data_fmt * data,
3815                             float *orig_page_height, float *orig_left_margin)
3816 {
3817     long locus;
3818     long pop;
3819     long numind;
3820     long nummiss;
3821     char dstring[LINESIZE];
3822     long *total;
3823     long *totalmiss;
3824     char *title = "Data summary";
3825     //    float w;
3826     float page_height = *orig_page_height;
3827     float left_margin = *orig_left_margin;
3828     float page_width;
3829 
3830 
3831     float col1 = left_margin + 300;
3832     float col2 = left_margin + 320;
3833     float col3 = left_margin + 400;
3834 
3835 
3836     total = (long *) mycalloc(data->loci,sizeof(long));
3837     totalmiss = (long *) mycalloc(data->loci,sizeof(long));
3838     // setup new page and title
3839     pdf_print_section_title(&page_width, &page_height, title);
3840     switch (options->datatype)
3841       {
3842         case 'a':
3843             strcpy (dstring, "Allelic data");
3844             break;
3845         case 'f':
3846         case 's':
3847             strcpy (dstring, "Sequence data");
3848             break;
3849         case 'b':
3850         case 'm':
3851             strcpy (dstring, "Microsatellite data");
3852             break;
3853         case 'n':
3854       case 'h':
3855         case 'u':
3856             strcpy (dstring, "SNP data");
3857             break;
3858         default:
3859             strcpy (dstring, "Unknown data [ERROR]");
3860             break;
3861       }
3862     pdf_print_contents_at(left_margin, page_height,"Datatype:");
3863     pdf_printf_right_next(left_margin, &page_height,"%s", dstring);
3864   if(!data->has_repeats)
3865     {
3866       pdf_printf_right_next(left_margin, &page_height,"[Fragment length is translated to repeats]");
3867     }
3868   else
3869     {
3870       if (dstring[0]=='M')
3871 	pdf_printf_right_next(left_margin, &page_height, "[Data was used as repeat-length information]\n");
3872     }
3873 
3874     pdf_print_contents_at(left_margin, page_height,"Number of loci:");
3875     pdf_printf_right_next(left_margin, &page_height,"%li", data->loci);
3876     pdf_advance(&page_height);
3877     if(options->has_datefile)
3878       {
3879 	//fprintf (file, "Sample dates:          %s\n", world->datefile);
3880 	pdf_print_contents_at(left_margin, page_height,"Sample dates:");
3881 	pdf_printf_right_next(left_margin, &page_height,"%s", options->datefilename);
3882 
3883 	//fprintf (file, "Generations per year:  %s\n", options->generation_year);
3884 	pdf_print_contents_at(left_margin, page_height,"Generations per year:");
3885 	pdf_printf_right_next(left_margin, &page_height,"%f", (float) options->generation_year);
3886 
3887 	//fprintf (file, "Mutationrate per year: %s", options->mutationrate_year[0]);
3888 	pdf_print_contents_at(left_margin, page_height,"Mutationrate per year:");
3889 	pdf_printf_right_next(left_margin, &page_height,"%f",  options->mutationrate_year[0]);
3890 	for(locus=1; locus < options->mutationrate_year_numalloc; locus++)
3891 	  {
3892 	    pdf_printf_right_next(left_margin, &page_height,"%f",  options->mutationrate_year[locus]);
3893 	  }
3894       }
3895     pdf_advance(&page_height);
3896     pdf_print_contents_at(left_margin, page_height,"Population");
3897     pdf_print_contents_at(col1, page_height,"Locus");
3898     pdf_print_contents_at(col3, page_height, "Gene copies");
3899     pdf_advance(&page_height);
3900     if (!strchr (SEQUENCETYPES, options->datatype))
3901       {
3902         pdf_print_contents_at(col3, page_height,"data");
3903         pdf_printf_right_next(left_margin, &page_height,"(missing)");
3904       }
3905 
3906     for (pop = 0; pop < data->numpop; pop++)
3907       {
3908         if (!strchr (SEQUENCETYPES, options->datatype))
3909           {
3910             nummiss = find_missing(data,pop,0);
3911             numind = data->numalleles[pop][0] - nummiss;
3912             pdf_printf(left_margin, page_height,'L', "%li %s", options->newpops[pop], data->popnames[pop]);
3913             pdf_printf_ralign(col2, page_height,"1");
3914             pdf_printf_ralign(col3, page_height,"%li",numind);
3915             pdf_printf_right_next(left_margin+10, &page_height,"(%li)", nummiss);
3916           }
3917         else
3918           {
3919             nummiss = 0;
3920             numind =  data->numind[pop][0];
3921 	    //(options->randomsubset > 0 && options->randomsubset < data->numind[pop][0]) ? options->randomsubset : data->numind[pop][0];
3922             pdf_printf(left_margin, page_height, 'L', "%li %s",options->newpops[pop], data->popnames[pop]);
3923             pdf_printf_ralign(col2, page_height,"1");
3924             pdf_printf_ralign(col3, page_height,"%li", numind);
3925             pdf_advance(&page_height);
3926           }
3927         total[0] += numind;
3928         totalmiss[0] += nummiss;
3929 
3930         for(locus=1; locus< data->loci; locus++)
3931           {
3932             if (!strchr (SEQUENCETYPES, options->datatype))
3933               {
3934                 nummiss = find_missing(data,pop,locus);
3935                 numind = data->numalleles[pop][locus] - nummiss;
3936                 pdf_printf_ralign(col2, page_height,"%li",locus+1);
3937                 pdf_printf_ralign(col3, page_height,"%li",numind);
3938                 pdf_printf_right_next(left_margin+10, &page_height,"(%li)", nummiss);
3939               }
3940             else
3941               {
3942                 nummiss=0;
3943                 numind = data->numind[pop][locus];
3944                 pdf_printf_ralign(col2, page_height,"%li",locus+1);
3945                 pdf_printf_ralign(col3, page_height,"%li",numind);
3946                 pdf_advance(&page_height);
3947               }
3948             total[locus] += numind;
3949             totalmiss[locus] += nummiss;
3950           }
3951       }
3952     pdf_printf(left_margin, page_height, 'L',
3953                "Total of all populations");
3954     pdf_printf_ralign(col2, page_height,"1");
3955     pdf_printf_ralign(col3, page_height,"%li",total[0]);
3956     if (!strchr (SEQUENCETYPES, options->datatype))
3957       {
3958         pdf_printf_right_next(left_margin+10, &page_height,"(%li)", totalmiss[0]);
3959         for(locus=1; locus< data->loci; locus++)
3960           {
3961             pdf_printf_ralign(col2, page_height,"%li",locus+1);
3962             pdf_printf_ralign(col3, page_height,"%li",total[locus]);
3963             pdf_printf_right_next(left_margin+10, &page_height,"(%li)", totalmiss[locus]);
3964           }
3965       }
3966     else
3967       {
3968         pdf_advance(&page_height);
3969         for(locus=1; locus< data->loci; locus++)
3970           {
3971             pdf_printf_ralign(col2, page_height,"%li",locus+1);
3972             pdf_printf_ralign(col3, page_height,"%li",total[locus]);
3973             pdf_advance(&page_height);
3974           }
3975       }
3976     myfree(total);
3977     myfree(totalmiss);
3978     *orig_page_height = page_height;
3979     *orig_left_margin = left_margin;
3980 }
3981 
3982 ///
3983 /// \param[in] *fmt format string identical to a fomrat string in printf()
3984 /// \reval int returns the number of elements by counting the %
count_elements(char * fmt)3985 int count_elements(char *fmt)
3986 {
3987     int element;
3988     int count = 0;
3989     for(element=0; element < (int) strlen(fmt); element++)
3990       {
3991         if(fmt[element]=='%')
3992             count++;
3993       }
3994     return count;
3995 }
3996 
3997 
3998 ///
3999 /// Print  a line in a table in the PDF file at a specific height on the page and with a given width
4000 /// \param *page_height gets modified by this function, page_height specifies the Y coordinate
4001 /// \param *width contains a list of floating points numbers that specify the columns, negative numbers
4002 /// mean left-adjusted and positive numbers are right-adjusted
4003 /// \param *fmt format string identical to printf (number % needs to match the element in width)
4004 /// \param ...  parameters to print
pdf_print_tableline(float * page_height,float * width,char * fmt,...)4005 void pdf_print_tableline(float *page_height, float *width, char *fmt, ...)
4006 {
4007     boolean start=FALSE;
4008     boolean stop=FALSE;
4009     char fmtval;
4010     char this_fmt[LINESIZE];
4011     long ival;
4012     va_list ap;
4013     double dval;
4014     long fmti=0;
4015     char cval, *sval;
4016     float y = *page_height;
4017     long ii=0;
4018     boolean left_aligned=FALSE;
4019     float offset = 55;
4020     va_start(ap, fmt);
4021     while (*fmt)
4022       {
4023         if(*fmt == '%')
4024           {
4025             if(width[ii] <= EPSILON)
4026               {
4027                 left_aligned = TRUE;
4028                 offset = 55 - width[ii++];
4029               }
4030             else
4031               {
4032                 left_aligned = FALSE;
4033                 offset = 55 + width[ii++];
4034               }
4035 
4036             start = TRUE;
4037             fmt++;
4038             this_fmt[0] = '%';
4039             fmti = 1;
4040             continue;
4041           }
4042         else
4043           {
4044             switch(*fmt)
4045               {
4046                 case 'c':                       /* string */
4047                     stop = TRUE;
4048                     fmtval = 'c';
4049                     cval = va_arg(ap, int);
4050                     this_fmt[fmti++] = fmtval;
4051                     this_fmt[fmti] = '\0';
4052                     if(left_aligned)
4053                         pdf_printf(offset, y, 'L', this_fmt, cval);
4054                     else
4055                         pdf_printf_ralign(offset, y,this_fmt, cval);
4056                     break;
4057                 case 's':                       /* string */
4058                     stop = TRUE;
4059                     fmtval = 's';
4060                     sval = va_arg(ap, char *);
4061                     this_fmt[fmti++] = fmtval;
4062                     this_fmt[fmti] = '\0';
4063                     if(left_aligned)
4064                         pdf_printf(offset, y,'L', this_fmt, sval);
4065                     else
4066                         pdf_printf_ralign(offset, y,this_fmt, sval);
4067                     break;
4068                 case 'i':                       /* int */
4069                     stop = TRUE;
4070                     fmtval = 'i';
4071                     ival = va_arg(ap, int);
4072                     this_fmt[fmti++] = fmtval;
4073                     this_fmt[fmti] = '\0';
4074                     if(left_aligned)
4075                         pdf_printf(offset, y,'L', this_fmt, ival);
4076                     else
4077                         pdf_printf_ralign(offset, y,this_fmt, ival);
4078                     break;
4079                 case 'f':                       /* char */
4080                     stop = TRUE;
4081                     fmtval = 'f';
4082                     dval = va_arg(ap, double);
4083                     this_fmt[fmti++] = fmtval;
4084                     this_fmt[fmti] = '\0';
4085                     if(left_aligned)
4086                         pdf_printf(offset, y,'L', this_fmt, dval);
4087                     else
4088                         pdf_printf_ralign(offset, y,this_fmt, dval);
4089                     break;
4090                 case '\n':
4091                     pdf_advance(&y);
4092                     break;
4093               }
4094             if(start)
4095               {
4096                 if(!stop)
4097                   {
4098                     if(strchr("1234567890.", *fmt)!=NULL)
4099                         this_fmt[fmti++] = *fmt;
4100                     if(*fmt == '-')
4101                         left_aligned = TRUE;
4102                   }
4103                 else
4104                   {
4105                     start = FALSE;
4106                     stop = FALSE;
4107                   }
4108               }
4109             fmt++;
4110           }
4111       }
4112     va_end(ap);
4113 }
4114 
4115 
pdf_print_allelelegend(float * column_width,float * page_height,long loci)4116 void pdf_print_allelelegend(float *column_width, float *page_height, long loci)
4117 {
4118     long locus;
4119     char stemp[LINESIZE];
4120     sprintf(stemp, "%-s", (loci == 1 ? "locus" : "loci "));
4121 
4122     pdf_printf(column_width[0], *page_height, 'L', "Indiv.");
4123     for(locus=1; locus < loci+1; locus++)
4124       {
4125         pdf_printf(column_width[locus], *page_height, 'L', "%li",locus);
4126         if(column_width[locus+1]<column_width[locus])
4127           {
4128             pdf_advance(page_height);
4129           }
4130       }
4131 }
4132 
4133 #define NOTFIRSTDATAPAGE (boolean) 0
4134 #define FIRSTDATAPAGE (boolean) 1
4135 ///
4136 /// print data header for allelic or sequence data
4137 void
pdf_print_dataheader(boolean first,char * title,float * page_height,float * column_width,long pop,world_fmt * world,option_fmt * options,data_fmt * data)4138 pdf_print_dataheader (boolean first, char *title, float *page_height, float *column_width, long pop, world_fmt * world,
4139                       option_fmt * options, data_fmt * data)
4140 {
4141 
4142     float w;
4143     float page_width;
4144     float left_margin = 55;
4145 
4146     // setup new page and title
4147     if(first)
4148       {
4149         pdf_new_page("");
4150         pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 18);
4151         w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
4152         *page_height = pdf_contents_get_height(canvas) - 75;
4153         page_width = pdf_contents_get_width(canvas);
4154         *page_height -= 20;
4155         pdf_print_contents_at((page_width - w)/2, *page_height, title);
4156         pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
4157         *page_height -= 20;
4158         pdf_draw_line(50, *page_height, page_width-50, *page_height);
4159         *page_height -= 20;
4160         pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
4161       }
4162     else
4163       {
4164         pdf_advance(page_height);
4165         page_width = pdf_contents_get_width(canvas);
4166         pdf_draw_line(50, *page_height, page_width-50, *page_height);
4167         pdf_advance(page_height);
4168       }
4169     pdf_printf_next(left_margin, page_height,"\n%-s", data->popnames[pop]);
4170     pdf_draw_line(50, *page_height, page_width-50, *page_height);
4171     pdf_advance(page_height);
4172     if (!strchr (SEQUENCETYPES, options->datatype))
4173         pdf_print_allelelegend(column_width, page_height, world->loci);
4174     //    else
4175     //    pdf_print_seqlegend(left_margin, page_height, world->loci);
4176 
4177     pdf_advance(page_height);
4178     pdf_draw_line(50, *page_height, page_width-50, *page_height);
4179     pdf_advance(page_height);
4180 }
4181 
4182 
4183 
4184 ///
4185 /// print the allele typ data in diploid format
4186 /// \param page_width page width
4187 /// \param page_height is manipulated and is always at the actual y coordinate on the page
4188 /// \param[in] margin is the margin that is used, either left or right margin
4189 /// \param[in] world contains all main data structures
4190 /// \param[in] data  contains all the biological data structures
4191 /// \param[in] options cintains all option structures
pdf_print_alleledata(float * page_height,float margin,world_fmt * world,data_fmt * data,option_fmt * options)4192 void pdf_print_alleledata (float *page_height, float margin, world_fmt * world, data_fmt * data, option_fmt * options)
4193 {
4194   long top, ii;
4195     long pop, ind, locus;
4196     char stemp[LINESIZE];
4197     float w;
4198     float * column_width = (float *) mycalloc(world->loci+2, sizeof(float));
4199     float pixel;
4200     float total;
4201     float oldpage_height;
4202     float page_width = pdf_contents_get_width(canvas);
4203 
4204     // calculate column width for indvidual name and each locus
4205     // we use a cummulative sum to set the x-coord just right without further
4206     // calculations
4207     for (locus = 0; locus < data->loci; locus++)
4208       {
4209         for (pop = 0; pop < data->numpop; pop++)
4210           {
4211 	    if(options->randomsubset > 0 && options->randomsubset < data->numind[pop][locus])
4212 	      {
4213 		top = options->randomsubset;
4214 	      }
4215 	    else
4216 	      {
4217 		top = data->numind[pop][locus];
4218 	      }
4219 
4220 	    for (ii = 0; ii < top; ii++)
4221 	      {
4222 		ind = data->shuffled[pop][locus][ii];
4223 
4224                 w = (float)( 5. + (float) (strlen (data->yy[pop][ind][locus][0]) +
4225                                            strlen (data->yy[pop][ind][locus][1])));
4226                 if(column_width[locus+2] < w)
4227                     column_width[locus+2] = w;
4228               }
4229           }
4230       }
4231     // calculate columnwidth for in page units for individual name and locus column
4232     column_width[1] = 5. + (float) sprintf(stemp, "%-*.*s", (int) options->nmlength,
4233                                            (int) options->nmlength, data->indnames[0][0][0]);
4234     w = (float) pdf_contents_get_text_width(canvas, stemp, NULL, NULL);
4235     pixel = w / options->nmlength;
4236     column_width[0] = margin;
4237     column_width[1] = margin + w;
4238     total = margin + w ;
4239     for (locus = 0; locus < data->loci; locus++)
4240       {
4241         column_width[locus+2] *= pixel;
4242         total += column_width[locus+2];
4243         if(total > (page_width - 55))
4244           {
4245             total = margin;
4246             column_width[locus+2] = total;
4247           }
4248         else
4249           {
4250             column_width[locus+2] = total;
4251           }
4252       }
4253 
4254     for (pop = 0; pop < data->numpop; pop++)
4255       {
4256         if(pop==0)
4257             pdf_print_dataheader (FIRSTDATAPAGE, "Allelic data", page_height, column_width, pop, world, options, data);
4258         else
4259             pdf_print_dataheader (NOTFIRSTDATAPAGE, "Allelic data",page_height, column_width, pop, world, options, data);
4260 
4261         for (ind = 0; ind < data->numind[pop][0]; ind++)
4262           {
4263             pdf_printf(column_width[0], *page_height, 'L', "%-*.*s", (int) options->nmlength,
4264                        (int) options->nmlength, data->indnames[pop][ind][0]);
4265             for (locus = 0; locus < data->loci; locus++)
4266               {
4267                 pdf_printf(column_width[locus+1], *page_height, 'L', " %s.%-s",
4268                            data->yy[pop][ind][locus][0],
4269                            data->yy[pop][ind][locus][1]);
4270                 if(column_width[locus+2]<column_width[locus+1])
4271                   {
4272                     pdf_advance(page_height);
4273                   }
4274               }
4275             oldpage_height = *page_height;
4276             pdf_advance(page_height);
4277             if(oldpage_height < *page_height)
4278                 pdf_print_dataheader (NOTFIRSTDATAPAGE, "Allelic data", page_height, column_width, pop, world, options, data);
4279 
4280           }
4281       }
4282     myfree(column_width);
4283 }
4284 
4285 
4286 
4287 
4288 void
pdf_print_data(world_fmt * world,option_fmt * options,data_fmt * data,float * orig_page_height,float * orig_left_margin)4289 pdf_print_data (world_fmt * world, option_fmt * options, data_fmt * data, float *orig_page_height, float *orig_left_margin)
4290 {
4291     if (options->printdata)
4292       {
4293         switch (options->datatype)
4294           {
4295             case 'a':
4296             case 'b':
4297             case 'm':
4298                 pdf_print_alleledata (orig_page_height,*orig_left_margin, world, data, options);
4299                 break;
4300             case 's':
4301             case 'n':
4302 	  case 'h':
4303             case 'u':
4304             case 'f':
4305 
4306                 pdf_print_seqdata (orig_page_height, *orig_left_margin, world, data, options);
4307                 break;
4308           }
4309       }
4310 }
4311 
4312 
4313 
pdf_print_sequence(float left_margin,float right_margin,float * page_height,data_fmt * data,long locus,long pop,long ind)4314 void pdf_print_sequence(float left_margin, float right_margin, float *page_height, data_fmt *data, long locus, long pop, long ind)
4315 {
4316     long site;
4317     float w = 0.;
4318     float wtot = 0.;
4319     char stemp[LINESIZE];
4320     w = 60.;
4321     for(site=0; site < data->seq[0]->sites[locus]; site+=10)
4322       {
4323         sprintf(stemp,"%-10.10s", &data->yy[pop][ind][locus][0][site]);
4324         pdf_contents_set_font_and_size(canvas, "Courier", 9);
4325         pdf_print_contents_at(left_margin + wtot, *page_height, stemp);
4326         wtot += w;
4327         if((left_margin + wtot + w) > right_margin)
4328           {
4329             wtot = 0;
4330             pdf_advance(page_height);
4331           }
4332       }
4333     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
4334 }
4335 
pdf_print_seqdata(float * page_height,float margin,world_fmt * world,data_fmt * data,option_fmt * options)4336 void pdf_print_seqdata (float *page_height, float margin, world_fmt * world, data_fmt * data, option_fmt * options)
4337 {
4338   long top;
4339   long ii;
4340     long pop, ind, locus=0;
4341     char stemp[LINESIZE];
4342     float w;
4343     float * column_width = (float *) mycalloc(world->loci+2, sizeof(float));
4344  //xcode   float pixel;
4345     float oldpage_height;
4346     float page_width = pdf_contents_get_width(canvas);
4347 
4348     // calculate columnwidth for in page units for individual name and locus column
4349     column_width[1] = 1. + (float) sprintf(stemp, "%-*.*s", (int) options->nmlength,
4350                                            (int) options->nmlength, data->indnames[0][0][0]);
4351     w = (float) pdf_contents_get_text_width(canvas, stemp, NULL, NULL);
4352     //xcode pixel = w / options->nmlength;
4353     column_width[0] = margin;
4354     column_width[1] = margin + w;
4355     column_width[2] = margin + w + (float) 10;
4356 
4357     for (pop = 0; pop < data->numpop; pop++)
4358       {
4359         if(pop==0)
4360             pdf_print_dataheader (FIRSTDATAPAGE, "Sequence data", page_height, column_width, pop, world, options, data);
4361         else
4362             pdf_print_dataheader (NOTFIRSTDATAPAGE,  "Sequence data", page_height, column_width, pop, world, options, data);
4363 
4364 	for (locus = 0; locus < data->loci; locus++)
4365 	  {
4366 
4367 	    top = max_shuffled_individuals(options, data, pop, locus);
4368 
4369 	    for (ii = 0; ii < top; ii++)
4370 	      {
4371 		ind = data->shuffled[pop][locus][ii];
4372 		pdf_printf(column_width[0], *page_height, 'L', "%-*.*s", (int) options->nmlength,
4373 			   (int) options->nmlength, data->indnames[pop][ind][0]);
4374                 pdf_printf(column_width[1], *page_height, 'L', "%li",locus+1);
4375                 pdf_print_sequence(column_width[1]+10, page_width - 55, page_height, data, locus, pop, ind);
4376                 pdf_advance(page_height);
4377               }
4378             oldpage_height = *page_height;
4379             pdf_advance(page_height);
4380             pdf_advance(page_height);
4381             if(oldpage_height < *page_height)
4382                 pdf_print_dataheader (NOTFIRSTDATAPAGE,  "Sequence data", page_height, column_width, pop, world, options, data);
4383           }
4384       }
4385     myfree(column_width);
4386 }
4387 
4388 //void format_helper_vec(atl_fmt *atl, long pop, long locus, long maxrep, long numpop, long *fmt_vector)
4389 //{
4390 //  for (i=0; i < atl.params; i++)
4391 //}
4392 
format_helper(MYREAL * matrix,long len,int * fmt1,int * fmt2)4393 void format_helper(MYREAL * matrix, long len, int *fmt1, int *fmt2)
4394 {
4395     long i;
4396     long count = 0;
4397     long maxcount = 0;
4398     MYREAL val;
4399 
4400     for(i=0;i<len; i++)
4401       {
4402         val = matrix[i];
4403         if(val>0.)
4404             count = (long)(log10(val)) + 1;
4405         if(count>maxcount)
4406             maxcount = count;
4407       }
4408     *fmt1 = 7;
4409     if(maxcount<2)
4410       {
4411         *fmt2 = 5;
4412       }
4413     else
4414       {
4415         *fmt2 = 2;
4416       }
4417 }
4418 
4419 
4420 ///
4421 /// print matrix line for various uses
4422 /// - print linear shortened migration matrix in n x n matrix with - as diagonals
4423 /// alowing for some pretty print using a format_helper() the columns are right-aligned
4424 /// based on the width.
pdf_print_matrix_line(long whichline,float * page_height,float left_margin,float width,long cols,long rows,MYREAL * matrix,boolean ismig)4425 void pdf_print_matrix_line(long whichline, float *page_height, float left_margin, float width, long cols,long rows,MYREAL * matrix,boolean ismig)
4426 {
4427     long i=0;
4428     long col, row = whichline;
4429     float offset;
4430     float page_width = pdf_contents_get_width(canvas);
4431     int fmt1=5, fmt2=3;
4432     long pad = ((ismig)?cols:0);
4433     format_helper(matrix+pad, cols * rows - pad ,&fmt1, &fmt2);
4434     offset = left_margin;
4435     if(ismig)
4436         i = cols;
4437     for(col = 0; col < cols; col++)
4438       {
4439         if(offset > page_width - 55)
4440           {
4441             offset = left_margin;
4442             pdf_advance(page_height);
4443           }
4444         if(ismig && row==col)
4445           {
4446             pdf_printf_ralign(offset+width - 15, *page_height, "-");
4447           }
4448         else
4449           {
4450             pdf_printf_ralign(offset + width - 5, *page_height, "%*.*f", fmt1, fmt2, matrix[i]);
4451             i++;
4452           }
4453         offset += width;
4454       }
4455     pdf_advance(page_height);
4456 }
4457 
4458 ///
4459 /// print text using a simple formatter that works on a single paramgraph
4460 /// breaking it approx at the end of the line.
pdf_print_comment(float lx,float * ly,char * this_text)4461 void pdf_print_comment(float lx, float *ly, char *this_text)
4462 {
4463     pdf_printf(lx, *ly,'L', this_text);
4464     pdf_advance(ly);
4465 }
4466 
4467 
4468 
4469 /*
4470  * print header
4471  * ===========================================================================
4472  * === Titletext
4473  * ===========================================================================
4474  * === Population     Loci  Ln(L)   Theta    xNm [xNe mu] xx     xx     xx
4475  * xx     xx     xx xx.... -------------- ---- -------- --------
4476  * ----------------------------------------
4477  */
4478 /// print the MLE table header
4479 void
pdf_print_result_header(float * lx,float * page_height,char * titletext,world_fmt * world)4480 pdf_print_result_header (float *lx, float *page_height, char *titletext, world_fmt * world)
4481 {
4482     long p1, zz;
4483     float *ly = page_height;
4484     float page_width;
4485 
4486     pdf_print_section_title(&page_width, ly, titletext);
4487     pdf_advance(page_height);
4488     pdf_printf(lx[0], *ly,'L',"Population [x]");
4489     pdf_printf(lx[1], *ly,'L',"Loc.");
4490     pdf_printf(lx[2], *ly,'L',"Ln(L/L0)");
4491     symbol_Theta(lx[3], *ly,12,-1);
4492     //    pdf_printf(lx[3], *ly,'L',"Theta");
4493     if(world->numpop>1)
4494       {
4495         if(world->options->usem)
4496             pdf_printf(lx[4], *ly,'L',"M (m/mu) [+=receiving population");
4497         else
4498             pdf_printf(lx[4], *ly,'L',"xNm [+=receiving population");
4499       }
4500     pdf_advance(ly);
4501     pdf_printf(lx[3], *ly,'L',"[x Ne mu]");
4502 
4503     zz = 4;
4504     for (p1 = 0; p1 < world->numpop; p1++)
4505       {
4506         if (zz > 8)
4507           {
4508             zz = 4;
4509             pdf_advance(ly);
4510           }
4511         pdf_printf(lx[zz], *ly,'L',"%2li,+", p1 + 1);
4512         zz++;
4513       }
4514     pdf_advance(ly);
4515     pdf_draw_line(lx[0],*ly, page_width - 55, *ly);
4516     pdf_advance(ly);
4517 }
4518 
4519 /// print the string for a population
pdf_print_popstring(float * lx,float * page_height,long pop,world_fmt * world,option_fmt * options,data_fmt * data)4520 void pdf_print_popstring(float *lx, float *page_height, long pop, world_fmt *world, option_fmt *options, data_fmt *data)
4521 {
4522     float *ly = page_height;
4523     //    char popstring[LINESIZE];
4524     if (options->readsum)
4525       {
4526         pdf_printf(lx[0], *ly, 'L', "%2li:",pop+1);
4527       }
4528     else
4529       {
4530         pdf_printf(lx[0],*ly, 'L', "%2li:%10.10s",pop+1, data->popnames[options->newpops[pop]-1]);
4531       }
4532 }
4533 
4534 
4535 /// print the replicate number
pdf_print_replicate(float lx,float * page_height,world_fmt * world,long maxrep,long rep,long locus)4536 void pdf_print_replicate(float lx, float *page_height, world_fmt *world, long maxrep, long rep, long locus)
4537 {
4538     float *ly = page_height;
4539     char repstring[LINESIZE];
4540     sprintf (repstring, "%li", rep + 1);
4541     pdf_printf(lx, *ly, 'L', "%li %s", locus + 1, maxrep > 1 ? (rep == maxrep - 1 ? " A" : repstring) : "  ");
4542 }
4543 
4544 /// print the MLE table content for each population
4545 void
pdf_print_result_population(float * lx,float * page_height,long pop,world_fmt * world,option_fmt * options,data_fmt * data)4546 pdf_print_result_population (float *lx, float *page_height, long pop, world_fmt * world,
4547                              option_fmt * options, data_fmt * data)
4548 {
4549     float *ly = page_height;
4550     long skipped = 0, locus;
4551     long maxrep = world->options->replicate ?
4552         (world->options->replicatenum > 0 ?
4553          world->options->replicatenum + 1 : world->options->lchains + 1) : 1;
4554     long rep;
4555     pdf_print_popstring(lx, page_height, pop, world, options, data);
4556     for (locus = 0; locus < world->loci; locus++)
4557       {
4558         if (world->data->skiploci[locus])
4559           {
4560             skipped++;
4561             continue;
4562           }
4563         for (rep = 0; rep < maxrep; rep++)
4564           {
4565             pdf_print_replicate(lx[1], page_height, world, maxrep, rep, locus);
4566             pdf_printf(lx[2], *ly, 'L', "% 8.3f ",
4567                        world->atl[rep][locus].param_like);
4568             pdf_print_result_param (lx, page_height,  world->atl[rep][locus].param,
4569                                     world->numpop, pop, world->options->usem);
4570           }
4571       }
4572     if (world->loci - skipped > 1)
4573       {
4574         pdf_printf(lx[1], *page_height, 'L', "All ");
4575         //locus is exactly world->loci
4576         // re is always one because we have only replication of single locus chains
4577         pdf_printf(lx[2],*page_height, 'L', "% 8.3f ", world->atl[0][locus].param_like);
4578         pdf_print_result_param (lx, page_height,  world->atl[0][locus].param,
4579                                 world->numpop, pop, world->options->usem);
4580       }
4581     /* FPRINTF(world->outfile,"%s\n",sline);     */
4582 }
4583 
4584 
4585 /// print the parameter for the MLE parameter printout
4586 void
pdf_print_result_param(float * lx,float * page_height,MYREAL * param,long numpop,long pop,boolean usem)4587 pdf_print_result_param (float *lx, float *page_height,  MYREAL *param, long numpop, long pop,
4588                         boolean usem)
4589 {
4590     char    temp[LINESIZE];
4591     long    i;
4592     long    zz;
4593     long    msta = mstart (pop, numpop);
4594     long    msto = mend (pop, numpop);
4595     float  *ly   = page_height;
4596     //int   fmtint = 8;
4597     //int fmtfloat = 5;
4598     //int digits;
4599     MYREAL  tmp  = 0;
4600 
4601     // population size
4602     if (param[pop] <= SICK_VALUE)
4603         pdf_printf (lx[3], *ly, 'L', "-");
4604     else
4605       {
4606         nice_element(param[pop], temp, 0.0001, 10, 100, 4, 2, '\0');
4607         pdf_printf (lx[3], *ly, 'L', "%s", temp);
4608         /*        if (param[pop] < 0.0001 && param[pop] > 0)
4609             pdf_printf (lx[3], *ly, 'L', "%3.2e ", param[pop]);
4610         else
4611           {
4612             digits = (int) log10(param[pop]);
4613             if(digits>3)
4614               {
4615                 fmtfloat=0;
4616                 fmtint=digits;
4617               }
4618             pdf_printf (lx[3], *ly, 'L', "%*.*f ", fmtint, fmtfloat, param[pop]);
4619           }
4620         */
4621       }
4622 
4623     // migration rate
4624     zz=4;
4625     for (i = msta; i < msto; i++)
4626       {
4627         if (zz > 8)
4628           {
4629             zz = 4;
4630             pdf_advance(ly);
4631           }
4632         if (pop == i - msta)
4633           {
4634             pdf_printf (lx[zz], *ly, 'L', "-");
4635             zz++;;
4636           }
4637         if ((param[i] <= SICK_VALUE) || (param[pop] <= SICK_VALUE))
4638             pdf_printf (lx[zz], *ly, 'L', "-");
4639         else
4640           {
4641             if (usem)
4642               {
4643                 //tmp = param[i];
4644                 nice_element(param[i], temp, 0.001, 100, 1000, 3, 2, '\0');
4645                 //if (tmp < 0.0001)
4646                 pdf_printf (lx[zz], *ly, 'L', "%s",temp);
4647                 //else
4648                 //pdf_printf (lx[zz], *ly, 'L', "%7.4f ", tmp);
4649               }
4650             else
4651               {
4652                 tmp = param[pop] * param[i];
4653                 nice_element(tmp, temp, 0.0001, 10, 100, 4, 2, '\0');
4654                 pdf_printf (lx[zz], *ly, 'L', "%s",temp);
4655                 /*		if (tmp < 0.00001)
4656                     pdf_printf (lx[zz], *ly, 'L', " 0.0000 ");
4657                 else
4658                     pdf_printf (lx[zz], *ly, 'L', "%7.4f ", tmp);
4659                 */
4660               }
4661           }
4662         zz++;
4663       }
4664     if (pop == numpop - 1)
4665         pdf_printf (lx[i-msta+4], *ly, 'L',"-");
4666     pdf_advance(ly);
4667 }
4668 
4669 
4670 
4671 void
pdf_print_results(float * page_height,world_fmt ** universe,option_fmt * options,data_fmt * data)4672 pdf_print_results (float *page_height, world_fmt ** universe, option_fmt * options, data_fmt * data)
4673 {
4674     float lx[]={55,140,170,220,270,320,370,420,470,520};
4675 
4676     long pop;
4677     float *ly = page_height;
4678 //xcode    FILE *outfile;
4679     world_fmt *world = universe[0];
4680     worldoption_fmt *wopt = world->options;
4681     char sch[10], lch[10], cva[50];
4682     long rep = world->loci > 1 ? 0 : (wopt->replicate ? world->repstop : 0);
4683     //xcode outfile = world->outfile;
4684     if (options->schains == 1)
4685         strcpy (sch, "chain");
4686     else
4687         strcpy (sch, "chains");
4688     if (options->lchains == 1)
4689         strcpy (lch, "chain");
4690     else
4691         strcpy (lch, "chains");
4692     pdf_print_result_header (lx, page_height, "Maximum Likelihood estimates", world);
4693     for (pop = 0; pop < world->numpop; pop++)
4694       {
4695         pdf_print_result_population (lx, page_height, pop, world, options, data);
4696       }
4697     pdf_advance(ly);
4698     pdf_printf(lx[0],*ly,'L', "Comments:");
4699     pdf_advance(ly);
4700     pdf_printf(lx[0],*ly,'L', "The x is 1, 2, or 4 for mtDNA, haploid, or diploid data, respectively");
4701     pdf_advance(ly);
4702     pdf_printf(lx[0],*ly,'L', "There were %li short %s (%li used trees out of sampled %li)",
4703                options->schains, sch, options->ssteps, options->sincrement * options->ssteps);
4704     pdf_advance(ly);
4705     pdf_printf(lx[0],*ly, 'L', "and %li long %s (%li used trees out of sampled %li)\n",
4706                options->lchains, lch, options->lsteps,
4707                options->lincrement * options->lsteps);
4708     pdf_advance(ly);
4709     if (wopt->heating)
4710       {
4711         if(options->adaptiveheat!=NOTADAPTIVE)
4712           {
4713 	    if(options->adaptiveheat==STANDARD)
4714 	      {
4715 		pdf_printf(lx[0],*ly,'L',
4716 			   "Adaptive heating with %li chains was active",options->heated_chains);
4717 	      }
4718 	    else
4719 	      {
4720 		pdf_printf(lx[0],*ly,'L',
4721 			   "Bounded adaptive heating with %li chains was active",options->heated_chains);
4722 	      }
4723             pdf_advance(ly);
4724             pdf_printf(lx[0],*ly,'L',"check Log file (if present) for average temperatures");
4725 
4726             pdf_printf(lx[0],*ly,'L',"Average last chain temp: 1.0",
4727                        options->heated_chains);
4728             for(pop=1;pop<options->heated_chains;pop++)
4729                 pdf_printf(lx[pop+2],*ly,'L', ", %f", universe[pop]->averageheat);
4730             pdf_advance(ly);
4731           }
4732         else
4733 	  {
4734             pdf_printf(lx[0],*ly,'L', "Static heating with %li chains was active\n",options->heated_chains);
4735             pdf_advance(ly);
4736 	  }
4737       }
4738     if (options->gamma)
4739       {
4740         if (world->atl[rep][world->loci].param[world->numpop2] < 10e-9)
4741             strcpy (cva, "0");
4742         else
4743             sprintf (cva, "%f",
4744                      sqrt (1. / world->atl[rep][world->loci].param[world->numpop2]));
4745         pdf_printf(lx[0],*ly,'L',"With shape parameter Alpha=%g ([1/CV(mu)]^2; CV(mu)=%s)",
4746                    world->atl[rep][world->loci].param[world->numpop2],
4747                    cva);
4748         pdf_advance(ly);
4749       }
4750     if (world->options->replicate)
4751       {
4752         if (world->repkind == MULTIPLECHAIN)
4753             pdf_printf(lx[0],*ly, 'L', "COMBINATION OF ALL LONG CHAINS");
4754         else
4755             pdf_printf(lx[0],*ly, 'L', "COMBINATION OF %li MULTIPLE RUNS",
4756                        world->options->replicatenum);
4757         pdf_advance(ly);
4758       }
4759     if (world->atl[rep][world->loci].normd > LOCI_NORM)
4760       {
4761         pdf_printf(lx[0],*ly,'L',"[Last maximization needed %li cycles of maximal %i,",
4762                    world->atl[rep][world->loci].trials,
4763                    NTRIALS);
4764         pdf_advance(ly);
4765         pdf_printf(lx[0],*ly,'L',"Norm(first derivatives)=%f (Normal stopping criteria is < %f)]",
4766                    world->atl[rep][world->loci].normd, LOCI_NORM);
4767       }
4768     pdf_advance(ly);
4769     pdf_advance(ly);
4770     pdf_print_citation(ly, "Likelihood inference", world);
4771 }
4772 
pdf_print_correlation_table(float * page_height,world_fmt * world,option_fmt * options,data_fmt * data)4773 void    pdf_print_correlation_table (float * page_height, world_fmt * world, option_fmt * options, data_fmt * data)
4774 {
4775   const long nn = world->numpop2 + world->bayes->mu;
4776   const float offset = 60;
4777   long i;
4778   long j;
4779   float right_margin = pdf_contents_get_width(canvas) - 2*55 - offset;
4780   float left_margin = 55;
4781   float lx=left_margin + 80;
4782   long frompop, topop;
4783   long locus;
4784   long loci = world->loci > 1 ? world->loci+1 : world->loci;
4785   pdf_advance(page_height);
4786   pdf_printf_next(left_margin, page_height, "Correlation tables:");
4787   pdf_advance(page_height);
4788   for (locus=0; loci; locus++)
4789     {
4790       pdf_printf (left_margin, *page_height, 'L', "Locus %li",locus+1);
4791       for (i = 0; i < nn; i++)
4792 	{
4793 	  if(i<world->numpop)
4794 	    symbol_Theta(left_margin, *page_height, 12, i+1);
4795 	  else
4796 	    if (i>world->numpop2)
4797 	      symbol_R(left_margin, *page_height, 12, i+1-world->numpop2);
4798 	    else
4799 	      {
4800 		m2mm(i,world->numpop,&frompop,&topop);
4801 		symbol_M(left_margin, *page_height, 12, frompop+1, topop+1, world->options->usem);
4802 	      }
4803 
4804 	  lx += offset;
4805 	  if(lx > right_margin)
4806 	    {
4807 	      lx = left_margin + 80;
4808 	      pdf_advance(page_height);
4809 	    }
4810     }
4811     }
4812   for (i = 0; i < data->numpop; i++)
4813     {
4814       lx = left_margin + 80;
4815       pdf_advance(page_height);
4816       pdf_printf (left_margin, *page_height, 'L', "%3li %-15.15s",options->newpops[i],  data->popnames[i]);
4817       for (j = 0; j < data->numpop; j++)
4818 	{
4819 	  pdf_printf(lx, *page_height, 'L', " %10.4f ", data->ogeo[j][i]);
4820 	  lx += offset;
4821 	  if(lx > right_margin)
4822 	    {
4823 	      lx = left_margin + 80;
4824 	      pdf_advance(page_height);
4825 	    }
4826 	}
4827     }
4828   pdf_advance(page_height);
4829   pdf_advance(page_height);
4830 }
4831 
4832 
prepare_profile_header(long which,char method,char * header,world_fmt * world)4833 void prepare_profile_header(long which, char method, char *header, world_fmt *world)
4834 {
4835     const long numpop = world->numpop;
4836 
4837     long pop;
4838     long pop2;
4839     long from;
4840     long to;
4841 //xcode     long z;
4842     long position = 0;
4843     char *mm;
4844 
4845     mm = (char *) mycalloc(LINESIZE,sizeof(char));
4846     if (world->options->profileparamtype == PLOT4NM)
4847         sprintf(mm,"%s","xNm");
4848     else
4849         sprintf(mm,"%s","M");
4850 
4851     if(method=='p')
4852       {
4853         position += sprintf(header + position, "Per. &");
4854       }
4855     else
4856       {
4857         position += sprintf(header + position," &");
4858       }
4859     position += sprintf(header + position,"Ln(L)&");
4860     if(which < numpop)
4861         position += sprintf(header + position,"%s_%li&","Q",which+1);
4862     else
4863       {
4864         m2mm(which,numpop,&from,&to);
4865         position += sprintf(header + position,"%s_%li->%li&",mm,from+1,to+1);
4866       }
4867     for(pop=0; pop < numpop; pop++)
4868       {
4869         position += sprintf(header + position,"%s_%li&","Q",pop+1);
4870       }
4871     //xcode z=pop+3;
4872     for(pop=0; pop < numpop; pop++)
4873       {
4874         for(pop2=0; pop2 < numpop; pop2++)
4875           {
4876             if(pop!=pop2)
4877               {
4878                 position += sprintf(header + position,"%s_%li->%li&",mm,pop2+1,pop+1);
4879               }
4880           }
4881       }
4882     //xcode position +=
4883     sprintf(header + position,"%%&");
4884     myfree(mm);
4885 }
4886 
4887 ///
4888 /// pretty print for tables
4889 /// takes a lower and upper bound below and above it uses scientific notation, the range in
4890 /// between prints fixed point notation below mid with low_mid_digits and above mid with mid_upper_digits.
nice_element(MYREAL param,char * element,MYREAL lower,MYREAL mid,MYREAL upper,int low_mid_digits,int mid_upper_digits,char delimiter)4891 long nice_element(MYREAL param, char *element, MYREAL lower, MYREAL mid, MYREAL upper,
4892                   int low_mid_digits, int mid_upper_digits, char delimiter)
4893 {
4894     long position = 0;
4895     if (param < lower)
4896         position = sprintf(element,"%.2e", param);
4897     else
4898       {
4899         if (param > upper)
4900             position = sprintf(element,"%.2e", param);
4901         else
4902           {
4903             if(param > mid)
4904                 position = sprintf(element,"%.*f", mid_upper_digits,param);
4905             else
4906                 position = sprintf(element,"%.*f", low_mid_digits,param);
4907           }
4908       }
4909     if(delimiter != '\0')
4910         position += sprintf(element + position,"%c",delimiter);
4911     return position;
4912 }
4913 
4914 
4915 ///
4916 /// prepare the table elements for the profile likelihood table
4917 long
prepare_profile_elements(char method,long which,MYREAL likes[],MYREAL ** param,world_fmt * world,char ** elements)4918 prepare_profile_elements (char method, long which,  MYREAL likes[],
4919                           MYREAL **param, world_fmt * world, char **elements)
4920 {
4921     const MYREAL probabilities[] = SHOWGRID;
4922     MYREAL       likemax         = -MYREAL_MAX;
4923     long         i;
4924     long         ii;
4925     long         j;
4926     long         elem     = world->options->gamma ? (world->numpop2 + 1) : world->numpop2;
4927     long         position = 0L;
4928     long         likei    = 0L;
4929     long         failed   = 0L;
4930     char         likestr[LINESIZE];
4931 
4932     for (i = 0; i < GRIDSIZE; i++)
4933       {
4934         if (likemax < MIN(likes[i], MYREAL_MAX))
4935           {
4936             likemax = likes[i];
4937             likei   = i;
4938           }
4939       }
4940 
4941     for(ii=0; ii< GRIDSIZE; ii++)
4942       {
4943         i = warp (ii);
4944         //printf("warped ii=%li --> i=%li\n",ii,i);
4945         position = 0;
4946         //first column
4947         if(method != 'd')
4948           {
4949             if(world->percentile_failed[which][i])
4950               {
4951                 position += sprintf(elements[i] + position,"****&");
4952                 failed++;
4953               }
4954             else
4955               {
4956                 if (probabilities[i]==0.5)
4957                     position += sprintf(elements[i] + position,"MLE&");
4958                 else
4959                     position += sprintf(elements[i] + position,"%4.3f&", probabilities[i]);
4960               }
4961           }
4962         else
4963           {
4964             position += sprintf(elements[i] + position,"&");
4965           }
4966 
4967         //second column
4968         if (likes[i] >= MYREAL_MAX - EPSILON)
4969             sprintf (likestr, "-");
4970         else
4971             sprintf (likestr, "%.3f%c", likes[i], likei == i ? '*' : ' ');
4972         position += sprintf(elements[i] + position,"%s&", likestr);
4973         // third column
4974         position += sprintf(elements[i] + position,"%.6g&", param[i][which]);
4975         // fourth and further columns
4976         for (j = 0; j < world->numpop; j++)
4977           {
4978             position += nice_element(param[i][j],elements[i] + position, 0.0001, 10, 100, 4, 2, '&');
4979           }
4980         for (j = world->numpop; j < elem; j++)
4981           {
4982             position += nice_element(param[i][j],elements[i] + position, 0.001, 100, 1000, 3, 1, '&');
4983           }
4984         if(ii<GRIDSIZE-1)
4985           {
4986             //xcode position +=
4987             sprintf(elements[i] + position,"@&");
4988           }
4989         else
4990           {
4991             //xcode position +=
4992             sprintf(elements[i] + position,"%%&");
4993           }
4994       }
4995     return failed;
4996 }
4997 
4998 ///
4999 /// Printing PROFILE table title for PDF
5000 /// \param world        master parameter structure
pdf_print_profile_title(world_fmt * world)5001 void pdf_print_profile_title(world_fmt *world)
5002 {
5003     char *title = "Profile likelihood tables and plots";
5004     float w;
5005     float page_width;
5006 
5007     // setup new page and title
5008     pdf_new_page("");
5009     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 18);
5010     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
5011     page_height = pdf_contents_get_height(canvas) - 75;
5012     page_width = pdf_contents_get_width(canvas);
5013     page_height -= 20;
5014     pdf_print_contents_at((page_width - w)/2, page_height, title);
5015     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
5016     page_height -= 20;
5017     pdf_draw_line(50, page_height, page_width-50, page_height);
5018     page_height -= 20;
5019     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
5020 }
5021 
method_set(float lx,float * page_height,char method)5022 void method_set(float lx, float *page_height, char method)
5023 {
5024     switch (method)
5025       {
5026         case 'p':
5027             pdf_printf(lx, *page_height, 'L', "Parameters are evaluated at percentiles using bisection method (slow, but exact).");
5028             break;
5029         case 's':
5030             pdf_printf(lx, *page_height, 'L',"Parameters are evaluated at percentiles");
5031             pdf_advance(page_height);
5032             pdf_printf(lx, *page_height, 'L',"using cubic splines of profiled parameter (faster, but not so exact).");
5033             break;
5034         case 'd':
5035             pdf_printf(lx, *page_height, 'L',"Parameters are evaluated at pre-defined values\n");
5036             break;
5037         case 'q':
5038             pdf_printf(lx, *page_height, 'L', "Parameters are evaluated assuming complete independence\n");
5039             break;
5040         case 'f':
5041             pdf_printf(lx, *page_height, 'L', "Parameters are evaluated assuming complete independence");
5042             pdf_advance(page_height);
5043             pdf_printf(lx, *page_height, 'L',"and then once maximized at the found profiled parameter value");
5044             break;
5045       }
5046     pdf_advance(page_height);
5047 }
5048 
pdf_table_footnote(float lx,float * page_height,long failed,boolean percentiles)5049 void pdf_table_footnote(float lx, float * page_height, long failed, boolean percentiles)
5050 {
5051     char * foot1 = "If the percentile column is marked with **** then the convergence to the percentile value failed";
5052     char * foot2 = "The values are still CORRECT but not at the percentile of the profile parameter";
5053     char * foot3 = "Values with a * are NOT at the percentiles!";
5054     char * foot4 = "The convergence to the percentile value FAILED.";
5055     if(failed>0)
5056       {
5057         pdf_printf(lx, *page_height, 'L', percentiles ? foot3 : foot1);
5058         pdf_advance(page_height);
5059         pdf_printf(lx, *page_height, 'L', percentiles ? foot4 : foot2);
5060         pdf_advance(page_height);
5061       }
5062 }
5063 
5064 ///
5065 /// Prepare PROFILE table for PDF and ASCII printing
5066 /// \param method       profile method type ('p'=percentiles)
5067 /// \param which        which parameter is currently profiled
5068 /// \param likes        likelihoods
5069 /// \param param        parameters
5070 /// \param world        master parameter structure
5071 /// \return failed      how many of the profile calculations failed
prepare_profile_table(char method,long which,MYREAL * likes,MYREAL ** param,world_fmt * world,long bufsize)5072 long prepare_profile_table(char method, long which, MYREAL *likes, MYREAL **param, world_fmt *world, long bufsize)
5073 {
5074     boolean failed;
5075     //  float left_margin = 55;
5076     long i;
5077     long ii;
5078     //  long pop;
5079     char *header;
5080     char **elements;
5081     //  long elem = world->options->gamma ? world->numpop2 + 1 : world->numpop2;
5082     long position = bufsize;
5083 
5084     world->buffer = (char *) myrealloc (world->buffer, (position + SUPERLINESIZE + 1) * sizeof (char));
5085     memset(world->buffer + position, 0 , (SUPERLINESIZE+1)* sizeof(char));
5086 
5087     header = (char *) mycalloc(WORDSIZE * world->numpop2, sizeof(char));
5088     charvec2d(&(elements), 9, WORDSIZE * world->numpop2);
5089 
5090     //  for(pop=0;pop < world->numpop2; pop++)
5091     //  {
5092     prepare_profile_header(which, method, header, world);
5093     position += sprintf(world->buffer + position,"%s",header);
5094     failed = prepare_profile_elements(method, which, likes, param, world, elements);
5095     for(i=0;i<GRIDSIZE;i++)
5096       {
5097         ii = warp(i);
5098         position += sprintf(world->buffer + position,"%s",elements[ii]);
5099       }
5100     //}
5101     myfree(header);
5102 free_charvec2d(elements);
5103 return failed;
5104 }
5105 
5106 
5107 ///
5108 /// translate buffer table (syntax similar to LaTeX) into table header and table elements
translate_buffer_table(long cols,long rows,char ** thebuffer,char ** header,char *** elements)5109 void  translate_buffer_table(long cols, long rows, char **thebuffer, char **header, char ***elements)
5110 {
5111     char *temp;
5112     char *buffer;
5113     char *savebuffer;
5114     long z = 0;
5115     long r = 0;
5116     //  long position=0;
5117 
5118     buffer = (char *) mycalloc(strlen(*thebuffer)+1,sizeof(char));
5119     savebuffer= buffer;
5120     strcpy(buffer,*thebuffer);
5121     while((temp=strsep(&buffer,"&"))!=NULL && buffer!=NULL )
5122       {
5123         if(temp[0]=='%')
5124             break;
5125         else
5126           {
5127             sprintf(header[z++],"%s",temp);
5128           }
5129       }
5130     z=0;
5131     r=0;
5132     while((temp=strsep(&buffer,"&"))!=NULL && buffer!=NULL)
5133       {
5134         if(r==rows-1 && z>=cols)
5135           {
5136             //	  position = (long) strlen(strstr(thebuffer,buffer))+1;
5137             // memcpy(*thebuffer,buffer,(strlen(buffer)+1)*sizeof(char));
5138             break;
5139           }
5140         if(temp[0]=='%')
5141             break;
5142         if(temp[0]=='@')
5143           {
5144             z=0;
5145             r++;
5146           }
5147         else
5148           {
5149             if(z<cols)
5150               {
5151                 sprintf(elements[r][z],"%s",temp);
5152                 z++;
5153               }
5154             else
5155               {
5156                 if(r<rows)
5157                     warning("column counter exceeded available columns: z=%li temp=%s\n",z, temp);
5158                 else
5159                     break;
5160               }
5161           }
5162       }
5163     myfree(savebuffer);
5164     //  return position;
5165 }
5166 ///
5167 /// extract column out of  buffer table (syntax similar to LaTeX) into table header and table elements
extract_column_buffer_table(long col,long cols,long rows,char ** thebuffer,float * x)5168 void  extract_column_buffer_table(long col, long cols, long rows, char **thebuffer, float *x)
5169 {
5170     char *temp;
5171     char *buffer;
5172     char *savebuffer;
5173     long z = 0;
5174     long r = 0;
5175     //  long position=0;
5176 
5177     buffer = (char *) mycalloc(strlen(*thebuffer)+1,sizeof(char));
5178     savebuffer= buffer;
5179     strcpy(buffer,*thebuffer);
5180     while((temp=strsep(&buffer,"&"))!=NULL && buffer!=NULL )
5181       {
5182         if(temp[0]=='%')
5183             break;
5184         else
5185           {
5186 	    z++;
5187 	    //            sprintf(header[z++],"%s",temp);
5188           }
5189       }
5190     z=0;
5191     r=0;
5192     while((temp=strsep(&buffer,"&"))!=NULL && buffer!=NULL)
5193       {
5194         if(r==rows-1 && z>=cols)
5195           {
5196             //	  position = (long) strlen(strstr(thebuffer,buffer))+1;
5197             // memcpy(*thebuffer,buffer,(strlen(buffer)+1)*sizeof(char));
5198             break;
5199           }
5200         if(temp[0]=='%')
5201             break;
5202         if(temp[0]=='@')
5203           {
5204             z=0;
5205             r++;
5206           }
5207         else
5208           {
5209 	    if(z==col)
5210 	      x[r] = atof(temp);
5211 
5212             if(z<cols)
5213               {
5214                 //sprintf(elements[r][z],"%s",temp);
5215                 z++;
5216               }
5217             else
5218               {
5219                 if(r<rows)
5220                     warning("column counter exceeded available columns: z=%li temp=%s\n",z, temp);
5221                 else
5222                     break;
5223               }
5224           }
5225       }
5226     myfree(savebuffer);
5227     //  return position;
5228 }
5229 
5230 ///
5231 /// Printing PROFILE table for PDF
5232 /// \param left_margin  left start x coord
5233 /// \param *page_height start y coordinate
5234 /// \param page_width   width of paper
5235 /// \param world        master parameter structure
5236 /// \param data         data structures
5237 /// \param options      options
5238 ///
pdf_print_profile_table(float left_margin,float * page_height,char method,char * buffer,world_fmt * world)5239 void pdf_print_profile_table(float left_margin, float * page_height, char method, char *buffer, world_fmt *world)
5240 {
5241     char *thisparam;
5242     char *savedparam;
5243     char *ptr;
5244     //  long position = 0;
5245 
5246     boolean failed = world->percentile_some_failed;
5247     float page_width;
5248     float red[3]={0.99,0.,0.};
5249     float *x = (float *) calloc(9,sizeof(float));
5250     float *y = (float *) calloc(9,sizeof(float));
5251 
5252     thisparam = (char *) mycalloc(LINESIZE,sizeof(char));
5253     savedparam = thisparam;
5254     strncpy(thisparam, buffer, LINESIZE-1);
5255     strsep(&thisparam,"&"); // remove first element
5256     strsep(&thisparam,"&"); // remove second  element
5257     ptr = strsep(&thisparam,"&"); // keep third
5258     page_width = pdf_contents_get_width(canvas);
5259     pdf_advance(page_height);
5260     pdf_draw_line(55,*page_height+5.0, page_width - 50, *page_height+5.0);
5261     pdf_advance(page_height);
5262     pdf_printf(left_margin, *page_height,'L',"Profile likelihood table and plot for parameter ");
5263     pdf_print_symbol(left_margin+205, page_height, 12, 'L', ptr);
5264     pdf_advance(page_height);
5265     method_set(left_margin, page_height, method);
5266 
5267     pdf_table(left_margin, page_height,world->numpop2 + 3, 9, &buffer/* + position*/,
5268               NULL, 4, 6.);
5269     pdf_table_footnote(left_margin, page_height, failed, NOT_PERCENTILES);
5270 
5271     extract_column_buffer_table(2, world->numpop2 + 3, 9, &buffer, x);
5272     extract_column_buffer_table(1, world->numpop2 + 3, 9, &buffer, y);
5273     pdf_page_advance_or_not(page_height, 100.);
5274     pdf_linedotplot(9, x, y, red, red, 1, page_height, page_width - 200., 100., TRUE, TRUE);
5275     myfree(savedparam);
5276 }
5277 
5278 // generic table generator package
5279 // containing functions:
5280 // pdf_table()
5281 // find_col_width()
5282 // define_col_start()
5283 // pdf_print_table_header()
5284 
5285 ///
5286 /// finds the width of all columns given the elements of the table
find_col_width(int cols,int rows,char *** elements,char ** header,float * col_widths)5287 void  find_col_width(int cols, int rows, char ***elements, char **header, float *col_widths)
5288 {
5289     float w;
5290     float keepw;
5291     int row;
5292     int col;
5293 
5294     for(col=0;col < cols; col++)
5295       {
5296         keepw = (float) pdf_contents_get_text_width(canvas, header[col], NULL, NULL);
5297         for(row=0;row < rows; row++)
5298           {
5299             w = (float) pdf_contents_get_text_width(canvas, elements[row][col], NULL, NULL);
5300             if(w > keepw)
5301                 keepw = w;
5302           }
5303         col_widths[col] = keepw;
5304       }
5305 }
5306 
5307 ///
5308 /// align column
align_column(char position,float cw,float left_margin)5309 float align_column(char position, float cw, float left_margin)
5310 {
5311     float loc = 0.;
5312     switch(position)
5313       {
5314         case 'R':
5315             loc = left_margin + cw;
5316             break;
5317         case 'C':
5318             loc = left_margin + cw/2.;
5319             break;
5320         case 'L':
5321         default:
5322             loc = left_margin;
5323             break;
5324       }
5325     return loc;
5326 }
5327 
5328 ///
5329 /// sets X-coordinates to start the columns
define_col_start(float cols,float * col_widths,int col_overflow,char * position,float left_margin,float page_width,float separator,float * col_starts)5330 void  define_col_start(float cols, float * col_widths, int col_overflow, char *position, float left_margin, float page_width, float separator, float *col_starts)
5331 {
5332     int col;
5333     char pos;
5334     if(position==NULL)
5335         pos='L';
5336     else
5337         pos=position[0];
5338     col_starts[0] = align_column(pos, col_widths[0], left_margin);
5339     for(col=1; col < cols; col++)
5340       {
5341         if(position==NULL)
5342             pos='L';
5343         else
5344             pos=position[col];
5345         col_starts[col] =  align_column(pos, col_widths[col], separator + col_starts[col-1] + col_widths[col-1]);
5346         if((col_starts[col] + col_widths[col]) > page_width) //correct for 'L', but questionable for 'R'
5347           {
5348             if(col_overflow==0)
5349                 col_starts[col] = col_starts[0];
5350             else
5351               {
5352                 if(col_overflow <= col)
5353                     col_starts[col] = col_starts[col_overflow];
5354                 else
5355                     col_starts[col] = col_starts[0];
5356               }
5357             //	  fprintf(stdout,">>> %f %f %f\n",col_starts[col],col_widths[col], separator);
5358           }
5359       }
5360 }
5361 
5362 ///
5363 /// prints the table header at column positions
pdf_print_table_header(float * page_height,char * position,int cols,float * col_starts,char ** header)5364 void  pdf_print_table_header(float *page_height, char * position, int cols, float *col_starts,char **header)
5365 {
5366     int col;
5367     char pos;
5368     long oldcolstarts = -1;
5369     for(col=0; col < cols; col++)
5370       {
5371         if(position==NULL)
5372             pos='L';
5373         else
5374             pos=position[col];
5375         if(col_starts[col] < oldcolstarts)
5376           {
5377             pdf_advance(page_height);
5378           }
5379 	pdf_print_symbol(col_starts[col], page_height, 10, pos, header[col]);
5380         oldcolstarts = col_starts[col];
5381       }
5382 }
5383 
pdf_print_symbol_no(char value,char * symbolstring,float lx,float * page_height,char pos)5384 void pdf_print_symbol_no(char value, char* symbolstring, float lx, float *page_height, char pos)
5385 {
5386       if (value!='?')
5387 	pdf_printf(lx, *page_height, pos, "%s", symbolstring);
5388       else
5389 	pdf_printf(lx, *page_height, pos, "%s", "?");
5390 }
5391 
5392 
pdf_print_symbol(float lx,float * page_height,long fontsize,char pos,char * symbolstring)5393 void pdf_print_symbol(float lx, float *page_height, long fontsize, char pos, char *symbolstring)
5394 {
5395   int topop;
5396   int frompop;
5397   char value = '?';
5398   if (symbolstring != NULL)
5399     {
5400       value = symbolstring[0];
5401     }
5402   switch(value)
5403     {
5404     case 'T':
5405       if(symbolstring[1]=='h')
5406 	{
5407 	  sscanf(symbolstring,"Theta_%i",&topop);
5408 	  symbol_Theta(lx, *page_height, fontsize, topop);
5409 	}
5410       else
5411 	pdf_print_symbol_no(value, symbolstring, lx, page_height, pos);
5412       break;
5413     case 'Q':
5414       if(symbolstring[1]=='_')
5415 	{
5416 	  sscanf(symbolstring,"Q_%i",&topop);
5417 	  symbol_Theta(lx, *page_height, fontsize, topop);
5418 	}
5419       else
5420 	pdf_print_symbol_no(value, symbolstring, lx, page_height, pos);
5421       break;
5422     case 'M':
5423       if(symbolstring[1]!='_')
5424 	pdf_printf(lx, *page_height, pos, "%s", symbolstring);
5425       else
5426 	{
5427 	  sscanf(symbolstring,"M_%i->%i",&frompop,&topop);
5428 	  symbol_M(lx, *page_height, fontsize, frompop, topop, TRUE);
5429 	}
5430       break;
5431     case 'x':
5432       if(symbolstring[1]=='N')
5433 	{
5434 	  sscanf(symbolstring,"xNm_%i->%i",&frompop,&topop);
5435 	  symbol_M(lx, *page_height, fontsize, frompop, topop, TRUE);
5436 	}
5437       else
5438 	pdf_print_symbol_no(value, symbolstring, lx, page_height, pos);
5439       break;
5440     case '_':
5441       switch (symbolstring[1])
5442 	{
5443 	case 'T':
5444 	  pdf_printf(lx, *page_height, pos, "%s", symbolstring+1);//should print TOTAL
5445 	  break;
5446 	case 'H':
5447 	  symbol_Hexp(lx, *page_height, fontsize);
5448 	  break;
5449 	}
5450       break;
5451     default:
5452       pdf_print_symbol_no(value, symbolstring, lx, page_height, pos);
5453     }
5454 }
5455 
5456 ///
5457 /// generic table generator using header and elements arrays
5458 /// \param float left_margin left edge of table
5459 /// \param float * page_height page height
5460 /// \param int cols number of columns in table if there are too many columns then new line
5461 /// \param int rows number of rows in table, if a new page is needed then header is repeated
5462 /// \param char *** elements all table elements, currently no formatting of these
5463 /// \param char ** header   header row
5464 /// \param char *position position of all elements: L=left, R=right, C=center
5465 /// \param int col_overflow when there are too many columns this is the column to restart
pdf_table2(float left_margin,float * page_height,int cols,int rows,char ** header,char *** elements,char * position,int col_overflow,float separator)5466 long pdf_table2(float left_margin, float *page_height, int cols, int rows, char **header, char ***elements, char *position, int col_overflow, float separator)
5467 {
5468     boolean new_page=FALSE;
5469 
5470     int row;
5471     int col;
5472     long location=0;
5473 
5474     char pos;
5475 
5476     float *col_widths;
5477     float page_width = pdf_contents_get_width(canvas);
5478     float right_margin = page_width - 55;
5479     float *col_starts;
5480     float oldcol = __FLT_MAX__ - 1.0f;
5481 
5482     col_widths = (float *) mycalloc(cols,sizeof(float));
5483     col_starts = (float *) mycalloc(cols,sizeof(float));
5484 
5485     find_col_width(cols, rows, elements, header, col_widths);
5486     define_col_start(cols, col_widths, col_overflow, position, left_margin, right_margin, separator, col_starts);
5487 
5488     pdf_print_table_header(page_height, position, cols, col_starts,header);
5489     new_page = pdf_advance(page_height);
5490     pdf_draw_line(55,*page_height+5.0,right_margin, *page_height+5.0);
5491 
5492     for(row=0; row< rows; row++)
5493       {
5494         if(new_page)
5495           {
5496             pdf_print_table_header(page_height, position, cols,col_starts,header);
5497             //xcode new_page =
5498             pdf_advance(page_height);
5499             pdf_draw_line(55.,*page_height,right_margin, *page_height);
5500             new_page = pdf_advance(page_height);
5501           }
5502         for(col=0;col < cols; col++)
5503           {
5504             if(col_starts[col] < oldcol)
5505               {
5506                 new_page = pdf_advance(page_height);
5507                 if(new_page)
5508                   {
5509                     pdf_print_table_header(page_height, position, cols,col_starts,header);
5510                     //xcode new_page =
5511                     pdf_advance(page_height);
5512                     pdf_draw_line(55.,*page_height,right_margin, *page_height);
5513                     new_page = pdf_advance(page_height);
5514                   }
5515               }
5516             if(position==NULL)
5517                 pos='L';
5518             else
5519                 pos=position[col];
5520             pdf_print_symbol(col_starts[col],page_height,10,pos,elements[row][col]);
5521 	    //            pdf_printf(col_starts[col],*page_height, pos, "%s",elements[row][col]);
5522             oldcol = col_starts[col];
5523           }
5524       }
5525     pdf_advance(page_height);
5526     myfree(col_widths);
5527     myfree(col_starts);
5528     return location;
5529 }
5530 
5531 ///
5532 /// generic table generator using a buffer that contains header and elements, these
5533 /// are then split into header and elements, this approach allows to use the existing
5534 /// machinery for MPI.
5535 /// \param float left_margin left edge of table
5536 /// \param float * page_height page height
5537 /// \param int cols number of columns in table if there are too many columns then new line
5538 /// \param int rows number of rows in table, if a new page is needed then header is repeated
5539 /// \param char *** elements all table elements, currently no formatting of these
5540 /// \param char ** header   header row
5541 /// \param char *position position of all elements: L=left, R=right, C=center
5542 /// \param int col_overflow when there are too many columns this is the column to restart
pdf_table(float left_margin,float * page_height,int cols,int rows,char ** buffer,char * position,int col_overflow,float separator)5543 void pdf_table(float left_margin, float *page_height, int cols, int rows, char **buffer, char *position, int col_overflow, float separator)
5544 {
5545     int row;
5546     //  long location=0;
5547     char **header;
5548     char ***elements;
5549 
5550     charvec2d(&header, cols, LINESIZE);
5551     elements = (char ***) mycalloc(rows, sizeof(char **));
5552     for(row=0; row < rows; row++)
5553       {
5554         charvec2d(&(elements[row]),cols, LINESIZE);
5555       }
5556 
5557     translate_buffer_table(cols, rows, buffer, header, elements);
5558 
5559     pdf_table2(left_margin, page_height, cols, rows, header, elements, position, col_overflow, separator);
5560 
5561     free_charvec2d(header);
5562     for(row=0; row < rows; row++)
5563         free_charvec2d(elements[row]);
5564     myfree(elements);
5565     // return location;
5566 }
5567 
5568 
5569 ///
5570 /// pdf print profile tables for percentiles, returns the number
5571 /// of failed convergences to a specific percentile.
5572 void
pdf_print_profile_percentile(world_fmt * world)5573 pdf_print_profile_percentile (world_fmt * world)
5574 {
5575     long i, j, jj;
5576     float page_width = pdf_contents_get_width(canvas);
5577     char **buffer = &world->buffer;
5578     long failed=0;
5579     long cols = 10;
5580     long maxrows = world->numpop2 + (long) world->options->gamma;
5581     long rows=0;
5582     long row;
5583     char **header;
5584     char ***elements;
5585     charvec2d(&header, cols, LINESIZE);
5586     sprintf(header[0]," ");
5587     sprintf(header[1],"0.005");
5588     sprintf(header[2],"0.025");
5589     sprintf(header[3],"0.05");
5590     sprintf(header[4],"0.25");
5591     sprintf(header[5],"MLE");
5592     sprintf(header[6],"0.75");
5593     sprintf(header[7],"0.95");
5594     sprintf(header[8],"0.975");
5595     sprintf(header[9],"0.995");
5596 
5597     elements = (char ***) mycalloc(maxrows, sizeof(char **));
5598     for(row=0; row < maxrows; row++)
5599       {
5600         charvec2d(&(elements[row]),cols, LINESIZE);
5601       }
5602     (*buffer)[0]='\0';
5603     pdf_print_section_title(&page_width, &page_height, "Summary of profile likelihood percentiles of all parameters");
5604     pdf_advance(&page_height);
5605     pdf_advance(&page_height);
5606     pdf_printf(55.,page_height,'L',"Parameter");
5607     pdf_printf(55.+100.,page_height,'L',"Percentiles");
5608     pdf_advance(&page_height);
5609     pdf_draw_line(100., page_height, page_width-55., page_height);
5610     pdf_advance(&page_height);
5611     rows=0;
5612     for (i = 0; i < maxrows; i++)
5613       {
5614         if (world->quantiles[i].name[0] == '\0')
5615             continue;  /* this variable was not estimated, so return */
5616 
5617         sprintf (elements[rows][0], "%-10.10s", world->quantiles[i].name);
5618         for (j = 0; j < GRIDSIZE; j++)
5619           {
5620             jj = warp (j);
5621             if (world->quantiles[i].param[j] < 0)
5622               {
5623                 sprintf (elements[rows][j], "-");
5624               }
5625             else
5626               {
5627                 nice_element(world->quantiles[i].param[jj],elements[rows][j+1], 0.0001, 100, 1000, 4 , 2, '\0');
5628               }
5629           }
5630         rows++;
5631       }
5632 
5633     pdf_table2(55., &page_height, cols, rows, header, elements, NULL, 1, 10.);
5634     pdf_table_footnote(55., &page_height, failed, PERCENTILES);
5635 
5636     myfree(header);
5637     for(row=0; row < maxrows; row++)
5638         free_charvec2d(elements[row]);
5639     myfree(elements);
5640 
5641 }
5642 
5643 
5644 
5645 
5646 ///
5647 /// plot event histograms
5648 void
pdf_event_histogram(long loci,long numparams,world_fmt * world)5649 pdf_event_histogram(long loci, long numparams,  world_fmt *world)
5650 {
5651     float   page_width;
5652     float   lx;
5653     float   ly;
5654     float   ph;
5655     float   delta;
5656     float   w;
5657     float * binning;
5658 
5659     long    eventbinnum_allmax = 0L;
5660     long    loc;
5661     long    i;
5662     long    i0;
5663     long    j;
5664     long    bins;
5665     long    frompop;
5666     long    topop;
5667     long  * eventbinnum;
5668 
5669     char  * set50;
5670     char  * set95;
5671     char    title[LINESIZE];
5672     float total;
5673 
5674     float ** eventbins_all;
5675 
5676     duo ** eventbins;
5677 
5678 
5679     if (loci > 1)
5680         sprintf(title,"Summary of events through time over all loci");
5681     else
5682         sprintf(title,"Events through time");
5683 
5684     // add a new page so that we can print at least four histograms
5685     pdf_new_page("");
5686     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
5687     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
5688 
5689     /* Start to print text. */
5690     page_height = pdf_contents_get_height(canvas);
5691     page_width = pdf_contents_get_width(canvas);
5692     pdf_print_contents_at((page_width - w)/2, page_height - 100, title);
5693     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
5694     page_height -= 126;
5695     pdf_draw_line(50, page_height, page_width-50, page_height);
5696     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
5697     // first histogram position
5698     page_height -= 150;
5699     lx = 100;
5700     ly = page_height;
5701 
5702     //    for (loc = 0; loc < loci; loc++)
5703     //  {
5704     loc = loci > 1 ? loci : 0;
5705     eventbinnum = world->mighistloci[loc].migeventbinnum;
5706     for(i0=0; i0< world->numpop2 ; i0++)
5707       {
5708         if(world->bayes->map[i0][1] == INVALID)
5709             continue;
5710         else
5711             i = world->bayes->map[i0][1];
5712 
5713         if(eventbinnum[i] > eventbinnum_allmax)
5714 	  eventbinnum_allmax = eventbinnum[i];
5715       }
5716     //}
5717     floatvec2d(&eventbins_all,world->numpop2,eventbinnum_allmax);
5718     total = 0.0F;
5719     for (loc = 0; loc < loci; loc++)
5720       {
5721 	eventbinnum = world->mighistloci[loc].migeventbinnum;
5722 	eventbins = world->mighistloci[loc].migeventbins;
5723 	for(i0=0; i0< numparams ; i0++)
5724 	  {
5725 	    if(world->bayes->map[i0][1] == INVALID)
5726 	      continue;
5727 	    else
5728 	      i = world->bayes->map[i0][1];
5729 
5730 	    for(j=0 ; j < eventbinnum[i]; j++)
5731 	      {
5732 		if(eventbins[i][j][0] > 0.0)
5733 		  {
5734 		    eventbins_all[i][j] += (float) eventbins[i][j][0];
5735 		    total += (MYREAL) eventbins[i][j][0];
5736 		  }
5737 	      }
5738 	  }
5739       }
5740     bins = eventbinnum_allmax;
5741 
5742     set50 = (char *) mycalloc(bins+1, sizeof(char));
5743     set95 = (char *) mycalloc(bins+1, sizeof(char));
5744     memset (set50, '0', bins * sizeof(char));
5745     memset (set95, '0', bins * sizeof(char));
5746 
5747     binning = (float *) mycalloc (bins+1, sizeof (float));
5748 
5749     delta = world->mighistloci[0].eventbinsize;
5750     binning[0] = 0.5 * delta;
5751     for (i = 1; i < bins; i++)
5752       binning[i] = delta + binning[i - 1];
5753 
5754     for (i0 = (world->options->mighist_all ? 0 : world->numpop); i0 < numparams; i0++)
5755       {
5756 	if(world->bayes->map[i0][1] == INVALID)
5757 	  continue;
5758 	else
5759 	  i = world->bayes->map[i0][1];
5760 
5761 	m2mm(i, world->numpop, &frompop, &topop);
5762 	if(frompop==topop)
5763 	  {
5764 	    pdf_print_contents_at(lx-30,ly+125,"Freq. for ");
5765 	    symbol_Theta(lx+12, ly+125,12,frompop+1);
5766 	  }
5767 	else
5768 	  {
5769 	    pdf_print_contents_at(lx-30,ly+125,"Freq. for ");
5770 	    symbol_M(lx+12, ly+125, 12, frompop+1, topop+1, world->options->usem);
5771 	  }
5772 	pdf_print_contents_at(lx+90,ly-25, "Time [scaled by mutation rate / site / generation]");
5773 	pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
5774 	pdf_histogram(eventbins_all[i], set50, set95, bins, delta,
5775 		      0., -999, lx, ly, page_width - 55 - lx, 116,TRUE,NULL);
5776 	page_height -= 160;
5777 	if(i < (numparams-1))
5778 	  {
5779 	    pdf_page_advance_or_not(&page_height, 50);
5780 	    ph = pdf_contents_get_height(canvas) - 55 - LINESTRETCH;
5781 	    if(page_height >= ph)
5782 	      page_height -= 150;
5783 	    ly = page_height;
5784 	  }
5785       }
5786     myfree(binning);
5787     myfree(set50);
5788     myfree(set95);
5789     free_floatvec2d(eventbins_all);
5790 }
5791 
5792 
5793 ///
5794 /// plot skyline histograms
5795 void
pdf_skyline_histogram(long loci,long numparams,world_fmt * world,boolean enlarged)5796 pdf_skyline_histogram(long loci, long numparams,  world_fmt *world, boolean enlarged)
5797 {
5798     float   page_width;
5799     float   lx;
5800     float   ly;
5801     float   ph;
5802     float   delta;
5803     float   w;
5804     float * binning;
5805     float **confidence;
5806     float   c;
5807     float   lasttimebin;
5808     float   upperlimit;
5809     float maxtime;
5810     MYREAL *eventbin1max;
5811     //    float  confidencesum;
5812     long    clong;
5813     long    eventbinnum_allmax = 0L;
5814     long    loc;
5815     long    i;
5816     long    i0;
5817     long    j;
5818     long    bins;
5819     long    adjustbins;
5820     long    pop;
5821     long    frompop;
5822     long    topop;
5823     long  * eventbinnum;
5824 
5825     char  * set50;
5826     char  * set95;
5827     char    title[LINESIZE];
5828 
5829 
5830     float ** eventbins_all;
5831     MYREAL **std;
5832 
5833     tetra ** eventbins;
5834 
5835 
5836     if (loci > 1)
5837       {
5838         sprintf(title,"Summary of parameter values through %s over all loci",
5839                 enlarged ? "RECENT time" : "time");
5840       }
5841     else
5842       {
5843         sprintf(title,"Parameter values through %s",enlarged ? "RECENT time" : "time");
5844       }
5845     // add a new page so that we can print at least four histograms
5846     pdf_new_page("");
5847     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
5848     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
5849 
5850     /* Start to print text. */
5851     page_height = pdf_contents_get_height(canvas);
5852     page_width = pdf_contents_get_width(canvas);
5853     pdf_print_contents_at((page_width - w)/2, page_height - 100, title);
5854     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
5855     page_height -= 126;
5856     pdf_draw_line(50, page_height, page_width-50, page_height);
5857     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
5858     // first histogram position
5859     page_height -= 150;
5860     lx = 100;
5861     ly = page_height;
5862 
5863     //    for (loc = 0; loc < loci; loc++)
5864     // {
5865     loc = (loci > 1) ? loci : 0;
5866     eventbinnum = world->mighistloci[loc].eventbinnum;
5867     for(i0=0; i0< world->numpop2 ; i0++)
5868       {
5869         if(world->bayes->map[i0][1] == INVALID)
5870             continue;
5871         else
5872             i = world->bayes->map[i0][1];
5873 
5874         if(eventbinnum[i] > eventbinnum_allmax)
5875             eventbinnum_allmax = eventbinnum[i];
5876       }
5877     // }
5878     floatvec2d(&eventbins_all,world->numpop2, eventbinnum_allmax+1);
5879     doublevec2d(&std,world->numpop2, eventbinnum_allmax+1);
5880     floatvec2d(&confidence,world->numpop2, eventbinnum_allmax+1);
5881     eventbin1max = (MYREAL *) mycalloc(world->numpop2,sizeof(MYREAL));
5882     loc = (loci > 1) ? loci : 0;
5883     eventbinnum = world->mighistloci[loc].eventbinnum;
5884     eventbins = world->mighistloci[loc].eventbins;
5885     for(i0=0; i0< numparams ; i0++)
5886       {
5887         if(world->bayes->map[i0][1] == INVALID)
5888             continue;
5889         else
5890             i = world->bayes->map[i0][1];
5891 
5892         for(j=0 ; j < eventbinnum[i]; j++)
5893           {
5894             if(eventbins[i][j][1] > 0.0)
5895               {
5896                 eventbins_all[i][j] = eventbins[i][j][0];
5897                 std[i][j] = (MYREAL) eventbins[i][j][2] * 1.96; // standard error * 1.96
5898                 //old e...[2] changed to stderr: std[i][j] = (MYREAL) eventbins[i][j][2]; // standard deviation
5899 		//never used                std[i][j] /= 0.510204 * eventbins[i][j][4]; // standard error[=std/number in bin] * 1.96
5900                 if(eventbins[i][j][1] > eventbin1max[i])
5901                     eventbin1max[i] = eventbins[i][j][1];
5902               }
5903           }
5904       }
5905 
5906     for(i0=0; i0< numparams ; i0++)
5907       {
5908         if(world->bayes->map[i0][1] == INVALID)
5909             continue;
5910         else
5911             i = world->bayes->map[i0][1];
5912 
5913         for(j=0 ; j < eventbinnum[i]; j++)
5914           {
5915 	    //c = MAX(0.0,MIN(1.0,(float) (eventbins[i][j][1])));
5916 	    clong = (long) eventbins[i][j][4];
5917 	    if(clong < 100 )
5918 	      c = 0.01;
5919 	    else if(clong < 400)
5920 	      c = 0.1;
5921 	    else if (clong < 1600)
5922 	      c = 0.5;
5923 	    else if (clong < 3200)
5924 	      c = 0.70;
5925 	    else if (clong < 6400)
5926 	      c = 0.8;
5927 	    else if (clong < 12800)
5928 	      c = 0.9;
5929 	    else
5930 	      c = 1.0;
5931 
5932             confidence[i][j] = 1.0 - c;
5933           }
5934       }
5935 
5936     bins = eventbinnum_allmax;
5937 
5938     set50 = (char *) mycalloc(bins+1, sizeof(char));
5939     set95 = (char *) mycalloc(bins+1, sizeof(char));
5940     memset (set50, '0', bins * sizeof(char));
5941     memset (set95, '0', bins * sizeof(char));
5942 
5943     binning = (float *) mycalloc (bins+1, sizeof (float));
5944 
5945     delta = world->mighistloci[0].eventbinsize;
5946     binning[0] = 0.5 * delta;
5947     for (i = 1; i < bins; i++)
5948         binning[i] = delta + binning[i - 1];
5949 
5950     for (i0 = (world->options->mighist_all ? 0 : world->numpop); i0 < numparams; i0++)
5951       {
5952         if(world->bayes->map[i0][1] == INVALID)
5953             continue;
5954         else
5955             i = world->bayes->map[i0][1];
5956 
5957         m2mm(i0, world->numpop, &frompop, &topop);
5958         if(frompop==topop)
5959           {
5960             symbol_Theta(lx-40, ly+125, 12, frompop+1);
5961             pdf_print_contents_at(lx+90,ly-25, "Time [scaled by mutation rate / generation (DNA: per site, other: per locus)]");
5962           }
5963         else
5964           {
5965             symbol_M(lx-40, ly+125, 12, frompop+1, topop+1, world->options->usem);
5966             pdf_print_contents_at(lx+90,ly-25, "Time [scaled by mutation rate / generation (DNA: per site, other: per locus)]");
5967           }
5968         pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
5969 
5970 	// focus on all recorded times or only on 0..mean of largest population
5971         if(!enlarged)
5972           {
5973 	    // all records
5974 	    upperlimit = quantiler(eventbins_all[i], 1.00, 1.00, (long) bins/2,bins);
5975 	    if(upperlimit < 2*world->bayes->histogram[loc].modes[i])
5976 	      upperlimit =  2*world->bayes->histogram[loc].modes[i];
5977 	    pdf_histogram_plus(eventbins_all[i], std[i], set50, set95, bins, delta,
5978 			       0., -9999, lx, ly, page_width - 55 - lx, 116, upperlimit, TRUE, world, confidence[i], topop);
5979           }
5980         else
5981           {
5982 	    // up to mean of largest population
5983             loc = (loci > 1) ? loci : 0;
5984 	    //            m2mm(i, world->numpop, &frompop, &topop);
5985 	    maxtime = world->bayes->histogram[loc].means[0];
5986 	    for(pop=1;pop<world->numpop;pop++)
5987 	      {
5988 		if(world->bayes->histogram[loc].means[pop]>maxtime)
5989 		  maxtime=world->bayes->histogram[loc].means[pop];
5990 	      }
5991 	    //xcode j=eventbinnum[i]-1;
5992 	    adjustbins = ceil(maxtime/delta);
5993 	    // why could bin be smaller than adjustbins?
5994             bins = bins < adjustbins ? bins : adjustbins;
5995 	    if(bins==0)
5996 	      continue;
5997 	    lasttimebin = delta * bins;
5998 	    // evaluates how much of the y-axis should be shown
5999 	    upperlimit = quantiler(eventbins_all[i], 1.0, 0.95, (long) bins/2,bins);
6000             pdf_histogram_plus(eventbins_all[i], std[i], set50, set95, bins, delta,
6001                                0., lasttimebin,
6002                                lx, ly, page_width - 55 - lx, 116, upperlimit ,TRUE, world, confidence[i], topop);
6003           }
6004         page_height -= 160;
6005         if(i < (numparams-1))
6006           {
6007             pdf_page_advance_or_not(&page_height, 50);
6008             ph = pdf_contents_get_height(canvas) - 55 - LINESTRETCH;
6009             if(page_height >= ph)
6010                 page_height -= 150;
6011             ly = page_height;
6012           }
6013       }
6014     myfree(binning);
6015     myfree(set50);
6016     myfree(set95);
6017     free_floatvec2d(eventbins_all);
6018     free_doublevec2d(std);
6019     free_floatvec2d(confidence);
6020     myfree(eventbin1max);
6021 }
6022 ///
6023 /// Data set was subsampled and used a random sample of size
pdf_print_random_subset(data_fmt * data,option_fmt * options)6024 void pdf_print_random_subset(data_fmt * data, option_fmt *options)
6025 {
6026   long locus;
6027   long pop;
6028   char *name;
6029   char **header;
6030   char ***elements;
6031   float page_width;
6032   long elements_alloc = data->loci * data->numpop;
6033   long linenumber;
6034   long maxnum;
6035   long count = 0;
6036   long ind;
6037   long index;
6038   long length;
6039   if(options->randomsubset > 0)
6040     {
6041     //print title
6042     page_width = pdf_contents_get_width(canvas);
6043     pdf_print_section_title(&page_width, &page_height, "Subsampled dataset");
6044     pdf_advance(&page_height);
6045     pdf_printf(55.,page_height, 'L', "Data set was subsampled randomly per population: %li samples taken",
6046 	       options->randomsubset);
6047     pdf_advance(&page_height);
6048     charvec2d(&header, 3,LINESIZE);
6049     sprintf(header[0],"Locus");
6050     sprintf(header[1],"Population");
6051     sprintf(header[2],"Individuals");
6052     name = (char*) mycalloc(options->nmlength+1,sizeof(char));
6053     elements = (char ***) mycalloc(elements_alloc, sizeof(char**));
6054     linenumber=0;
6055     for (locus=0; locus < data->loci; locus++)
6056       {
6057 	for (pop=0; pop < data->numpop; pop++)
6058 	    {
6059 	      if(linenumber>=elements_alloc)
6060 		{
6061 		  elements_alloc += data->loci * data->numpop;
6062 		  elements = (char***) realloc(elements,sizeof(char **) * elements_alloc);
6063 		}
6064 	      elements[linenumber] = (char **) mycalloc(3,sizeof(char *));
6065 	      elements[linenumber][0] = (char *) mycalloc(7, sizeof(char));
6066 	      elements[linenumber][1] = (char *) mycalloc(12, sizeof(char));
6067 	      elements[linenumber][2] = (char *) mycalloc(LINELENGTH, sizeof(char));
6068 	      if(pop==0)
6069 		sprintf(elements[linenumber][0],"%5li ",locus+1);
6070 	      else
6071 		sprintf(elements[linenumber][0]," ");
6072 	      sprintf(elements[linenumber][1], "%-10.10s ", data->popnames[pop]);
6073 	      maxnum = options->randomsubset < data->numind[pop][locus] ? options->randomsubset : data->numind[pop][locus];
6074 	      count = 0;//18 characters are already consumed on line, see below
6075 	      for(ind=0;ind<maxnum;ind++)
6076 		{
6077 		  index = data->shuffled[pop][locus][ind];
6078 		  if(data->indnames[pop][index][locus][0]=='\0')
6079 		    memcpy(name,data->indnames[pop][index][0],sizeof(char)*options->nmlength);
6080 		  else
6081 		    memcpy(name,data->indnames[pop][index][locus],sizeof(char)*options->nmlength);
6082 		  remove_trailing_blanks(&name);
6083 		  length = strlen(name);
6084 		  if (count+length < LINELENGTH-18)
6085 		    {
6086 		      count += sprintf(elements[linenumber][2] + count ,"%s ",name);
6087 		    }
6088 		  else
6089 		    {
6090 		      sprintf(elements[linenumber][2] + count ,"\n");
6091 		      count = 0;
6092 		      linenumber++;
6093 		      if(linenumber>=elements_alloc)
6094 			{
6095 			  elements_alloc += data->loci * data->numpop;
6096 			  elements = (char***) realloc(elements,sizeof(char **) * elements_alloc);
6097 			}
6098 		      elements[linenumber] = (char **) mycalloc(3,sizeof(char *));
6099 		      elements[linenumber][0] = (char *) mycalloc(7, sizeof(char));
6100 		      elements[linenumber][1] = (char *) mycalloc(12, sizeof(char));
6101 		      elements[linenumber][2] = (char *) mycalloc(LINELENGTH, sizeof(char));
6102 		      sprintf(elements[linenumber][0]," ");
6103 		      sprintf(elements[linenumber][1]," ");
6104 		      count += sprintf(elements[linenumber][2] + count ,"%s ",name);
6105 		    }
6106 		}
6107 	      linenumber++;
6108 	    }
6109       }
6110     pdf_table2(55., &page_height, 3, linenumber, header, elements, NULL, 2, 10.0);
6111     myfree(name);
6112     myfree(header);
6113     for (locus=0; locus < linenumber;locus++)
6114       {
6115 	myfree(elements[locus][0]);
6116 	myfree(elements[locus][1]);
6117 	myfree(elements[locus][2]);
6118 	myfree(elements[locus]);
6119       }
6120     myfree(elements);
6121     }
6122 }
6123 
pdf_print_spectra(data_fmt * data,option_fmt * options,MYREAL *** freq,MYREAL ** total,MYREAL * grandtotal,MYREAL * avghet,MYREAL avghet1,long * maxalleles)6124 void pdf_print_spectra(data_fmt *data, option_fmt *options, MYREAL ***freq, MYREAL ** total, MYREAL *grandtotal, MYREAL *avghet, MYREAL avghet1, long * maxalleles)
6125 {
6126     char **header;
6127     char ***elements;
6128     long mostalleles =0;
6129     long pop;
6130     long locus;
6131     long a;
6132     long *maxallelepop;
6133     float page_width;
6134     MYREAL allfreq;
6135     long pop1;
6136     float homo;
6137     float f;
6138     float fx;
6139     float general_homo;
6140     float v;
6141 
6142     //float numdiv = options->newpops_numpop;
6143     maxallelepop = (long *) mycalloc(data->numpop, sizeof(long));
6144     charvec2d(&header, data->numpop+2,LINESIZE);
6145     //print title
6146     page_width = pdf_contents_get_width(canvas);
6147     pdf_print_section_title(&page_width, &page_height, "Allele frequency spectra");
6148     // loop over loci
6149     pdf_advance(&page_height);
6150     // header
6151     sprintf(header[0],"Allele");
6152     for(pop1=0; pop1 < data->numpop; pop1++)
6153       {
6154 	pop = options->newpops[pop1]-1;
6155         sprintf(header[pop1+1],"Pop%-3li",pop+1);
6156       }
6157     sprintf(header[pop1+1],"All");
6158     for(locus=0; locus < data->loci; locus++)
6159       {
6160         if(mostalleles < maxalleles[locus])
6161             mostalleles = maxalleles[locus];
6162       }
6163     // max of alleles + Total + H_exp; this is done for each locus
6164     elements = (char ***) mycalloc(mostalleles+3, sizeof(char**));
6165     for(a=0; a < mostalleles+3; a++)
6166       {
6167         charvec2d(&elements[a],data->numpop+2, LINESIZE);
6168       }
6169     //avghet1 = 0.0;
6170     for(locus=0; locus < data->loci; locus++)
6171       {
6172         memset(maxallelepop,'\0',sizeof(long)*data->numpop);
6173         pdf_printf(55.,page_height, 'L', "Locus %i",locus+1);
6174         pdf_advance(&page_height);
6175 	general_homo=0.0;
6176         for(a=0; a < maxalleles[locus]; a++)
6177           {
6178             sprintf(elements[a][0],"%s ",data->allele[locus][a]);
6179             allfreq = 0.0;
6180             for(pop1=0; pop1 < data->numpop; pop1++)
6181               {
6182 		pop = options->newpops[pop1]-1;
6183 		// freq was constructed using newpop!!
6184 		if (freq[pop][locus][a]>0.0)
6185 		  {
6186 		    maxallelepop[pop1] += 1;
6187 		    sprintf(elements[a][pop1+1],"%1.3f",freq[pop][locus][a]/total[pop][locus]);
6188 		    allfreq += freq[pop][locus][a];
6189 		  }
6190 		else
6191 		  {
6192 		    sprintf(elements[a][pop1+1],"  -  ");
6193 		  }
6194 	      }
6195             sprintf(elements[a][pop1+1],"%1.3f",allfreq/grandtotal[locus]);
6196 	    fx  =  allfreq/grandtotal[locus];
6197 	    general_homo += fx * fx;
6198           }
6199 	// see symbol printing the _ triggers the correct printing of these keywords
6200 	//        sprintf(elements[a][0],"_Total");
6201         sprintf(elements[a][0],"Alleles");
6202         for(pop1=0; pop1 < data->numpop; pop1++)
6203           {
6204             sprintf(elements[a][pop1+1],"%li", maxallelepop[pop1]);
6205           }
6206         sprintf(elements[a][pop1+1],"%li",(long) maxalleles[locus]);
6207         sprintf(elements[a+1][0],"Samplesize");
6208         for(pop1=0; pop1 < data->numpop; pop1++)
6209           {
6210             sprintf(elements[a+1][pop1+1],"%li", (long) total[pop1][locus]);
6211           }
6212         sprintf(elements[a+1][pop1+1],"%li",(long) grandtotal[locus]);
6213 	sprintf(elements[a+2][0],"_H_exp");
6214 	//avghet1=0.0;
6215 	for (pop1 = 0; pop1 < data->numpop; pop1++)
6216 	  {
6217 	    pop = options->newpops[pop1]-1;
6218 	    homo = 0.0;
6219 	    for(a=0;a<maxalleles[locus];a++)
6220 	      {
6221 		f = freq[pop][locus][a]/total[pop][locus];
6222 		homo += f*f;
6223 	      }
6224 	    v = 1.0 - homo;
6225 	    //avghet1 += v;
6226 	    //avghet[pop1] += v;
6227 	    sprintf(elements[a+2][pop1+1],"%5.3f",v);
6228 	  }
6229 	sprintf(elements[a+2][pop1+1]," %5.3f",1.0-general_homo);
6230 	//avghet1 += 1.0 - general_homo;
6231         pdf_table2(55., &page_height, data->numpop+2,maxalleles[locus]+3, header, elements, NULL, 2, 10.0);
6232         pdf_advance(&page_height);
6233       }
6234     pdf_printf(55.,page_height, 'L', "Average expected heterozygosity");
6235     pdf_advance(&page_height);
6236     for (pop1 = 0; pop1 < data->numpop; pop1++)
6237     {
6238       pop = options->newpops[pop1]-1;
6239       sprintf(elements[0][pop1+1], "%5.3f ",avghet[pop1] / data->loci);
6240       //avghetall += avghet[pop1] / data->loci;
6241     }
6242     sprintf(elements[0][pop1+1],"%5.3f",avghet1/data->loci);
6243     strcpy(header[0]," ");
6244     strcpy(elements[0][0],"_H_exp");
6245     pdf_table2(55., &page_height, data->numpop+2,1, header, elements, NULL, 2, 10.0);
6246     free_charvec2d(header);
6247     for(a=0; a < mostalleles+2; a++)
6248         free_charvec2d(elements[a]);
6249     myfree(elements);
6250     myfree(maxallelepop);
6251     //myfree(avghet);
6252 }
6253 
6254 ///
6255 /// print average temperatures
pdf_print_averageheat(world_fmt ** universe,option_fmt * options)6256 void pdf_print_averageheat(world_fmt **universe, option_fmt *options)
6257 {
6258   long a;
6259     char **header;
6260     char ***elements;
6261     //  float position[10] = {55., 100., 150., 200., 250., 300., 350., 400., 450., 500.};
6262     float page_width;
6263     charvec2d(&header, 2,LINESIZE);
6264     //print title
6265     page_width = pdf_contents_get_width(canvas);
6266     pdf_print_section_title(&page_width, &page_height, "Average temperatures during the run");
6267     pdf_advance(&page_height);
6268     // header
6269     sprintf(header[0],"Chain");
6270     sprintf(header[1],"Temperatures");
6271     elements = (char ***) mycalloc(options->heated_chains, sizeof(char**));
6272     for(a=0; a < options->heated_chains; a++)
6273         charvec2d(&elements[a],2, LINESIZE);
6274     for(a=0; a < options->heated_chains; a++)
6275       {
6276 	sprintf(elements[a][0],"%5li ",a+1);
6277 	sprintf(elements[a][1],"%10.5f ",universe[a]->averageheat);
6278       }
6279     pdf_table2(55., &page_height, 2, options->heated_chains, header, elements, NULL, 2, 10.0);
6280     pdf_advance(&page_height);
6281     pdf_advance(&page_height);
6282     pdf_printf_next(55., &page_height,"Adaptive heating often fails, if the average temperatures are very close together\n");
6283     pdf_printf_next(55., &page_height,"try to rerun using static heating! If you want to compare models using marginal\n");
6284     pdf_printf_next(55., &page_height,"likelihoods then you MUST use static heating\n");
6285     pdf_advance(&page_height);
6286     free_charvec2d(header);
6287     for(a=0; a < options->heated_chains; a++)
6288         free_charvec2d(elements[a]);
6289     myfree(elements);
6290 }
6291 
6292 ///
6293 /// table frequency of events through time for each locus and all loci
pdf_print_eventtime_table(world_fmt * world)6294 void pdf_print_eventtime_table(world_fmt *world)
6295 {
6296     float   page_width;
6297     float   w;
6298     long    i;
6299     long    j;
6300     long    j0;
6301     long    frompop;
6302     long    topop;
6303     long  * eventbinnum;
6304     long locus;
6305     duo ** eventbins;
6306     float  age;
6307     char    title[LINESIZE];
6308     float left_margin = 55;
6309 
6310     sprintf(title,"Distribution of events trough time");
6311     pdf_new_page("");
6312     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
6313     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
6314 
6315     /* Start to print text. */
6316     page_height = pdf_contents_get_height(canvas);
6317     page_width = pdf_contents_get_width(canvas);
6318     pdf_print_contents_at((page_width - w)/2, page_height - 100, title);
6319     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
6320     page_height -= 126;
6321     pdf_draw_line(50, page_height, page_width-50, page_height);
6322     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
6323     for(locus=0;locus < world->loci + (world->loci > 1 ? 1 : 0); locus++)
6324       {
6325 	if(locus<world->loci)
6326 	  {
6327 	    if(world->data->skiploci[locus])
6328 	      continue;
6329 	  }
6330 	eventbins = world->mighistloci[locus].migeventbins;
6331 	eventbinnum = world->mighistloci[locus].migeventbinnum;
6332 	// population sizes
6333 	for(j0=0; j0 < world->numpop2; j0++)
6334 	  {
6335 	    if(world->bayes->map[j0][0] != INVALID)
6336 	      {
6337 		j = world->bayes->map[j0][1];
6338 
6339                 pdf_advance(&page_height);
6340                 if(locus == world->loci)
6341 		  pdf_printf(left_margin, page_height, 'L' , "All loci");
6342                 else
6343 		  pdf_printf(left_margin, page_height, 'L' , "Locus %li:",locus);
6344                 if(j0 < world->numpop)
6345 		  symbol_Theta(left_margin+80, page_height, 12, j0+1);
6346                 else
6347                   {
6348                     m2mm (j0, world->numpop, &frompop, &topop);
6349                     symbol_M(left_margin+80, page_height, 12, frompop+1, topop+1, world->options->usem);
6350                   }
6351                 pdf_advance(&page_height);
6352                 pdf_printf(left_margin, page_height, 'L', "Time");
6353                 pdf_printf(left_margin + 200, page_height, 'L', "Frequency of visit");
6354                 pdf_printf(left_margin + 400, page_height, 'L', "MRCA frequency");
6355                 pdf_advance_half(&page_height);
6356                 pdf_draw_line(50, page_height, page_width-50, page_height);
6357                 pdf_advance(&page_height);
6358                 age = -world->mighistloci[locus].eventbinsize/2.;
6359                 for(i = 0; i < eventbinnum[j]; i++)
6360                   {
6361                     age += world->mighistloci[locus].eventbinsize;
6362                     pdf_printf(left_margin, page_height, 'L', "%10.10f", age);
6363                     pdf_printf(left_margin+200, page_height, 'L', "%8.5f", (MYREAL) eventbins[j][i][0]);
6364                     pdf_printf(left_margin+400, page_height, 'L', "%8.5f", (MYREAL) eventbins[j][i][1]);
6365                     pdf_advance(&page_height);
6366                   }
6367                 pdf_draw_line(50, page_height, page_width-50, page_height);
6368                 pdf_advance(&page_height);
6369               }
6370           }
6371       }
6372 }
6373 ///
6374 /// average and median time for a events
pdf_print_time_table(world_fmt * world,float * meantime,float * mediantime,float * stdtime,float * freq,boolean mrca)6375 void pdf_print_time_table(world_fmt *world,
6376                           float *meantime, float *mediantime, float *stdtime, float *freq,
6377                           boolean mrca)
6378 {
6379     float   page_width;
6380     float   w;
6381     //    long    j;
6382     //    long    j0;
6383     long    pop;
6384     long    lp;
6385     long    frompop;
6386     long    topop;
6387 //    long  * eventbinnum;
6388     long    locus;
6389 //    duo **  eventbins;
6390     char    title[LINESIZE];
6391     float   left_margin = 55;
6392     if(mrca)
6393         sprintf(title,"Time and probability of location of most recent common ancestor");
6394     else
6395         sprintf(title,"Summary statistics of events through time");
6396     pdf_new_page("");
6397     pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
6398     w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
6399 
6400     /* Start to print text. */
6401     page_height = pdf_contents_get_height(canvas);
6402     page_width = pdf_contents_get_width(canvas);
6403     pdf_print_contents_at((page_width - w)/2, page_height - 100, title);
6404     pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
6405     page_height -= 126;
6406     pdf_draw_line(50, page_height, page_width-50, page_height);
6407     pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
6408     for(locus=0;locus < world->loci + (world->loci > 1 ? 1 : 0); locus++)
6409       {
6410 	if(world->data->skiploci[locus])
6411 	  continue;
6412 
6413       //xcode eventbins = world->mighistloci[locus].migeventbins;
6414       //xcode eventbinnum = world->mighistloci[locus].migeventbinnum;
6415 
6416         pdf_advance(&page_height);
6417         if(locus == world->loci)
6418             pdf_printf(left_margin, page_height, 'L' , "All loci");
6419         else
6420             pdf_printf(left_margin, page_height, 'L' , "Locus %li",locus+1);
6421 
6422         pdf_advance(&page_height);
6423         pdf_printf(left_margin, page_height, 'L', "Population");
6424         pdf_printf(left_margin + 100, page_height, 'L', "Time");
6425         pdf_printf(left_margin + 400, page_height, 'L', "Frequency");
6426         pdf_advance_half(&page_height);
6427         pdf_draw_line(left_margin + 100, page_height, left_margin+390, page_height);
6428         pdf_advance(&page_height);
6429         if(!mrca)
6430           {
6431             pdf_printf(left_margin, page_height, 'L', "From");
6432             pdf_printf(left_margin + 50, page_height, 'L', "To");
6433           }
6434         pdf_printf(left_margin + 100, page_height, 'L', "Average");
6435         pdf_printf(left_margin + 200, page_height, 'L', "Median");
6436         pdf_printf(left_margin + 300, page_height, 'L', "Std");
6437         pdf_advance_half(&page_height);
6438         pdf_draw_line(50, page_height, page_width-50, page_height);
6439         pdf_advance(&page_height);
6440         for (pop = (world->options->mighist_all ? 0 : world->numpop);
6441              pop <  (mrca ? world->numpop : world->numpop2); pop++)
6442           {
6443 	    if(world->bayes->map[pop][1] == INVALID)
6444 	      continue;
6445             lp = locus * world->numpop2 + pop;
6446             m2mm(pop,world->numpop,&frompop,&topop);
6447             if(freq[lp]>0.0)
6448               {
6449                 pdf_printf(left_margin,       page_height, 'L', "%li",frompop+1);
6450                 if(!mrca)
6451                     pdf_printf(left_margin + 50,  page_height, 'L', "%li", topop+1);
6452                 pdf_printf(left_margin + 100, page_height, 'L', "%f", meantime[lp]);
6453                 pdf_printf(left_margin + 200, page_height, 'L', "%f", mediantime[lp]);
6454                 pdf_printf(left_margin + 300, page_height, 'L', "%f", stdtime[lp]);
6455                 pdf_printf(left_margin + 400, page_height, 'L', "%f", freq[lp]);
6456                 pdf_advance(&page_height);
6457               }
6458           }
6459         pdf_advance(&page_height);
6460       }
6461 }
6462 
6463 
6464 ///
6465 /// plot event histograms
6466 void
pdf_histogram_legend()6467 pdf_histogram_legend()
6468 {
6469   float   page_width;
6470   float   lx;
6471   float   w;
6472   char    title[LINESIZE];
6473 
6474   // add a new page for the legend
6475   pdf_new_page("");
6476   sprintf(title,"%s","Legend for Skyline and Event plots");
6477   pdf_contents_set_font_and_size(canvas, "Helvetica-Oblique", 16);
6478   w = (float) pdf_contents_get_text_width(canvas, title, NULL, NULL);
6479 
6480   /* Start to print text. */
6481   page_height = pdf_contents_get_height(canvas);
6482   page_width = pdf_contents_get_width(canvas);
6483   pdf_print_contents_at((page_width - w)/2, page_height - 100, title);
6484   pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0, 0, 0));
6485   page_height -= 126;
6486   pdf_draw_line(50, page_height, page_width-50, page_height);
6487   pdf_contents_set_font_and_size(canvas, "Helvetica", 10);
6488   // first histogram position
6489   pdf_advance(&page_height);
6490   lx = 60;
6491   pdf_printf_next(lx-5, &page_height, "Skyline plots:");
6492   pdf_printf_next(lx, &page_height, "Skyline plots visualize the changes of population sizes and migration rates through time");
6493   pdf_printf_next(lx, &page_height, "(today is on the left side and time is measured into the past. The time scale is in units of");
6494   pdf_printf_next(lx, &page_height, "expected mutations per generation. To calculate the absolute time scale you must supply an");
6495   pdf_printf_next(lx, &page_height, "mutation rate per year and the duration of a  generation in years in the data option.");
6496   pdf_printf_next(lx, &page_height, "You can calculate the absolute time by multiplying the scale by generation time times ");
6497   pdf_printf_next(lx, &page_height, "mutation rate per year (per site for DNA; per locus for all other datatypes).");
6498   pdf_advance(&page_height);
6499   pdf_printf_next(lx, &page_height, "With estimated mutation rate only the combined rate modifier is plotted.");
6500   pdf_printf_next(lx, &page_height, "[this will change to  mutation rate plot].");
6501   pdf_advance(&page_height);
6502   pdf_printf_next(lx, &page_height, "The gray bars cover 1.96 * approximate standard error (std in file skylinefile/number");
6503   pdf_printf_next(lx, &page_height, "of observations in the bin) up and down from the expected value.");
6504   pdf_printf_next(lx, &page_height, "The bar with different shades of gray on top of each plot indicates the number of values that were used to");
6505   pdf_printf_next(lx, &page_height, "to calculate the expected value, white means there were very few and black means");
6506   pdf_printf_next(lx, &page_height, "that there were many thousands of samples per bin.");
6507   pdf_advance(&page_height);
6508   pdf_printf_next(lx, &page_height, "On some plots one can see red squares below the grayscale bar, these suggest that either the");
6509   pdf_printf_next(lx, &page_height, "upper quantile and/or the main value was higher than the visible part of the  axis.");
6510   pdf_advance(&page_height);
6511   pdf_advance(&page_height);
6512 
6513   pdf_printf_next(lx-5, &page_height, "Event histograms:");
6514   pdf_printf_next(lx, &page_height, "All accepted events (migration events, coalescent events) are recorded and their frequency");
6515   pdf_printf_next(lx, &page_height, "are shown as histograms over time with recent time on the left side. The frequency plots of");
6516   pdf_printf_next(lx, &page_height, "populations with constant size and constant immigration rates show histograms that are similar");
6517   pdf_printf_next(lx, &page_height, "to exponential distribution, if the populations come from a divergence model without migration");
6518   pdf_printf_next(lx, &page_height, "then the frequency of migration events can show a peak in the past.");
6519 }
6520 
6521 ///
6522 ///
findminmax(float * vals,const long n,float * min,float * max)6523 void findminmax(float *vals, const long n, float *min, float *max)
6524 {
6525   long i;
6526 #ifdef WINDOWS
6527   *min = 1000000;
6528   *max = -1000000;
6529 #else
6530   *min = HUGE;
6531   *max = -HUGE;
6532 #endif
6533   for(i=0; i < n; i++)
6534     {
6535       float v = (float) vals[i];
6536       if(*min > v)
6537 	*min = v;
6538       if(*max < v)
6539 	*max = v;
6540     }
6541   //  printf("min=%f, max=%f\n",*min,*max);
6542 }
6543 
6544 ///
6545 /// Line plot assumes that x and y are a series of coordinates, connection with a colored line with given thickness, dots are marked in color
pdf_linedotplot(long n,float * x,float * y,float dotcolor[],float linecolor[],MYREAL linethickness,float * page_height,float width,float height,boolean has_dots,boolean has_line)6546 void pdf_linedotplot(long n, float *x, float *y, float dotcolor[], float linecolor[], MYREAL linethickness, float * page_height, float width, float height, boolean has_dots, boolean has_line)
6547 {
6548   float minx;
6549   float miny;
6550   float maxx;
6551   float maxy;
6552   //  float page_width = pdf_contents_get_width(canvas);
6553   float lx = 100;
6554   float ly = *page_height - height;
6555   long i;
6556   float red = linecolor[0];
6557   float green = linecolor[1];
6558   float blue = linecolor[2];
6559   float xrange;
6560   float yrange;
6561   *page_height = ly;
6562   pdf_advance(page_height);
6563   findminmax(x, n, &minx, &maxx);
6564   findminmax(y, n, &miny, &maxy);
6565   pdf_create_axes(VERTICAL, miny, maxy, 5, lx, ly, height);
6566   pdf_create_axes(HORIZONTAL, minx , maxx, 9, lx, ly, width);
6567   if(has_line)
6568     {
6569       pdf_contents_set_line_width(canvas, linethickness);
6570       pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(red, green, blue));
6571       xrange = maxx - minx;
6572       yrange = maxy - miny;
6573       width /= xrange;
6574       height/= yrange;
6575       for(i=0; i < n-1; i++)
6576 	{
6577 	  pdf_draw_line(lx+(x[i]-minx)*width, ly+(y[i]-miny)*height,lx+(x[i+1]-minx)*width,ly+(y[i+1]-miny)*height);
6578 	}
6579       pdf_contents_set_rgb_stroke(canvas, PdfRGBColor(0.,0.,0.));//reset to black
6580     }
6581   if(has_dots)
6582     {
6583       for(i=0; i < n; i++)
6584 	{
6585 	  pdf_print_dot(lx+(x[i]-minx)*width, ly+(y[i]-miny)*height, 3, SQUARE, dotcolor);
6586 	}
6587     }
6588 }
6589 
6590 
6591 /*
6592 ==============================================================================
6593 Likelihood ratio tests
6594 ==============================================================================
6595 Over all loci
6596 Legend for the LRT tables
6597 -------------------------------------------------------------------------------
6598   Null-Hypothesis: your test model         | Log(likelihood) of test model
6599        =same=                                   | Log(likelihood) of full model
6600        full model (the model under which the    | Likelihood ratio test value
6601 		   genealogies were sampled)                | Degrees of freedom of test
6602 [Theta values are on the diagonal of the | Probability*
6603  Migration matrix, migration rates are    | Probability**
6604 specified as M]                          | Akaike's Information Criterion***
6605                                          | Number of parameters used
6606 -------------------------------------------------------------------------------
6607   *) Probability under the assumption that parameters have range -Inf to Inf
6608  **) Probability under the assumption that parameters have range 0 to Inf
6609 ***) AIC: the smaller the value the better the model
6610           [the full model has AIC=-2.396909, num(param)=4]
6611 */
6612 #define OFFSET 300
6613 #define OFFSET2 280
6614 #define ADDED 70
pdf_print_lrt_header(MYREAL aicfull,long aicfullparamnum,float * page_width,float * page_height)6615 void pdf_print_lrt_header(MYREAL aicfull, long aicfullparamnum,  float *page_width,  float *page_height)
6616 {
6617   float lx=55;
6618   float tempheight ;
6619   pdf_print_section_title(page_width, page_height, "Approximate Likelihood Ratio Tests");
6620   pdf_advance(page_height);
6621   lx = 60;
6622   pdf_printf_next(lx, page_height, "Legend for the likelihood ratio tables");
6623   pdf_draw_line(lx, *page_height, *page_width-lx, *page_height);
6624   tempheight = *page_height;
6625   pdf_advance(page_height);
6626   pdf_printf(lx, *page_height, 'L', "Null-Hypothesis: your test model");
6627   pdf_printf_next(lx+OFFSET, page_height, "Log(likelihood) of test model");
6628   //
6629   pdf_printf(lx, *page_height, 'L', "is equal to");
6630   pdf_printf_next(lx+OFFSET, page_height, "Log(likelihood) of full model");
6631   pdf_printf(lx, *page_height, 'L', "full model (the model under which the");
6632   pdf_printf_next(lx+OFFSET, page_height, "Likelihood ratio test value");
6633   pdf_printf(lx, *page_height, 'L', "genealogies were sampled)");
6634   pdf_printf_next(lx+OFFSET, page_height, "Degrees of freedom of test");
6635   pdf_printf_next(lx+OFFSET, page_height, "[Theta values are on the diagonal of the");
6636   pdf_printf_next(lx+OFFSET, page_height, "Probability*");
6637   pdf_printf(lx, *page_height, 'L',"Migration matrix, migration rates are");
6638   pdf_printf_next(lx+OFFSET, page_height, "Probability**");
6639   pdf_printf(lx, *page_height, 'L', "specified as M]");
6640   pdf_printf_next(lx+OFFSET, page_height, "Akaike's Information Criterion***");
6641   pdf_printf_next(lx+OFFSET, page_height, "Number of parameters used");
6642   pdf_draw_line(lx, *page_height, *page_width-lx, *page_height);
6643   pdf_draw_line(OFFSET2+lx, tempheight, OFFSET2+lx, *page_height);
6644   pdf_advance(page_height);
6645   pdf_printf_next(lx, page_height, "  *) Probability under the assumption that parameters have range -Inf to Inf");
6646   pdf_printf_next(lx, page_height, " **) Probability under the assumption that parameters have range 0 to Inf");
6647   pdf_printf_next(lx, page_height, "***) AIC: the smaller the value the better the model");
6648   pdf_printf_next(lx, page_height, "     [the full model has AIC=%f, num(param)=%li]",aicfull, aicfullparamnum);
6649 }
6650 
6651 /*
6652 -------------------------------------------------------------------------------
6653 H0: 0.0085 0.0000 262.32 0.0262                    | LnL(test) = 4.213529
6654  =  0.0085 12.065 262.32 0.0262                    | LnL(full) = 5.198454
6655 [ *, 0, *, *,]                                     | LRT       = 1.969850
6656                                                    | df        = 1
6657                                                    | Prob      = 0.160464
6658                                                    | Probc     = 0.047160
6659                                                    | AIC       = -2.427058
6660                                                    | num(param)= 3
6661 -------------------------------------------------------------------------------
6662 */
6663     //remember: param0 is the parameterset to test and
6664     // NOT the parameterset from migrate.
6665 #define BOXSIZE 50 /*defines the print width of the left box containing the H0*/
6666 #define BOXSIZE2 40 /*defines the print width of the left box with the legend*/
pdf_print_LRT_box(world_fmt * world,char ** box,long size,MYREAL like0,MYREAL like1,MYREAL lrt,MYREAL chiprob,MYREAL chiprob2,MYREAL aic,long df,long aicparamnum,float * page_height,float * page_width)6667 void pdf_print_LRT_box(world_fmt* world,char **box,long size,
6668 		       MYREAL like0, MYREAL like1,MYREAL lrt, MYREAL chiprob, MYREAL chiprob2, MYREAL aic, long df, long aicparamnum, float *page_height, float *page_width)
6669 {
6670   float lx=60;
6671   float tempheight;
6672   pdf_page_advance_or_not(page_height, 200.);
6673   tempheight = *page_height;
6674   //printf("%f\n",tempheight);
6675   pdf_draw_line(lx, *page_height, *page_width-lx, *page_height);
6676   pdf_advance(page_height);
6677   pdf_printf(lx, *page_height, 'L', "%-*.*s",BOXSIZE,BOXSIZE, box[0]);
6678   pdf_printf(lx+OFFSET, *page_height, 'L', "LnL(test)");
6679   pdf_printf_next(lx+OFFSET+ADDED, page_height, "= %f",like0);
6680   pdf_printf(lx, *page_height, 'L', "%-*.*s",BOXSIZE,BOXSIZE, box[1]);
6681   pdf_printf(lx+OFFSET, *page_height, 'L', "LnL(full)");
6682   pdf_printf_next(lx+OFFSET+ADDED, page_height, "= %f",like1);
6683   pdf_printf(lx, *page_height, 'L', "%-*.*s",BOXSIZE,BOXSIZE, box[2]);
6684   pdf_printf(lx+OFFSET, *page_height, 'L', "LRT");
6685   pdf_printf_next(lx+OFFSET+ADDED, page_height, "= %f", lrt);
6686   pdf_printf(lx, *page_height, 'L', "%-*.*s",BOXSIZE,BOXSIZE, box[3]);
6687   pdf_printf(lx+OFFSET, *page_height, 'L', "df");
6688   pdf_printf_next(lx+OFFSET+ADDED, page_height, "= %li",(long) df);
6689   pdf_printf(lx, *page_height, 'L', "%-*.*s",BOXSIZE,BOXSIZE, box[4]);
6690   pdf_printf(lx+OFFSET, *page_height, 'L', "Prob");
6691   pdf_printf_next(lx+OFFSET+ADDED, page_height, "= %f",chiprob);
6692   pdf_printf(lx, *page_height, 'L', "%-*.*s",BOXSIZE,BOXSIZE, box[5]);
6693   pdf_printf(lx+OFFSET, *page_height, 'L', "Probc");
6694   pdf_printf_next(lx+OFFSET+ADDED, page_height, "= %f",chiprob2);
6695   pdf_printf(lx, *page_height, 'L', "%-*.*s",BOXSIZE,BOXSIZE, box[6]);
6696   pdf_printf(lx+OFFSET, *page_height, 'L', "AIC");
6697   pdf_printf_next(lx+OFFSET+ADDED, page_height, "= %f",aic);
6698   pdf_printf(lx, *page_height, 'L', "%-*.*s",BOXSIZE,BOXSIZE, box[7]);
6699   pdf_printf(lx+OFFSET, *page_height, 'L', "num(param)");
6700   pdf_printf_next(lx+OFFSET+ADDED, page_height, "= %li",aicparamnum);
6701   //pdf_printf(lx+OFFSET, *page_height, 'L', "num(param)= %li",aicparamnum);
6702   pdf_draw_line(lx, *page_height, *page_width-lx, *page_height);
6703   pdf_draw_line(OFFSET2+lx, tempheight, OFFSET2+lx, *page_height);
6704   //pdf_advance(page_height);
6705 }
6706 
6707   // citations
pdf_print_citation(float * page_height,char type[],world_fmt * world)6708 void pdf_print_citation(float *page_height, char type[],world_fmt *world)
6709 {
6710   char mytype = type[0];
6711   pdf_printf(left_margin, *page_height,'L',"%s","Citation suggestions:");
6712   pdf_advance(page_height);
6713   switch(mytype)
6714     {
6715     case 'M': // marginal likelihood
6716       pdf_printf(left_margin, *page_height,'L',"Beerli P. and M. Palczewski, 2010. Unified framework to evaluate panmixia and migration direction among");
6717       pdf_advance(page_height);
6718       pdf_printf(left_margin, *page_height,'L',"    multiple sampling locations, Genetics, 185: 313-326.");
6719       pdf_advance(page_height);
6720       break;
6721     case 'L': // maximum likelihood
6722       pdf_advance(page_height);
6723       pdf_printf(left_margin, *page_height,'L',"Beerli P., 1998. Estimation of migration rates and population sizes in geographically structured populations.");
6724       pdf_advance(page_height);
6725       pdf_printf(left_margin, *page_height,'L',"    In Advances in Molecular Ecology, G. R. Carvalho, ed., vol. 306 of NATO sciences series, Series A: Life sciences,");
6726       pdf_advance(page_height);
6727       pdf_printf(left_margin, *page_height,'L',"    ISO Press, Amsterdam, pp. 39-53.");
6728       pdf_advance(page_height);
6729       pdf_printf(left_margin, *page_height,'L',"Beerli P. and J. Felsenstein, 1999. Maximum-likelihood estimation of migration rates and effective population");
6730       pdf_advance(page_height);
6731       pdf_printf(left_margin, *page_height,'L',"    numbers in two populations using a coalescent approach, Genetics, 152:763-773.");
6732       pdf_advance(page_height);
6733       pdf_printf(left_margin, *page_height,'L',"Beerli P. and J. Felsenstein, 2001. Maximum likelihood estimation of a migration matrix and effective ");
6734       pdf_advance(page_height);
6735       pdf_printf(left_margin, *page_height,'L',"    population sizes in n subpopulations by using a coalescent approach, Proceedings of the National Academy ");
6736       pdf_advance(page_height);
6737       pdf_printf(left_margin, *page_height,'L',"    of Sciences of the United States of America, 98: p. 4563-4568.");
6738       pdf_advance(page_height);
6739       pdf_printf(left_margin, *page_height,'L',"Beerli P., 2007. Estimation of the population scaled mutation rate from microsatellite data,");
6740       pdf_advance(page_height);
6741       pdf_printf(left_margin, *page_height,'L',"    Genetics, 177:1967-1968.");
6742       pdf_advance(page_height);
6743       if (world->options->datatype=='m' || world->options->datatype=='s')
6744 	{
6745 	  pdf_printf(left_margin, *page_height,'L',"Beerli P., 2007. Estimation of the population scaled mutation rate from microsatellite data,");
6746 	  pdf_advance(page_height);
6747 	  pdf_printf(left_margin, *page_height,'L',"    Genetics, 177:1967-1968.");
6748 	  pdf_advance(page_height);
6749 	}
6750     case 'B': // Bayesian inference
6751       pdf_advance(page_height);
6752       pdf_printf(left_margin, *page_height,'L',"Beerli P., 2006. Comparison of Bayesian and maximum-likelihood inference of population genetic parameters.");
6753       pdf_advance(page_height);
6754       pdf_printf(left_margin, *page_height,'L',"    Bioinformatics 22:341-345");
6755       pdf_advance(page_height);
6756       if (world->options->datatype=='m' || world->options->datatype=='s')
6757 	{
6758 	  pdf_printf(left_margin, *page_height,'L',"Beerli P., 2007. Estimation of the population scaled mutation rate from microsatellite data,");
6759 	  pdf_advance(page_height);
6760 	  pdf_printf(left_margin, *page_height,'L',"    Genetics, 177:1967-1968.");
6761 	  pdf_advance(page_height);
6762 	}
6763       pdf_printf(left_margin, *page_height,'L',"Beerli P., 2009. How to use MIGRATE or why are Markov chain Monte Carlo programs difficult to use?");
6764       pdf_advance(page_height);
6765       pdf_printf(left_margin, *page_height,'L',"    In Population Genetics for Animal Conservation, G. Bertorelle, M. W. Bruford, H. C. Hauffe, A. Rizzoli,");
6766       pdf_advance(page_height);
6767       pdf_printf(left_margin, *page_height,'L',"    and C. Vernesi, eds., vol. 17 of Conservation Biology, Cambridge University Press, Cambridge UK, pp. 42-79.");
6768       pdf_advance(page_height);
6769     }
6770 }
6771 
6772 #endif /*end of PRETTY*/
6773 
6774 
6775 
6776 
6777 
6778 
6779 
6780 
6781 
6782 
6783 
6784 
6785 
6786