3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
33 * Green Red Orange Magenta Azure Cyan Skyblue
49 #include "gmx_fatal.h"
71 char tickfont
[STRLEN
];
86 char leglabel
[STRLEN
];
87 char leg2label
[STRLEN
];
97 /* MUST correspond to char *legend[] in main() */
98 enum { elSel
, elBoth
, elFirst
, elSecond
, elNone
, elNR
};
100 /* MUST correspond to char *combine[] in main() */
101 enum { ecSel
, ecHalves
, ecAdd
, ecSub
, ecMult
, ecDiv
, ecNR
};
103 void get_params(const char *mpin
,const char *mpout
,t_psrec
*psr
)
105 static const char *gmx_bools
[BOOL_NR
+1] = { "no", "yes", NULL
};
106 /* this must correspond to t_rgb *linecolors[] below */
107 static const char *colors
[] = { "none", "black", "white", NULL
};
113 wi
= init_warning(FALSE
,0);
116 inp
= read_inpfile(mpin
,&ninp
,NULL
,wi
);
120 ETYPE("black&white", psr
->bw
, gmx_bools
);
121 RTYPE("linewidth", psr
->linewidth
, 1.0);
122 STYPE("titlefont", psr
->titfont
, "Helvetica");
123 RTYPE("titlefontsize", psr
->titfontsize
, 20.0);
124 ETYPE("legend", psr
->legend
, gmx_bools
);
125 STYPE("legendfont", psr
->legfont
, psr
->titfont
);
126 STYPE("legendlabel", psr
->leglabel
, "");
127 STYPE("legend2label", psr
->leg2label
, psr
->leglabel
);
128 RTYPE("legendfontsize", psr
->legfontsize
, 14.0);
129 RTYPE("xbox", psr
->xboxsize
, 0.0);
130 RTYPE("ybox", psr
->yboxsize
, 0.0);
131 RTYPE("matrixspacing", psr
->boxspacing
, 20.0);
132 RTYPE("xoffset", psr
->xoffs
, 0.0);
133 RTYPE("yoffset", psr
->yoffs
, psr
->xoffs
);
134 RTYPE("boxlinewidth", psr
->boxlinewidth
, psr
->linewidth
);
135 RTYPE("ticklinewidth", psr
->ticklinewidth
, psr
->linewidth
);
136 RTYPE("zerolinewidth", psr
->zerolinewidth
, psr
->ticklinewidth
);
137 ETYPE("x-lineat0value", psr
->X
.lineatzero
, colors
);
138 RTYPE("x-major", psr
->X
.major
, NOTSET
);
139 RTYPE("x-minor", psr
->X
.minor
, NOTSET
);
140 RTYPE("x-firstmajor", psr
->X
.offset
, 0.0);
141 ETYPE("x-majorat0", psr
->X
.first
, gmx_bools
);
142 RTYPE("x-majorticklen", psr
->X
.majorticklen
, 8.0);
143 RTYPE("x-minorticklen", psr
->X
.minorticklen
, 4.0);
144 STYPE("x-label", psr
->X
.label
, "");
145 RTYPE("x-fontsize", psr
->X
.fontsize
, 16.0);
146 STYPE("x-font", psr
->X
.font
, psr
->titfont
);
147 RTYPE("x-tickfontsize", psr
->X
.tickfontsize
, 10.0);
148 STYPE("x-tickfont", psr
->X
.tickfont
, psr
->X
.font
);
149 ETYPE("y-lineat0value", psr
->Y
.lineatzero
, colors
);
150 RTYPE("y-major", psr
->Y
.major
, psr
->X
.major
);
151 RTYPE("y-minor", psr
->Y
.minor
, psr
->X
.minor
);
152 RTYPE("y-firstmajor", psr
->Y
.offset
, psr
->X
.offset
);
153 ETYPE("y-majorat0", psr
->Y
.first
, gmx_bools
);
154 RTYPE("y-majorticklen", psr
->Y
.majorticklen
, psr
->X
.majorticklen
);
155 RTYPE("y-minorticklen", psr
->Y
.minorticklen
, psr
->X
.minorticklen
);
156 STYPE("y-label", psr
->Y
.label
, psr
->X
.label
);
157 RTYPE("y-fontsize", psr
->Y
.fontsize
, psr
->X
.fontsize
);
158 STYPE("y-font", psr
->Y
.font
, psr
->X
.font
);
159 RTYPE("y-tickfontsize", psr
->Y
.tickfontsize
, psr
->X
.tickfontsize
);
160 STYPE("y-tickfont", psr
->Y
.tickfont
, psr
->Y
.font
);
163 write_inpfile(mpout
,ninp
,inp
,TRUE
,wi
);
166 done_warning(wi
,FARGS
);
169 t_rgb black
= { 0, 0, 0 };
170 t_rgb white
= { 1, 1, 1 };
171 t_rgb red
= { 1, 0, 0 };
172 t_rgb blue
= { 0, 0, 1 };
173 #define BLACK (&black)
174 /* this must correspond to *colors[] in get_params */
175 t_rgb
*linecolors
[] = { NULL
, &black
, &white
, NULL
};
177 gmx_bool
diff_maps(int nmap1
,t_mapping
*map1
,int nmap2
,t_mapping
*map2
)
180 gmx_bool bDiff
,bColDiff
=FALSE
;
186 for(i
=0; i
<nmap1
; i
++) {
187 if (!matelmt_cmp(map1
[i
].code
, map2
[i
].code
)) bDiff
=TRUE
;
188 if (strcmp(map1
[i
].desc
,map2
[i
].desc
) != 0) bDiff
=TRUE
;
189 if ((map1
[i
].rgb
.r
!=map2
[i
].rgb
.r
) ||
190 (map1
[i
].rgb
.g
!=map2
[i
].rgb
.g
) ||
191 (map1
[i
].rgb
.b
!=map2
[i
].rgb
.b
))
194 if (!bDiff
&& bColDiff
)
195 fprintf(stderr
,"Warning: two colormaps differ only in RGB value, using one colormap.\n");
201 void leg_discrete(t_psdata ps
,real x0
,real y0
,char *label
,
202 real fontsize
,char *font
,int nmap
,t_mapping map
[])
211 ps_strfont(ps
,font
,fontsize
);
212 yhh
=y0
+fontsize
+3*DDD
;
213 if ((int)strlen(label
) > 0)
214 ps_ctext(ps
,x0
,yhh
,label
,eXLeft
);
216 for(i
=0; (i
<nmap
); i
++) {
218 ps_rgb(ps
,&(map
[i
].rgb
));
219 ps_fillbox(ps
,DDD
,DDD
,DDD
+fontsize
,boxhh
-DDD
);
221 ps_box(ps
,DDD
,DDD
,DDD
+fontsize
,boxhh
-DDD
);
222 ps_ctext(ps
,boxhh
+2*DDD
,fontsize
/3,map
[i
].desc
,eXLeft
);
224 ps_moverel(ps
,DDD
,-fontsize
/3);
228 void leg_continuous(t_psdata ps
,real x0
,real x
,real y0
,char *label
,
229 real fontsize
,char *font
,
230 int nmap
,t_mapping map
[],
235 real yhh
,boxxh
,boxyh
;
240 boxxh
=(real
)x
/(real
)(nmap
-mapoffset
);
245 xx0
=x0
-((nmap
-mapoffset
)*boxxh
)/2.0;
247 for(i
=0; (i
<nmap
-mapoffset
); i
++) {
248 ps_rgb(ps
,&(map
[i
+mapoffset
].rgb
));
249 ps_fillbox(ps
,xx0
+i
*boxxh
,y0
,xx0
+(i
+1)*boxxh
,y0
+boxyh
);
251 ps_strfont(ps
,font
,fontsize
);
253 ps_box(ps
,xx0
,y0
,xx0
+(nmap
-mapoffset
)*boxxh
,y0
+boxyh
);
256 ps_ctext(ps
,xx0
+boxxh
/2,yhh
,map
[0].desc
,eXCenter
);
257 if ((int)strlen(label
) > 0)
258 ps_ctext(ps
,x0
,yhh
,label
,eXCenter
);
259 ps_ctext(ps
,xx0
+((nmap
-mapoffset
)*boxxh
)
260 - boxxh
/2,yhh
,map
[nmap
-1].desc
,eXCenter
);
263 void leg_bicontinuous(t_psdata ps
,real x0
,real x
,real y0
,char *label1
,
264 char *label2
, real fontsize
,char *font
,
265 int nmap1
,t_mapping map1
[],int nmap2
,t_mapping map2
[])
269 x1
=x
/(nmap1
+nmap2
)*nmap1
;/* width of legend 1 */
270 x2
=x
/(nmap1
+nmap2
)*nmap2
;/* width of legend 2 */
271 xx1
=x0
-(x2
/2.0)-fontsize
;/* center of legend 1 */
272 xx2
=x0
+(x1
/2.0)+fontsize
;/* center of legend 2 */
273 x1
-=fontsize
/2;/* adjust width */
274 x2
-=fontsize
/2;/* adjust width */
275 leg_continuous(ps
,xx1
,x1
,y0
,label1
,fontsize
,font
,nmap1
,map1
,0);
276 leg_continuous(ps
,xx2
,x2
,y0
,label2
,fontsize
,font
,nmap2
,map2
,0);
279 static real
box_height(t_matrix
*mat
,t_psrec
*psr
)
281 return mat
->ny
*psr
->yboxsize
;
284 static real
box_dh(t_psrec
*psr
)
286 return psr
->boxspacing
;
289 #define IS_ONCE (i==nmat-1)
290 static real
box_dh_top(gmx_bool bOnce
, t_psrec
*psr
)
294 if (psr
->bTitle
|| (psr
->bTitleOnce
&& bOnce
) )
295 dh
=2*psr
->titfontsize
;
302 static gmx_bool
box_do_all_x_maj_ticks(t_psrec
*psr
)
304 return (psr
->boxspacing
>(1.5*psr
->X
.majorticklen
));
307 static gmx_bool
box_do_all_x_min_ticks(t_psrec
*psr
)
309 return (psr
->boxspacing
>(1.5*psr
->X
.minorticklen
));
312 static void draw_boxes(t_psdata ps
,real x0
,real y0
,real w
,
313 int nmat
,t_matrix mat
[],t_psrec
*psr
)
318 char **xtick
,**ytick
;
319 real xx
,yy
,dy
,xx00
,yy00
,offset_x
,offset_y
;
320 int i
,j
,x
,y
,ntx
,nty
,strlength
;
322 /* Only necessary when there will be no y-labels */
327 ps_linewidth(ps
,psr
->boxlinewidth
);
329 for(i
=0; (i
<nmat
); i
++) {
330 dy
=box_height(&(mat
[i
]),psr
);
331 ps_box(ps
,x0
-1,yy00
-1,x0
+w
+1,yy00
+dy
+1);
332 yy00
+=dy
+box_dh(psr
)+box_dh_top(IS_ONCE
,psr
);
335 /* Draw the ticks on the axes */
336 ps_linewidth(ps
,psr
->ticklinewidth
);
339 for (i
=0; (i
<nmat
); i
++) {
340 if (mat
[i
].flags
& MAT_SPATIAL_X
) {
347 if (mat
[i
].flags
& MAT_SPATIAL_Y
) {
355 for(j
=0; (j
<ntx
); j
++) {
356 sprintf(buf
,"%g",mat
[i
].axis_x
[j
]);
357 xtick
[j
]=strdup(buf
);
359 ps_strfont(ps
,psr
->X
.tickfont
,psr
->X
.tickfontsize
);
360 for(x
=0; (x
<ntx
); x
++) {
361 xx
= xx00
+ (x
+ offset_x
)*psr
->xboxsize
;
362 if ( ( bRmod(mat
[i
].axis_x
[x
], psr
->X
.offset
, psr
->X
.major
) ||
363 (psr
->X
.first
&& (x
==0))) &&
364 ( (i
== 0) || box_do_all_x_maj_ticks(psr
) ) ) {
365 /* Longer tick marks */
366 ps_line (ps
,xx
,yy00
,xx
,yy00
-psr
->X
.majorticklen
);
367 /* Plot label on lowest graph only */
370 yy00
-DDD
-psr
->X
.majorticklen
-psr
->X
.tickfontsize
*0.8,
372 } else if ( bRmod(mat
[i
].axis_x
[x
], psr
->X
.offset
, psr
->X
.minor
) &&
373 ( (i
== 0) || box_do_all_x_min_ticks(psr
) ) ){
374 /* Shorter tick marks */
375 ps_line(ps
,xx
,yy00
,xx
,yy00
-psr
->X
.minorticklen
);
376 } else if ( bRmod(mat
[i
].axis_x
[x
], psr
->X
.offset
, psr
->X
.major
) ) {
377 /* Even shorter marks, only each X.major */
378 ps_line(ps
,xx
,yy00
,xx
,yy00
-(psr
->boxspacing
/2));
381 ps_strfont(ps
,psr
->Y
.tickfont
,psr
->Y
.tickfontsize
);
383 for(j
=0; (j
<nty
); j
++) {
384 sprintf(buf
,"%g",mat
[i
].axis_y
[j
]);
385 ytick
[j
]=strdup(buf
);
388 for(y
=0; (y
<nty
); y
++) {
389 yy
= yy00
+ (y
+ offset_y
)*psr
->yboxsize
;
390 if ( bRmod(mat
[i
].axis_y
[y
], psr
->Y
.offset
, psr
->Y
.major
) ||
391 (psr
->Y
.first
&& (y
==0))) {
393 strlength
=max(strlength
,(int)strlen(ytick
[y
]));
394 ps_line (ps
,xx00
,yy
,xx00
-psr
->Y
.majorticklen
,yy
);
395 ps_ctext(ps
,xx00
-psr
->Y
.majorticklen
-DDD
,
396 yy
-psr
->Y
.tickfontsize
/3.0,ytick
[y
],eXRight
);
398 else if ( bRmod(mat
[i
].axis_y
[y
], psr
->Y
.offset
, psr
->Y
.minor
) ) {
400 ps_line(ps
,xx00
,yy
,xx00
-psr
->Y
.minorticklen
,yy
);
406 /* Label on Y-axis */
407 if (!psr
->bYonce
|| i
==nmat
/2) {
408 if (strlen(psr
->Y
.label
) > 0)
409 mylab
= psr
->Y
.label
;
411 mylab
= mat
[i
].label_y
;
412 if (strlen(mylab
) > 0) {
413 ps_strfont(ps
,psr
->Y
.font
,psr
->Y
.fontsize
);
415 xxx
=x0
-psr
->X
.majorticklen
-psr
->X
.tickfontsize
*strlength
-DDD
;
416 ps_ctext(ps
,yy00
+box_height(&mat
[i
],psr
)/2.0,612.5-xxx
,
422 yy00
+=box_height(&(mat
[i
]),psr
)+box_dh(psr
)+box_dh_top(IS_ONCE
,psr
);
424 /* Label on X-axis */
425 if (strlen(psr
->X
.label
) > 0)
426 mylab
= psr
->X
.label
;
428 mylab
= mat
[0].label_x
;
429 if (strlen(mylab
) > 0) {
430 ps_strfont(ps
,psr
->X
.font
,psr
->X
.fontsize
);
431 ps_ctext(ps
,x0
+w
/2,y0
-DDD
-psr
->X
.majorticklen
-psr
->X
.tickfontsize
*FUDGE
-
432 psr
->X
.fontsize
,mylab
,eXCenter
);
436 static void draw_zerolines(t_psdata out
,real x0
,real y0
,real w
,
437 int nmat
,t_matrix mat
[],t_psrec
*psr
)
439 real xx
,yy
,dy
,xx00
,yy00
;
444 ps_linewidth(out
,psr
->zerolinewidth
);
445 for (i
=0; (i
<nmat
); i
++) {
446 dy
=box_height(&(mat
[i
]),psr
);
447 /* mat[i].axis_x and _y were already set by draw_boxes */
448 if (psr
->X
.lineatzero
) {
449 ps_rgb(out
,linecolors
[psr
->X
.lineatzero
]);
450 for(x
=0; (x
<mat
[i
].nx
); x
++) {
451 xx
=xx00
+(x
+0.7)*psr
->xboxsize
;
452 /* draw lines whenever tick label almost zero (e.g. next trajectory) */
453 if ( x
!=0 && x
<mat
[i
].nx
-1 &&
454 abs(mat
[i
].axis_x
[x
]) <
455 0.1*abs(mat
[i
].axis_x
[x
+1]-mat
[i
].axis_x
[x
]) ) {
456 ps_line (out
,xx
,yy00
,xx
,yy00
+dy
+2);
460 if (psr
->Y
.lineatzero
) {
461 ps_rgb(out
,linecolors
[psr
->Y
.lineatzero
]);
462 for(y
=0; (y
<mat
[i
].ny
); y
++) {
463 yy
=yy00
+(y
+0.7)*psr
->yboxsize
;
464 /* draw lines whenever tick label almost zero (e.g. next trajectory) */
465 if ( y
!=0 && y
<mat
[i
].ny
-1 &&
466 abs(mat
[i
].axis_y
[y
]) <
467 0.1*abs(mat
[i
].axis_y
[y
+1]-mat
[i
].axis_y
[y
]) ) {
468 ps_line (out
,xx00
,yy
,xx00
+w
+2,yy
);
472 yy00
+=box_height(&(mat
[i
]),psr
)+box_dh(psr
)+box_dh_top(IS_ONCE
,psr
);
476 static void box_dim(int nmat
,t_matrix mat
[],t_matrix
*mat2
,t_psrec
*psr
,
477 int elegend
,gmx_bool bFrame
,
478 real
*w
,real
*h
,real
*dw
,real
*dh
)
487 for(i
=0; (i
<nmat
); i
++) {
488 ww
=max(ww
,mat
[i
].nx
*psr
->xboxsize
);
489 hh
+=box_height(&(mat
[i
]),psr
);
490 maxytick
=max(maxytick
,mat
[i
].nx
);
493 if (mat
[0].label_y
[0])
494 dww
+=2.0*(psr
->Y
.fontsize
+DDD
);
495 if (psr
->Y
.major
> 0)
496 dww
+= psr
->Y
.majorticklen
+ DDD
+
497 psr
->Y
.tickfontsize
*(log(maxytick
)/log(10.0));
498 else if (psr
->Y
.minor
> 0)
499 dww
+=psr
->Y
.minorticklen
;
501 if (mat
[0].label_x
[0])
502 dhh
+=psr
->X
.fontsize
+2*DDD
;
503 if (/* fool emacs auto-indent */
504 (elegend
==elBoth
&& (mat
[0].legend
[0] || mat2
[0].legend
[0])) ||
505 (elegend
==elFirst
&& mat
[0].legend
[0]) ||
506 (elegend
==elSecond
&& mat2
[0].legend
[0]) )
507 dhh
+=2*(psr
->legfontsize
*FUDGE
+2*DDD
);
509 dhh
+=psr
->legfontsize
*FUDGE
+2*DDD
;
510 if (psr
->X
.major
> 0)
511 dhh
+=psr
->X
.tickfontsize
*FUDGE
+2*DDD
+psr
->X
.majorticklen
;
512 else if (psr
->X
.minor
> 0)
513 dhh
+=psr
->X
.minorticklen
;
515 hh
+=(nmat
-1)*box_dh(psr
);
516 hh
+=box_dh_top(TRUE
,psr
);
518 hh
+=(nmat
-1)*box_dh_top(FALSE
,psr
);
526 int add_maps(t_mapping
**newmap
,
527 int nmap1
, t_mapping map1
[], int nmap2
, t_mapping map2
[])
529 static char mapper
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+{}|;:',<.>/?";
534 nsymbols
= strlen(mapper
);
536 if (nmap
> nsymbols
*nsymbols
)
537 gmx_fatal(FARGS
,"Not enough symbols to merge the two colormaps\n");
538 printf("Combining colormaps of %d and %d elements into one of %d elements\n",
541 for(j
=0; j
<nmap1
; j
++) {
542 map
[j
].code
.c1
=mapper
[j
% nsymbols
];
544 map
[j
].code
.c2
=mapper
[j
/nsymbols
];
545 map
[j
].rgb
.r
= map1
[j
].rgb
.r
;
546 map
[j
].rgb
.g
= map1
[j
].rgb
.g
;
547 map
[j
].rgb
.b
= map1
[j
].rgb
.b
;
548 map
[j
].desc
= map1
[j
].desc
;
550 for(j
=0; j
<nmap2
; j
++) {
552 map
[k
].code
.c1
=mapper
[k
% nsymbols
];
554 map
[k
].code
.c2
=mapper
[k
/nsymbols
];
555 map
[k
].rgb
.r
= map2
[j
].rgb
.r
;
556 map
[k
].rgb
.g
= map2
[j
].rgb
.g
;
557 map
[k
].rgb
.b
= map2
[j
].rgb
.b
;
558 map
[k
].desc
= map2
[j
].desc
;
565 void xpm_mat(const char *outf
, int nmat
,t_matrix
*mat
,t_matrix
*mat2
,
566 gmx_bool bDiag
,gmx_bool bFirstDiag
)
574 out
=ffopen(outf
,"w");
576 for(i
=0; i
<nmat
; i
++) {
577 if (!mat2
|| !diff_maps(mat
[i
].nmap
,mat
[i
].map
,mat2
[i
].nmap
,mat2
[i
].map
))
578 write_xpm_m(out
,mat
[0]);
580 nmap
= add_maps(&map
, mat
[i
].nmap
,mat
[i
].map
, mat2
[i
].nmap
,mat2
[i
].map
);
581 for(x
=0; (x
<mat
[i
].nx
); x
++) {
582 for(y
=0; (y
<mat
[i
].nx
); y
++) {
583 if ((x
<y
) || ((x
==y
) && bFirstDiag
)) /* upper left -> map1 */
584 col
=mat
[i
].matrix
[x
][y
];
585 else /* lower right -> map2 */
586 col
=mat
[i
].nmap
+mat
[i
].matrix
[x
][y
];
587 if ((bDiag
) || (x
!=y
))
588 mat
[i
].matrix
[x
][y
]=col
;
590 mat
[i
].matrix
[x
][y
]=0;
596 if (mat2
&& (strcmp(mat
[i
].title
,mat2
[i
].title
) != 0))
597 sprintf(mat
[i
].title
+strlen(mat
[i
].title
)," / %s",mat2
[i
].title
);
598 if (mat2
&& (strcmp(mat
[i
].legend
,mat2
[i
].legend
) != 0))
599 sprintf(mat
[i
].legend
+strlen(mat
[i
].legend
)," / %s",mat2
[i
].legend
);
600 write_xpm_m(out
,mat
[i
]);
606 static void tick_spacing(int n
, real axis
[], real offset
, char axisnm
,
607 real
*major
, real
*minor
)
610 gmx_bool bTryAgain
,bFive
;
613 real major_fact
[NFACT
] = {5, 4, 2, 1};
614 real minor_fact
[NFACT
] = {5, 4, 4, 5};
616 /* start with interval between 10 matrix points: */
617 space
= max(10*axis
[1]-axis
[0], axis
[min(10,n
-1)]-axis
[0]);
618 /* get power of 10 */
619 ten
= (int)ceil(log(space
)/log(10))-1;
621 for(t
=ten
+2; t
>ten
-3 && bTryAgain
; t
--) {
622 for(f
=0; f
<NFACT
&& bTryAgain
; f
++) {
623 space
= pow(10,t
) * major_fact
[f
];
624 /* count how many ticks we would get: */
627 if ( bRmod(axis
[j
], offset
, space
) )
629 /* do we have a reasonable number of ticks ? */
630 bTryAgain
= (i
> min(10, n
-1)) || (i
< 5);
634 space
= max(10*axis
[1]-axis
[0], axis
[min(10,n
-1)]-axis
[0]);
635 fprintf(stderr
,"Auto tick spacing failed for %c-axis, guessing %g\n",
639 *minor
= space
/ minor_fact
[f
-1];
640 fprintf(stderr
,"Auto tick spacing for %c-axis: major %g, minor %g\n",
641 axisnm
, *major
, *minor
);
644 void ps_mat(const char *outf
,int nmat
,t_matrix mat
[],t_matrix mat2
[],
645 gmx_bool bFrame
,gmx_bool bDiag
,gmx_bool bFirstDiag
,
646 gmx_bool bTitle
,gmx_bool bTitleOnce
,gmx_bool bYonce
,int elegend
,
647 real size
,real boxx
,real boxy
,const char *m2p
,const char *m2pout
,
651 char buf
[256],*legend
;
655 int i
,j
,x
,y
,col
,leg
=0;
658 int nmap1
=0,nmap2
=0,leg_nmap
;
659 t_mapping
*map1
=NULL
,*map2
=NULL
,*leg_map
;
660 gmx_bool bMap1
,bNextMap1
,bDiscrete
;
663 libm2p
= m2p
? gmxlibfn(m2p
) : m2p
;
664 get_params(libm2p
,m2pout
,&psrec
);
668 if (psr
->X
.major
<= 0 )
669 tick_spacing((mat
[0].flags
& MAT_SPATIAL_X
) ? mat
[0].nx
+ 1 : mat
[0].nx
,
670 mat
[0].axis_x
, psr
->X
.offset
, 'X',
671 &(psr
->X
.major
), &(psr
->X
.minor
) );
672 if (psr
->X
.minor
<= 0 )
673 psr
->X
.minor
= psr
->X
.major
/ 2;
674 if (psr
->Y
.major
<= 0)
675 tick_spacing((mat
[0].flags
& MAT_SPATIAL_Y
) ? mat
[0].ny
+ 1 : mat
[0].ny
,
676 mat
[0].axis_y
, psr
->Y
.offset
, 'Y',
677 &(psr
->Y
.major
), &(psr
->Y
.minor
) );
678 if (psr
->Y
.minor
<= 0)
679 psr
->Y
.minor
= psr
->Y
.major
/ 2;
688 if (psr
->xboxsize
==0) {
689 psr
->xboxsize
= size
/mat
[0].nx
;
690 printf("Set the x-size of the box to %.3f\n",psr
->xboxsize
);
692 if (psr
->yboxsize
==0) {
693 psr
->yboxsize
= size
/mat
[0].nx
;
694 printf("Set the y-size of the box to %.3f\n",psr
->yboxsize
);
698 for (i
=0; (i
<nmat
); i
++)
699 if (mat
[i
].nmap
>nmap1
) {
705 printf("Selected legend of matrix # %d for display\n",leg
);
708 for (i
=0; (i
<nmat
); i
++)
709 if (mat2
[i
].nmap
>nmap2
) {
715 printf("Selected legend of matrix # %d for second display\n",leg
);
717 if ( (mat
[0].legend
[0]==0) && psr
->legend
)
718 strcpy(mat
[0].legend
, psr
->leglabel
);
720 bTitle
= bTitle
&& mat
[nmat
-1].title
[0];
721 bTitleOnce
= bTitleOnce
&& mat
[nmat
-1].title
[0];
722 psr
->bTitle
= bTitle
;
723 psr
->bTitleOnce
= bTitleOnce
;
724 psr
->bYonce
= bYonce
;
726 /* Set up size of box for nice colors */
727 box_dim(nmat
,mat
,mat2
,psr
,elegend
,bFrame
,&w
,&h
,&dw
,&dh
);
729 /* Set up bounding box */
742 out
=ps_open(outf
,0,0,x
,y
);
743 ps_linewidth(out
,psr
->linewidth
);
744 ps_init_rgb_box(out
,psr
->xboxsize
,psr
->yboxsize
);
745 ps_init_rgb_nbox(out
,psr
->xboxsize
,psr
->yboxsize
);
746 ps_translate(out
,psr
->xoffs
,psr
->yoffs
);
749 ps_comment(out
,"Here starts the BOX drawing");
750 draw_boxes(out
,x0
,y0
,w
,nmat
,mat
,psr
);
753 for(i
=0; (i
<nmat
); i
++) {
754 if (bTitle
|| (bTitleOnce
&& i
==nmat
-1) ) {
755 /* Print title, if any */
757 ps_strfont(out
,psr
->titfont
,psr
->titfontsize
);
758 if (!mat2
|| (strcmp(mat
[i
].title
,mat2
[i
].title
) == 0))
759 strcpy(buf
,mat
[i
].title
);
761 sprintf(buf
,"%s / %s",mat
[i
].title
,mat2
[i
].title
);
762 ps_ctext(out
,x0
+w
/2,y0
+box_height(&(mat
[i
]),psr
)+psr
->titfontsize
,
765 sprintf(buf
,"Here starts the filling of box #%d",i
);
767 for(x
=0; (x
<mat
[i
].nx
); x
++) {
771 xx
=x0
+x
*psr
->xboxsize
;
772 ps_moveto(out
,xx
,y0
);
774 bMap1
= (!mat2
|| (x
<y
|| (x
==y
&& bFirstDiag
)));
775 if ((bDiag
) || (x
!=y
))
776 col
= mat
[i
].matrix
[x
][y
];
779 for(nexty
=1; (nexty
<=mat
[i
].ny
); nexty
++) {
780 bNextMap1
= (!mat2
|| (x
<nexty
|| (x
==nexty
&& bFirstDiag
)));
781 /* TRUE: upper left -> map1 */
782 /* FALSE: lower right -> map2 */
783 if ((nexty
==mat
[i
].ny
) || (!bDiag
&& (x
==nexty
)))
786 nextcol
=mat
[i
].matrix
[x
][nexty
];
787 if ( (nexty
==mat
[i
].ny
) || (col
!=nextcol
) || (bMap1
!=bNextMap1
) ) {
790 ps_rgb_nbox(out
,&(mat
[i
].map
[col
].rgb
),nexty
-y
);
792 ps_rgb_nbox(out
,&(mat2
[i
].map
[col
].rgb
),nexty
-y
);
794 ps_moverel(out
,0,psr
->yboxsize
);
801 y0
+=box_height(&(mat
[i
]),psr
)+box_dh(psr
)+box_dh_top(IS_ONCE
,psr
);
804 if (psr
->X
.lineatzero
|| psr
->Y
.lineatzero
) {
805 /* reset y0 for first box */
807 ps_comment(out
,"Here starts the zero lines drawing");
808 draw_zerolines(out
,x0
,y0
,w
,nmat
,mat
,psr
);
811 if (elegend
!=elNone
) {
812 ps_comment(out
,"Now it's legend time!");
813 ps_linewidth(out
,psr
->linewidth
);
814 if ( mat2
==NULL
|| elegend
!=elSecond
) {
815 bDiscrete
= mat
[0].bDiscrete
;
816 legend
= mat
[0].legend
;
820 bDiscrete
= mat2
[0].bDiscrete
;
821 legend
= mat2
[0].legend
;
826 leg_discrete(out
,psr
->legfontsize
,DDD
,legend
,
827 psr
->legfontsize
,psr
->legfont
,leg_nmap
,leg_map
);
829 if ( elegend
!=elBoth
)
830 leg_continuous(out
,x0
+w
/2,w
/2,DDD
,legend
,
831 psr
->legfontsize
,psr
->legfont
,leg_nmap
,leg_map
,
834 leg_bicontinuous(out
,x0
+w
/2,w
,DDD
,mat
[0].legend
,mat2
[0].legend
,
835 psr
->legfontsize
,psr
->legfont
,nmap1
,map1
,nmap2
,map2
);
837 ps_comment(out
,"Were there, dude");
843 void make_axis_labels(int nmat
, t_matrix
*mat
)
847 for (i
=0; (i
<nmat
); i
++) {
848 /* Make labels for x axis */
849 if (mat
[i
].axis_x
==NULL
) {
850 snew(mat
[i
].axis_x
,mat
[i
].nx
);
851 for(j
=0; (j
<mat
[i
].nx
); j
++)
854 /* Make labels for y axis */
855 if (mat
[i
].axis_y
==NULL
) {
856 snew(mat
[i
].axis_y
,mat
[i
].ny
);
857 for(j
=0; (j
<mat
[i
].ny
); j
++)
863 void prune_mat(int nmat
, t_matrix
*mat
,t_matrix
*mat2
, int skip
)
867 for(i
=0; i
<nmat
; i
++) {
868 fprintf(stderr
,"converting %dx%d matrix to %dx%d\n",
869 mat
[i
].nx
, mat
[i
].ny
,
870 (mat
[i
].nx
+skip
-1)/skip
, (mat
[i
].ny
+skip
-1)/skip
);
871 /* walk through matrix */
873 for(x
=0; (x
<mat
[i
].nx
); x
++)
875 mat
[i
].axis_x
[xs
] = mat
[i
].axis_x
[x
];
877 mat2
[i
].axis_x
[xs
] = mat2
[i
].axis_x
[x
];
879 for(y
=0; (y
<mat
[i
].ny
); y
++) {
881 mat
[i
].axis_y
[ys
] = mat
[i
].axis_y
[y
];
883 mat2
[i
].axis_y
[ys
] = mat2
[i
].axis_y
[y
];
886 mat
[i
].matrix
[xs
][ys
] = mat
[i
].matrix
[x
][y
];
888 mat2
[i
].matrix
[xs
][ys
] = mat2
[i
].matrix
[x
][y
];
894 /* adjust parameters */
895 mat
[i
].nx
= (mat
[i
].nx
+skip
-1)/skip
;
896 mat
[i
].ny
= (mat
[i
].ny
+skip
-1)/skip
;
898 mat2
[i
].nx
= (mat2
[i
].nx
+skip
-1)/skip
;
899 mat2
[i
].ny
= (mat2
[i
].ny
+skip
-1)/skip
;
904 void zero_lines(int nmat
, t_matrix
*mat
, t_matrix
*mat2
)
909 for(i
=0; i
<nmat
; i
++)
910 for(m
=0; m
< (mat2
? 2 : 1) ; m
++) {
915 for(x
=0; x
<mats
[i
].nx
-1; x
++)
916 if (abs(mats
[i
].axis_x
[x
+1]) < 1e-5)
917 for(y
=0; y
<mats
[i
].ny
; y
++)
918 mats
[i
].matrix
[x
][y
]=0;
919 for(y
=0; y
<mats
[i
].ny
-1; y
++)
920 if (abs(mats
[i
].axis_y
[y
+1]) < 1e-5)
921 for(x
=0; x
<mats
[i
].nx
; x
++)
922 mats
[i
].matrix
[x
][y
]=0;
926 void write_combined_matrix(int ecombine
, const char *fn
,
927 int nmat
, t_matrix
*mat1
, t_matrix
*mat2
,
928 real
*cmin
,real
*cmax
)
930 int i
, j
, k
, nlevels
;
933 real
**rmat1
, **rmat2
;
936 out
= ffopen(fn
, "w");
937 for(k
=0; k
<nmat
; k
++) {
938 if ( mat2
[k
].nx
!=mat1
[k
].nx
|| mat2
[k
].ny
!=mat1
[k
].ny
)
939 gmx_fatal(FARGS
,"Size of frame %d in 1st (%dx%d) and 2nd matrix (%dx%d) do"
940 " not match.\n",k
,mat1
[k
].nx
,mat1
[k
].ny
,mat2
[k
].nx
,mat2
[k
].ny
);
941 printf("Combining two %dx%d matrices\n",mat1
[k
].nx
,mat1
[k
].ny
);
942 rmat1
= matrix2real(&mat1
[k
], NULL
);
943 rmat2
= matrix2real(&mat2
[k
], NULL
);
946 for(j
=0; j
<mat1
[k
].ny
; j
++)
947 for(i
=0; i
<mat1
[k
].nx
; i
++) {
949 case ecAdd
: rmat1
[i
][j
] += rmat2
[i
][j
]; break;
950 case ecSub
: rmat1
[i
][j
] -= rmat2
[i
][j
]; break;
951 case ecMult
: rmat1
[i
][j
] *= rmat2
[i
][j
]; break;
952 case ecDiv
: rmat1
[i
][j
] /= rmat2
[i
][j
]; break;
954 gmx_fatal(FARGS
,"No such combination rule %d for matrices",ecombine
);
956 rlo
= min(rlo
, rmat1
[i
][j
]);
957 rhi
= max(rhi
, rmat1
[i
][j
]);
963 nlevels
= max(mat1
[k
].nmap
,mat2
[k
].nmap
);
966 "combination results in uniform matrix (%g), no output\n",rhi
);
968 else if (rlo>=0 || rhi<=0)
969 write_xpm(out, mat1[k].flags, mat1[k].title, mat1[k].legend,
970 mat1[k].label_x, mat1[k].label_y,
971 mat1[k].nx, mat1[k].ny, mat1[k].axis_x, mat1[k].axis_y,
972 rmat1, rlo, rhi, rhi<=0?red:white, rhi<=0?white:blue,
975 write_xpm3(out, mat2[k].flags, mat1[k].title, mat1[k].legend,
976 mat1[k].label_x, mat1[k].label_y,
977 mat1[k].nx, mat1[k].ny, mat1[k].axis_x, mat1[k].axis_y,
978 rmat1, rlo, 0, rhi, red, white, blue, &nlevels);
981 write_xpm(out
, mat1
[k
].flags
, mat1
[k
].title
, mat1
[k
].legend
,
982 mat1
[k
].label_x
, mat1
[k
].label_y
,
983 mat1
[k
].nx
, mat1
[k
].ny
, mat1
[k
].axis_x
, mat1
[k
].axis_y
,
984 rmat1
, rlo
, rhi
, white
, black
, &nlevels
);
989 void do_mat(int nmat
,t_matrix
*mat
,t_matrix
*mat2
,
990 gmx_bool bFrame
,gmx_bool bZeroLine
,gmx_bool bDiag
,gmx_bool bFirstDiag
,gmx_bool bTitle
,
991 gmx_bool bTitleOnce
,gmx_bool bYonce
,int elegend
,
992 real size
,real boxx
,real boxy
,
993 const char *epsfile
,const char *xpmfile
,const char *m2p
,
994 const char *m2pout
,int skip
, int mapoffset
)
999 for (k
=0; (k
<nmat
); k
++) {
1000 if ((mat2
[k
].nx
!=mat
[k
].nx
) || (mat2
[k
].ny
!=mat
[k
].ny
))
1001 gmx_fatal(FARGS
,"WAKE UP!! Size of frame %d in 2nd matrix file (%dx%d) does not match size of 1st matrix (%dx%d) or the other way around.\n",
1002 k
,mat2
[k
].nx
,mat2
[k
].ny
,mat
[k
].nx
,mat
[k
].ny
);
1003 for (j
=0; (j
<mat
[k
].ny
); j
++)
1004 for (i
=bFirstDiag
?j
+1:j
; (i
<mat
[k
].nx
); i
++)
1005 mat
[k
].matrix
[i
][j
]=mat2
[k
].matrix
[i
][j
];
1008 for(i
=0; (i
<nmat
); i
++)
1009 fprintf(stderr
,"Matrix %d is %d x %d\n",i
,mat
[i
].nx
,mat
[i
].ny
);
1011 make_axis_labels(nmat
, mat
);
1014 prune_mat(nmat
,mat
,mat2
,skip
);
1017 zero_lines(nmat
,mat
,mat
);
1020 ps_mat(epsfile
,nmat
,mat
,mat2
,bFrame
,bDiag
,bFirstDiag
,
1021 bTitle
,bTitleOnce
,bYonce
,elegend
,
1022 size
,boxx
,boxy
,m2p
,m2pout
,mapoffset
);
1024 xpm_mat(xpmfile
,nmat
,mat
,mat2
,bDiag
,bFirstDiag
);
1027 void gradient_map(rvec grad
, int nmap
, t_mapping map
[])
1032 for(i
=0; i
<nmap
; i
++) {
1034 map
[i
].rgb
.r
= 1-c
*(1-grad
[XX
]);
1035 map
[i
].rgb
.g
= 1-c
*(1-grad
[YY
]);
1036 map
[i
].rgb
.b
= 1-c
*(1-grad
[ZZ
]);
1040 void gradient_mat(rvec grad
, int nmat
, t_matrix mat
[])
1044 for(m
=0; m
<nmat
; m
++)
1045 gradient_map(grad
, mat
[m
].nmap
, mat
[m
].map
);
1048 void rainbow_map(gmx_bool bBlue
, int nmap
, t_mapping map
[])
1053 for(i
=0; i
<nmap
; i
++) {
1054 c
= (map
[i
].rgb
.r
+ map
[i
].rgb
.g
+ map
[i
].rgb
.b
)/3;
1059 if (c
<= 0.25) { /* 0-0.25 */
1063 } else if (c
<= 0.5) { /* 0.25-0.5 */
1066 b
= pow(2-4*c
,0.666);
1067 } else if (c
<= 0.75) { /* 0.5-0.75 */
1068 r
= pow(4*c
-2,0.666);
1071 } else { /* 0.75-1 */
1073 g
= pow(4-4*c
,0.666);
1082 void rainbow_mat(gmx_bool bBlue
, int nmat
, t_matrix mat
[])
1086 for(m
=0; m
<nmat
; m
++)
1087 rainbow_map(bBlue
, mat
[m
].nmap
, mat
[m
].map
);
1090 int gmx_xpm2ps(int argc
,char *argv
[])
1092 const char *desc
[] = {
1093 "xpm2ps makes a beautiful color plot of an XPixelMap file.",
1094 "Labels and axis can be displayed, when they are supplied",
1095 "in the correct matrix format.",
1096 "Matrix data may be generated by programs such as do_dssp, g_rms or",
1098 "Parameters are set in the [TT]m2p[tt] file optionally supplied with",
1099 "[TT]-di[tt]. Reasonable defaults are provided. Settings for the y-axis",
1100 "default to those for the x-axis. Font names have a defaulting hierarchy:",
1101 "titlefont -> legendfont; titlefont -> (xfont -> yfont -> ytickfont)",
1102 "-> xtickfont, e.g. setting titlefont sets all fonts, setting xfont",
1103 "sets yfont, ytickfont and xtickfont.[PAR]",
1104 "When no [TT]m2p[tt] file is supplied, many setting are set by",
1105 "command line options. The most important option is [TT]-size[tt]",
1106 "which sets the size of the whole matrix in postscript units.",
1107 "This option can be overridden with the [TT]-bx[tt] and [TT]-by[tt]",
1108 "options (and the corresponding parameters in the [TT]m2p[tt] file),",
1109 "which set the size of a single matrix element.[PAR]",
1110 "With [TT]-f2[tt] a 2nd matrix file can be supplied, both matrix",
1111 "files will be read simultaneously and the upper left half of the",
1112 "first one ([TT]-f[tt]) is plotted together with the lower right",
1113 "half of the second one ([TT]-f2[tt]). The diagonal will contain",
1114 "values from the matrix file selected with [TT]-diag[tt].",
1115 "Plotting of the diagonal values can be suppressed altogether by",
1116 "setting [TT]-diag[tt] to [TT]none[tt].",
1117 "In this case, a new color map will be generated with",
1118 "a red gradient for negative numbers and a blue for positive.",
1119 "If the color coding and legend labels of both matrices are identical,",
1120 "only one legend will be displayed, else two separate legends are",
1122 "With [TT]-combine[tt] an alternative operation can be selected",
1123 "to combine the matrices. The output range is automatically set",
1124 "to the actual range of the combined matrix. This can be overridden",
1125 "with [TT]-cmin[tt] and [TT]-cmax[tt].[PAR]",
1126 "[TT]-title[tt] can be set to [TT]none[tt] to suppress the title, or to",
1127 "[TT]ylabel[tt] to show the title in the Y-label position (alongside",
1128 "the Y-axis).[PAR]",
1129 "With the [TT]-rainbow[tt] option dull grey-scale matrices can be turned",
1130 "into attractive color pictures.[PAR]",
1131 "Merged or rainbowed matrices can be written to an XPixelMap file with",
1132 "the [TT]-xpm[tt] option."
1136 const char *fn
,*epsfile
=NULL
,*xpmfile
=NULL
;
1137 int i
,nmat
,nmat2
,etitle
,elegend
,ediag
,erainbow
,ecombine
;
1138 t_matrix
*mat
=NULL
,*mat2
=NULL
;
1139 gmx_bool bTitle
,bTitleOnce
,bDiag
,bFirstDiag
,bGrad
;
1140 static gmx_bool bFrame
=TRUE
,bZeroLine
=FALSE
,bYonce
=FALSE
,bAdd
=FALSE
;
1141 static real size
=400,boxx
=0,boxy
=0,cmin
=0,cmax
=0;
1142 static rvec grad
={0,0,0};
1143 enum { etSel
, etTop
, etOnce
, etYlabel
, etNone
, etNR
};
1144 const char *title
[] = { NULL
, "top", "once", "ylabel", "none", NULL
};
1145 /* MUST correspond to enum elXxx as defined at top of file */
1146 const char *legend
[] = { NULL
, "both", "first", "second", "none", NULL
};
1147 enum { edSel
, edFirst
, edSecond
, edNone
, edNR
};
1148 const char *diag
[] = { NULL
, "first", "second", "none", NULL
};
1149 enum { erSel
, erNo
, erBlue
, erRed
, erNR
};
1150 const char *rainbow
[] = { NULL
, "no", "blue", "red", NULL
};
1151 /* MUST correspond to enum ecXxx as defined at top of file */
1152 const char *combine
[] = {
1153 NULL
, "halves", "add", "sub", "mult", "div", NULL
};
1154 static int skip
=1,mapoffset
=0;
1156 { "-frame", FALSE
, etBOOL
, {&bFrame
},
1157 "Display frame, ticks, labels, title and legend" },
1158 { "-title", FALSE
, etENUM
, {title
}, "Show title at" },
1159 { "-yonce", FALSE
, etBOOL
, {&bYonce
}, "Show y-label only once" },
1160 { "-legend", FALSE
, etENUM
, {legend
}, "Show legend" },
1161 { "-diag", FALSE
, etENUM
, {diag
}, "Diagonal" },
1162 { "-size", FALSE
, etREAL
, {&size
},
1163 "Horizontal size of the matrix in ps units" },
1164 { "-bx", FALSE
, etREAL
, {&boxx
},
1165 "Element x-size, overrides -size (also y-size when -by is not set)" },
1166 { "-by", FALSE
, etREAL
, {&boxy
}, "Element y-size" },
1167 { "-rainbow", FALSE
, etENUM
, {rainbow
},
1168 "Rainbow colors, convert white to" },
1169 { "-gradient",FALSE
, etRVEC
, {grad
},
1170 "Re-scale colormap to a smooth gradient from white {1,1,1} to {r,g,b}" },
1171 { "-skip", FALSE
, etINT
, {&skip
},
1172 "only write out every nr-th row and column" },
1173 { "-zeroline",FALSE
, etBOOL
, {&bZeroLine
},
1174 "insert line in xpm matrix where axis label is zero"},
1175 { "-legoffset", FALSE
, etINT
, {&mapoffset
},
1176 "Skip first N colors from xpm file for the legend" },
1177 { "-combine", FALSE
, etENUM
, {combine
}, "Combine two matrices" },
1178 { "-cmin", FALSE
, etREAL
, {&cmin
}, "Minimum for combination output" },
1179 { "-cmax", FALSE
, etREAL
, {&cmax
}, "Maximum for combination output" }
1181 #define NPA asize(pa)
1183 { efXPM
, "-f", NULL
, ffREAD
},
1184 { efXPM
, "-f2", "root2", ffOPTRD
},
1185 { efM2P
, "-di", NULL
, ffLIBOPTRD
},
1186 { efM2P
, "-do", "out", ffOPTWR
},
1187 { efEPS
, "-o", NULL
, ffOPTWR
},
1188 { efXPM
, "-xpm",NULL
, ffOPTWR
}
1190 #define NFILE asize(fnm)
1192 CopyRight(stderr
,argv
[0]);
1193 parse_common_args(&argc
,argv
,PCA_CAN_VIEW
,
1195 asize(desc
),desc
,0,NULL
,&oenv
);
1197 etitle
= nenum(title
);
1198 elegend
= nenum(legend
);
1199 ediag
= nenum(diag
);
1200 erainbow
= nenum(rainbow
);
1201 ecombine
= nenum(combine
);
1202 bGrad
= opt2parg_bSet("-gradient",NPA
,pa
);
1203 for(i
=0; i
<DIM
; i
++)
1204 if (grad
[i
] < 0 || grad
[i
] > 1)
1205 gmx_fatal(FARGS
, "RGB value %g out of range (0.0-1.0)", grad
[i
]);
1211 epsfile
=ftp2fn_null(efEPS
,NFILE
,fnm
);
1212 xpmfile
=opt2fn_null("-xpm",NFILE
,fnm
);
1213 if ( epsfile
==NULL
&& xpmfile
==NULL
) {
1214 if (ecombine
!=ecHalves
)
1215 xpmfile
=opt2fn("-xpm",NFILE
,fnm
);
1217 epsfile
=ftp2fn(efEPS
,NFILE
,fnm
);
1219 if (ecombine
!=ecHalves
&& epsfile
) {
1221 "WARNING: can only write result of arithmetic combination "
1222 "of two matrices to .xpm file\n"
1223 " file %s will not be written\n", epsfile
);
1227 bDiag
= ediag
!=edNone
;
1228 bFirstDiag
= ediag
!=edSecond
;
1230 fn
=opt2fn("-f",NFILE
,fnm
);
1231 nmat
=read_xpm_matrix(fn
,&mat
);
1232 fprintf(stderr
,"There are %d matrices in %s\n",nmat
,fn
);
1233 fn
=opt2fn_null("-f2",NFILE
,fnm
);
1235 nmat2
=read_xpm_matrix(fn
,&mat2
);
1236 fprintf(stderr
,"There are %d matrices in %s\n",nmat2
,fn
);
1237 if (nmat
!= nmat2
) {
1238 fprintf(stderr
,"Different number of matrices, using the smallest number.\n");
1239 nmat
=nmat2
=min(nmat
,nmat2
);
1242 if (ecombine
!=ecHalves
)
1244 "WARNING: arithmetic matrix combination selected (-combine), "
1245 "but no second matrix (-f2) supplied\n"
1246 " no matrix combination will be performed\n");
1250 bTitle
= etitle
==etTop
;
1251 bTitleOnce
= etitle
==etOnce
;
1252 if ( etitle
==etYlabel
)
1253 for (i
=0; (i
<nmat
); i
++) {
1254 strcpy(mat
[i
].label_y
, mat
[i
].title
);
1256 strcpy(mat2
[i
].label_y
, mat2
[i
].title
);
1259 gradient_mat(grad
,nmat
,mat
);
1261 gradient_mat(grad
,nmat2
,mat2
);
1263 if (erainbow
!=erNo
) {
1264 rainbow_mat(erainbow
==erBlue
,nmat
,mat
);
1266 rainbow_mat(erainbow
==erBlue
,nmat2
,mat2
);
1269 if ((mat2
== NULL
) && (elegend
!=elNone
))
1272 if (ecombine
&& ecombine
!=ecHalves
)
1273 write_combined_matrix(ecombine
, xpmfile
, nmat
, mat
, mat2
,
1274 opt2parg_bSet("-cmin",NPA
,pa
) ? &cmin
: NULL
,
1275 opt2parg_bSet("-cmax",NPA
,pa
) ? &cmax
: NULL
);
1277 do_mat(nmat
,mat
,mat2
,bFrame
,bZeroLine
,bDiag
,bFirstDiag
,
1278 bTitle
,bTitleOnce
,bYonce
,
1279 elegend
,size
,boxx
,boxy
,epsfile
,xpmfile
,
1280 opt2fn_null("-di",NFILE
,fnm
),opt2fn_null("-do",NFILE
,fnm
), skip
,
1283 view_all(oenv
,NFILE
, fnm
);