4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * Great Red Oystrich Makes All Chemists Sane
29 static char *SRCID_xpm2ps_c
= "$Id$";
58 char tickfont
[STRLEN
];
70 char leglabel
[STRLEN
];
71 char leg2label
[STRLEN
];
78 void get_params(char *mpin
,char *mpout
,t_psrec
*psr
)
80 static char *bools
[BOOL_NR
+1] = { "no", "yes", NULL
};
85 inp
=read_inpfile(mpin
,&ninp
);
86 ETYPE("black&white", psr
->bw
, bools
);
87 STYPE("titlefont", psr
->titfont
, "Helvetica");
88 RTYPE("titlefontsize", psr
->titfontsize
, 20.0);
89 ETYPE("legend", psr
->legend
, bools
);
90 STYPE("legendfont", psr
->legfont
, "Helvetica");
91 STYPE("legendlabel", psr
->leglabel
, "");
92 STYPE("legend2label", psr
->leg2label
, psr
->leglabel
);
93 RTYPE("legendfontsize", psr
->legfontsize
, 14.0);
94 RTYPE("xbox", psr
->xboxsize
, 2.0);
95 RTYPE("ybox", psr
->yboxsize
, 2.0);
96 RTYPE("matrixspacing", psr
->boxspacing
, 20.0);
97 RTYPE("xoffset", psr
->xoffs
, 0.0);
98 RTYPE("yoffset", psr
->yoffs
, 0.0);
99 ITYPE("x-major", psr
->X
.major
, 20);
100 ITYPE("x-minor", psr
->X
.minor
, 5);
101 ITYPE("x-firstmajor", psr
->X
.offset
, 0);
102 ETYPE("x-majorat0", psr
->X
.first
, bools
);
103 RTYPE("x-majorticklen", psr
->X
.majorticklen
, 8.0);
104 RTYPE("x-minorticklen", psr
->X
.minorticklen
, 4.0);
105 STYPE("x-label", psr
->X
.label
, "");
106 RTYPE("x-fontsize", psr
->X
.fontsize
, 16.0);
107 STYPE("x-font", psr
->X
.font
, "Helvetica");
108 RTYPE("x-tickfontsize", psr
->X
.tickfontsize
, 10.0);
109 STYPE("x-tickfont", psr
->X
.tickfont
, "Helvetica");
110 ITYPE("y-major", psr
->Y
.major
, 20);
111 ITYPE("y-minor", psr
->Y
.minor
, 5);
112 ITYPE("y-firstmajor", psr
->Y
.offset
, 0);
113 ETYPE("y-majorat0", psr
->Y
.first
, bools
);
114 RTYPE("y-majorticklen", psr
->Y
.majorticklen
, 8.0);
115 RTYPE("y-minorticklen", psr
->Y
.minorticklen
, 4.0);
116 STYPE("y-label", psr
->Y
.label
, "");
117 RTYPE("y-fontsize", psr
->Y
.fontsize
, 16.0);
118 STYPE("y-font", psr
->Y
.font
, "Helvetica");
119 RTYPE("y-tickfontsize", psr
->Y
.tickfontsize
, 10.0);
120 STYPE("y-tickfont", psr
->Y
.tickfont
, "Helvetica");
122 write_inpfile(mpout
,ninp
,inp
);
125 t_rgb black
={ 0.0, 0.0, 0.0 };
126 #define BLACK (&black)
128 bool diff_maps(int nmap1
,t_mapping
*map1
,int nmap2
,t_mapping
*map2
)
131 bool bDiff
,bColDiff
=FALSE
;
137 for(i
=0; i
<nmap1
; i
++) {
138 if (!matelmt_cmp(map1
[i
].code
, map2
[i
].code
)) bDiff
=TRUE
;
139 if (strcmp(map1
[i
].desc
,map2
[i
].desc
) != 0) bDiff
=TRUE
;
140 if ((map1
[i
].rgb
.r
!=map2
[i
].rgb
.r
) ||
141 (map1
[i
].rgb
.g
!=map2
[i
].rgb
.g
) ||
142 (map1
[i
].rgb
.b
!=map2
[i
].rgb
.b
))
145 if (!bDiff
&& bColDiff
)
146 fprintf(stderr
,"Warning: two colormaps differ only in RGB value, using one colormap.\n");
152 void leg_discrete(FILE *ps
,real x0
,real y0
,char *label
,
153 real fontsize
,char *font
,int nmap
,t_mapping map
[])
162 ps_strfont(ps
,font
,fontsize
);
163 yhh
=y0
+fontsize
+3*DDD
;
164 if ((int)strlen(label
) > 0)
165 ps_ctext(ps
,x0
,yhh
,label
,eXLeft
);
167 for(i
=0; (i
<nmap
); i
++) {
169 ps_rgb(ps
,&(map
[i
].rgb
));
170 ps_fillbox(ps
,DDD
,DDD
,DDD
+fontsize
,boxhh
-DDD
);
172 ps_box(ps
,DDD
,DDD
,DDD
+fontsize
,boxhh
-DDD
);
173 ps_ctext(ps
,boxhh
+2*DDD
,fontsize
/3,map
[i
].desc
,eXLeft
);
175 ps_moverel(ps
,DDD
,-fontsize
/3);
179 void leg_continuous(FILE *ps
,real x0
,real x
,real y0
,char *label
,
180 real fontsize
,char *font
,
181 int nmap
,t_mapping map
[])
185 real yhh
,boxxh
,boxyh
;
190 boxxh
=(real
)x
/(real
)nmap
;
195 xx0
=x0
-(nmap
*boxxh
)/2.0;
197 for(i
=0; (i
<nmap
); i
++) {
198 ps_rgb(ps
,&(map
[i
].rgb
));
199 ps_fillbox(ps
,xx0
+i
*boxxh
,y0
,xx0
+(i
+1)*boxxh
,y0
+boxyh
);
201 ps_strfont(ps
,font
,fontsize
);
203 ps_box(ps
,xx0
,y0
,xx0
+nmap
*boxxh
,y0
+boxyh
);
206 ps_ctext(ps
,xx0
+boxxh
/2,yhh
,map
[0].desc
,eXCenter
);
207 if ((int)strlen(label
) > 0)
208 ps_ctext(ps
,x0
,yhh
,label
,eXCenter
);
209 ps_ctext(ps
,xx0
+(nmap
*boxxh
)-boxxh
/2,yhh
,map
[nmap
-1].desc
,eXCenter
);
212 void leg_bicontinuous(FILE *ps
,real x0
,real x
,real y0
,char *label1
,char *label2
,
213 real fontsize
,char *font
,
214 int nmap1
,t_mapping map1
[],int nmap2
,t_mapping map2
[])
218 x1
=x
/(nmap1
+nmap2
)*nmap1
;/* width of legend 1 */
219 x2
=x
/(nmap1
+nmap2
)*nmap2
;/* width of legend 2 */
220 xx1
=x0
-(x2
/2.0)-fontsize
;/* center of legend 1 */
221 xx2
=x0
+(x1
/2.0)+fontsize
;/* center of legend 2 */
222 x1
-=fontsize
/2;/* adjust width */
223 x2
-=fontsize
/2;/* adjust width */
224 leg_continuous(ps
,xx1
,x1
,y0
,label1
,fontsize
,font
,nmap1
,map1
);
225 leg_continuous(ps
,xx2
,x2
,y0
,label2
,fontsize
,font
,nmap2
,map2
);
228 static real
box_height(t_matrix
*mat
,t_psrec
*psr
)
230 return mat
->ny
*psr
->yboxsize
;
233 static real
box_dh(t_psrec
*psr
)
235 return psr
->boxspacing
;
238 static real
box_dh_top(t_psrec
*psr
)
243 dh
=2*psr
->titfontsize
;
250 static bool box_do_all_x_maj_ticks(t_psrec
*psr
)
252 return (psr
->boxspacing
>(1.5*psr
->X
.majorticklen
));
255 static bool box_do_all_x_min_ticks(t_psrec
*psr
)
257 return (psr
->boxspacing
>(1.5*psr
->X
.minorticklen
));
260 static void draw_boxes(FILE *out
,real x0
,real y0
,real w
,real h
,
261 int nmat
,t_matrix mat
[],t_psrec
*psr
)
265 char **xtick
,**ytick
;
266 real xx
,yy
,dy
,xx00
,yy00
;
267 int i
,j
,x
,y
,strlength
;
269 /* Only necessary when there will be no y-labels */
275 for(i
=0; (i
<nmat
); i
++) {
276 dy
=box_height(&(mat
[i
]),psr
);
277 ps_box(out
,x0
-1,yy00
-1,x0
+w
+1,yy00
+dy
+1);
278 yy00
+=dy
+box_dh(psr
)+box_dh_top(psr
);
281 /* Draw the ticks on the axes */
284 for (i
=0; (i
<nmat
); i
++) {
285 if (mat
[i
].axis_x
==NULL
) {
286 snew(mat
[i
].axis_x
,mat
[i
].nx
);
287 for(j
=0; (j
<mat
[i
].nx
); j
++)
290 /* Make labels for x axis */
291 snew(xtick
,mat
[i
].nx
);
292 for(j
=0; (j
<mat
[i
].nx
); j
++) {
293 sprintf(buf
,"%g",mat
[i
].axis_x
[j
]);
294 xtick
[j
]=strdup(buf
);
296 ps_strfont(out
,psr
->X
.tickfont
,psr
->X
.tickfontsize
);
297 for(x
=0; (x
<mat
[i
].nx
); x
++) {
298 xx
=xx00
+(x
+0.7)*psr
->xboxsize
;
299 if ( ( (x
% psr
->X
.major
== psr
->X
.offset
) ||
300 (psr
->X
.first
&& (x
==0))) &&
301 ( (i
== 0) || box_do_all_x_maj_ticks(psr
) ) ) {
302 /* Longer tick marks */
303 ps_line (out
,xx
,yy00
,xx
,yy00
-psr
->X
.majorticklen
);
304 /* Plot label on lowest graph only */
307 yy00
-DDD
-psr
->X
.majorticklen
-psr
->X
.tickfontsize
*0.8,
309 } else if ( ( (x
-psr
->X
.offset
) % psr
->X
.minor
== 0) &&
310 ( (i
== 0) || box_do_all_x_min_ticks(psr
) ) ){
311 /* Shorter tick marks */
312 ps_line(out
,xx
,yy00
,xx
,yy00
-psr
->X
.minorticklen
);
313 } else if (x
% psr
->X
.major
== psr
->X
.offset
) {
314 /* Even shorter marks, only each X.offset */
315 ps_line(out
,xx
,yy00
,xx
,yy00
-(psr
->boxspacing
/2));
318 ps_strfont(out
,psr
->Y
.tickfont
,psr
->Y
.tickfontsize
);
319 /* Make labels for Y axis */
320 if (mat
[i
].axis_y
==NULL
) {
321 snew(mat
[i
].axis_y
,mat
[i
].ny
);
322 for(j
=0; (j
<mat
[i
].ny
); j
++)
325 snew(ytick
,mat
[i
].ny
);
326 for(j
=0; (j
<mat
[i
].ny
); j
++) {
327 sprintf(buf
,"%g",mat
[i
].axis_y
[j
]);
328 ytick
[j
]=strdup(buf
);
331 for(y
=0; (y
<mat
[i
].ny
); y
++) {
332 yy
=yy00
+(y
+0.7)*psr
->yboxsize
;
333 if ( (y
% psr
->Y
.major
== psr
->Y
.offset
) || (psr
->Y
.first
&& (y
==0))) {
335 strlength
=max(strlength
,(int)strlen(ytick
[y
]));
336 ps_line (out
,xx00
,yy
,xx00
-psr
->Y
.majorticklen
,yy
);
337 ps_ctext(out
,xx00
-psr
->Y
.majorticklen
-DDD
,
338 yy
-psr
->Y
.tickfontsize
/3.0,ytick
[y
],eXRight
);
340 else if ((y
-psr
->Y
.offset
) % psr
->Y
.minor
== 0) {
342 ps_line(out
,xx00
,yy
,xx00
-psr
->Y
.minorticklen
,yy
);
348 /* Label on Y-axis */
349 ps_strfont(out
,psr
->Y
.font
,psr
->Y
.fontsize
);
351 xxx
=x0
-psr
->X
.majorticklen
-psr
->X
.tickfontsize
*strlength
-DDD
;
352 ps_ctext(out
,yy00
+box_height(&mat
[i
],psr
)/2.0,612.5-xxx
,
353 mat
[i
].label_y
,eXCenter
);
354 ps_rotate(out
,FALSE
);
356 yy00
+=box_height(&(mat
[i
]),psr
)+box_dh(psr
)+box_dh_top(psr
);
358 /* Label on X-axis */
359 ps_strfont(out
,psr
->X
.font
,psr
->X
.fontsize
);
360 if (strlen(mat
[0].label_x
) == 0)
361 ps_ctext(out
,x0
+w
/2,y0
-DDD
-psr
->X
.majorticklen
-psr
->X
.tickfontsize
*FUDGE
-
362 psr
->X
.fontsize
,psr
->X
.label
,eXCenter
);
364 ps_ctext(out
,x0
+w
/2,y0
-DDD
-psr
->X
.majorticklen
-psr
->X
.tickfontsize
*FUDGE
-
365 psr
->X
.fontsize
,mat
[0].label_x
,eXCenter
);
368 static void box_dim(int nmat
,t_matrix mat
[],t_matrix
*mat2
,t_psrec
*psr
,
369 char w_legend
,real
*w
,real
*h
,real
*dw
,real
*dh
)
378 for(i
=0; (i
<nmat
); i
++) {
379 ww
=max(ww
,mat
[i
].nx
*psr
->xboxsize
);
380 hh
+=box_height(&(mat
[i
]),psr
);
381 maxytick
=max(maxytick
,mat
[i
].nx
);
384 if (mat
[0].label_y
[0])
385 dww
+=2.0*(psr
->Y
.fontsize
+DDD
);
386 if (psr
->Y
.major
> 0)
387 dww
+=psr
->Y
.majorticklen
+DDD
+psr
->Y
.tickfontsize
*(log(maxytick
)/log(10.0));
388 else if (psr
->Y
.minor
> 0)
389 dww
+=psr
->Y
.minorticklen
;
392 if (mat
[0].label_x
[0])
393 dhh
+=psr
->X
.fontsize
+2*DDD
;
394 if (((w_legend
== 'b') && (mat
[0].legend
[0] || mat2
[0].legend
[0])) ||
395 ((w_legend
== 'f') && mat
[0].legend
[0]) ||
396 ((w_legend
== 's') && mat2
[0].legend
[0]))
397 dhh
+=2*(psr
->legfontsize
*FUDGE
+2*DDD
);
399 dhh
+=psr
->legfontsize
*FUDGE
+2*DDD
;
400 if (psr
->X
.major
> 0)
401 dhh
+=psr
->X
.tickfontsize
*FUDGE
+2*DDD
+psr
->X
.majorticklen
;
402 else if (psr
->X
.minor
> 0)
403 dhh
+=psr
->X
.minorticklen
;
405 hh
+=(nmat
-1)*box_dh(psr
)+nmat
*box_dh_top(psr
);
413 void xpm_mat(char *outf
,
414 int nmat
,t_matrix
*mat
,t_matrix
*mat2
,bool bDiag
,bool bFirstDiag
)
419 static char mapper
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+{}|;:',<.>/?";
420 #define NMAP strlen(mapper)
421 int nmap
,nmap1
,nmap2
;
424 out
=ffopen(outf
,"w");
426 for(i
=0; i
<nmat
; i
++) {
427 if (!mat2
|| !diff_maps(mat
[i
].nmap
,mat
[i
].map
,mat2
[i
].nmap
,mat2
[i
].map
))
428 write_xpm_m(out
,mat
[0]);
434 if (nmap
> NMAP
*NMAP
)
435 fatal_error(0,"Not enough symbols to merge the two colormaps\n");
436 for(j
=0; j
<nmap1
; j
++) {
437 map
[j
].code
.c1
=mapper
[j
% NMAP
];
439 map
[j
].code
.c2
=mapper
[j
/NMAP
];
440 map
[j
].rgb
.r
=mat
[i
].map
[j
].rgb
.r
;
441 map
[j
].rgb
.g
=mat
[i
].map
[j
].rgb
.g
;
442 map
[j
].rgb
.b
=mat
[i
].map
[j
].rgb
.b
;
443 map
[j
].desc
=mat
[i
].map
[j
].desc
;
445 for(j
=0; j
<nmap2
; j
++) {
447 map
[k
].code
.c1
=mapper
[k
% NMAP
];
449 map
[k
].code
.c2
=mapper
[k
/NMAP
];
450 map
[k
].rgb
.r
=mat2
[i
].map
[j
].rgb
.r
;
451 map
[k
].rgb
.g
=mat2
[i
].map
[j
].rgb
.g
;
452 map
[k
].rgb
.b
=mat2
[i
].map
[j
].rgb
.b
;
453 map
[k
].desc
=mat2
[i
].map
[j
].desc
;
455 for(x
=0; (x
<mat
[i
].nx
); x
++) {
456 for(y
=0; (y
<mat
[i
].nx
); y
++) {
457 if ((x
<y
) || ((x
==y
) && bFirstDiag
)) /* upper left -> map1 */
458 col
=mat
[i
].matrix
[x
][y
];
459 else /* lower right -> map2 */
460 col
=nmap1
+mat
[i
].matrix
[x
][y
];
461 if ((bDiag
) || (x
!=y
))
462 mat
[i
].matrix
[x
][y
]=col
;
464 mat
[i
].matrix
[x
][y
]=0;
469 if (mat2
&& (strcmp(mat
[i
].title
,mat2
[i
].title
) != 0))
470 sprintf(mat
[i
].title
,"%s / %s",mat
[i
].title
,mat2
[i
].title
);
471 if (mat2
&& (strcmp(mat
[i
].legend
,mat2
[i
].legend
) != 0))
472 sprintf(mat
[i
].legend
,"%s / %s",mat
[i
].legend
,mat2
[i
].legend
);
473 write_xpm_m(out
,mat
[i
]);
479 void ps_mat(char *outf
,int nmat
,t_matrix mat
[],t_matrix mat2
[],
480 bool bDiag
,bool bFirstDiag
,bool bTitle
,char w_legend
,
481 real boxx
,real boxy
,char *m2p
,char *m2pout
)
483 char buf
[256],*legend
;
490 int nmap1
=0,nmap2
=0,leg_nmap
;
491 t_mapping
*map1
=NULL
,*map2
=NULL
,*leg_map
;
492 bool bMap1
,bNextMap1
,bDiscrete
;
494 get_params(libfn(m2p
),m2pout
,&psrec
);
506 for (i
=0; (i
<nmat
); i
++)
507 if (mat
[i
].nmap
>nmap1
) {
513 printf("Selected legend of matrix # %d for display\n",leg
);
516 for (i
=0; (i
<nmat
); i
++)
517 if (mat2
[i
].nmap
>nmap2
) {
523 printf("Selected legend of matrix # %d for second display\n",leg
);
525 if ( (mat
[0].legend
[0]==0) && psr
->legend
)
526 strcpy(mat
[0].legend
, psr
->leglabel
);
528 bTitle
= bTitle
&& mat
[nmat
-1].title
[0];
529 psr
->bTitle
= bTitle
;
531 /* Set up size of box for nice colors */
532 box_dim(nmat
,mat
,mat2
,psr
,w_legend
,&w
,&h
,&dw
,&dh
);
534 /* Set up bounding box */
543 out=ps_open(outf,0,0,W+psr->xoffs+5*DDD,H+psr->yoffs+4*DDD+
547 out
=ps_open(outf
,0,0,W
+psr
->xoffs
+5*DDD
,H
+psr
->yoffs
+4*DDD
);
548 ps_init_rgb_box(out
,psr
->xboxsize
,psr
->yboxsize
);
549 ps_init_rgb_nbox(out
,psr
->xboxsize
,psr
->yboxsize
);
550 ps_translate(out
,psr
->xoffs
,psr
->yoffs
);
552 ps_comment(out
,"Here starts the BOX drawing");
553 draw_boxes(out
,x0
,y0
,w
,h
,nmat
,mat
,psr
);
556 ps_strfont(out,psr->titfont,psr->titfontsize);
557 if (!mat2 || (strcmp(mat[nmat-1].title,mat2[nmat-1].title) == 0))
558 strcpy(buf,mat[nmat-1].title);
560 sprintf(buf,"%s / %s",mat[nmat-1].title,mat2[nmat-1].title);
561 ps_ctext(out,x0+w/2,y0+h+2*DDD+psr->titfontsize,
567 for(i
=0; (i
<nmat
); i
++) {
569 /* Print title, if any */
571 ps_strfont(out
,psr
->titfont
,psr
->titfontsize
);
572 if (!mat2
|| (strcmp(mat
[i
].title
,mat2
[i
].title
) == 0))
573 strcpy(buf
,mat
[i
].title
);
575 sprintf(buf
,"%s / %s",mat
[i
].title
,mat2
[i
].title
);
576 ps_ctext(out
,x0
+w
/2,y0
+box_height(&(mat
[i
]),psr
)+psr
->titfontsize
,
579 sprintf(buf
,"Here starts the filling of box #%d",i
);
581 for(x
=0; (x
<mat
[i
].nx
); x
++) {
585 xx
=x0
+x
*psr
->xboxsize
;
586 ps_moveto(out
,xx
,y0
);
588 bMap1
= (!mat2
|| (x
<y
|| (x
==y
&& bFirstDiag
)));
589 if ((bDiag
) || (x
!=y
))
590 col
= mat
[i
].matrix
[x
][y
];
593 for(nexty
=1; (nexty
<=mat
[i
].ny
); nexty
++) {
594 bNextMap1
= (!mat2
|| (x
<nexty
|| (x
==nexty
&& bFirstDiag
)));
595 /* TRUE: upper left -> map1 */
596 /* FALSE: lower right -> map2 */
597 if ((nexty
==mat
[i
].ny
) || (!bDiag
&& (x
==nexty
)))
600 nextcol
=mat
[i
].matrix
[x
][nexty
];
601 if ( (nexty
==mat
[i
].ny
) || (col
!=nextcol
) || (bMap1
!=bNextMap1
) ) {
604 ps_rgb_nbox(out
,&(mat
[i
].map
[col
].rgb
),nexty
-y
);
606 ps_rgb_nbox(out
,&(mat2
[i
].map
[col
].rgb
),nexty
-y
);
608 ps_moverel(out
,0,psr
->yboxsize
);
615 y0
+=box_height(&(mat
[i
]),psr
)+box_dh(psr
)+box_dh_top(psr
);
618 if (w_legend
!= 'n') {
619 ps_comment(out
,"Now it's legend time!");
620 if ((mat2
==NULL
) || (w_legend
!= 's')) {
621 bDiscrete
= mat
[0].bDiscrete
;
622 legend
= mat
[0].legend
;
626 bDiscrete
= mat2
[0].bDiscrete
;
627 legend
= mat2
[0].legend
;
632 leg_discrete(out
,psr
->legfontsize
,DDD
,legend
,
633 psr
->legfontsize
,psr
->legfont
,leg_nmap
,leg_map
);
636 leg_continuous(out
,x0
+w
/2,w
/2,DDD
,legend
,
637 psr
->legfontsize
,psr
->legfont
,leg_nmap
,leg_map
);
639 leg_bicontinuous(out
,x0
+w
/2,w
,DDD
,mat
[0].legend
,mat2
[0].legend
,
640 psr
->legfontsize
,psr
->legfont
,nmap1
,map1
,nmap2
,map2
);
642 ps_comment(out
,"Were there, dude");
648 void do_mat(int nmat
,t_matrix
*mat
,int nmat2
,t_matrix
*mat2
,
649 bool bDiag
,bool bFirstDiag
,bool bTitle
,char w_legend
,
651 char *epsfile
,char *xpmfile
,char *m2p
,char *m2pout
)
653 int i
,j
,k
,copy_start
;
656 for (k
=0; (k
<nmat
); k
++) {
657 if ((mat2
[k
].nx
!=mat
[k
].nx
) || (mat2
[k
].ny
!=mat
[k
].ny
))
658 fatal_error(0,"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",
659 k
,mat2
[k
].nx
,mat2
[k
].ny
,mat
[k
].nx
,mat
[k
].ny
);
660 for (j
=0; (j
<mat
[k
].ny
); j
++) {
665 for (i
=copy_start
; (i
<mat
[k
].nx
); i
++)
666 mat
[k
].matrix
[i
][j
]=mat2
[k
].matrix
[i
][j
];
670 for(i
=0; (i
<nmat
); i
++)
671 fprintf(stderr
,"Matrix %d is %d x %d\n",i
,mat
[i
].nx
,mat
[i
].ny
);
675 ps_mat(epsfile
,nmat
,mat
,mat2
,bDiag
,bFirstDiag
,
676 bTitle
,w_legend
,boxx
,boxy
,m2p
,m2pout
);
678 xpm_mat(xpmfile
,nmat
,mat
,mat2
,bDiag
,bFirstDiag
);
681 void rainbow_map(char *rainbow
, int nmat
, t_matrix mat
[])
687 for(m
=0; m
<nmat
; m
++) {
689 for(i
=0; i
<mat
[m
].nmap
; i
++) {
690 c
= (map
[i
].rgb
.r
+ map
[i
].rgb
.g
+ map
[i
].rgb
.b
)/3;
693 if (rainbow
[0] == 'b')
699 } else if (c
<= 0.5) {
702 b
= pow(2-4*c
,0.666);
703 } else if (c
<= 0.75) {
704 r
= pow(4*c
-2,0.666);
709 g
= pow(4-4*c
,0.666);
719 int main(int argc
,char *argv
[])
721 static char *desc
[] = {
722 "xpm2ps makes a beautiful color plot of an XPixelMap file.",
723 "Labels and axis can be displayed, when they are supplied",
724 "in the correct matrix format.",
725 "Matrix data may be generated by programs such as do_dssp, g_rms or",
727 "Parameters are set in the [TT]m2p[tt] file optionally supplied with",
728 "[TT]-di[tt]. Reasonable defaults are supplied in a library file.[PAR]",
729 "With [TT]-f2[tt] a 2nd matrix file can be supplied, both matrix",
730 "files will be read simultaneously and the upper left half of the",
731 "first one ([TT]-f[tt]) is plotted together with the lower right",
732 "half of the second one ([TT]-f2[tt]). The diagonal will contain",
733 "values from the matrix file selected with [TT]-diag[tt].",
734 "Plotting of the diagonal values can be suppressed altogether by",
735 "setting [TT]-diag[tt] to [TT]none[tt].[PAR]",
736 "If the color coding and legend labels of both matrices are identical,",
737 "only one legend will be displayed, else two separate legends are",
739 "[TT]-title[tt] can be set to [TT]none[tt] to suppress the title, or to",
740 "[TT]ylabel[tt] to show the title in the Y-label position (alongside",
742 "With the [TT]-rainbow[tt] option dull grey-scale matrices can be turned",
743 "into attractive color pictures.[PAR]",
744 "Merged or rainbowed matrices can be written to an XPixelMap file with",
745 "the [TT]-xpm[tt] option."
748 char *fn
,*epsfile
=NULL
,*xpmfile
=NULL
;
751 t_matrix
*mat
=NULL
,*mat2
=NULL
;
752 bool bTitle
,bDiag
,bFirstDiag
;
753 static real boxx
=0,boxy
=0;
754 static char *title
[] = { NULL
, "top", "ylabel", "none", NULL
};
755 static char *legend
[] = { NULL
, "both", "first", "second", "none", NULL
};
756 static char *diag
[] = { NULL
, "first", "second", "none", NULL
};
757 static char *rainbow
[] = { NULL
, "no", "blue", "red", NULL
};
759 { "-title", FALSE
, etENUM
, {title
}, "Show title at" },
760 { "-legend", FALSE
, etENUM
, {legend
}, "Show legend" },
761 { "-diag", FALSE
, etENUM
, {diag
}, "Diagonal" },
762 { "-bx", FALSE
, etREAL
, {&boxx
},
763 "Box x-size (also y-size when -by is not set)" },
764 { "-by", FALSE
, etREAL
, {&boxy
}, "Box y-size" },
765 { "-rainbow", FALSE
, etENUM
, {rainbow
}, "Rainbow colors, convert white to" }
768 { efXPM
, "-f", NULL
, ffREAD
},
769 { efXPM
, "-f2", "root2", ffOPTRD
},
770 { efM2P
, "-di", NULL
, ffLIBRD
},
771 { efM2P
, "-do", "out", ffOPTWR
},
772 { efEPS
, "-o", NULL
, ffOPTWR
},
773 { efXPM
, "-xpm",NULL
, ffOPTWR
}
775 #define NFILE asize(fnm)
777 CopyRight(stdout
,argv
[0]);
778 parse_common_args(&argc
,argv
,PCA_CAN_VIEW
,FALSE
,
779 NFILE
,fnm
,asize(pa
),pa
,
780 asize(desc
),desc
,0,NULL
);
782 if (ftp2bSet(efEPS
,NFILE
,fnm
))
783 epsfile
=ftp2fn(efEPS
,NFILE
,fnm
);
784 if (opt2bSet("-xpm",NFILE
,fnm
))
785 xpmfile
=opt2fn("-xpm",NFILE
,fnm
);
786 if ((epsfile
==NULL
) && (xpmfile
==NULL
))
787 epsfile
=ftp2fn(efEPS
,NFILE
,fnm
);
789 bDiag
= (diag
[0][0] != 'n');
790 bFirstDiag
= (diag
[0][0] != 's');
792 fn
=opt2fn("-f",NFILE
,fnm
);
793 nmat
=read_xpm_matrix(fn
,&mat
);
794 fprintf(stderr
,"There are %d matrices in %s\n",nmat
,fn
);
795 if (opt2bSet("-f2",NFILE
,fnm
)) {
796 fn
=opt2fn("-f2",NFILE
,fnm
);
797 nmat2
=read_xpm_matrix(fn
,&mat2
);
798 fprintf(stderr
,"There are %d matrices in %s\n",nmat2
,fn
);
800 fprintf(stderr
,"Different number of matrices, using the smallest number.\n");
801 nmat
=nmat2
=min(nmat
,nmat2
);
807 bTitle
= (title
[0][0] == 't');
808 if (title
[0][0] == 'y') {
809 bTitle
=FALSE
; /* don't print title in two places at once */
810 for (i
=0; (i
<nmat
); i
++)
811 strcpy(mat
[i
].label_y
, mat
[i
].title
);
812 for (i
=0; (i
<nmat2
); i
++)
813 strcpy(mat2
[i
].label_y
, mat2
[i
].title
);
815 if (rainbow
[0][0] != 'n') {
816 rainbow_map(rainbow
[0],nmat
,mat
);
817 rainbow_map(rainbow
[0],nmat2
,mat2
);
820 w_legend
= legend
[0][0];
821 if ((mat2
== NULL
) && (w_legend
!= 'n'))
824 do_mat(nmat
,mat
,nmat2
,mat2
,bDiag
,bFirstDiag
,bTitle
,w_legend
,
825 boxx
,boxy
,epsfile
,xpmfile
,
826 opt2fn_null("-di",NFILE
,fnm
),opt2fn_null("-do",NFILE
,fnm
));
829 viewps(ftp2fn(efEPS
,NFILE
,fnm
));