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 * GROningen Mixture of Alchemy and Childrens' Stories
46 #include "gmx_fatal.h"
52 #define round(a) (int)(a+0.5)
54 static const char mapper
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+{}|;:',<.>/?";
55 #define NMAP (long int)strlen(mapper)
57 #define MAX_XPM_LINELENGTH 4096
59 real
**mk_matrix(int nx
, int ny
, gmx_bool b1D
)
77 void done_matrix(int nx
, real
***m
)
87 void clear_matrix(int nx
, int ny
, real
**m
)
96 gmx_bool
matelmt_cmp(t_xpmelmt e1
, t_xpmelmt e2
)
98 return (e1
.c1
== e2
.c1
) && (e1
.c2
== e2
.c2
);
101 t_matelmt
searchcmap(int n
,t_mapping map
[],t_xpmelmt c
)
106 if (matelmt_cmp(map
[i
].code
, c
))
112 int getcmap(FILE *in
,const char *fn
,t_mapping
**map
)
116 char code
[STRLEN
],desc
[STRLEN
];
120 if (fgets2(line
,STRLEN
-1,in
) == NULL
)
121 gmx_fatal(FARGS
,"Not enough lines in colormap file %s"
122 "(just wanted to read number of entries)",fn
);
123 sscanf(line
,"%d",&n
);
125 for(i
=0; (i
<n
); i
++) {
126 if (fgets2(line
,STRLEN
-1,in
) == NULL
)
127 gmx_fatal(FARGS
,"Not enough lines in colormap file %s"
128 "(should be %d, found only %d)",fn
,n
+1,i
);
129 sscanf(line
,"%s%s%lf%lf%lf",code
,desc
,&r
,&g
,&b
);
130 m
[i
].code
.c1
=code
[0];
132 m
[i
].desc
=strdup(desc
);
142 int readcmap(const char *fn
,t_mapping
**map
)
148 n
=getcmap(in
,fn
,map
);
154 void printcmap(FILE *out
,int n
,t_mapping map
[])
158 fprintf(out
,"%d\n",n
);
160 fprintf(out
,"%c%c %20s %10g %10g %10g\n",
161 map
[i
].code
.c1
?map
[i
].code
.c1
:' ',
162 map
[i
].code
.c2
?map
[i
].code
.c2
:' ',
163 map
[i
].desc
,map
[i
].rgb
.r
,map
[i
].rgb
.g
,map
[i
].rgb
.b
);
166 void writecmap(const char *fn
,int n
,t_mapping map
[])
170 out
=gmx_fio_fopen(fn
,"w");
171 printcmap(out
,n
,map
);
175 void do_wmap(FILE *out
,int i0
,int imax
,
176 int nlevels
,t_rgb rlo
,t_rgb rhi
,real lo
,real hi
)
181 for(i
=0; (i
<imax
); i
++) {
183 r
=(nlo
*rlo
.r
+i
*rhi
.r
)/nlevels
;
184 g
=(nlo
*rlo
.g
+i
*rhi
.g
)/nlevels
;
185 b
=(nlo
*rlo
.b
+i
*rhi
.b
)/nlevels
;
186 fprintf(out
,"%c %10.3g %10g %10g %10g\n",
187 mapper
[i
+i0
],(nlo
*lo
+i
*hi
)/nlevels
,r
,g
,b
);
191 static char *fgetline(char **line
,int llmax
,int *llalloc
,FILE *in
)
195 if (llmax
> *llalloc
)
197 srenew(*line
,llmax
+1);
200 fg
=fgets(*line
,llmax
,in
);
206 void skipstr(char *line
)
212 while((line
[c
] != ' ') && (line
[c
] != '\0'))
215 while(line
[c
] != '\0')
223 char *line2string(char **line
)
228 while (((*line
)[0] != '\"' ) && ( (*line
)[0] != '\0' ))
231 if ((*line
)[0] != '\"')
236 while (( (*line
)[i
] != '\"' ) && ( (*line
)[i
] != '\0' ))
239 if ((*line
)[i
] != '\"')
248 void parsestring(char *line
,const char *label
, char *string
)
250 if (strstr(line
,label
)) {
251 if (strstr(line
,label
) < strchr(line
,'\"')) {
258 void read_xpm_entry(FILE *in
,t_matrix
*mm
)
261 char *line_buf
=NULL
,*line
=NULL
,*str
,buf
[256];
262 int i
,m
,col_len
,nch
,n_axis_x
,n_axis_y
,llmax
;
266 gmx_bool bGetOnWithIt
,bSetLine
;
281 while ((NULL
!= fgetline(&line_buf
,llmax
,&llalloc
,in
)) &&
282 (strncmp(line_buf
,"static",6) != 0)) {
284 parsestring(line
,"title",(mm
->title
));
285 parsestring(line
,"legend",(mm
->legend
));
286 parsestring(line
,"x-label",(mm
->label_x
));
287 parsestring(line
,"y-label",(mm
->label_y
));
288 parsestring(line
,"type",buf
);
290 if (buf
[0] && (gmx_strcasecmp(buf
,"Discrete")==0))
294 fprintf(debug
,"%s %s %s %s\n",
295 mm
->title
,mm
->legend
,mm
->label_x
,mm
->label_y
);
297 if (strncmp(line
,"static",6) != 0)
298 gmx_input("Invalid XPixMap");
301 while (!bGetOnWithIt
&& (NULL
!= fgetline(&line_buf
,llmax
,&llalloc
,in
))) {
303 while (( line
[0] != '\"' ) && ( line
[0] != '\0' ))
306 if ( line
[0] == '\"' ) {
308 sscanf(line
,"%d %d %d %d",&(mm
->nx
),&(mm
->ny
),&(mm
->nmap
),&nch
);
310 gmx_fatal(FARGS
,"Sorry can only read xpm's with at most 2 caracters per pixel\n");
311 llmax
= max(STRLEN
,mm
->nx
+10);
316 fprintf(debug
,"mm->nx %d mm->ny %d mm->nmap %d nch %d\n",
317 mm
->nx
,mm
->ny
,mm
->nmap
,nch
);
322 while ((m
< mm
->nmap
) && (NULL
!= fgetline(&line_buf
,llmax
,&llalloc
,in
))) {
323 line
= strchr(line_buf
,'\"');
326 /* Read xpm color map entry */
327 map
[m
].code
.c1
= line
[0];
331 map
[m
].code
.c2
= line
[1];
333 str
= strchr(line
,'#');
337 while (isxdigit(str
[col_len
]))
340 sscanf(line
,"%*s #%2x%2x%2x",&r
,&g
,&b
);
341 map
[m
].rgb
.r
=r
/255.0;
342 map
[m
].rgb
.g
=g
/255.0;
343 map
[m
].rgb
.b
=b
/255.0;
344 } else if (col_len
==12) {
345 sscanf(line
,"%*s #%4x%4x%4x",&r
,&g
,&b
);
346 map
[m
].rgb
.r
=r
/65535.0;
347 map
[m
].rgb
.g
=g
/65535.0;
348 map
[m
].rgb
.b
=b
/65535.0;
350 gmx_file("Unsupported or invalid colormap in X PixMap");
352 str
= strchr(line
,'c');
356 gmx_file("Unsupported or invalid colormap in X PixMap");
357 fprintf(stderr
,"Using white for color \"%s",str
);
362 line
=strchr(line
,'\"');
365 map
[m
].desc
= strdup(line
);
370 gmx_fatal(FARGS
,"Number of read colors map entries (%d) does not match the number in the header (%d)",m
,mm
->nmap
);
373 /* Read axes, if there are any */
382 if (strstr(line
,"x-axis")) {
383 line
=strstr(line
,"x-axis");
385 if (mm
->axis_x
==NULL
)
386 snew(mm
->axis_x
,mm
->nx
+ 1);
387 while (sscanf(line
,"%lf",&u
)==1) {
388 if (n_axis_x
> mm
->nx
) {
389 gmx_fatal(FARGS
,"Too many x-axis labels in xpm (max %d)",mm
->nx
);
390 } else if (n_axis_x
== mm
->nx
) {
391 mm
->flags
|= MAT_SPATIAL_X
;
393 mm
->axis_x
[n_axis_x
] = u
;
398 else if (strstr(line
,"y-axis")) {
399 line
=strstr(line
,"y-axis");
401 if (mm
->axis_y
==NULL
)
402 snew(mm
->axis_y
,mm
->ny
+ 1);
403 while (sscanf(line
,"%lf",&u
)==1) {
404 if (n_axis_y
> mm
->ny
) {
405 gmx_file("Too many y-axis labels in xpm");
406 } else if (n_axis_y
== mm
->ny
) {
407 mm
->flags
|= MAT_SPATIAL_Y
;
409 mm
->axis_y
[n_axis_y
] = u
;
414 } while ((line
[0] != '\"') && (NULL
!= fgetline(&line_buf
,llmax
,&llalloc
,in
)));
417 snew(mm
->matrix
,mm
->nx
);
418 for(i
=0; i
<mm
->nx
; i
++)
419 snew(mm
->matrix
[i
],mm
->ny
);
426 if(m
%(1+mm
->ny
/100)==0)
427 fprintf(stderr
,"%3d%%\b\b\b\b",(100*(mm
->ny
-m
))/mm
->ny
);
428 while ((line
[0] != '\"') && (line
[0] != '\0'))
431 gmx_fatal(FARGS
,"Not enough caracters in row %d of the matrix\n",m
+1);
434 for(i
=0; i
<mm
->nx
; i
++) {
440 mm
->matrix
[i
][m
]=searchcmap(mm
->nmap
,mm
->map
,c
);
444 } while ((m
>=0) && (NULL
!= fgetline(&line_buf
,llmax
,&llalloc
,in
)));
446 gmx_incons("Not enough rows in the matrix");
451 int read_xpm_matrix(const char *fnm
,t_matrix
**matrix
)
458 in
=gmx_fio_fopen(fnm
,"r");
461 while (NULL
!= fgetline(&line
,STRLEN
,&llalloc
,in
)) {
462 if (strstr(line
,"/* XPM */")) {
463 srenew(*matrix
,nmat
+1);
464 read_xpm_entry(in
,&(*matrix
)[nmat
]);
471 gmx_file("Invalid XPixMap");
478 real
**matrix2real(t_matrix
*matrix
,real
**mat
)
489 for(i
=0; i
<nmap
; i
++) {
490 if ((map
[i
].desc
==NULL
) || (sscanf(map
[i
].desc
,"%lf",&tmp
)!=1)) {
491 fprintf(stderr
,"Could not convert matrix to reals,\n"
492 "color map entry %d has a non-real description: \"%s\"\n",
501 snew(mat
,matrix
->nx
);
502 for(i
=0; i
<matrix
->nx
; i
++)
503 snew(mat
[i
],matrix
->ny
);
505 for(i
=0; i
<matrix
->nx
; i
++)
506 for(j
=0; j
<matrix
->ny
; j
++)
507 mat
[i
][j
]=rmap
[matrix
->matrix
[i
][j
]];
511 fprintf(stderr
,"Converted a %dx%d matrix with %d levels to reals\n",
512 matrix
->nx
,matrix
->ny
,nmap
);
517 void write_xpm_header(FILE *out
,
518 const char *title
,const char *legend
,
519 const char *label_x
,const char *label_y
,
522 fprintf(out
, "/* XPM */\n");
523 fprintf(out
, "/* Generated by %s */\n",Program());
524 fprintf(out
, "/* This file can be converted to EPS by the GROMACS program xpm2ps */\n");
525 fprintf(out
, "/* title: \"%s\" */\n",title
);
526 fprintf(out
, "/* legend: \"%s\" */\n",legend
);
527 fprintf(out
, "/* x-label: \"%s\" */\n",label_x
);
528 fprintf(out
, "/* y-label: \"%s\" */\n",label_y
);
530 fprintf(out
,"/* type: \"Discrete\" */\n");
532 fprintf(out
,"/* type: \"Continuous\" */\n");
535 static int calc_nmid(int nlevels
,real lo
,real mid
,real hi
)
537 /* Take care that we have at least 1 entry in the mid to hi range
539 return min(max(0,((mid
-lo
)/(hi
-lo
))*(nlevels
-1)),nlevels
-1);
542 void write_xpm_map3(FILE *out
,int n_x
,int n_y
,int *nlevels
,
543 real lo
,real mid
,real hi
,
544 t_rgb rlo
,t_rgb rmid
,t_rgb rhi
)
547 real r
,g
,b
,clev_lo
,clev_hi
;
549 if (*nlevels
> NMAP
*NMAP
) {
550 fprintf(stderr
,"Warning, too many levels (%d) in matrix, using %d only\n",
551 *nlevels
,(int)(NMAP
*NMAP
));
554 else if (*nlevels
< 2) {
555 fprintf(stderr
,"Warning, too few levels (%d) in matrix, using 2 instead\n",
559 if (!((mid
>= lo
) && (mid
< hi
)))
560 gmx_fatal(FARGS
,"Lo: %f, Mid: %f, Hi: %f\n",lo
,mid
,hi
);
562 fprintf(out
,"static char *gromacs_xpm[] = {\n");
563 fprintf(out
,"\"%d %d %d %d\",\n",
564 n_x
,n_y
,*nlevels
,(*nlevels
<= NMAP
) ? 1 : 2);
566 nmid
= calc_nmid(*nlevels
,lo
,mid
,hi
);
568 clev_hi
= (*nlevels
- 1 - nmid
);
569 for(i
=0; (i
<nmid
); i
++) {
570 r
= rlo
.r
+(i
*(rmid
.r
-rlo
.r
)/clev_lo
);
571 g
= rlo
.g
+(i
*(rmid
.g
-rlo
.g
)/clev_lo
);
572 b
= rlo
.b
+(i
*(rmid
.b
-rlo
.b
)/clev_lo
);
573 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
575 (*nlevels
<= NMAP
) ? ' ' : mapper
[i
/NMAP
],
576 (unsigned int)round(255*r
),
577 (unsigned int)round(255*g
),
578 (unsigned int)round(255*b
),
579 ((nmid
- i
)*lo
+ i
*mid
)/clev_lo
);
581 for(i
=0; (i
<(*nlevels
-nmid
)); i
++) {
582 r
= rmid
.r
+(i
*(rhi
.r
-rmid
.r
)/clev_hi
);
583 g
= rmid
.g
+(i
*(rhi
.g
-rmid
.g
)/clev_hi
);
584 b
= rmid
.b
+(i
*(rhi
.b
-rmid
.b
)/clev_hi
);
585 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
586 mapper
[(i
+nmid
) % NMAP
],
587 (*nlevels
<= NMAP
) ? ' ' : mapper
[(i
+nmid
)/NMAP
],
588 (unsigned int)round(255*r
),
589 (unsigned int)round(255*g
),
590 (unsigned int)round(255*b
),
591 ((*nlevels
- 1 - nmid
- i
)*mid
+ i
*hi
)/clev_hi
);
595 static void pr_simple_cmap(FILE *out
,real lo
,real hi
,int nlevel
,t_rgb rlo
,
601 for(i
=0; (i
<nlevel
); i
++) {
602 fac
= (i
+1.0)/(nlevel
);
603 r
= rlo
.r
+fac
*(rhi
.r
-rlo
.r
);
604 g
= rlo
.g
+fac
*(rhi
.g
-rlo
.g
);
605 b
= rlo
.b
+fac
*(rhi
.b
-rlo
.b
);
606 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
607 mapper
[(i
+i0
) % NMAP
],
608 (nlevel
<= NMAP
) ? ' ' : mapper
[(i
+i0
)/NMAP
],
609 (unsigned int)round(255*r
),
610 (unsigned int)round(255*g
),
611 (unsigned int)round(255*b
),
616 static void pr_discrete_cmap(FILE *out
,int *nlevel
,int i0
)
619 { 1.0, 1.0, 1.0 }, /* white */
620 { 1.0, 0.0, 0.0 }, /* red */
621 { 1.0, 1.0, 0.0 }, /* yellow */
622 { 0.0, 0.0, 1.0 }, /* blue */
623 { 0.0, 1.0, 0.0 }, /* green */
624 { 1.0, 0.0, 1.0 }, /* purple */
625 { 1.0, 0.4, 0.0 }, /* orange */
626 { 0.0, 1.0, 1.0 }, /* cyan */
627 { 1.0, 0.4, 0.4 }, /* pink */
628 { 1.0, 1.0, 0.0 }, /* yellow */
629 { 0.4, 0.4, 1.0 }, /* lightblue */
630 { 0.4, 1.0, 0.4 }, /* lightgreen */
631 { 1.0, 0.4, 1.0 }, /* lightpurple */
632 { 1.0, 0.7, 0.4 }, /* lightorange */
633 { 0.4, 1.0, 1.0 }, /* lightcyan */
634 { 0.0, 0.0, 0.0 } /* black */
639 *nlevel
= min(16,*nlevel
);
641 for(i
=0; (i
<n
); i
++) {
642 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%3d\" */,\n",
643 mapper
[(i
+i0
) % NMAP
],
644 (n
<= NMAP
) ? ' ' : mapper
[(i
+i0
)/NMAP
],
645 (unsigned int)round(255*rgbd
[i
].r
),
646 (unsigned int)round(255*rgbd
[i
].g
),
647 (unsigned int)round(255*rgbd
[i
].b
),
654 void write_xpm_map_split(FILE *out
,int n_x
,int n_y
,
655 int *nlevel_top
,real lo_top
,real hi_top
,
656 t_rgb rlo_top
,t_rgb rhi_top
,
657 gmx_bool bDiscreteColor
,
658 int *nlevel_bot
,real lo_bot
,real hi_bot
,
659 t_rgb rlo_bot
,t_rgb rhi_bot
)
664 ntot
= *nlevel_top
+ *nlevel_bot
;
666 gmx_fatal(FARGS
,"Warning, too many levels (%d) in matrix",ntot
);
668 fprintf(out
,"static char *gromacs_xpm[] = {\n");
669 fprintf(out
,"\"%d %d %d %d\",\n",n_x
,n_y
,ntot
,1);
672 pr_discrete_cmap(out
,nlevel_bot
,0);
674 pr_simple_cmap(out
,lo_bot
,hi_bot
,*nlevel_bot
,rlo_bot
,rhi_bot
,0);
676 pr_simple_cmap(out
,lo_top
,hi_top
,*nlevel_top
,rlo_top
,rhi_top
,*nlevel_bot
);
680 void write_xpm_map(FILE *out
,int n_x
, int n_y
,int *nlevels
,real lo
,real hi
,
686 if (*nlevels
> NMAP
*NMAP
) {
687 fprintf(stderr
,"Warning, too many levels (%d) in matrix, using %d only\n",
688 *nlevels
,(int)(NMAP
*NMAP
));
691 else if (*nlevels
< 2) {
692 fprintf(stderr
,"Warning, too few levels (%d) in matrix, using 2 instead\n",*nlevels
);
696 fprintf(out
,"static char *gromacs_xpm[] = {\n");
697 fprintf(out
,"\"%d %d %d %d\",\n",
698 n_x
,n_y
,*nlevels
,(*nlevels
<= NMAP
) ? 1 : 2);
700 invlevel
=1.0/(*nlevels
-1);
701 for(i
=0; (i
<*nlevels
); i
++) {
703 r
=(nlo
*rlo
.r
+i
*rhi
.r
)*invlevel
;
704 g
=(nlo
*rlo
.g
+i
*rhi
.g
)*invlevel
;
705 b
=(nlo
*rlo
.b
+i
*rhi
.b
)*invlevel
;
706 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
707 mapper
[i
% NMAP
],(*nlevels
<= NMAP
) ? ' ' : mapper
[i
/NMAP
],
708 (unsigned int)round(255*r
),
709 (unsigned int)round(255*g
),
710 (unsigned int)round(255*b
),
711 (nlo
*lo
+i
*hi
)*invlevel
);
715 void write_xpm_axis(FILE *out
, const char *axis
, gmx_bool bSpatial
, int n
,
721 for(i
=0;i
<(bSpatial
? n
+1 : n
);i
++) {
725 fprintf(out
,"/* %s-axis: ",axis
);
727 fprintf(out
,"%g ",label
[i
]);
733 void write_xpm_data(FILE *out
, int n_x
, int n_y
, real
**matrix
,
734 real lo
, real hi
, int nlevels
)
739 invlevel
=(nlevels
-1)/(hi
-lo
);
740 for(j
=n_y
-1; (j
>=0); j
--) {
742 fprintf(stderr
,"%3d%%\b\b\b\b",(100*(n_y
-j
))/n_y
);
744 for(i
=0; (i
<n_x
); i
++) {
745 c
=gmx_nint((matrix
[i
][j
]-lo
)*invlevel
);
747 if (c
>=nlevels
) c
=nlevels
-1;
749 fprintf(out
,"%c",mapper
[c
]);
751 fprintf(out
,"%c%c",mapper
[c
% NMAP
],mapper
[c
/ NMAP
]);
754 fprintf(out
,"\",\n");
760 void write_xpm_data3(FILE *out
,int n_x
,int n_y
,real
**matrix
,
761 real lo
,real mid
,real hi
,int nlevels
)
764 real invlev_lo
,invlev_hi
;
766 nmid
= calc_nmid(nlevels
,lo
,mid
,hi
);
767 invlev_hi
=(nlevels
-1-nmid
)/(hi
-mid
);
768 invlev_lo
=(nmid
)/(mid
-lo
);
770 for(j
=n_y
-1; (j
>=0); j
--) {
772 fprintf(stderr
,"%3d%%\b\b\b\b",(100*(n_y
-j
))/n_y
);
774 for(i
=0; (i
<n_x
); i
++) {
775 if (matrix
[i
][j
] >= mid
)
776 c
=nmid
+gmx_nint((matrix
[i
][j
]-mid
)*invlev_hi
);
777 else if (matrix
[i
][j
] >= lo
)
778 c
=gmx_nint((matrix
[i
][j
]-lo
)*invlev_lo
);
787 fprintf(out
,"%c",mapper
[c
]);
789 fprintf(out
,"%c%c",mapper
[c
% NMAP
],mapper
[c
/ NMAP
]);
792 fprintf(out
,"\",\n");
798 void write_xpm_data_split(FILE *out
,int n_x
,int n_y
,real
**matrix
,
799 real lo_top
,real hi_top
,int nlevel_top
,
800 real lo_bot
,real hi_bot
,int nlevel_bot
)
803 real invlev_top
,invlev_bot
;
805 invlev_top
=(nlevel_top
-1)/(hi_top
-lo_top
);
806 invlev_bot
=(nlevel_bot
-1)/(hi_bot
-lo_bot
);
808 for(j
=n_y
-1; (j
>=0); j
--) {
809 if(j
% (1+n_y
/100)==0)
810 fprintf(stderr
,"%3d%%\b\b\b\b",(100*(n_y
-j
))/n_y
);
812 for(i
=0; (i
<n_x
); i
++) {
814 c
= nlevel_bot
+round((matrix
[i
][j
]-lo_top
)*invlev_top
);
815 if ((c
< nlevel_bot
) || (c
>= nlevel_bot
+nlevel_top
))
816 gmx_fatal(FARGS
,"Range checking i = %d, j = %d, c = %d, bot = %d, top = %d matrix[i,j] = %f",i
,j
,c
,nlevel_bot
,nlevel_top
,matrix
[i
][j
]);
819 c
= round((matrix
[i
][j
]-lo_bot
)*invlev_bot
);
820 if ((c
< 0) || (c
>= nlevel_bot
+nlevel_bot
))
821 gmx_fatal(FARGS
,"Range checking i = %d, j = %d, c = %d, bot = %d, top = %d matrix[i,j] = %f",i
,j
,c
,nlevel_bot
,nlevel_top
,matrix
[i
][j
]);
826 fprintf(out
,"%c",mapper
[c
]);
829 fprintf(out
,"\",\n");
835 void write_xpm_m(FILE *out
, t_matrix m
)
837 /* Writes a t_matrix struct to .xpm file */
843 bOneChar
=(m
.map
[0].code
.c2
== 0);
844 write_xpm_header(out
,m
.title
,m
.legend
,m
.label_x
,m
.label_y
,
846 fprintf(out
,"static char *gromacs_xpm[] = {\n");
847 fprintf(out
,"\"%d %d %d %d\",\n",m
.nx
,m
.ny
,m
.nmap
,bOneChar
? 1 : 2);
848 for(i
=0; (i
<m
.nmap
); i
++)
849 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%s\" */,\n",
851 bOneChar
? ' ' : m
.map
[i
].code
.c2
,
852 (unsigned int)round(m
.map
[i
].rgb
.r
*255),
853 (unsigned int)round(m
.map
[i
].rgb
.g
*255),
854 (unsigned int)round(m
.map
[i
].rgb
.b
*255),m
.map
[i
].desc
);
855 write_xpm_axis(out
,"x",m
.flags
& MAT_SPATIAL_X
,m
.nx
,m
.axis_x
);
856 write_xpm_axis(out
,"y",m
.flags
& MAT_SPATIAL_Y
,m
.ny
,m
.axis_y
);
857 for(j
=m
.ny
-1; (j
>=0); j
--) {
858 if(j
%(1+m
.ny
/100)==0)
859 fprintf(stderr
,"%3d%%\b\b\b\b",(100*(m
.ny
-j
))/m
.ny
);
862 for(i
=0; (i
<m
.nx
); i
++)
863 fprintf(out
,"%c",m
.map
[m
.matrix
[i
][j
]].code
.c1
);
865 for(i
=0; (i
<m
.nx
); i
++) {
866 c
=m
.map
[m
.matrix
[i
][j
]].code
;
867 fprintf(out
,"%c%c",c
.c1
,c
.c2
);
870 fprintf(out
,"\",\n");
876 void write_xpm3(FILE *out
,unsigned int flags
,
877 const char *title
,const char *legend
,
878 const char *label_x
,const char *label_y
,
879 int n_x
,int n_y
,real axis_x
[],real axis_y
[],
880 real
*matrix
[],real lo
,real mid
,real hi
,
881 t_rgb rlo
,t_rgb rmid
,t_rgb rhi
,int *nlevels
)
884 * Writes a colormap varying as rlo -> rmid -> rhi.
888 gmx_fatal(FARGS
,"hi (%g) <= lo (%g)",hi
,lo
);
890 write_xpm_header(out
,title
,legend
,label_x
,label_y
,FALSE
);
891 write_xpm_map3(out
,n_x
,n_y
,nlevels
,lo
,mid
,hi
,rlo
,rmid
,rhi
);
892 write_xpm_axis(out
,"x",flags
& MAT_SPATIAL_X
,n_x
,axis_x
);
893 write_xpm_axis(out
,"y",flags
& MAT_SPATIAL_Y
,n_y
,axis_y
);
894 write_xpm_data3(out
,n_x
,n_y
,matrix
,lo
,mid
,hi
,*nlevels
);
897 void write_xpm_split(FILE *out
,unsigned int flags
,
898 const char *title
,const char *legend
,
899 const char *label_x
,const char *label_y
,
900 int n_x
,int n_y
,real axis_x
[],real axis_y
[],
902 real lo_top
,real hi_top
,int *nlevel_top
,
903 t_rgb rlo_top
,t_rgb rhi_top
,
904 real lo_bot
,real hi_bot
,int *nlevel_bot
,
905 gmx_bool bDiscreteColor
,
906 t_rgb rlo_bot
,t_rgb rhi_bot
)
909 * Writes a colormap varying as rlo -> rmid -> rhi.
912 if (hi_top
<= lo_top
)
913 gmx_fatal(FARGS
,"hi_top (%g) <= lo_top (%g)",hi_top
,lo_top
);
914 if (hi_bot
<= lo_bot
)
915 gmx_fatal(FARGS
,"hi_bot (%g) <= lo_bot (%g)",hi_bot
,lo_bot
);
916 if (bDiscreteColor
&& (*nlevel_bot
>= 16))
917 gmx_impl("Can not plot more than 16 discrete colors");
919 write_xpm_header(out
,title
,legend
,label_x
,label_y
,FALSE
);
920 write_xpm_map_split(out
,n_x
,n_y
,nlevel_top
,lo_top
,hi_top
,rlo_top
,rhi_top
,
921 bDiscreteColor
,nlevel_bot
,lo_bot
,hi_bot
,rlo_bot
,rhi_bot
);
922 write_xpm_axis(out
,"x",flags
& MAT_SPATIAL_X
,n_x
,axis_x
);
923 write_xpm_axis(out
,"y",flags
& MAT_SPATIAL_Y
,n_y
,axis_y
);
924 write_xpm_data_split(out
,n_x
,n_y
,matrix
,lo_top
,hi_top
,*nlevel_top
,
925 lo_bot
,hi_bot
,*nlevel_bot
);
928 void write_xpm(FILE *out
,unsigned int flags
,
929 const char *title
,const char *legend
,
930 const char *label_x
,const char *label_y
,
931 int n_x
,int n_y
,real axis_x
[],real axis_y
[],
932 real
*matrix
[],real lo
,real hi
,
933 t_rgb rlo
,t_rgb rhi
,int *nlevels
)
937 * legend label for the continuous legend
938 * label_x label for the x-axis
939 * label_y label for the y-axis
940 * n_x, n_y size of the matrix
941 * axis_x[] the x-ticklabels
942 * axis_y[] the y-ticklables
943 * *matrix[] element x,y is matrix[x][y]
944 * lo output lower than lo is set to lo
945 * hi output higher than hi is set to hi
946 * rlo rgb value for level lo
947 * rhi rgb value for level hi
948 * nlevels number of color levels for the output
952 gmx_fatal(FARGS
,"hi (%f) <= lo (%f)",hi
,lo
);
954 write_xpm_header(out
,title
,legend
,label_x
,label_y
,FALSE
);
955 write_xpm_map(out
,n_x
,n_y
,nlevels
,lo
,hi
,rlo
,rhi
);
956 write_xpm_axis(out
,"x",flags
& MAT_SPATIAL_X
,n_x
,axis_x
);
957 write_xpm_axis(out
,"y",flags
& MAT_SPATIAL_Y
,n_y
,axis_y
);
958 write_xpm_data(out
,n_x
,n_y
,matrix
,lo
,hi
,*nlevels
);