2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
49 #include "gmx_fatal.h"
55 #define round(a) (int)(a+0.5)
57 static const char mapper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+{}|;:',<.>/?";
58 #define NMAP (long int)strlen(mapper)
60 #define MAX_XPM_LINELENGTH 4096
62 real **mk_matrix(int nx, int ny, gmx_bool b1D)
80 void done_matrix(int nx, real ***m)
90 void clear_matrix(int nx, int ny, real **m)
99 gmx_bool matelmt_cmp(t_xpmelmt e1, t_xpmelmt e2)
101 return (e1.c1 == e2.c1) && (e1.c2 == e2.c2);
104 t_matelmt searchcmap(int n,t_mapping map[],t_xpmelmt c)
109 if (matelmt_cmp(map[i].code, c))
115 int getcmap(FILE *in,const char *fn,t_mapping **map)
119 char code[STRLEN],desc[STRLEN];
123 if (fgets2(line,STRLEN-1,in) == NULL)
124 gmx_fatal(FARGS,"Not enough lines in colormap file %s"
125 "(just wanted to read number of entries)",fn);
126 sscanf(line,"%d",&n);
128 for(i=0; (i<n); i++) {
129 if (fgets2(line,STRLEN-1,in) == NULL)
130 gmx_fatal(FARGS,"Not enough lines in colormap file %s"
131 "(should be %d, found only %d)",fn,n+1,i);
132 sscanf(line,"%s%s%lf%lf%lf",code,desc,&r,&g,&b);
133 m[i].code.c1=code[0];
135 m[i].desc=strdup(desc);
145 int readcmap(const char *fn,t_mapping **map)
151 n=getcmap(in,fn,map);
157 void printcmap(FILE *out,int n,t_mapping map[])
161 fprintf(out,"%d\n",n);
163 fprintf(out,"%c%c %20s %10g %10g %10g\n",
164 map[i].code.c1?map[i].code.c1:' ',
165 map[i].code.c2?map[i].code.c2:' ',
166 map[i].desc,map[i].rgb.r,map[i].rgb.g,map[i].rgb.b);
169 void writecmap(const char *fn,int n,t_mapping map[])
173 out=gmx_fio_fopen(fn,"w");
174 printcmap(out,n,map);
178 static char *fgetline(char **line,int llmax,int *llalloc,FILE *in)
182 if (llmax > *llalloc)
184 srenew(*line,llmax+1);
187 fg=fgets(*line,llmax,in);
193 void skipstr(char *line)
199 while((line[c] != ' ') && (line[c] != '\0'))
202 while(line[c] != '\0')
210 char *line2string(char **line)
215 while (((*line)[0] != '\"' ) && ( (*line)[0] != '\0' ))
218 if ((*line)[0] != '\"')
223 while (( (*line)[i] != '\"' ) && ( (*line)[i] != '\0' ))
226 if ((*line)[i] != '\"')
235 void parsestring(char *line,const char *label, char *string)
237 if (strstr(line,label)) {
238 if (strstr(line,label) < strchr(line,'\"')) {
245 void read_xpm_entry(FILE *in,t_matrix *mm)
248 char *line_buf=NULL,*line=NULL,*str,buf[256]={0};
249 int i,m,col_len,nch,n_axis_x,n_axis_y,llmax;
253 gmx_bool bGetOnWithIt,bSetLine;
268 while ((NULL != fgetline(&line_buf,llmax,&llalloc,in)) &&
269 (strncmp(line_buf,"static",6) != 0)) {
271 parsestring(line,"title",(mm->title));
272 parsestring(line,"legend",(mm->legend));
273 parsestring(line,"x-label",(mm->label_x));
274 parsestring(line,"y-label",(mm->label_y));
275 parsestring(line,"type",buf);
278 if (!line || strncmp(line,"static",6) != 0)
280 gmx_input("Invalid XPixMap");
283 if (buf[0] && (gmx_strcasecmp(buf,"Discrete")==0))
287 fprintf(debug,"%s %s %s %s\n",
288 mm->title,mm->legend,mm->label_x,mm->label_y);
292 while (!bGetOnWithIt && (NULL != fgetline(&line_buf,llmax,&llalloc,in))) {
294 while (( line[0] != '\"' ) && ( line[0] != '\0' ))
297 if ( line[0] == '\"' ) {
299 sscanf(line,"%d %d %d %d",&(mm->nx),&(mm->ny),&(mm->nmap),&nch);
302 gmx_fatal(FARGS,"Sorry can only read xpm's with at most 2 caracters per pixel\n");
304 if (mm->nx <= 0 || mm->ny <= 0 )
306 gmx_fatal(FARGS,"Dimensions of xpm-file have to be larger than 0\n");
308 llmax = max(STRLEN,mm->nx+10);
313 fprintf(debug,"mm->nx %d mm->ny %d mm->nmap %d nch %d\n",
314 mm->nx,mm->ny,mm->nmap,nch);
319 while ((m < mm->nmap) && (NULL != fgetline(&line_buf,llmax,&llalloc,in))) {
320 line = strchr(line_buf,'\"');
323 /* Read xpm color map entry */
324 map[m].code.c1 = line[0];
328 map[m].code.c2 = line[1];
330 str = strchr(line,'#');
334 while (isxdigit(str[col_len]))
337 sscanf(line,"%*s #%2x%2x%2x",&r,&g,&b);
338 map[m].rgb.r=r/255.0;
339 map[m].rgb.g=g/255.0;
340 map[m].rgb.b=b/255.0;
341 } else if (col_len==12) {
342 sscanf(line,"%*s #%4x%4x%4x",&r,&g,&b);
343 map[m].rgb.r=r/65535.0;
344 map[m].rgb.g=g/65535.0;
345 map[m].rgb.b=b/65535.0;
347 gmx_file("Unsupported or invalid colormap in X PixMap");
349 str = strchr(line,'c');
353 gmx_file("Unsupported or invalid colormap in X PixMap");
354 fprintf(stderr,"Using white for color \"%s",str);
359 line=strchr(line,'\"');
362 map[m].desc = strdup(line);
367 gmx_fatal(FARGS,"Number of read colors map entries (%d) does not match the number in the header (%d)",m,mm->nmap);
370 /* Read axes, if there are any */
379 if (strstr(line,"x-axis")) {
380 line=strstr(line,"x-axis");
382 if (mm->axis_x==NULL)
383 snew(mm->axis_x,mm->nx + 1);
384 while (sscanf(line,"%lf",&u)==1) {
385 if (n_axis_x > mm->nx) {
386 gmx_fatal(FARGS,"Too many x-axis labels in xpm (max %d)",mm->nx);
387 } else if (n_axis_x == mm->nx) {
388 mm->flags |= MAT_SPATIAL_X;
390 mm->axis_x[n_axis_x] = u;
395 else if (strstr(line,"y-axis")) {
396 line=strstr(line,"y-axis");
398 if (mm->axis_y==NULL)
399 snew(mm->axis_y,mm->ny + 1);
400 while (sscanf(line,"%lf",&u)==1) {
401 if (n_axis_y > mm->ny) {
402 gmx_file("Too many y-axis labels in xpm");
403 } else if (n_axis_y == mm->ny) {
404 mm->flags |= MAT_SPATIAL_Y;
406 mm->axis_y[n_axis_y] = u;
411 } while ((line[0] != '\"') && (NULL != fgetline(&line_buf,llmax,&llalloc,in)));
414 snew(mm->matrix,mm->nx);
415 for(i=0; i<mm->nx; i++)
416 snew(mm->matrix[i],mm->ny);
423 if(m%(1+mm->ny/100)==0)
424 fprintf(stderr,"%3d%%\b\b\b\b",(100*(mm->ny-m))/mm->ny);
425 while ((line[0] != '\"') && (line[0] != '\0'))
428 gmx_fatal(FARGS,"Not enough caracters in row %d of the matrix\n",m+1);
431 for(i=0; i<mm->nx; i++) {
437 mm->matrix[i][m]=searchcmap(mm->nmap,mm->map,c);
441 } while ((m>=0) && (NULL != fgetline(&line_buf,llmax,&llalloc,in)));
443 gmx_incons("Not enough rows in the matrix");
448 int read_xpm_matrix(const char *fnm,t_matrix **matrix)
455 in=gmx_fio_fopen(fnm,"r");
458 while (NULL != fgetline(&line,STRLEN,&llalloc,in)) {
459 if (strstr(line,"/* XPM */")) {
460 srenew(*matrix,nmat+1);
461 read_xpm_entry(in,&(*matrix)[nmat]);
468 gmx_file("Invalid XPixMap");
475 real **matrix2real(t_matrix *matrix,real **mat)
486 for(i=0; i<nmap; i++) {
487 if ((map[i].desc==NULL) || (sscanf(map[i].desc,"%lf",&tmp)!=1)) {
488 fprintf(stderr,"Could not convert matrix to reals,\n"
489 "color map entry %d has a non-real description: \"%s\"\n",
498 snew(mat,matrix->nx);
499 for(i=0; i<matrix->nx; i++)
500 snew(mat[i],matrix->ny);
502 for(i=0; i<matrix->nx; i++)
503 for(j=0; j<matrix->ny; j++)
504 mat[i][j]=rmap[matrix->matrix[i][j]];
508 fprintf(stderr,"Converted a %dx%d matrix with %d levels to reals\n",
509 matrix->nx,matrix->ny,nmap);
514 void write_xpm_header(FILE *out,
515 const char *title,const char *legend,
516 const char *label_x,const char *label_y,
519 fprintf(out, "/* XPM */\n");
520 fprintf(out, "/* Generated by %s */\n",Program());
521 fprintf(out, "/* This file can be converted to EPS by the GROMACS program xpm2ps */\n");
522 fprintf(out, "/* title: \"%s\" */\n",title);
523 fprintf(out, "/* legend: \"%s\" */\n",legend);
524 fprintf(out, "/* x-label: \"%s\" */\n",label_x);
525 fprintf(out, "/* y-label: \"%s\" */\n",label_y);
527 fprintf(out,"/* type: \"Discrete\" */\n");
529 fprintf(out,"/* type: \"Continuous\" */\n");
532 static int calc_nmid(int nlevels,real lo,real mid,real hi)
534 /* Take care that we have at least 1 entry in the mid to hi range
536 return min(max(0,((mid-lo)/(hi-lo))*(nlevels-1)),nlevels-1);
539 void write_xpm_map3(FILE *out,int n_x,int n_y,int *nlevels,
540 real lo,real mid,real hi,
541 t_rgb rlo,t_rgb rmid,t_rgb rhi)
544 real r,g,b,clev_lo,clev_hi;
546 if (*nlevels > NMAP*NMAP) {
547 fprintf(stderr,"Warning, too many levels (%d) in matrix, using %d only\n",
548 *nlevels,(int)(NMAP*NMAP));
551 else if (*nlevels < 2) {
552 fprintf(stderr,"Warning, too few levels (%d) in matrix, using 2 instead\n",
556 if (!((mid >= lo) && (mid < hi)))
557 gmx_fatal(FARGS,"Lo: %f, Mid: %f, Hi: %f\n",lo,mid,hi);
559 fprintf(out,"static char *gromacs_xpm[] = {\n");
560 fprintf(out,"\"%d %d %d %d\",\n",
561 n_x,n_y,*nlevels,(*nlevels <= NMAP) ? 1 : 2);
563 nmid = calc_nmid(*nlevels,lo,mid,hi);
565 clev_hi = (*nlevels - 1 - nmid);
566 for(i=0; (i<nmid); i++) {
567 r = rlo.r+(i*(rmid.r-rlo.r)/clev_lo);
568 g = rlo.g+(i*(rmid.g-rlo.g)/clev_lo);
569 b = rlo.b+(i*(rmid.b-rlo.b)/clev_lo);
570 fprintf(out,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
572 (*nlevels <= NMAP) ? ' ' : mapper[i/NMAP],
573 (unsigned int)round(255*r),
574 (unsigned int)round(255*g),
575 (unsigned int)round(255*b),
576 ((nmid - i)*lo + i*mid)/clev_lo);
578 for(i=0; (i<(*nlevels-nmid)); i++) {
579 r = rmid.r+(i*(rhi.r-rmid.r)/clev_hi);
580 g = rmid.g+(i*(rhi.g-rmid.g)/clev_hi);
581 b = rmid.b+(i*(rhi.b-rmid.b)/clev_hi);
582 fprintf(out,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
583 mapper[(i+nmid) % NMAP],
584 (*nlevels <= NMAP) ? ' ' : mapper[(i+nmid)/NMAP],
585 (unsigned int)round(255*r),
586 (unsigned int)round(255*g),
587 (unsigned int)round(255*b),
588 ((*nlevels - 1 - nmid - i)*mid + i*hi)/clev_hi);
592 static void pr_simple_cmap(FILE *out,real lo,real hi,int nlevel,t_rgb rlo,
598 for(i=0; (i<nlevel); i++) {
599 fac = (i+1.0)/(nlevel);
600 r = rlo.r+fac*(rhi.r-rlo.r);
601 g = rlo.g+fac*(rhi.g-rlo.g);
602 b = rlo.b+fac*(rhi.b-rlo.b);
603 fprintf(out,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
604 mapper[(i+i0) % NMAP],
605 (nlevel <= NMAP) ? ' ' : mapper[(i+i0)/NMAP],
606 (unsigned int)round(255*r),
607 (unsigned int)round(255*g),
608 (unsigned int)round(255*b),
613 static void pr_discrete_cmap(FILE *out,int *nlevel,int i0)
616 { 1.0, 1.0, 1.0 }, /* white */
617 { 1.0, 0.0, 0.0 }, /* red */
618 { 1.0, 1.0, 0.0 }, /* yellow */
619 { 0.0, 0.0, 1.0 }, /* blue */
620 { 0.0, 1.0, 0.0 }, /* green */
621 { 1.0, 0.0, 1.0 }, /* purple */
622 { 1.0, 0.4, 0.0 }, /* orange */
623 { 0.0, 1.0, 1.0 }, /* cyan */
624 { 1.0, 0.4, 0.4 }, /* pink */
625 { 1.0, 1.0, 0.0 }, /* yellow */
626 { 0.4, 0.4, 1.0 }, /* lightblue */
627 { 0.4, 1.0, 0.4 }, /* lightgreen */
628 { 1.0, 0.4, 1.0 }, /* lightpurple */
629 { 1.0, 0.7, 0.4 }, /* lightorange */
630 { 0.4, 1.0, 1.0 }, /* lightcyan */
631 { 0.0, 0.0, 0.0 } /* black */
636 *nlevel = min(16,*nlevel);
638 for(i=0; (i<n); i++) {
639 fprintf(out,"\"%c%c c #%02X%02X%02X \" /* \"%3d\" */,\n",
640 mapper[(i+i0) % NMAP],
641 (n <= NMAP) ? ' ' : mapper[(i+i0)/NMAP],
642 (unsigned int)round(255*rgbd[i].r),
643 (unsigned int)round(255*rgbd[i].g),
644 (unsigned int)round(255*rgbd[i].b),
651 void write_xpm_map_split(FILE *out,int n_x,int n_y,
652 int *nlevel_top,real lo_top,real hi_top,
653 t_rgb rlo_top,t_rgb rhi_top,
654 gmx_bool bDiscreteColor,
655 int *nlevel_bot,real lo_bot,real hi_bot,
656 t_rgb rlo_bot,t_rgb rhi_bot)
661 ntot = *nlevel_top + *nlevel_bot;
663 gmx_fatal(FARGS,"Warning, too many levels (%d) in matrix",ntot);
665 fprintf(out,"static char *gromacs_xpm[] = {\n");
666 fprintf(out,"\"%d %d %d %d\",\n",n_x,n_y,ntot,1);
669 pr_discrete_cmap(out,nlevel_bot,0);
671 pr_simple_cmap(out,lo_bot,hi_bot,*nlevel_bot,rlo_bot,rhi_bot,0);
673 pr_simple_cmap(out,lo_top,hi_top,*nlevel_top,rlo_top,rhi_top,*nlevel_bot);
677 void write_xpm_map(FILE *out,int n_x, int n_y,int *nlevels,real lo,real hi,
683 if (*nlevels > NMAP*NMAP) {
684 fprintf(stderr,"Warning, too many levels (%d) in matrix, using %d only\n",
685 *nlevels,(int)(NMAP*NMAP));
688 else if (*nlevels < 2) {
689 fprintf(stderr,"Warning, too few levels (%d) in matrix, using 2 instead\n",*nlevels);
693 fprintf(out,"static char *gromacs_xpm[] = {\n");
694 fprintf(out,"\"%d %d %d %d\",\n",
695 n_x,n_y,*nlevels,(*nlevels <= NMAP) ? 1 : 2);
697 invlevel=1.0/(*nlevels-1);
698 for(i=0; (i<*nlevels); i++) {
700 r=(nlo*rlo.r+i*rhi.r)*invlevel;
701 g=(nlo*rlo.g+i*rhi.g)*invlevel;
702 b=(nlo*rlo.b+i*rhi.b)*invlevel;
703 fprintf(out,"\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n",
704 mapper[i % NMAP],(*nlevels <= NMAP) ? ' ' : mapper[i/NMAP],
705 (unsigned int)round(255*r),
706 (unsigned int)round(255*g),
707 (unsigned int)round(255*b),
708 (nlo*lo+i*hi)*invlevel);
712 void write_xpm_axis(FILE *out, const char *axis, gmx_bool bSpatial, int n,
718 for(i=0;i<(bSpatial ? n+1 : n);i++) {
722 fprintf(out,"/* %s-axis: ",axis);
724 fprintf(out,"%g ",label[i]);
730 void write_xpm_data(FILE *out, int n_x, int n_y, real **matrix,
731 real lo, real hi, int nlevels)
736 invlevel=(nlevels-1)/(hi-lo);
737 for(j=n_y-1; (j>=0); j--) {
739 fprintf(stderr,"%3d%%\b\b\b\b",(100*(n_y-j))/n_y);
741 for(i=0; (i<n_x); i++) {
742 c=gmx_nint((matrix[i][j]-lo)*invlevel);
744 if (c>=nlevels) c=nlevels-1;
746 fprintf(out,"%c",mapper[c]);
748 fprintf(out,"%c%c",mapper[c % NMAP],mapper[c / NMAP]);
751 fprintf(out,"\",\n");
757 void write_xpm_data3(FILE *out,int n_x,int n_y,real **matrix,
758 real lo,real mid,real hi,int nlevels)
761 real invlev_lo,invlev_hi;
763 nmid = calc_nmid(nlevels,lo,mid,hi);
764 invlev_hi=(nlevels-1-nmid)/(hi-mid);
765 invlev_lo=(nmid)/(mid-lo);
767 for(j=n_y-1; (j>=0); j--) {
769 fprintf(stderr,"%3d%%\b\b\b\b",(100*(n_y-j))/n_y);
771 for(i=0; (i<n_x); i++) {
772 if (matrix[i][j] >= mid)
773 c=nmid+gmx_nint((matrix[i][j]-mid)*invlev_hi);
774 else if (matrix[i][j] >= lo)
775 c=gmx_nint((matrix[i][j]-lo)*invlev_lo);
784 fprintf(out,"%c",mapper[c]);
786 fprintf(out,"%c%c",mapper[c % NMAP],mapper[c / NMAP]);
789 fprintf(out,"\",\n");
795 void write_xpm_data_split(FILE *out,int n_x,int n_y,real **matrix,
796 real lo_top,real hi_top,int nlevel_top,
797 real lo_bot,real hi_bot,int nlevel_bot)
800 real invlev_top,invlev_bot;
802 invlev_top=(nlevel_top-1)/(hi_top-lo_top);
803 invlev_bot=(nlevel_bot-1)/(hi_bot-lo_bot);
805 for(j=n_y-1; (j>=0); j--) {
806 if(j % (1+n_y/100)==0)
807 fprintf(stderr,"%3d%%\b\b\b\b",(100*(n_y-j))/n_y);
809 for(i=0; (i<n_x); i++) {
811 c = nlevel_bot+round((matrix[i][j]-lo_top)*invlev_top);
812 if ((c < nlevel_bot) || (c >= nlevel_bot+nlevel_top))
813 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]);
816 c = round((matrix[i][j]-lo_bot)*invlev_bot);
817 if ((c < 0) || (c >= nlevel_bot+nlevel_bot))
818 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]);
823 fprintf(out,"%c",mapper[c]);
826 fprintf(out,"\",\n");
832 void write_xpm_m(FILE *out, t_matrix m)
834 /* Writes a t_matrix struct to .xpm file */
840 bOneChar=(m.map[0].code.c2 == 0);
841 write_xpm_header(out,m.title,m.legend,m.label_x,m.label_y,
843 fprintf(out,"static char *gromacs_xpm[] = {\n");
844 fprintf(out,"\"%d %d %d %d\",\n",m.nx,m.ny,m.nmap,bOneChar ? 1 : 2);
845 for(i=0; (i<m.nmap); i++)
846 fprintf(out,"\"%c%c c #%02X%02X%02X \" /* \"%s\" */,\n",
848 bOneChar ? ' ' : m.map[i].code.c2,
849 (unsigned int)round(m.map[i].rgb.r*255),
850 (unsigned int)round(m.map[i].rgb.g*255),
851 (unsigned int)round(m.map[i].rgb.b*255),m.map[i].desc);
852 write_xpm_axis(out,"x",m.flags & MAT_SPATIAL_X,m.nx,m.axis_x);
853 write_xpm_axis(out,"y",m.flags & MAT_SPATIAL_Y,m.ny,m.axis_y);
854 for(j=m.ny-1; (j>=0); j--) {
855 if(j%(1+m.ny/100)==0)
856 fprintf(stderr,"%3d%%\b\b\b\b",(100*(m.ny-j))/m.ny);
859 for(i=0; (i<m.nx); i++)
860 fprintf(out,"%c",m.map[m.matrix[i][j]].code.c1);
862 for(i=0; (i<m.nx); i++) {
863 c=m.map[m.matrix[i][j]].code;
864 fprintf(out,"%c%c",c.c1,c.c2);
867 fprintf(out,"\",\n");
873 void write_xpm3(FILE *out,unsigned int flags,
874 const char *title,const char *legend,
875 const char *label_x,const char *label_y,
876 int n_x,int n_y,real axis_x[],real axis_y[],
877 real *matrix[],real lo,real mid,real hi,
878 t_rgb rlo,t_rgb rmid,t_rgb rhi,int *nlevels)
881 * Writes a colormap varying as rlo -> rmid -> rhi.
885 gmx_fatal(FARGS,"hi (%g) <= lo (%g)",hi,lo);
887 write_xpm_header(out,title,legend,label_x,label_y,FALSE);
888 write_xpm_map3(out,n_x,n_y,nlevels,lo,mid,hi,rlo,rmid,rhi);
889 write_xpm_axis(out,"x",flags & MAT_SPATIAL_X,n_x,axis_x);
890 write_xpm_axis(out,"y",flags & MAT_SPATIAL_Y,n_y,axis_y);
891 write_xpm_data3(out,n_x,n_y,matrix,lo,mid,hi,*nlevels);
894 void write_xpm_split(FILE *out,unsigned int flags,
895 const char *title,const char *legend,
896 const char *label_x,const char *label_y,
897 int n_x,int n_y,real axis_x[],real axis_y[],
899 real lo_top,real hi_top,int *nlevel_top,
900 t_rgb rlo_top,t_rgb rhi_top,
901 real lo_bot,real hi_bot,int *nlevel_bot,
902 gmx_bool bDiscreteColor,
903 t_rgb rlo_bot,t_rgb rhi_bot)
906 * Writes a colormap varying as rlo -> rmid -> rhi.
909 if (hi_top <= lo_top)
910 gmx_fatal(FARGS,"hi_top (%g) <= lo_top (%g)",hi_top,lo_top);
911 if (hi_bot <= lo_bot)
912 gmx_fatal(FARGS,"hi_bot (%g) <= lo_bot (%g)",hi_bot,lo_bot);
913 if (bDiscreteColor && (*nlevel_bot >= 16))
914 gmx_impl("Can not plot more than 16 discrete colors");
916 write_xpm_header(out,title,legend,label_x,label_y,FALSE);
917 write_xpm_map_split(out,n_x,n_y,nlevel_top,lo_top,hi_top,rlo_top,rhi_top,
918 bDiscreteColor,nlevel_bot,lo_bot,hi_bot,rlo_bot,rhi_bot);
919 write_xpm_axis(out,"x",flags & MAT_SPATIAL_X,n_x,axis_x);
920 write_xpm_axis(out,"y",flags & MAT_SPATIAL_Y,n_y,axis_y);
921 write_xpm_data_split(out,n_x,n_y,matrix,lo_top,hi_top,*nlevel_top,
922 lo_bot,hi_bot,*nlevel_bot);
925 void write_xpm(FILE *out,unsigned int flags,
926 const char *title,const char *legend,
927 const char *label_x,const char *label_y,
928 int n_x,int n_y,real axis_x[],real axis_y[],
929 real *matrix[],real lo,real hi,
930 t_rgb rlo,t_rgb rhi,int *nlevels)
934 * legend label for the continuous legend
935 * label_x label for the x-axis
936 * label_y label for the y-axis
937 * n_x, n_y size of the matrix
938 * axis_x[] the x-ticklabels
939 * axis_y[] the y-ticklables
940 * *matrix[] element x,y is matrix[x][y]
941 * lo output lower than lo is set to lo
942 * hi output higher than hi is set to hi
943 * rlo rgb value for level lo
944 * rhi rgb value for level hi
945 * nlevels number of color levels for the output
949 gmx_fatal(FARGS,"hi (%f) <= lo (%f)",hi,lo);
951 write_xpm_header(out,title,legend,label_x,label_y,FALSE);
952 write_xpm_map(out,n_x,n_y,nlevels,lo,hi,rlo,rhi);
953 write_xpm_axis(out,"x",flags & MAT_SPATIAL_X,n_x,axis_x);
954 write_xpm_axis(out,"y",flags & MAT_SPATIAL_Y,n_y,axis_y);
955 write_xpm_data(out,n_x,n_y,matrix,lo,hi,*nlevels);