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
=NULL
,*str
,buf
[256];
262 int i
,m
,col_len
,nch
,n_axis_x
,n_axis_y
,llmax
;
266 gmx_bool bGetOnWithIt
;
281 while ((NULL
!= fgetline(&line
,llmax
,&llalloc
,in
)) &&
282 (strncmp(line
,"static",6) != 0)) {
283 parsestring(line
,"title",(mm
->title
));
284 parsestring(line
,"legend",(mm
->legend
));
285 parsestring(line
,"x-label",(mm
->label_x
));
286 parsestring(line
,"y-label",(mm
->label_y
));
287 parsestring(line
,"type",buf
);
289 if (buf
[0] && (gmx_strcasecmp(buf
,"Discrete")==0))
293 fprintf(debug
,"%s %s %s %s\n",
294 mm
->title
,mm
->legend
,mm
->label_x
,mm
->label_y
);
296 if (strncmp(line
,"static",6) != 0)
297 gmx_input("Invalid XPixMap");
300 while (!bGetOnWithIt
&& (NULL
!= fgetline(&line
,llmax
,&llalloc
,in
))) {
301 while (( line
[0] != '\"' ) && ( line
[0] != '\0' ))
304 if ( line
[0] == '\"' ) {
306 sscanf(line
,"%d %d %d %d",&(mm
->nx
),&(mm
->ny
),&(mm
->nmap
),&nch
);
308 gmx_fatal(FARGS
,"Sorry can only read xpm's with at most 2 caracters per pixel\n");
309 llmax
= max(STRLEN
,mm
->nx
+10);
314 fprintf(debug
,"mm->nx %d mm->ny %d mm->nmap %d nch %d\n",
315 mm
->nx
,mm
->ny
,mm
->nmap
,nch
);
320 while ((m
< mm
->nmap
) && (NULL
!= fgetline(&line
,llmax
,&llalloc
,in
))) {
321 line
=strchr(line
,'\"');
324 /* Read xpm color map entry */
325 map
[m
].code
.c1
= line
[0];
329 map
[m
].code
.c2
= line
[1];
331 str
= strchr(line
,'#');
335 while (isxdigit(str
[col_len
]))
338 sscanf(line
,"%*s #%2x%2x%2x",&r
,&g
,&b
);
339 map
[m
].rgb
.r
=r
/255.0;
340 map
[m
].rgb
.g
=g
/255.0;
341 map
[m
].rgb
.b
=b
/255.0;
342 } else if (col_len
==12) {
343 sscanf(line
,"%*s #%4x%4x%4x",&r
,&g
,&b
);
344 map
[m
].rgb
.r
=r
/65535.0;
345 map
[m
].rgb
.g
=g
/65535.0;
346 map
[m
].rgb
.b
=b
/65535.0;
348 gmx_file("Unsupported or invalid colormap in X PixMap");
350 str
= strchr(line
,'c');
354 gmx_file("Unsupported or invalid colormap in X PixMap");
355 fprintf(stderr
,"Using white for color \"%s",str
);
360 line
=strchr(line
,'\"');
363 map
[m
].desc
= strdup(line
);
368 gmx_fatal(FARGS
,"Number of read colors map entries (%d) does not match the number in the header (%d)",m
,mm
->nmap
);
371 /* Read axes, if there are any */
376 if (strstr(line
,"x-axis")) {
377 line
=strstr(line
,"x-axis");
379 if (mm
->axis_x
==NULL
)
380 snew(mm
->axis_x
,mm
->nx
+ 1);
381 while (sscanf(line
,"%lf",&u
)==1) {
382 if (n_axis_x
> mm
->nx
) {
383 gmx_fatal(FARGS
,"Too many x-axis labels in xpm (max %d)",mm
->nx
);
384 } else if (n_axis_x
== mm
->nx
) {
385 mm
->flags
|= MAT_SPATIAL_X
;
387 mm
->axis_x
[n_axis_x
] = u
;
392 else if (strstr(line
,"y-axis")) {
393 line
=strstr(line
,"y-axis");
395 if (mm
->axis_y
==NULL
)
396 snew(mm
->axis_y
,mm
->ny
+ 1);
397 while (sscanf(line
,"%lf",&u
)==1) {
398 if (n_axis_y
> mm
->ny
) {
399 gmx_file("Too many y-axis labels in xpm");
400 } else if (n_axis_y
== mm
->ny
) {
401 mm
->flags
|= MAT_SPATIAL_Y
;
403 mm
->axis_y
[n_axis_y
] = u
;
408 } while ((line
[0] != '\"') && (NULL
!= fgetline(&line
,llmax
,&llalloc
,in
)));
411 snew(mm
->matrix
,mm
->nx
);
412 for(i
=0; i
<mm
->nx
; i
++)
413 snew(mm
->matrix
[i
],mm
->ny
);
416 if(m
%(1+mm
->ny
/100)==0)
417 fprintf(stderr
,"%3d%%\b\b\b\b",(100*(mm
->ny
-m
))/mm
->ny
);
418 while ((line
[0] != '\"') && (line
[0] != '\0'))
421 gmx_fatal(FARGS
,"Not enough caracters in row %d of the matrix\n",m
+1);
424 for(i
=0; i
<mm
->nx
; i
++) {
430 mm
->matrix
[i
][m
]=searchcmap(mm
->nmap
,mm
->map
,c
);
434 } while ((m
>=0) && (NULL
!= fgetline(&line
,llmax
,&llalloc
,in
)));
436 gmx_incons("Not enough rows in the matrix");
438 /* This code makes me cry. DvdS 2010-07-08 */
442 int read_xpm_matrix(const char *fnm
,t_matrix
**matrix
)
449 in
=gmx_fio_fopen(fnm
,"r");
452 while (NULL
!= fgetline(&line
,STRLEN
,&llalloc
,in
)) {
453 if (strstr(line
,"/* XPM */")) {
454 srenew(*matrix
,nmat
+1);
455 read_xpm_entry(in
,&(*matrix
)[nmat
]);
462 gmx_file("Invalid XPixMap");
469 real
**matrix2real(t_matrix
*matrix
,real
**mat
)
480 for(i
=0; i
<nmap
; i
++) {
481 if ((map
[i
].desc
==NULL
) || (sscanf(map
[i
].desc
,"%lf",&tmp
)!=1)) {
482 fprintf(stderr
,"Could not convert matrix to reals,\n"
483 "color map entry %d has a non-real description: \"%s\"\n",
492 snew(mat
,matrix
->nx
);
493 for(i
=0; i
<matrix
->nx
; i
++)
494 snew(mat
[i
],matrix
->ny
);
496 for(i
=0; i
<matrix
->nx
; i
++)
497 for(j
=0; j
<matrix
->ny
; j
++)
498 mat
[i
][j
]=rmap
[matrix
->matrix
[i
][j
]];
502 fprintf(stderr
,"Converted a %dx%d matrix with %d levels to reals\n",
503 matrix
->nx
,matrix
->ny
,nmap
);
508 void write_xpm_header(FILE *out
,
509 const char *title
,const char *legend
,
510 const char *label_x
,const char *label_y
,
513 fprintf(out
, "/* XPM */\n");
514 fprintf(out
, "/* Generated by %s */\n",Program());
515 fprintf(out
, "/* This file can be converted to EPS by the GROMACS program xpm2ps */\n");
516 fprintf(out
, "/* title: \"%s\" */\n",title
);
517 fprintf(out
, "/* legend: \"%s\" */\n",legend
);
518 fprintf(out
, "/* x-label: \"%s\" */\n",label_x
);
519 fprintf(out
, "/* y-label: \"%s\" */\n",label_y
);
521 fprintf(out
,"/* type: \"Discrete\" */\n");
523 fprintf(out
,"/* type: \"Continuous\" */\n");
526 static int calc_nmid(int nlevels
,real lo
,real mid
,real hi
)
528 /* Take care that we have at least 1 entry in the mid to hi range
530 return min(max(0,((mid
-lo
)/(hi
-lo
))*(nlevels
-1)),nlevels
-1);
533 void write_xpm_map3(FILE *out
,int n_x
,int n_y
,int *nlevels
,
534 real lo
,real mid
,real hi
,
535 t_rgb rlo
,t_rgb rmid
,t_rgb rhi
)
538 real r
,g
,b
,clev_lo
,clev_hi
;
540 if (*nlevels
> NMAP
*NMAP
) {
541 fprintf(stderr
,"Warning, too many levels (%d) in matrix, using %d only\n",
542 *nlevels
,(int)(NMAP
*NMAP
));
545 else if (*nlevels
< 2) {
546 fprintf(stderr
,"Warning, too few levels (%d) in matrix, using 2 instead\n",
550 if (!((mid
>= lo
) && (mid
< hi
)))
551 gmx_fatal(FARGS
,"Lo: %f, Mid: %f, Hi: %f\n",lo
,mid
,hi
);
553 fprintf(out
,"static char *gromacs_xpm[] = {\n");
554 fprintf(out
,"\"%d %d %d %d\",\n",
555 n_x
,n_y
,*nlevels
,(*nlevels
<= NMAP
) ? 1 : 2);
557 nmid
= calc_nmid(*nlevels
,lo
,mid
,hi
);
559 clev_hi
= (*nlevels
- 1 - nmid
);
560 for(i
=0; (i
<nmid
); i
++) {
561 r
= rlo
.r
+(i
*(rmid
.r
-rlo
.r
)/clev_lo
);
562 g
= rlo
.g
+(i
*(rmid
.g
-rlo
.g
)/clev_lo
);
563 b
= rlo
.b
+(i
*(rmid
.b
-rlo
.b
)/clev_lo
);
564 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
566 (*nlevels
<= NMAP
) ? ' ' : mapper
[i
/NMAP
],
567 (unsigned int)round(255*r
),
568 (unsigned int)round(255*g
),
569 (unsigned int)round(255*b
),
570 ((nmid
- i
)*lo
+ i
*mid
)/clev_lo
);
572 for(i
=0; (i
<(*nlevels
-nmid
)); i
++) {
573 r
= rmid
.r
+(i
*(rhi
.r
-rmid
.r
)/clev_hi
);
574 g
= rmid
.g
+(i
*(rhi
.g
-rmid
.g
)/clev_hi
);
575 b
= rmid
.b
+(i
*(rhi
.b
-rmid
.b
)/clev_hi
);
576 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
577 mapper
[(i
+nmid
) % NMAP
],
578 (*nlevels
<= NMAP
) ? ' ' : mapper
[(i
+nmid
)/NMAP
],
579 (unsigned int)round(255*r
),
580 (unsigned int)round(255*g
),
581 (unsigned int)round(255*b
),
582 ((*nlevels
- 1 - nmid
- i
)*mid
+ i
*hi
)/clev_hi
);
586 static void pr_simple_cmap(FILE *out
,real lo
,real hi
,int nlevel
,t_rgb rlo
,
592 for(i
=0; (i
<nlevel
); i
++) {
593 fac
= (i
+1.0)/(nlevel
);
594 r
= rlo
.r
+fac
*(rhi
.r
-rlo
.r
);
595 g
= rlo
.g
+fac
*(rhi
.g
-rlo
.g
);
596 b
= rlo
.b
+fac
*(rhi
.b
-rlo
.b
);
597 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
598 mapper
[(i
+i0
) % NMAP
],
599 (nlevel
<= NMAP
) ? ' ' : mapper
[(i
+i0
)/NMAP
],
600 (unsigned int)round(255*r
),
601 (unsigned int)round(255*g
),
602 (unsigned int)round(255*b
),
607 static void pr_discrete_cmap(FILE *out
,int *nlevel
,int i0
)
610 { 1.0, 1.0, 1.0 }, /* white */
611 { 1.0, 0.0, 0.0 }, /* red */
612 { 1.0, 1.0, 0.0 }, /* yellow */
613 { 0.0, 0.0, 1.0 }, /* blue */
614 { 0.0, 1.0, 0.0 }, /* green */
615 { 1.0, 0.0, 1.0 }, /* purple */
616 { 1.0, 0.4, 0.0 }, /* orange */
617 { 0.0, 1.0, 1.0 }, /* cyan */
618 { 1.0, 0.4, 0.4 }, /* pink */
619 { 1.0, 1.0, 0.0 }, /* yellow */
620 { 0.4, 0.4, 1.0 }, /* lightblue */
621 { 0.4, 1.0, 0.4 }, /* lightgreen */
622 { 1.0, 0.4, 1.0 }, /* lightpurple */
623 { 1.0, 0.7, 0.4 }, /* lightorange */
624 { 0.4, 1.0, 1.0 }, /* lightcyan */
625 { 0.0, 0.0, 0.0 } /* black */
630 *nlevel
= min(16,*nlevel
);
632 for(i
=0; (i
<n
); i
++) {
633 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%3d\" */,\n",
634 mapper
[(i
+i0
) % NMAP
],
635 (n
<= NMAP
) ? ' ' : mapper
[(i
+i0
)/NMAP
],
636 (unsigned int)round(255*rgbd
[i
].r
),
637 (unsigned int)round(255*rgbd
[i
].g
),
638 (unsigned int)round(255*rgbd
[i
].b
),
645 void write_xpm_map_split(FILE *out
,int n_x
,int n_y
,
646 int *nlevel_top
,real lo_top
,real hi_top
,
647 t_rgb rlo_top
,t_rgb rhi_top
,
648 gmx_bool bDiscreteColor
,
649 int *nlevel_bot
,real lo_bot
,real hi_bot
,
650 t_rgb rlo_bot
,t_rgb rhi_bot
)
655 ntot
= *nlevel_top
+ *nlevel_bot
;
657 gmx_fatal(FARGS
,"Warning, too many levels (%d) in matrix",ntot
);
659 fprintf(out
,"static char *gromacs_xpm[] = {\n");
660 fprintf(out
,"\"%d %d %d %d\",\n",n_x
,n_y
,ntot
,1);
663 pr_discrete_cmap(out
,nlevel_bot
,0);
665 pr_simple_cmap(out
,lo_bot
,hi_bot
,*nlevel_bot
,rlo_bot
,rhi_bot
,0);
667 pr_simple_cmap(out
,lo_top
,hi_top
,*nlevel_top
,rlo_top
,rhi_top
,*nlevel_bot
);
671 void write_xpm_map(FILE *out
,int n_x
, int n_y
,int *nlevels
,real lo
,real hi
,
677 if (*nlevels
> NMAP
*NMAP
) {
678 fprintf(stderr
,"Warning, too many levels (%d) in matrix, using %d only\n",
679 *nlevels
,(int)(NMAP
*NMAP
));
682 else if (*nlevels
< 2) {
683 fprintf(stderr
,"Warning, too few levels (%d) in matrix, using 2 instead\n",*nlevels
);
687 fprintf(out
,"static char *gromacs_xpm[] = {\n");
688 fprintf(out
,"\"%d %d %d %d\",\n",
689 n_x
,n_y
,*nlevels
,(*nlevels
<= NMAP
) ? 1 : 2);
691 invlevel
=1.0/(*nlevels
-1);
692 for(i
=0; (i
<*nlevels
); i
++) {
694 r
=(nlo
*rlo
.r
+i
*rhi
.r
)*invlevel
;
695 g
=(nlo
*rlo
.g
+i
*rhi
.g
)*invlevel
;
696 b
=(nlo
*rlo
.b
+i
*rhi
.b
)*invlevel
;
697 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
698 mapper
[i
% NMAP
],(*nlevels
<= NMAP
) ? ' ' : mapper
[i
/NMAP
],
699 (unsigned int)round(255*r
),
700 (unsigned int)round(255*g
),
701 (unsigned int)round(255*b
),
702 (nlo
*lo
+i
*hi
)*invlevel
);
706 void write_xpm_axis(FILE *out
, const char *axis
, gmx_bool bSpatial
, int n
,
712 for(i
=0;i
<(bSpatial
? n
+1 : n
);i
++) {
716 fprintf(out
,"/* %s-axis: ",axis
);
718 fprintf(out
,"%g ",label
[i
]);
724 void write_xpm_data(FILE *out
, int n_x
, int n_y
, real
**matrix
,
725 real lo
, real hi
, int nlevels
)
730 invlevel
=(nlevels
-1)/(hi
-lo
);
731 for(j
=n_y
-1; (j
>=0); j
--) {
733 fprintf(stderr
,"%3d%%\b\b\b\b",(100*(n_y
-j
))/n_y
);
735 for(i
=0; (i
<n_x
); i
++) {
736 c
=gmx_nint((matrix
[i
][j
]-lo
)*invlevel
);
738 if (c
>=nlevels
) c
=nlevels
-1;
740 fprintf(out
,"%c",mapper
[c
]);
742 fprintf(out
,"%c%c",mapper
[c
% NMAP
],mapper
[c
/ NMAP
]);
745 fprintf(out
,"\",\n");
751 void write_xpm_data3(FILE *out
,int n_x
,int n_y
,real
**matrix
,
752 real lo
,real mid
,real hi
,int nlevels
)
755 real invlev_lo
,invlev_hi
;
757 nmid
= calc_nmid(nlevels
,lo
,mid
,hi
);
758 invlev_hi
=(nlevels
-1-nmid
)/(hi
-mid
);
759 invlev_lo
=(nmid
)/(mid
-lo
);
761 for(j
=n_y
-1; (j
>=0); j
--) {
763 fprintf(stderr
,"%3d%%\b\b\b\b",(100*(n_y
-j
))/n_y
);
765 for(i
=0; (i
<n_x
); i
++) {
766 if (matrix
[i
][j
] >= mid
)
767 c
=nmid
+gmx_nint((matrix
[i
][j
]-mid
)*invlev_hi
);
768 else if (matrix
[i
][j
] >= lo
)
769 c
=gmx_nint((matrix
[i
][j
]-lo
)*invlev_lo
);
778 fprintf(out
,"%c",mapper
[c
]);
780 fprintf(out
,"%c%c",mapper
[c
% NMAP
],mapper
[c
/ NMAP
]);
783 fprintf(out
,"\",\n");
789 void write_xpm_data_split(FILE *out
,int n_x
,int n_y
,real
**matrix
,
790 real lo_top
,real hi_top
,int nlevel_top
,
791 real lo_bot
,real hi_bot
,int nlevel_bot
)
794 real invlev_top
,invlev_bot
;
796 invlev_top
=(nlevel_top
-1)/(hi_top
-lo_top
);
797 invlev_bot
=(nlevel_bot
-1)/(hi_bot
-lo_bot
);
799 for(j
=n_y
-1; (j
>=0); j
--) {
800 if(j
% (1+n_y
/100)==0)
801 fprintf(stderr
,"%3d%%\b\b\b\b",(100*(n_y
-j
))/n_y
);
803 for(i
=0; (i
<n_x
); i
++) {
805 c
= nlevel_bot
+round((matrix
[i
][j
]-lo_top
)*invlev_top
);
806 if ((c
< nlevel_bot
) || (c
>= nlevel_bot
+nlevel_top
))
807 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
]);
810 c
= round((matrix
[i
][j
]-lo_bot
)*invlev_bot
);
811 if ((c
< 0) || (c
>= nlevel_bot
+nlevel_bot
))
812 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
]);
817 fprintf(out
,"%c",mapper
[c
]);
820 fprintf(out
,"\",\n");
826 void write_xpm_m(FILE *out
, t_matrix m
)
828 /* Writes a t_matrix struct to .xpm file */
834 bOneChar
=(m
.map
[0].code
.c2
== 0);
835 write_xpm_header(out
,m
.title
,m
.legend
,m
.label_x
,m
.label_y
,
837 fprintf(out
,"static char *gromacs_xpm[] = {\n");
838 fprintf(out
,"\"%d %d %d %d\",\n",m
.nx
,m
.ny
,m
.nmap
,bOneChar
? 1 : 2);
839 for(i
=0; (i
<m
.nmap
); i
++)
840 fprintf(out
,"\"%c%c c #%02X%02X%02X \" /* \"%s\" */,\n",
842 bOneChar
? ' ' : m
.map
[i
].code
.c2
,
843 (unsigned int)round(m
.map
[i
].rgb
.r
*255),
844 (unsigned int)round(m
.map
[i
].rgb
.g
*255),
845 (unsigned int)round(m
.map
[i
].rgb
.b
*255),m
.map
[i
].desc
);
846 write_xpm_axis(out
,"x",m
.flags
& MAT_SPATIAL_X
,m
.nx
,m
.axis_x
);
847 write_xpm_axis(out
,"y",m
.flags
& MAT_SPATIAL_Y
,m
.ny
,m
.axis_y
);
848 for(j
=m
.ny
-1; (j
>=0); j
--) {
849 if(j
%(1+m
.ny
/100)==0)
850 fprintf(stderr
,"%3d%%\b\b\b\b",(100*(m
.ny
-j
))/m
.ny
);
853 for(i
=0; (i
<m
.nx
); i
++)
854 fprintf(out
,"%c",m
.map
[m
.matrix
[i
][j
]].code
.c1
);
856 for(i
=0; (i
<m
.nx
); i
++) {
857 c
=m
.map
[m
.matrix
[i
][j
]].code
;
858 fprintf(out
,"%c%c",c
.c1
,c
.c2
);
861 fprintf(out
,"\",\n");
867 void write_xpm3(FILE *out
,unsigned int flags
,
868 const char *title
,const char *legend
,
869 const char *label_x
,const char *label_y
,
870 int n_x
,int n_y
,real axis_x
[],real axis_y
[],
871 real
*matrix
[],real lo
,real mid
,real hi
,
872 t_rgb rlo
,t_rgb rmid
,t_rgb rhi
,int *nlevels
)
875 * Writes a colormap varying as rlo -> rmid -> rhi.
879 gmx_fatal(FARGS
,"hi (%g) <= lo (%g)",hi
,lo
);
881 write_xpm_header(out
,title
,legend
,label_x
,label_y
,FALSE
);
882 write_xpm_map3(out
,n_x
,n_y
,nlevels
,lo
,mid
,hi
,rlo
,rmid
,rhi
);
883 write_xpm_axis(out
,"x",flags
& MAT_SPATIAL_X
,n_x
,axis_x
);
884 write_xpm_axis(out
,"y",flags
& MAT_SPATIAL_Y
,n_y
,axis_y
);
885 write_xpm_data3(out
,n_x
,n_y
,matrix
,lo
,mid
,hi
,*nlevels
);
888 void write_xpm_split(FILE *out
,unsigned int flags
,
889 const char *title
,const char *legend
,
890 const char *label_x
,const char *label_y
,
891 int n_x
,int n_y
,real axis_x
[],real axis_y
[],
893 real lo_top
,real hi_top
,int *nlevel_top
,
894 t_rgb rlo_top
,t_rgb rhi_top
,
895 real lo_bot
,real hi_bot
,int *nlevel_bot
,
896 gmx_bool bDiscreteColor
,
897 t_rgb rlo_bot
,t_rgb rhi_bot
)
900 * Writes a colormap varying as rlo -> rmid -> rhi.
903 if (hi_top
<= lo_top
)
904 gmx_fatal(FARGS
,"hi_top (%g) <= lo_top (%g)",hi_top
,lo_top
);
905 if (hi_bot
<= lo_bot
)
906 gmx_fatal(FARGS
,"hi_bot (%g) <= lo_bot (%g)",hi_bot
,lo_bot
);
907 if (bDiscreteColor
&& (*nlevel_bot
>= 16))
908 gmx_impl("Can not plot more than 16 discrete colors");
910 write_xpm_header(out
,title
,legend
,label_x
,label_y
,FALSE
);
911 write_xpm_map_split(out
,n_x
,n_y
,nlevel_top
,lo_top
,hi_top
,rlo_top
,rhi_top
,
912 bDiscreteColor
,nlevel_bot
,lo_bot
,hi_bot
,rlo_bot
,rhi_bot
);
913 write_xpm_axis(out
,"x",flags
& MAT_SPATIAL_X
,n_x
,axis_x
);
914 write_xpm_axis(out
,"y",flags
& MAT_SPATIAL_Y
,n_y
,axis_y
);
915 write_xpm_data_split(out
,n_x
,n_y
,matrix
,lo_top
,hi_top
,*nlevel_top
,
916 lo_bot
,hi_bot
,*nlevel_bot
);
919 void write_xpm(FILE *out
,unsigned int flags
,
920 const char *title
,const char *legend
,
921 const char *label_x
,const char *label_y
,
922 int n_x
,int n_y
,real axis_x
[],real axis_y
[],
923 real
*matrix
[],real lo
,real hi
,
924 t_rgb rlo
,t_rgb rhi
,int *nlevels
)
928 * legend label for the continuous legend
929 * label_x label for the x-axis
930 * label_y label for the y-axis
931 * n_x, n_y size of the matrix
932 * axis_x[] the x-ticklabels
933 * axis_y[] the y-ticklables
934 * *matrix[] element x,y is matrix[x][y]
935 * lo output lower than lo is set to lo
936 * hi output higher than hi is set to hi
937 * rlo rgb value for level lo
938 * rhi rgb value for level hi
939 * nlevels number of color levels for the output
943 gmx_fatal(FARGS
,"hi (%f) <= lo (%f)",hi
,lo
);
945 write_xpm_header(out
,title
,legend
,label_x
,label_y
,FALSE
);
946 write_xpm_map(out
,n_x
,n_y
,nlevels
,lo
,hi
,rlo
,rhi
);
947 write_xpm_axis(out
,"x",flags
& MAT_SPATIAL_X
,n_x
,axis_x
);
948 write_xpm_axis(out
,"y",flags
& MAT_SPATIAL_Y
,n_y
,axis_y
);
949 write_xpm_data(out
,n_x
,n_y
,matrix
,lo
,hi
,*nlevels
);