• Main Page
  • Classes
  • Files
  • File List
  • File Members

output_pgm.c

Go to the documentation of this file.
00001 #include "copyright.h"
00002 /*============================================================================*/
00003 /*! \file output_pgm.c
00004  *  \brief Writes Portable Gray Map (PGM) outputs.
00005  *
00006  * PURPOSE: Writes Portable Gray Map (PGM) outputs.  These are extremely simple
00007  *   grayscale 2D images, see e.g. sourceforge for documentation. With SMR,
00008  *   dumps are made for all levels and domains, unless nlevel and ndomain are
00009  *   specified in <output> block.
00010  *
00011  * CONTAINS PUBLIC FUNCTIONS: 
00012  * - output_pgm() -  outputs 2D PGM images
00013  *============================================================================*/
00014 
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <float.h>
00019 #include "defs.h"
00020 #include "athena.h"
00021 #include "prototypes.h"
00022 
00023 /*----------------------------------------------------------------------------*/
00024 /*! \fn void output_pgm(MeshS *pM, OutputS *pOut)
00025  *  \brief  Output 2D PGM image   */
00026 
00027 void output_pgm(MeshS *pM, OutputS *pOut)
00028 {
00029   GridS *pGrid;
00030   FILE *pfile;
00031   char *fname,*plev=NULL,*pdom=NULL;
00032   char levstr[8],domstr[8];
00033   int nl,nd,nx1,nx2,gray,i,j;
00034   Real **data, dmin, dmax, max_min, sfact;
00035 
00036 /* check output data is 2D (output must be a 2D slice for 3D runs) */
00037   if (pOut->ndim != 2) {
00038     ath_error("[output_pgm]: Output must be a 2D slice\n");
00039     return;
00040   }
00041 
00042 /* Loop over all Domains in Mesh, and output Grid data */
00043 
00044   for (nl=0; nl<(pM->NLevels); nl++){
00045     for (nd=0; nd<(pM->DomainsPerLevel[nl]); nd++){
00046       if (pM->Domain[nl][nd].Grid != NULL){
00047 
00048 /* write files if domain and level match input, or are not specified (-1) */
00049       if ((pOut->nlevel == -1 || pOut->nlevel == nl) &&
00050           (pOut->ndomain == -1 || pOut->ndomain == nd)){
00051         pGrid = pM->Domain[nl][nd].Grid;
00052 
00053 /* Extract 2D data from 3D data,  Can either be slice or average along axis,
00054  * depending on range of ix1,ix2,ix3 in <ouput> block.  If OutData2 returns
00055  * NULL pointer, then slice is outside range of data in pGrid, so skip */
00056 
00057         data = OutData2(pGrid,pOut,&nx1,&nx2);
00058         if (data != NULL) {
00059 
00060 /* construct output filename.  pOut->id will either be name of variable,
00061  * if 'id=...' was included in <ouput> block, or 'outN' where N is number of
00062  * <output> block.  */
00063           if (nl>0) {
00064             plev = &levstr[0];
00065             sprintf(plev,"lev%d",nl);
00066           }
00067           if (nd>0) {
00068             pdom = &domstr[0];
00069             sprintf(pdom,"dom%d",nd);
00070           }
00071 
00072           if((fname = ath_fname(plev,pM->outfilename,plev,pdom,num_digit,
00073             pOut->num,pOut->id,"pgm")) == NULL){
00074             ath_error("[output_pgm]: Error constructing filename\n");
00075           }
00076 
00077 /* open output file */
00078           if((pfile = fopen(fname,"w")) == NULL){
00079             ath_error("[output_pgm]: Unable to open pgm file %s\n",fname);
00080             return;
00081           }
00082 
00083           fprintf(pfile,"P5\n%d %d\n255\n",nx1,nx2);
00084 
00085 /* Store the global min / max, for output at end of run */
00086           minmax2(data,nx2,nx1,&dmin,&dmax);
00087           pOut->gmin = MIN(dmin,pOut->gmin);
00088           pOut->gmax = MAX(dmax,pOut->gmax);
00089 
00090 /* Override auto-scale? */
00091           if (pOut->sdmin != 0) dmin = pOut->dmin;
00092           if (pOut->sdmax != 0) dmax = pOut->dmax;
00093   
00094           max_min = (dmax - dmin)*(1.0 + FLT_EPSILON);
00095 
00096 /* map the data which satisfies [min <= data <= max] to the range 
00097  * [0.0 , 256.0] -- Not inclusive of 256 */
00098 
00099           if(max_min > 0.0) {
00100             sfact = 256.0/max_min;
00101             for (j=nx2-1; j>=0; j--) {
00102               for (i=0; i<nx1; i++) {
00103 /* Map the data to an 8 bit int, i.e. 0 -> 255 */
00104                 gray = (int)(sfact*(data[j][i] - dmin));
00105 /* Out of bounds data is mapped to the min or max integer value */
00106                 gray = gray >   0 ? gray :   0;
00107                 gray = gray < 255 ? gray : 255;
00108 
00109                 fputc(gray,pfile);
00110               }
00111             }
00112 
00113 /* else, if max=min set image to constant */
00114 
00115           } else {
00116             gray = 0;
00117             for (j=0; j<nx2; j++) {
00118               for (i=0; i<nx1; i++) {
00119                 fputc(gray,pfile);
00120               }
00121             }
00122           }
00123 
00124 /* Close the file, free memory */
00125 
00126           fclose(pfile); 
00127           free_2d_array(data);
00128           free(fname);
00129         }
00130       }}
00131     }
00132   }
00133 }

Generated on Mon Sep 27 2010 23:03:07 for Athena by  doxygen 1.7.1