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