r309: plotfile changes
authorKevin M. Rosenberg <kevin@rosenberg.net>
Wed, 20 Dec 2000 20:08:48 +0000 (20:08 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Wed, 20 Dec 2000 20:08:48 +0000 (20:08 +0000)
13 files changed:
include/ctsupport.h
include/msvc_compat.h
include/plotfile.h
libctgraphics/ezplot.cpp
libctsim/imagefile.cpp
libctsupport/mathfuncs.cpp
libctsupport/plotfile.cpp
msvc/ctsim/ctsim.plg
src/ctsim.h
src/dialogs.cpp
src/dialogs.h
src/views.cpp
src/views.h

index c933488..cea4f14 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: ctsupport.h,v 1.14 2000/12/17 23:09:46 kevin Exp $
+**  $Id: ctsupport.h,v 1.15 2000/12/20 20:08:48 kevin Exp $
 **
 **
 **  This program is free software; you can redistribute it and/or modify
@@ -44,6 +44,8 @@
 #include <cstdlib>
 #include <cstring>
 #include <cstdarg>
+#include <vector>\r
+#include <algorithm>\r
 
 #define TRUE   1
 #define FALSE  0
@@ -234,6 +236,7 @@ void scale2d (double x[], double y[], int pts, double xfact, double yfact);
 // mathfuncs.cpp
 double normalizeAngle (double theta);
 double integrateSimpson (const double xmin, const double xmax, const double *y, const int np);
+void vectorNumericStatistics (std::vector<double> vec, double& min, double& max, double& mean, double& mode, double& median, double& stddev);\r
 
 
 /*----------------------------------------------------------------------*/
index d77f435..188d849 100644 (file)
@@ -10,6 +10,7 @@
   #define strcasecmp _stricmp
   #define strncasecmp _strnicmp
   #define snprintf _snprintf
-  #define vsnprintf _vsnprintf
+  #define vsnprintf _vsnprintf\r
+  #pragma warning(disable:4786)
 #endif
 #endif
index af627b4..c60e579 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: plotfile.h,v 1.2 2000/12/20 14:39:09 kevin Exp $
+**  $Id: plotfile.h,v 1.3 2000/12/20 20:08:48 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
@@ -137,6 +137,10 @@ public:
 
   int getNumRecords () const
     { return m_iNumRecords; }
+\r
+  bool getMinMax (int startingCol, double& min, double& max) const;\r
+\r
+  bool statistics (int startingCol, double& min, double& max, double& mean, double& mode, double& median, double &stddev) const;\r
 
   unsigned int getNumDescriptions (void) const
       { return m_vecStrDescriptions.size(); }
index 7d6e23e..5a2ec69 100644 (file)
@@ -6,7 +6,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: ezplot.cpp,v 1.19 2000/12/18 06:32:13 kevin Exp $
+**  $Id: ezplot.cpp,v 1.20 2000/12/20 20:08:48 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
@@ -754,9 +754,7 @@ EZPlot::drawAxes()
        snprintf (str, sizeof(str), y_numfmt, ygw_min + yw_tickinc * i);
        rSGP.moveAbs (yaxispos + ytl_ofs, y + 0.5 * charheight);
        rSGP.setTextColor (clr_number, -1);\r
-       rSGP.setTextAngle(HALFPI);
        rSGP.drawText (str);
-       rSGP.setTextAngle(0.);\r
       }
     }
   }            // Y - Axis
index 3e97fb2..d4c973c 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: imagefile.cpp,v 1.21 2000/12/17 19:08:06 kevin Exp $
+**  $Id: imagefile.cpp,v 1.22 2000/12/20 20:08:48 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
 
 
 F32Image::F32Image (int nx, int ny)\r
-      : Array2dFile (nx, ny, sizeof(kfloat32), Array2dFile::PIXEL_FLOAT32)\r
-  {\r
-  }\r
+: Array2dFile (nx, ny, sizeof(kfloat32), Array2dFile::PIXEL_FLOAT32)\r
+{\r
+}\r
 \r
 F32Image::F32Image (void)\r
-      : Array2dFile()\r
-  {\r
-      setPixelFormat (Array2dFile::PIXEL_FLOAT32);\r
-      setPixelSize (sizeof(kfloat32));\r
-  }\r
+: Array2dFile()\r
+{\r
+       setPixelFormat (Array2dFile::PIXEL_FLOAT32);\r
+       setPixelSize (sizeof(kfloat32));\r
+}\r
 \r
 F64Image::F64Image (int nx, int ny)\r
-      : Array2dFile (nx, ny, sizeof(kfloat64), Array2dFile::PIXEL_FLOAT64)\r
-  {\r
-  }\r
+: Array2dFile (nx, ny, sizeof(kfloat64), Array2dFile::PIXEL_FLOAT64)\r
+{\r
+}\r
 \r
 F64Image::F64Image (void)\r
-      : Array2dFile ()\r
-  {\r
-      setPixelFormat (PIXEL_FLOAT64);\r
-      setPixelSize (sizeof(kfloat64));\r
-  }\r
+: Array2dFile ()\r
+{\r
+       setPixelFormat (PIXEL_FLOAT64);\r
+       setPixelSize (sizeof(kfloat64));\r
+}\r
 
 void 
 ImageFile::filterResponse (const char* const domainName, double bw, const char* const filterName, double filt_param)
 {
-  int hx = (m_nx - 1) / 2;
-  int hy = (m_ny - 1) / 2;
-  ImageFileArray v = getArray();
-  SignalFilter filter (filterName, domainName, bw, filt_param);
-
-  for (int i = -hx; i <= hx; i++) {
-    for (int j = -hy; j <= hy; j++) {
-      double r = sqrt (i * i + j * j);
-      
-      v[i+hx][j+hy] = filter.response (r);
-    }
-  }
+       int hx = (m_nx - 1) / 2;
+       int hy = (m_ny - 1) / 2;
+       ImageFileArray v = getArray();
+       SignalFilter filter (filterName, domainName, bw, filt_param);
+       
+       for (int i = -hx; i <= hx; i++) {
+               for (int j = -hy; j <= hy; j++) {
+                       double r = sqrt (i * i + j * j);
+                       
+                       v[i+hx][j+hy] = filter.response (r);
+               }
+       }
 }
 
 int
 ImageFile::display (void) const
 {
     double pmin, pmax;
-
+       
     getMinMax (pmin, pmax);
-
+       
     return (displayScaling (1, pmin, pmax));
 }
 
@@ -86,35 +86,35 @@ ImageFile::displayScaling (const int scale, const ImageFileValue pmin, const Ima
     int ny = m_ny;
     ImageFileArrayConst v = getArray();
     if (v == NULL || nx == 0 || ny == 0)
-      return 0;
-
+               return 0;
+       
 #if HAVE_G2_H
     int* pPens = new int [nx * ny * scale * scale ];
-
+       
     double view_scale = 255 / (pmax - pmin);
     int id_X11 = g2_open_X11 (nx * scale, ny * scale);
     int grayscale[256];
     for (int i = 0; i < 256; i++) {
-       double cval = i / 255.;
-       grayscale[i] = g2_ink (id_X11, cval, cval, cval);
+               double cval = i / 255.;
+               grayscale[i] = g2_ink (id_X11, cval, cval, cval);
     }
-
+       
     for (int iy = ny - 1; iy >= 0; iy--) {
-      int iRowPos = ((ny - 1 - iy) * scale) * (nx * scale);
-      for (int ix = 0; ix < nx; ix++) {
-       int cval = static_cast<int>((v[ix][iy] - pmin) * view_scale);
-       if (cval < 0)  
-         cval = 0;
-       else if (cval > 255) 
-         cval = 255;
-       for (int sy = 0; sy < scale; sy++)
-         for (int sx = 0; sx < scale; sx++)
-           pPens[iRowPos+(sy * nx * scale)+(sx + (ix * scale))] = grayscale[cval];
-       }
+               int iRowPos = ((ny - 1 - iy) * scale) * (nx * scale);
+               for (int ix = 0; ix < nx; ix++) {
+                       int cval = static_cast<int>((v[ix][iy] - pmin) * view_scale);
+                       if (cval < 0)  
+                               cval = 0;
+                       else if (cval > 255) 
+                               cval = 255;
+                       for (int sy = 0; sy < scale; sy++)
+                               for (int sx = 0; sx < scale; sx++)
+                                       pPens[iRowPos+(sy * nx * scale)+(sx + (ix * scale))] = grayscale[cval];
+               }
     }
-
+       
     g2_image (id_X11, 0., 0., nx * scale, ny * scale, pPens);
-
+       
     delete pPens;
     return (id_X11);
 #else
@@ -138,56 +138,56 @@ bool
 ImageFile::comparativeStatistics (const ImageFile& imComp, double& d, double& r, double& e) const
 {
     if (imComp.nx() != m_nx && imComp.ny() != m_ny) {
-       sys_error (ERR_WARNING, "Image sizes differ [ImageFile::comparativeStatistics]");
-       return false;
+               sys_error (ERR_WARNING, "Image sizes differ [ImageFile::comparativeStatistics]");
+               return false;
     }
     ImageFileArrayConst v = getArray();
     if (v == NULL || m_nx == 0 || m_ny == 0)
-      return false;
-
+               return false;
+       
     ImageFileArrayConst vComp = imComp.getArray();
-
+       
     double myMean = 0.;
     for (unsigned int ix = 0; ix < m_nx; ix++) {
-       for (unsigned int iy = 0; iy < m_ny; iy++) {
-           myMean += v[ix][iy];
-       }
+               for (unsigned int iy = 0; iy < m_ny; iy++) {
+                       myMean += v[ix][iy];
+               }
     }
     myMean /= (m_nx * m_ny);
-
+       
     double sqErrorSum = 0.;
     double absErrorSum = 0.;
     double sqDiffFromMeanSum = 0.;
     double absValueSum = 0.;
     for (unsigned int ix2 = 0; ix2 < m_nx; ix2++) {
-       for (unsigned int iy = 0; iy < m_ny; iy++) {
-           double diff = v[ix2][iy] - vComp[ix2][iy];
-           sqErrorSum += diff * diff;
-           absErrorSum += fabs(diff);
-           double diffFromMean = v[ix2][iy] - myMean;
-           sqDiffFromMeanSum += diffFromMean * diffFromMean;
-           absValueSum += fabs(v[ix2][iy]);
-       }
+               for (unsigned int iy = 0; iy < m_ny; iy++) {
+                       double diff = v[ix2][iy] - vComp[ix2][iy];
+                       sqErrorSum += diff * diff;
+                       absErrorSum += fabs(diff);
+                       double diffFromMean = v[ix2][iy] - myMean;
+                       sqDiffFromMeanSum += diffFromMean * diffFromMean;
+                       absValueSum += fabs(v[ix2][iy]);
+               }
     }
-
+       
     d = sqrt (sqErrorSum / sqDiffFromMeanSum);
     r = absErrorSum / absValueSum;
-
+       
     int hx = m_nx / 2;
     int hy = m_ny / 2;
     double eMax = -1;
     for (int ix3 = 0; ix3 < hx; ix3++) {
-      for (int iy = 0; iy < hy; iy++) {
-       double avgPixel = 0.25 * (v[2*ix3][2*iy] + v[2*ix3+1][2*iy] + v[2*ix3][2*iy+1] + v[2*ix3+1][2*iy+1]);
-       double avgPixelComp = 0.25 * (vComp[2*ix3][2*iy] + vComp[2*ix3+1][2*iy] + vComp[2*ix3][2*iy+1] + vComp[2*ix3+1][2*iy+1]);
-       double error = fabs (avgPixel - avgPixelComp);
-       if (error > eMax)
-         eMax = error;
-      }
+               for (int iy = 0; iy < hy; iy++) {
+                       double avgPixel = 0.25 * (v[2*ix3][2*iy] + v[2*ix3+1][2*iy] + v[2*ix3][2*iy+1] + v[2*ix3+1][2*iy+1]);
+                       double avgPixelComp = 0.25 * (vComp[2*ix3][2*iy] + vComp[2*ix3+1][2*iy] + vComp[2*ix3][2*iy+1] + vComp[2*ix3+1][2*iy+1]);
+                       double error = fabs (avgPixel - avgPixelComp);
+                       if (error > eMax)
+                               eMax = error;
+               }
     }
-
+       
     e = eMax;
-
+       
     return true;
 }
 
@@ -195,15 +195,15 @@ ImageFile::comparativeStatistics (const ImageFile& imComp, double& d, double& r,
 bool
 ImageFile::printComparativeStatistics (const ImageFile& imComp, std::ostream& os) const
 {
-  double d, r, e;
-
-  if (comparativeStatistics (imComp, d, r, e)) {
-         os << "  Normalized root mean squared distance (d): " << d << std::endl;
-         os << "      Normalized mean absolute distance (r): " << r << std::endl;
-         os << "Worst case distance (2x2 pixel average) (e): " << e << std::endl;
-    return true;
-  }
-  return false;
+       double d, r, e;
+       
+       if (comparativeStatistics (imComp, d, r, e)) {
+               os << "  Normalized root mean squared distance (d): " << d << std::endl;
+               os << "      Normalized mean absolute distance (r): " << r << std::endl;
+               os << "Worst case distance (2x2 pixel average) (e): " << e << std::endl;
+               return true;
+       }
+       return false;
 }
 
 
@@ -211,9 +211,9 @@ void
 ImageFile::printStatistics (std::ostream& os) const
 {
     double min, max, mean, mode, median, stddev;
-
+       
     statistics (min, max, mean, mode, median, stddev);
-
+       
     os << "   min: " << min << std::endl;
     os << "   max: " << max << std::endl;
     os << "  mean: " << mean << std::endl;
@@ -231,59 +231,15 @@ ImageFile::statistics (double& min, double& max, double& mean, double& mode, dou
     ImageFileArrayConst v = getArray();
     
     if (v == NULL || nx == 0 || ny == 0)
-      return;
-
-    mean = 0;
-    min = v[0][0];
-    max = v[0][0];
-    for (int ix = 0; ix < nx; ix++) {
-      for (int iy = 0; iy < ny; iy++) {
-       if (v[ix][iy] > max)
-         max = v[ix][iy];
-       if (v[ix][iy] < min)
-         min = v[ix][iy];
-       mean += v[ix][iy];
-      }
-    }
-    mean /= (nx * ny);
-
-    static const int nbin = 1024;
-    int hist[ nbin ] = {0};
-    double spread = max - min;
-    mode = 0;
-    stddev = 0;
-    for (int ix4 = 0; ix4 < nx; ix4++) {
-      for (int iy = 0; iy < ny; iy++) {
-       int b = static_cast<int>((((v[ix4][iy] - min) / spread) * (nbin - 1)) + 0.5);
-       hist[b]++;
-       double diff = (v[ix4][iy] - mean);
-       stddev += diff * diff;
-       }
-    }
-    stddev = sqrt(stddev / (nx * ny));
-
-    int max_binindex = 0;
-    int max_bin = -1;
-    for (int ibin = 0; ibin < nbin; ibin++) {
-      if (hist[ibin] > max_bin) {
-       max_bin = hist[ibin];
-       max_binindex = ibin;
-      }
-    }
-
-    mode = (max_binindex * spread / (nbin - 1)) + min;
-
-    int nPixels = nx * ny;
-       std::vector<double> vecImage;
-    for (int ix5 = 0; ix5 < nx; ix5++)
-      for (int iy = 0; iy < ny; iy++)
-            vecImage.push_back (v[ix5][iy]);
-    std::sort(vecImage.begin(), vecImage.end());\r
+               return;
 \r
-    if (nPixels % 2)  // Odd
-         median = vecImage[((nPixels - 1) / 2)];\r
-    else                // Even
-      median = (vecImage[(nPixels / 2) - 1] + vecImage[nPixels / 2]) / 2;
+       std::vector<double> vecImage (nx * ny);\r
+    for (int ix = 0; ix < nx; ix++) {\r
+               for (int iy = 0; iy < ny; iy++)\r
+                       vecImage.push_back (v[ix][iy]);\r
+       }\r
+\r
+       vectorNumericStatistics (vecImage, min, max, mean, mode, median, stddev);\r
 }
 
 
@@ -295,91 +251,91 @@ ImageFile::getMinMax (double& min, double& max) const
     ImageFileArrayConst v = getArray();
     
     if (v == NULL || nx == 0 || ny == 0)
-      return;
-
+               return;
+       
     min = v[0][0];
     max = v[0][0];
     for (int ix = 0; ix < nx; ix++) {
-      for (int iy = 0; iy < ny; iy++) {
-       if (v[ix][iy] > max)
-         max = v[ix][iy];
-       if (v[ix][iy] < min)
-         min = v[ix][iy];
-      }
+               for (int iy = 0; iy < ny; iy++) {
+                       if (v[ix][iy] > max)
+                               max = v[ix][iy];
+                       if (v[ix][iy] < min)
+                               min = v[ix][iy];
+               }
     }
 }
 
 void 
 ImageFile::writeImagePGM (const char *outfile, int nxcell, int nycell, double densmin, double densmax)
 {
-  FILE *fp;
-  int nx = m_nx;
-  int ny = m_ny;
-  ImageFileArray v = getArray();
-
-  unsigned char* rowp = new unsigned char [nx * nxcell];
-
-  if ((fp = fopen (outfile, "wb")) == NULL)
-     return;
-
-  fprintf(fp, "P5\n");
-  fprintf(fp, "%d %d\n", nx, ny);
-  fprintf(fp, "255\n");
-
-  for (int irow = ny - 1; irow >= 0; irow--) {
-    for (int icol = 0; icol < nx; icol++) {
-      int pos = icol * nxcell;
-      double dens = (v[icol][irow] - densmin) / (densmax - densmin);
-      dens = clamp (dens, 0., 1.);
-      for (int p = pos; p < pos + nxcell; p++) {
-       rowp[p] = static_cast<unsigned int> (dens * 255.);
-      }
-    }
-    for (int ir = 0; ir < nycell; ir++) {
-      for (int ic = 0; ic < nx * nxcell; ic++) 
-       fputc( rowp[ic], fp );
-    }
-  }
-\r
-  delete rowp;
-  fclose(fp);
+       FILE *fp;
+       int nx = m_nx;
+       int ny = m_ny;
+       ImageFileArray v = getArray();
+       
+       unsigned char* rowp = new unsigned char [nx * nxcell];
+       
+       if ((fp = fopen (outfile, "wb")) == NULL)
+               return;
+       
+       fprintf(fp, "P5\n");
+       fprintf(fp, "%d %d\n", nx, ny);
+       fprintf(fp, "255\n");
+       
+       for (int irow = ny - 1; irow >= 0; irow--) {
+               for (int icol = 0; icol < nx; icol++) {
+                       int pos = icol * nxcell;
+                       double dens = (v[icol][irow] - densmin) / (densmax - densmin);
+                       dens = clamp (dens, 0., 1.);
+                       for (int p = pos; p < pos + nxcell; p++) {
+                               rowp[p] = static_cast<unsigned int> (dens * 255.);
+                       }
+               }
+               for (int ir = 0; ir < nycell; ir++) {
+                       for (int ic = 0; ic < nx * nxcell; ic++) 
+                               fputc( rowp[ic], fp );
+               }
+       }
+       \r
+       delete rowp;
+       fclose(fp);
 }
 
 void 
 ImageFile::writeImagePGMASCII (const char *outfile, int nxcell, int nycell, double densmin, double densmax)
 {
-  FILE *fp;
-  int nx = m_nx;
-  int ny = m_ny;
-  ImageFileArray v = getArray();
-
-  unsigned char* rowp = new unsigned char [nx * nxcell];
-
-  if ((fp = fopen (outfile, "wb")) == NULL)
-     return;
-
-  fprintf(fp, "P2\n");
-  fprintf(fp, "%d %d\n", nx, ny);
-  fprintf(fp, "255\n");
-
-  for (int irow = ny - 1; irow >= 0; irow--) {
-    for (int icol = 0; icol < nx; icol++) {
-      int pos = icol * nxcell;
-      double dens = (v[icol][irow] - densmin) / (densmax - densmin);
-      dens = clamp (dens, 0., 1.);
-      for (int p = pos; p < pos + nxcell; p++) {
-       rowp[p] = static_cast<unsigned int> (dens * 255.);
-      }
-    }
-    for (int ir = 0; ir < nycell; ir++) {
-      for (int ic = 0; ic < nx * nxcell; ic++) 
-       fprintf(fp, "%d ", rowp[ic]);
-      fprintf(fp, "\n");
-    }
-  }
-\r
-  delete rowp;
-  fclose(fp);
+       FILE *fp;
+       int nx = m_nx;
+       int ny = m_ny;
+       ImageFileArray v = getArray();
+       
+       unsigned char* rowp = new unsigned char [nx * nxcell];
+       
+       if ((fp = fopen (outfile, "wb")) == NULL)
+               return;
+       
+       fprintf(fp, "P2\n");
+       fprintf(fp, "%d %d\n", nx, ny);
+       fprintf(fp, "255\n");
+       
+       for (int irow = ny - 1; irow >= 0; irow--) {
+               for (int icol = 0; icol < nx; icol++) {
+                       int pos = icol * nxcell;
+                       double dens = (v[icol][irow] - densmin) / (densmax - densmin);
+                       dens = clamp (dens, 0., 1.);
+                       for (int p = pos; p < pos + nxcell; p++) {
+                               rowp[p] = static_cast<unsigned int> (dens * 255.);
+                       }
+               }
+               for (int ir = 0; ir < nycell; ir++) {
+                       for (int ic = 0; ic < nx * nxcell; ic++) 
+                               fprintf(fp, "%d ", rowp[ic]);
+                       fprintf(fp, "\n");
+               }
+       }
+       \r
+       delete rowp;
+       fclose(fp);
 }
 
 
@@ -387,69 +343,69 @@ ImageFile::writeImagePGMASCII (const char *outfile, int nxcell, int nycell, doub
 void 
 ImageFile::writeImagePNG (const char *outfile, int bitdepth, int nxcell, int nycell, double densmin, double densmax)
 {
-  FILE *fp;
-  png_structp png_ptr;
-  png_infop info_ptr;
-  double max_out_level = (1 << bitdepth) - 1;
-  int nx = m_nx;
-  int ny = m_ny;
-  ImageFileArray v = getArray();
-
-  unsigned char* rowp = new unsigned char [nx * nxcell * (bitdepth / 8)];
-
-  if ((fp = fopen (outfile, "wb")) == NULL)
-     return;
-
-  png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-  if (! png_ptr)
-    return;
-
-  info_ptr = png_create_info_struct(png_ptr);
-  if (! info_ptr) {
-    png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
-    fclose(fp);
-    return;
-  }
-
-  if (setjmp(png_ptr->jmpbuf)) {
-    png_destroy_write_struct(&png_ptr, &info_ptr);
-    fclose(fp);
-    return;
-  }
-
-  png_init_io(png_ptr, fp);
-
-  png_set_IHDR(png_ptr, info_ptr, nx * nxcell, ny * nycell, bitdepth, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_DEFAULT);
-
-  png_write_info(png_ptr, info_ptr);
-  for (int irow = ny - 1; irow >= 0; irow--) {
-    png_bytep row_pointer = rowp;
-    
-    for (int icol = 0; icol < nx; icol++) {
-      int pos = icol * nxcell;
-      double dens = (v[icol][irow] - densmin) / (densmax - densmin);
-      dens = clamp (dens, 0., 1.);
-      unsigned int outval = static_cast<unsigned int> (dens * max_out_level);
-
-      for (int p = pos; p < pos + nxcell; p++) {
-       if (bitdepth == 8)
-         rowp[p] = outval;
-       else {
-         int rowpos = p * 2;
-         rowp[rowpos] = (outval >> 8) & 0xFF;
-         rowp[rowpos+1] = (outval & 0xFF);
+       FILE *fp;
+       png_structp png_ptr;
+       png_infop info_ptr;
+       double max_out_level = (1 << bitdepth) - 1;
+       int nx = m_nx;
+       int ny = m_ny;
+       ImageFileArray v = getArray();
+       
+       unsigned char* rowp = new unsigned char [nx * nxcell * (bitdepth / 8)];
+       
+       if ((fp = fopen (outfile, "wb")) == NULL)
+               return;
+       
+       png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       if (! png_ptr)
+               return;
+       
+       info_ptr = png_create_info_struct(png_ptr);
+       if (! info_ptr) {
+               png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
+               fclose(fp);
+               return;
        }
-      }
-    }
-    for (int ir = 0; ir < nycell; ir++)
-      png_write_rows (png_ptr, &row_pointer, 1);
-  }
-
-  png_write_end(png_ptr, info_ptr);
-  png_destroy_write_struct(&png_ptr, &info_ptr);
-  delete rowp;\r
-
-  fclose(fp);
+       
+       if (setjmp(png_ptr->jmpbuf)) {
+               png_destroy_write_struct(&png_ptr, &info_ptr);
+               fclose(fp);
+               return;
+       }
+       
+       png_init_io(png_ptr, fp);
+       
+       png_set_IHDR(png_ptr, info_ptr, nx * nxcell, ny * nycell, bitdepth, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_DEFAULT);
+       
+       png_write_info(png_ptr, info_ptr);
+       for (int irow = ny - 1; irow >= 0; irow--) {
+               png_bytep row_pointer = rowp;
+               
+               for (int icol = 0; icol < nx; icol++) {
+                       int pos = icol * nxcell;
+                       double dens = (v[icol][irow] - densmin) / (densmax - densmin);
+                       dens = clamp (dens, 0., 1.);
+                       unsigned int outval = static_cast<unsigned int> (dens * max_out_level);
+                       
+                       for (int p = pos; p < pos + nxcell; p++) {
+                               if (bitdepth == 8)
+                                       rowp[p] = outval;
+                               else {
+                                       int rowpos = p * 2;
+                                       rowp[rowpos] = (outval >> 8) & 0xFF;
+                                       rowp[rowpos+1] = (outval & 0xFF);
+                               }
+                       }
+               }
+               for (int ir = 0; ir < nycell; ir++)
+                       png_write_rows (png_ptr, &row_pointer, 1);
+       }
+       
+       png_write_end(png_ptr, info_ptr);
+       png_destroy_write_struct(&png_ptr, &info_ptr);
+       delete rowp;\r
+       
+       fclose(fp);
 }
 #endif
 
@@ -460,44 +416,44 @@ static const int N_GRAYSCALE=256;
 void
 ImageFile::writeImageGIF (const char *outfile, int nxcell, int nycell, double densmin, double densmax)
 {
-  gdImagePtr gif;
-  FILE *out;
-  int gs_indices[N_GRAYSCALE];
-  int nx = m_nx;
-  int ny = m_ny;
-  ImageFileArray v = getArray();
-
-  unsigned char rowp [nx * nxcell];
-  if (rowp == NULL)
-    return;
-
-  gif = gdImageCreate(nx * nxcell, ny * nycell);
-  for (int i = 0; i < N_GRAYSCALE; i++)
-    gs_indices[i] = gdImageColorAllocate(gif, i, i, i);
-
-  int lastrow = ny * nycell - 1;
-  for (int irow = 0; irow < ny; irow++) {
-    int rpos = irow * nycell;
-    for (int ir = rpos; ir < rpos + nycell; ir++) {
-      for (int icol = 0; icol < nx; icol++) {
-       int cpos = icol * nxcell;
-       double dens = (v[icol][irow] - densmin) / (densmax - densmin);
-       dens = clamp(dens, 0., 1.);
-       for (int ic = cpos; ic < cpos + nxcell; ic++) {
-         rowp[ic] = (unsigned int) (dens * (double) (N_GRAYSCALE - 1));
-         gdImageSetPixel(gif, ic, lastrow - ir, gs_indices[rowp[ic]]);
+       gdImagePtr gif;
+       FILE *out;
+       int gs_indices[N_GRAYSCALE];
+       int nx = m_nx;
+       int ny = m_ny;
+       ImageFileArray v = getArray();
+       
+       unsigned char rowp [nx * nxcell];
+       if (rowp == NULL)
+               return;
+       
+       gif = gdImageCreate(nx * nxcell, ny * nycell);
+       for (int i = 0; i < N_GRAYSCALE; i++)
+               gs_indices[i] = gdImageColorAllocate(gif, i, i, i);
+       
+       int lastrow = ny * nycell - 1;
+       for (int irow = 0; irow < ny; irow++) {
+               int rpos = irow * nycell;
+               for (int ir = rpos; ir < rpos + nycell; ir++) {
+                       for (int icol = 0; icol < nx; icol++) {
+                               int cpos = icol * nxcell;
+                               double dens = (v[icol][irow] - densmin) / (densmax - densmin);
+                               dens = clamp(dens, 0., 1.);
+                               for (int ic = cpos; ic < cpos + nxcell; ic++) {
+                                       rowp[ic] = (unsigned int) (dens * (double) (N_GRAYSCALE - 1));
+                                       gdImageSetPixel(gif, ic, lastrow - ir, gs_indices[rowp[ic]]);
+                               }
+                       }
+               }
        }
-      }
-    }
-  }
-
-  if ((out = fopen(outfile,"w")) == NULL) {
-    sys_error(ERR_FATAL, "Error opening output file %s for writing", outfile);
-    return (1);
-  }
-  gdImageGif(gif,out);
-  fclose(out);
-  gdImageDestroy(gif);
+       
+       if ((out = fopen(outfile,"w")) == NULL) {
+               sys_error(ERR_FATAL, "Error opening output file %s for writing", outfile);
+               return (1);
+       }
+       gdImageGif(gif,out);
+       fclose(out);
+       gdImageDestroy(gif);
 }
 #endif
 
index 1773c8b..c074452 100644 (file)
@@ -2,7 +2,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: mathfuncs.cpp,v 1.2 2000/08/31 08:38:58 kevin Exp $
+**  $Id: mathfuncs.cpp,v 1.3 2000/12/20 20:08:48 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
@@ -81,3 +81,58 @@ normalizeAngle (double theta)
   
   return (theta);
 }
+\r
+\r
+void \r
+vectorNumericStatistics (std::vector<double> vec, double& min, double& max, double& mean, double& mode, double& median, double& stddev)\r
+{\r
+       int n = vec.size();\r
+       if (n <= 0)\r
+               return;\r
+\r
+    mean = 0;\r
+    min = vec[0];\r
+    max = vec[0];\r
+       int i;\r
+    for (i = 0; i < n; i++) {\r
+               double v = vec[i];\r
+               if (v > max)\r
+                       max = v;\r
+               if (v < min)\r
+                       min = v;\r
+               mean += v;\r
+    }\r
+    mean /= n;\r
+       \r
+    static const int nbin = 1024;\r
+    int hist[ nbin ] = {0};\r
+    double spread = max - min;\r
+    mode = 0;\r
+    stddev = 0;\r
+    for (i = 0; i < n; i++) {\r
+               double v = vec[i];\r
+               int b = static_cast<int>((((v - min) / spread) * (nbin - 1)) + 0.5);\r
+               hist[b]++;\r
+               double diff = (v - mean);\r
+               stddev += diff * diff;\r
+    }\r
+    stddev = sqrt (stddev / n);\r
+       \r
+    int max_binindex = 0;\r
+    int max_bin = -1;\r
+    for (int ibin = 0; ibin < nbin; ibin++) {\r
+               if (hist[ibin] > max_bin) {\r
+                       max_bin = hist[ibin];\r
+                       max_binindex = ibin;\r
+               }\r
+    }\r
+       \r
+    mode = (max_binindex * spread / (nbin - 1)) + min;\r
+       \r
+       std::sort(vec.begin(), vec.end());\r
+       \r
+       if (n % 2)  // Odd\r
+               median = vec[((n - 1) / 2)];\r
+       else        // Even\r
+               median = (vec[ (n / 2) - 1 ] + vec[ n / 2 ]) / 2;\r
+}\r
index b874451..5a160cd 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: plotfile.cpp,v 1.2 2000/12/20 14:39:09 kevin Exp $
+**  $Id: plotfile.cpp,v 1.3 2000/12/20 20:08:48 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
@@ -117,6 +117,55 @@ PlotFile::getColumn (int iCol, double* pdColData) const
 \r
 }\r
 \r
+bool\r
+PlotFile::getMinMax (int iStartingCol, double& dMin, double& dMax) const\r
+{\r
+       if (iStartingCol >= m_iNumColumns) {\r
+               sys_error (ERR_WARNING, "iStartingCol >= iNumColumns");\r
+               return false;\r
+       }\r
+\r
+       int iOffset = iStartingCol * m_iNumRecords;\r
+       dMin = m_vecCurves[ 0 + iOffset ];\r
+       dMax = dMin;\r
+\r
+       for (int iCol = iStartingCol; iCol < m_iNumColumns; iCol++) {\r
+               int iOffset = iCol * m_iNumRecords;\r
+               for (int iRec = 0; iRec < m_iNumRecords; iRec++) {\r
+                       double dVal = m_vecCurves[ iRec + iOffset ];\r
+                       if (dVal < dMin)\r
+                               dMin = dVal;\r
+                       else if (dVal > dMax)\r
+                               dMax = dVal;\r
+               }\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+bool \r
+PlotFile::statistics (int iStartingCol, double& min, double& max, double& mean, double& mode, double& median, double &stddev) const\r
+{\r
+       if (iStartingCol >= m_iNumColumns) {\r
+               sys_error (ERR_WARNING, "iStartingCol >= iNumColumns");\r
+               return false;\r
+       }\r
+\r
+       int iOffset = iStartingCol * m_iNumRecords;\r
+       int iNPoints = (m_iNumColumns - iStartingCol) * m_iNumRecords;\r
+       std::vector<double> vec (iNPoints);\r
+\r
+       for (int iCol = iStartingCol; iCol < m_iNumColumns; iCol++) {\r
+               int iOffset = iCol * m_iNumRecords;\r
+               for (int iRec = 0; iRec < m_iNumRecords; iRec++)\r
+                       vec.push_back( m_vecCurves[ iRec + iOffset ] );\r
+       }\r
+\r
+       vectorNumericStatistics (vec, min, max, mean, mode, median, stddev);\r
+\r
+       return true;\r
+}\r
+\r
 bool
 PlotFile::fileWrite (const char* const filename)
 {
index 64467e7..dfc535a 100644 (file)
@@ -6,13 +6,14 @@
 --------------------Configuration: ctsim - Win32 Debug--------------------\r
 </h3>\r
 <h3>Command Lines</h3>\r
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSPEA.tmp" with contents\r
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP16A.tmp" with contents\r
 [\r
 /nologo /G6 /MTd /W3 /Gm /GR /GX /ZI /Od /I "\wx2\include" /I "." /I "..\..\include" /I "..\..\getopt" /I "..\..\..\lpng108" /I "..\..\..\zlib" /I "..\..\..\fftw-2.1.3\fftw" /I "..\..\..\fftw-2.1.3\rfftw" /D VERSION=\"2.5.0\" /D "_DEBUG" /D "__WXMSW__" /D "HAVE_SGP" /D "HAVE_PNG" /D "HAVE_WXWINDOWS" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "HAVE_STRING_H" /D "HAVE_FFTW" /D "HAVE_RFFTW" /D "HAVE_GETOPT_H" /D "MSVC" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /D CTSIMVERSION=\"2.5.0\" /FR"Debug/" /Fp"Debug/ctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c \r
+"C:\ctsim-2.0.6\src\dialogs.cpp"\r
 "C:\ctsim-2.0.6\src\views.cpp"\r
 ]\r
-Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSPEA.tmp" \r
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSPEB.tmp" with contents\r
+Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP16A.tmp" \r
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP16B.tmp" with contents\r
 [\r
 comctl32.lib winmm.lib rpcrt4.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ../libctsim/Debug/libctsim.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\..\lpng108\msvc\win32\libpng\lib_dbg\libpng.lib ..\..\..\lpng108\msvc\win32\zlib\lib_dbg\zlib.lib libcmtd.lib ..\..\..\fftw-2.1.3\Win32\FFTW2st\Debug\FFTW2st.lib ..\..\..\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib ../../../wx2/lib/wxd.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/ctsim.pdb" /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrtd.lib" /out:"Debug/ctsim.exe" /pdbtype:sept /libpath:"..\..\..\lpng108\msvc\win32\libpng\lib" /libpath:"..\..\..\lpng108\msvc\win32\zlib\lib" \r
 ".\Debug\ctsim.obj"\r
@@ -27,24 +28,20 @@ comctl32.lib winmm.lib rpcrt4.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib w
 "\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib"\r
 "\wx2\lib\wxd.lib"\r
 ]\r
-Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSPEB.tmp"\r
+Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP16B.tmp"\r
 <h3>Output Window</h3>\r
 Compiling...\r
+dialogs.cpp\r
 views.cpp\r
-c:\program files\microsoft visual studio\vc98\include\vector(114) : warning C4786: 'std::reverse_iterator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > const &,std::basic_string<char,std::char_traits<char>,std::allocator<char> > const *,int>' : identifier was truncated to '255' characters in the debug information\r
-        c:\program files\microsoft visual studio\vc98\include\vector(114) : while compiling class-template member function 'unsigned int __thiscall std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::size(void) const'\r
-c:\program files\microsoft visual studio\vc98\include\vector(114) : warning C4786: 'std::reverse_iterator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > &,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,int>' : identifier was truncated to '255' characters in the debug information\r
-        c:\program files\microsoft visual studio\vc98\include\vector(114) : while compiling class-template member function 'unsigned int __thiscall std::vector<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::size(void) const'\r
 Linking...\r
 Creating command line "bscmake.exe /nologo /o"Debug/ctsim.bsc"  ".\Debug\ctsim.sbr" ".\Debug\dialogs.sbr" ".\Debug\dlgprojections.sbr" ".\Debug\dlgreconstruct.sbr" ".\Debug\docs.sbr" ".\Debug\views.sbr""\r
 Creating browse info file...\r
-BSCMAKE: warning BK4503 : minor error in .SBR file '.\Debug\views.sbr' ignored\r
 <h3>Output Window</h3>\r
 \r
 \r
 \r
 <h3>Results</h3>\r
-ctsim.exe - 0 error(s), 3 warning(s)\r
+ctsim.exe - 0 error(s), 0 warning(s)\r
 </pre>\r
 </body>\r
 </html>\r
index 220a540..d925599 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: ctsim.h,v 1.9 2000/12/19 21:37:51 kevin Exp $
+**  $Id: ctsim.h,v 1.10 2000/12/20 20:08:48 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
@@ -137,7 +137,9 @@ enum {
     IFMENU_VIEW_SCALE_AUTO,
     IFMENU_VIEW_SCALE_MINMAX,
     PHMMENU_PROCESS_RASTERIZE,
-    PHMMENU_PROCESS_PROJECTIONS,
+    PHMMENU_PROCESS_PROJECTIONS,\r
+       PLOTMENU_VIEW_SCALE_MINMAX,\r
+       PLOTMENU_VIEW_SCALE_AUTO,
     MAINMENU_WINDOW_BASE,
 };
 
index f2102d0..622efb2 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: dialogs.cpp,v 1.17 2000/12/17 19:30:02 kevin Exp $
+**  $Id: dialogs.cpp,v 1.18 2000/12/20 20:08:48 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
@@ -117,13 +117,17 @@ DialogGetPhantom::getPhantom(void)
     return m_pListBoxPhantom->getSelectionStringValue();
 }
 
+\r
+/////////////////////////////////////////////////////////////////////\r
+// CLASS DiaglogGetMinMax Implementation\r
+/////////////////////////////////////////////////////////////////////\r
 
-DialogGetImageMinMax::DialogGetImageMinMax (wxFrame* pParent, const ImageFile& rImagefile, double dDefaultMin, double dDefaultMax)
-    : wxDialog (pParent, -1, "Set Image Display Minimum & Maximum", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxCAPTION)
+DialogGetMinMax::DialogGetMinMax (wxFrame* pParent, const char* const pszTitle, double dDefaultMin, double dDefaultMax)
+    : wxDialog (pParent, -1, pszTitle, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxCAPTION)
 {
   wxBoxSizer* pTopSizer = new wxBoxSizer (wxVERTICAL);
 
-  pTopSizer->Add (new wxStaticText (this, -1, "Set Image Display Minimum and Maximum"), 0, wxALIGN_CENTER | wxTOP | wxLEFT | wxRIGHT, 5);
+  pTopSizer->Add (new wxStaticText (this, -1, pszTitle), 0, wxALIGN_CENTER | wxTOP | wxLEFT | wxRIGHT, 5);
                   
   pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5);
 
@@ -157,16 +161,12 @@ DialogGetImageMinMax::DialogGetImageMinMax (wxFrame* pParent, const ImageFile& r
   pTopSizer->SetSizeHints (this);
 }
 
-DialogGetImageMinMax::~DialogGetImageMinMax (void)
+DialogGetMinMax::~DialogGetMinMax (void)
 {
-#if 0
-  delete m_pTextCtrlMin;
-  delete m_pTextCtrlMax;
-#endif
 }
 
 double
-DialogGetImageMinMax::getMinimum (void)
+DialogGetMinMax::getMinimum (void)
 {
     wxString strCtrl = m_pTextCtrlMin->GetValue();
     double dValue;
@@ -177,7 +177,7 @@ DialogGetImageMinMax::getMinimum (void)
 }
 
 double
-DialogGetImageMinMax::getMaximum (void)
+DialogGetMinMax::getMaximum (void)
 {
     wxString strCtrl = m_pTextCtrlMax->GetValue();
     double dValue;
@@ -188,6 +188,89 @@ DialogGetImageMinMax::getMaximum (void)
 }
 
 
+/////////////////////////////////////////////////////////////////////\r
+// CLASS DialogAutoScaleParameters IMPLEMENTATION\r
+/////////////////////////////////////////////////////////////////////\r
+\r
+DialogAutoScaleParameters::DialogAutoScaleParameters (wxFrame *pParent, double mean, double mode, double median, double stddev, double dDefaultScaleFactor)\r
+  : wxDialog (pParent, -1, "Auto Scale Parameters", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxCAPTION), m_dMean(mean), m_dMode(mode), m_dMedian(median), m_dStdDev(stddev)\r
+{\r
+  wxBoxSizer* pTopSizer = new wxBoxSizer (wxVERTICAL);\r
+\r
+  pTopSizer->Add (new wxStaticText (this, -1, "Auto Scale Parameters"), 0, wxALIGN_CENTER | wxTOP | wxLEFT | wxRIGHT, 5);\r
+                  \r
+  pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5);\r
+\r
+  wxString asTitle[3];\r
+  asTitle[0] = "Median";\r
+  asTitle[1] = "Mode";\r
+  asTitle[2] = "Mean";\r
+\r
+  m_pListBoxCenter = new wxListBox (this, -1, wxDefaultPosition, wxDefaultSize, 3, asTitle, wxLB_SINGLE | wxLB_NEEDED_SB);\r
+  m_pListBoxCenter->SetSelection (0);\r
+  pTopSizer->Add (m_pListBoxCenter, 0, wxALL | wxALIGN_CENTER | wxEXPAND);\r
+\r
+  wxGridSizer *pGridSizer = new wxGridSizer (2);\r
+  pGridSizer->Add (new wxStaticText (this, -1, "Standard Deviation Factor"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);\r
+  std::ostringstream osDefaultFactor;\r
+  osDefaultFactor << dDefaultScaleFactor;\r
+  m_pTextCtrlStdDevFactor = new wxTextCtrl (this, -1, osDefaultFactor.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);\r
+  pGridSizer->Add (m_pTextCtrlStdDevFactor, 0, wxALIGN_CENTER_VERTICAL);\r
+  pTopSizer->Add (pGridSizer, 1, wxALL, 10);\r
+\r
+  pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5);\r
+\r
+  wxBoxSizer* pButtonSizer = new wxBoxSizer (wxHORIZONTAL);\r
+  wxButton* pButtonOk = new wxButton (this, wxID_OK, "Okay");\r
+  wxButton* pButtonCancel = new wxButton (this, wxID_CANCEL, "Cancel");\r
+  pButtonSizer->Add (pButtonOk, 0, wxEXPAND | wxALL, 10);\r
+  pButtonSizer->Add (pButtonCancel, 0, wxEXPAND | wxALL, 10);\r
+\r
+  pTopSizer->Add (pButtonSizer, 0, wxALIGN_CENTER);\r
+\r
+  SetAutoLayout (true);\r
+  SetSizer (pTopSizer);\r
+  pTopSizer->Fit (this);\r
+  pTopSizer->SetSizeHints (this);\r
+}\r
+\r
+bool\r
+DialogAutoScaleParameters::getMinMax (double* pMin, double* pMax)\r
+{\r
+  int iCenter = m_pListBoxCenter->GetSelection();\r
+  double dCenter = m_dMedian;\r
+  if (iCenter == 1)\r
+    dCenter = m_dMode;\r
+  else if (iCenter == 2)\r
+    dCenter = m_dMode;\r
+  \r
+  wxString sStddevFactor = m_pTextCtrlStdDevFactor->GetValue();\r
+  double dValue;\r
+  if (! sStddevFactor.ToDouble (&dValue)) {\r
+    *theApp->getLog() << "Error: Non-numeric Standard Deviation Factor of " << sStddevFactor << "\n";\r
+       return false;\r
+  }\r
+  double dHalfWidth = dValue * m_dStdDev / 2;\r
+  *pMin = dCenter - dHalfWidth;\r
+  *pMax = dCenter + dHalfWidth;\r
+  *theApp->getLog() << "Setting minimum to " << *pMin << " and maximum to " << *pMax << "\n";\r
+\r
+  return true;\r
+}\r
+\r
+double\r
+DialogAutoScaleParameters::getAutoScaleFactor ()\r
+{\r
+  wxString sStddevFactor = m_pTextCtrlStdDevFactor->GetValue();\r
+  double dValue = 1.;\r
+  if (! sStddevFactor.ToDouble (&dValue)) {\r
+    *theApp->getLog() << "Error: Non-numeric Standard Deviation Factor of " << sStddevFactor << "\n";\r
+  }\r
+\r
+  return dValue;\r
+}\r
+\r
+\r
 /////////////////////////////////////////////////////////////////////
 // CLASS IDENTIFICATION
 //
@@ -650,82 +733,4 @@ DialogGetReconstructionParameters::getFilterGenerationName (void)
   return m_pListBoxFilterGeneration->getSelectionStringValue();
 }
 
-
-DialogAutoScaleParameters::DialogAutoScaleParameters (wxFrame *pParent, const ImageFile& rIF, double dDefaultScaleFactor)
-  : wxDialog (pParent, -1, "Auto Scale Parameters", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxCAPTION), m_rImageFile(rIF)
-{
-  wxBoxSizer* pTopSizer = new wxBoxSizer (wxVERTICAL);
-
-  pTopSizer->Add (new wxStaticText (this, -1, "Auto Scale Parameters"), 0, wxALIGN_CENTER | wxTOP | wxLEFT | wxRIGHT, 5);
-                  
-  pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5);
-
-  wxString asTitle[3];
-  asTitle[0] = "Median";
-  asTitle[1] = "Mode";
-  asTitle[2] = "Mean";
-
-  m_pListBoxCenter = new wxListBox (this, -1, wxDefaultPosition, wxDefaultSize, 3, asTitle, wxLB_SINGLE | wxLB_NEEDED_SB);
-  m_pListBoxCenter->SetSelection (0);
-  pTopSizer->Add (m_pListBoxCenter, 0, wxALL | wxALIGN_CENTER | wxEXPAND);
-
-  wxGridSizer *pGridSizer = new wxGridSizer (2);
-  pGridSizer->Add (new wxStaticText (this, -1, "Standard Deviation Factor"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
-  std::ostringstream osDefaultFactor;
-  osDefaultFactor << dDefaultScaleFactor;
-  m_pTextCtrlStdDevFactor = new wxTextCtrl (this, -1, osDefaultFactor.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
-  pGridSizer->Add (m_pTextCtrlStdDevFactor, 0, wxALIGN_CENTER_VERTICAL);
-  pTopSizer->Add (pGridSizer, 1, wxALL, 10);
-
-  pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5);
-
-  wxBoxSizer* pButtonSizer = new wxBoxSizer (wxHORIZONTAL);
-  wxButton* pButtonOk = new wxButton (this, wxID_OK, "Okay");
-  wxButton* pButtonCancel = new wxButton (this, wxID_CANCEL, "Cancel");
-  pButtonSizer->Add (pButtonOk, 0, wxEXPAND | wxALL, 10);
-  pButtonSizer->Add (pButtonCancel, 0, wxEXPAND | wxALL, 10);
-
-  pTopSizer->Add (pButtonSizer, 0, wxALIGN_CENTER);
-
-  SetAutoLayout (true);
-  SetSizer (pTopSizer);
-  pTopSizer->Fit (this);
-  pTopSizer->SetSizeHints (this);
-}
-
-void 
-DialogAutoScaleParameters::getMinMax (double* pMin, double* pMax)
-{
-  int iCenter = m_pListBoxCenter->GetSelection();
-  double min, max, mean, mode, median, stddev;
-  m_rImageFile.statistics (min, max, mean, mode, median, stddev);
-  double dCenter = median;
-  if (iCenter == 1)
-    dCenter = mode;
-  else if (iCenter == 2)
-    dCenter = mean;
-  
-  wxString sStddevFactor = m_pTextCtrlStdDevFactor->GetValue();
-  double dValue;
-  if (! sStddevFactor.ToDouble (&dValue)) {
-    *theApp->getLog() << "Error: Non-numeric Standard Deviation Factor of " << sStddevFactor << "\n";
-    *pMin = min;
-    *pMax = max;
-  }
-  double dHalfWidth = dValue * stddev / 2;
-  *pMin = dCenter - dHalfWidth;
-  *pMax = dCenter + dHalfWidth;
-  *theApp->getLog() << "Setting minimum to " << *pMin << " and maximum to " << *pMax << "\n";
-}
-
-double
-DialogAutoScaleParameters::getAutoScaleFactor ()
-{
-  wxString sStddevFactor = m_pTextCtrlStdDevFactor->GetValue();
-  double dValue = 1.;
-  if (! sStddevFactor.ToDouble (&dValue)) {
-    *theApp->getLog() << "Error: Non-numeric Standard Deviation Factor of " << sStddevFactor << "\n";
-  }
-
-  return dValue;
-}
+\r
index 1cd86e3..b14fa78 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: dialogs.h,v 1.13 2000/09/02 05:10:39 kevin Exp $
+**  $Id: dialogs.h,v 1.14 2000/12/20 20:08:48 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
@@ -68,11 +68,11 @@ class DialogGetPhantom : public wxDialog
 
 
 class ImageFile;
-class DialogGetImageMinMax : public wxDialog
+class DialogGetMinMax : public wxDialog
 {
  public:
-    DialogGetImageMinMax (wxFrame* pParent, const ImageFile& rImagefile, double dDefaultMin = 0., double dDefaultMax = 0.);
-    virtual ~DialogGetImageMinMax ();
+    DialogGetMinMax (wxFrame* pParent, const char* const pszTitle, double dDefaultMin = 0., double dDefaultMax = 0.);
+    virtual ~DialogGetMinMax ();
 
     double getMinimum ();
     double getMaximum ();
@@ -189,14 +189,17 @@ class DialogGetReconstructionParameters : public wxDialog
 class DialogAutoScaleParameters : public wxDialog
 {
  public:
-    DialogAutoScaleParameters (wxFrame* pParent, const ImageFile& rImageFile, double dDefaultScaleFactor = 1.);
+    DialogAutoScaleParameters (wxFrame* pParent, double mean, double mode, double median, double stddev, double dDefaultScaleFactor = 1.);
     virtual ~DialogAutoScaleParameters() {}
 
-    void getMinMax (double* pMin, double* pMax);
+    bool getMinMax (double* pMin, double* pMax);
     double getAutoScaleFactor ();
 
  private:
-    const ImageFile& m_rImageFile;
+    const double m_dMean;\r
+       const double m_dMode;
+       const double m_dMedian;\r
+       const double m_dStdDev;\r
 
     wxTextCtrl* m_pTextCtrlStdDevFactor;
     wxListBox* m_pListBoxCenter;
index d40fd5e..04adab9 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: views.cpp,v 1.33 2000/12/20 14:52:30 kevin Exp $
+**  $Id: views.cpp,v 1.34 2000/12/20 20:08:48 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
@@ -90,7 +90,7 @@ ImageFileCanvas::DrawRubberBandCursor (wxDC& dc, int x, int y)
        ImageFileArrayConst v = rIF.getArray();\r
        int nx = rIF.nx();\r
        int ny = rIF.ny();\r
-\r
+       \r
        dc.SetLogicalFunction (wxINVERT);\r
        dc.SetPen (*wxGREEN_PEN);\r
        dc.DrawLine (0, y, nx, y);\r
@@ -103,7 +103,7 @@ ImageFileCanvas::GetCurrentCursor (int& x, int& y)
 {\r
        x = m_xCursor;\r
        y = m_yCursor;\r
-\r
+       \r
        if (m_xCursor >= 0 && m_yCursor >= 0)\r
                return true;\r
        else\r
@@ -120,7 +120,7 @@ ImageFileCanvas::OnMouseEvent(wxMouseEvent& event)
     PrepareDC(dc);
     
     wxPoint pt(event.GetLogicalPosition(dc));
-\r
+       \r
     if (event.RightIsDown()) {\r
                const ImageFile& rIF = m_pView->GetDocument()->getImageFile();\r
                ImageFileArrayConst v = rIF.getArray();\r
@@ -134,7 +134,7 @@ ImageFileCanvas::OnMouseEvent(wxMouseEvent& event)
                } else\r
                        *theApp->getLog() << "Mouse out of image range (" << pt.x << "," << pt.y << ")\n";\r
     }\r
-    else if (event.LeftIsDown()) {\r
+    else if (event.LeftIsDown() || event.LeftUp()) {\r
                const ImageFile& rIF = m_pView->GetDocument()->getImageFile();\r
                ImageFileArrayConst v = rIF.getArray();\r
                int nx = rIF.nx();\r
@@ -147,11 +147,13 @@ ImageFileCanvas::OnMouseEvent(wxMouseEvent& event)
                        DrawRubberBandCursor (dc, pt.x, pt.y);\r
                        m_xCursor = pt.x;\r
                        m_yCursor = pt.y;\r
+               } else\r
+                       *theApp->getLog() << "Mouse out of image range (" << pt.x << "," << pt.y << ")\n";\r
+       }\r
+    if (event.LeftUp()) {\r
                        std::ostringstream os;\r
                        os << "Selected column" << pt.x << " and row" << pt.y << "\n";\r
                        *theApp->getLog() << os.str().c_str();\r
-               } else\r
-                       *theApp->getLog() << "Mouse out of image range (" << pt.x << "," << pt.y << ")\n";\r
     }\r
 }
 
@@ -198,17 +200,20 @@ void
 ImageFileView::OnScaleAuto (wxCommandEvent& event)
 {
     const ImageFile& rIF = GetDocument()->getImageFile();
-    DialogAutoScaleParameters dialogAutoScale (m_frame, rIF, m_dAutoScaleFactor);
+    double min, max, mean, mode, median, stddev;\r
+       rIF.statistics(min, max, mean, mode, median, stddev);\r
+    DialogAutoScaleParameters dialogAutoScale (m_frame, mean, mode, median, stddev, m_dAutoScaleFactor);
     int iRetVal = dialogAutoScale.ShowModal();
     if (iRetVal == wxID_OK) {
                m_bMinSpecified = true;
                m_bMaxSpecified = true;
-               double dMin, dMax;
-               dialogAutoScale.getMinMax (&dMin, &dMax);
-               m_dMinPixel = dMin;
-               m_dMaxPixel = dMax;
-               m_dAutoScaleFactor = dialogAutoScale.getAutoScaleFactor();
-               OnUpdate (this, NULL);
+               double dMin, dMax;\r
+               if (dialogAutoScale.getMinMax (&dMin, &dMax)) {
+                       m_dMinPixel = dMin;
+                       m_dMaxPixel = dMax;
+                       m_dAutoScaleFactor = dialogAutoScale.getAutoScaleFactor();
+                       OnUpdate (this, NULL);\r
+               }
     }
 }
 
@@ -225,7 +230,7 @@ ImageFileView::OnScaleMinMax (wxCommandEvent& event)
     if (m_bMaxSpecified)
                max = m_dMaxPixel;
        
-    DialogGetImageMinMax dialogMinMax (m_frame, rIF, min, max);
+    DialogGetMinMax dialogMinMax (m_frame, "Set Image Minimum & Maximum", min, max);
     int retVal = dialogMinMax.ShowModal();
     if (retVal == wxID_OK) {
                m_bMinSpecified = true;
@@ -281,7 +286,7 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
        wxMenu *plot_menu = new wxMenu;\r
        plot_menu->Append (IFMENU_PLOT_ROW, "Plot &Row");\r
        plot_menu->Append (IFMENU_PLOT_COL, "Plot &Column");\r
-
+       
     wxMenu *help_menu = new wxMenu;
     help_menu->Append(MAINMENU_HELP_ABOUT, "&About");
     
@@ -330,7 +335,7 @@ ImageFileView::OnDraw (wxDC* dc)
 {
        if (m_bitmap.Ok())
                dc->DrawBitmap(m_bitmap, 0, 0, false);
-\r
+       \r
        int xCursor, yCursor;\r
        if (m_canvas->GetCurrentCursor (xCursor, yCursor))\r
                m_canvas->DrawRubberBandCursor (*dc, xCursor, yCursor);\r
@@ -414,12 +419,12 @@ ImageFileView::OnPlotRow (wxCommandEvent& event)
                *theApp->getLog() << "No row selected. Please use left mouse button on image to select row\n";\r
                return;\r
        }\r
-\r
+       \r
     const ImageFile& rIF = dynamic_cast<ImageFileDocument*>(GetDocument())->getImageFile();\r
     ImageFileArrayConst v = rIF.getArray();\r
     int nx = rIF.nx();\r
     int ny = rIF.ny();\r
-\r
+       \r
     if (v != NULL && yCursor < ny) {\r
                double* pX = new double [nx];\r
                double* pY = new double [nx];\r
@@ -431,20 +436,21 @@ ImageFileView::OnPlotRow (wxCommandEvent& event)
                if (! pPlotDoc) {\r
                        sys_error (ERR_SEVERE, "Internal error: unable to create Plot file");\r
                } else {\r
-                       PlotFile& rPlot = pPlotDoc->getPlotFile();\r
+                       PlotFile& rPlotFile = pPlotDoc->getPlotFile();\r
                        std::ostringstream title;\r
                        title << "Row " << yCursor;\r
-                       rPlot.setTitle(title.str());\r
-                       rPlot.setXLabel("Column");\r
-                       rPlot.setYLabel("Pixel Value");\r
-                       rPlot.setCurveSize (2, nx);\r
-                       rPlot.addColumn (0, pX);\r
-                       rPlot.addColumn (1, pY);\r
+                       rPlotFile.setTitle(title.str());\r
+                       rPlotFile.setXLabel("Column");\r
+                       rPlotFile.setYLabel("Pixel Value");\r
+                       rPlotFile.setCurveSize (2, nx);\r
+                       rPlotFile.addColumn (0, pX);\r
+                       rPlotFile.addColumn (1, pY);\r
                }\r
                delete pX;\r
                delete pY;\r
+               pPlotDoc->Modify(true);\r
        }\r
-\r
+       \r
 }\r
 
 void\r
@@ -455,12 +461,12 @@ ImageFileView::OnPlotCol (wxCommandEvent& event)
                // os << "No column selected. Please use left mouse button on image to select column\n";\r
                return;\r
        }\r
-\r
+       \r
     const ImageFile& rIF = dynamic_cast<ImageFileDocument*>(GetDocument())->getImageFile();\r
     ImageFileArrayConst v = rIF.getArray();\r
     int nx = rIF.nx();\r
     int ny = rIF.ny();\r
-\r
+       \r
     if (v != NULL && xCursor < nx) {\r
                double* pX = new double [ny];\r
                double* pY = new double [ny];\r
@@ -479,18 +485,19 @@ ImageFileView::OnPlotCol (wxCommandEvent& event)
                if (! pPlotDoc) {\r
                        sys_error (ERR_SEVERE, "Internal error: unable to create Plot file");\r
                } else {\r
-                       PlotFile& rPlot = pPlotDoc->getPlotFile();\r
+                       PlotFile& rPlotFile = pPlotDoc->getPlotFile();\r
                        std::ostringstream title;\r
                        title << "Column " << xCursor;\r
-                       rPlot.setTitle(title.str());\r
-                       rPlot.setXLabel("Row");\r
-                       rPlot.setYLabel("Pixel Value");\r
-                       rPlot.setCurveSize (2, nx);\r
-                       rPlot.addColumn (0, pX);\r
-                       rPlot.addColumn (1, pY);\r
+                       rPlotFile.setTitle(title.str());\r
+                       rPlotFile.setXLabel("Row");\r
+                       rPlotFile.setYLabel("Pixel Value");\r
+                       rPlotFile.setCurveSize (2, nx);\r
+                       rPlotFile.addColumn (0, pX);\r
+                       rPlotFile.addColumn (1, pY);\r
                }\r
                delete pX;\r
                delete pY;\r
+               pPlotDoc->Modify(true);\r
        }\r
 }\r
 \r
@@ -571,7 +578,11 @@ PhantomView::OnProjections (wxCommandEvent& event)
                
                if (m_iDefaultNDet > 0 && m_iDefaultNView > 0 && sGeometry != "") {
                        const Phantom& rPhantom = GetDocument()->getPhantom();
-                       ProjectionFileDocument* pProjectionDoc = dynamic_cast<ProjectionFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.pj", wxDOC_SILENT));
+                       ProjectionFileDocument* pProjectionDoc = dynamic_cast<ProjectionFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.pj", wxDOC_SILENT));\r
+                       if (! pProjectionDoc) {\r
+                               sys_error (ERR_SEVERE, "Unable to create projection document");\r
+                               return;\r
+                       }
                        Projections& rProj = pProjectionDoc->getProjections();
                        Scanner theScanner (rPhantom, sGeometry.c_str(), m_iDefaultNDet, m_iDefaultNView, m_iDefaultNSample, m_dDefaultRotation, m_dDefaultFocalLength, m_dDefaultFieldOfView);
                        if (theScanner.fail()) {
@@ -648,7 +659,11 @@ PhantomView::OnRasterize (wxCommandEvent& event)
                        nSamples = 1;
                if (xSize > 0 && ySize > 0) {
                        const Phantom& rPhantom = GetDocument()->getPhantom();
-                       ImageFileDocument* pRasterDoc = dynamic_cast<ImageFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.if", wxDOC_SILENT));
+                       ImageFileDocument* pRasterDoc = dynamic_cast<ImageFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.if", wxDOC_SILENT));\r
+                       if (! pRasterDoc) {\r
+                               sys_error (ERR_SEVERE, "Unable to create image file");\r
+                               return;\r
+                       }
                        ImageFile& imageFile = pRasterDoc->getImageFile();
                        
                        imageFile.setArraySize (xSize, ySize);
@@ -883,7 +898,11 @@ ProjectionFileView::OnReconstruct (wxCommandEvent& event)
                m_iDefaultBackprojector = Backprojector::convertBackprojectNameToID (optBackprojectName.c_str());
                m_iDefaultTrace = dialogReconstruction.getTrace();
                if (m_iDefaultNX > 0 && m_iDefaultNY > 0) {
-                       ImageFileDocument* pReconDoc = dynamic_cast<ImageFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.if", wxDOC_SILENT));
+                       ImageFileDocument* pReconDoc = dynamic_cast<ImageFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.if", wxDOC_SILENT));\r
+                       if (pReconDoc) {\r
+                               sys_error (ERR_SEVERE, "Unable to create image file");\r
+                               return;\r
+                       }
                        ImageFile& imageFile = pReconDoc->getImageFile();
                        const Projections& rProj = GetDocument()->getProjections();
                        imageFile.setArraySize (m_iDefaultNX, m_iDefaultNY);
@@ -1135,7 +1154,8 @@ PlotFileCanvas::OnDraw(wxDC& dc)
 {
     if (m_pView)
         m_pView->OnDraw(& dc);
-}
+}\r
+
 
 // PlotFileView
 
@@ -1143,10 +1163,12 @@ IMPLEMENT_DYNAMIC_CLASS(PlotFileView, wxView)
 
 BEGIN_EVENT_TABLE(PlotFileView, wxView)
 EVT_MENU(PJMENU_FILE_PROPERTIES, PlotFileView::OnProperties)
+EVT_MENU(PLOTMENU_VIEW_SCALE_MINMAX, PlotFileView::OnScaleMinMax)\r
+EVT_MENU(PLOTMENU_VIEW_SCALE_AUTO, PlotFileView::OnScaleAuto)\r
 END_EVENT_TABLE()
 
 PlotFileView::PlotFileView(void) 
-: wxView(), m_canvas(NULL), m_frame(NULL)
+: wxView(), m_canvas(NULL), m_frame(NULL), m_bMinSpecified(false), m_bMaxSpecified(false)
 {
 }
 
@@ -1166,6 +1188,57 @@ PlotFileView::OnProperties (wxCommandEvent& event)
 }
 
 
+void \r
+PlotFileView::OnScaleAuto (wxCommandEvent& event)\r
+{\r
+       const PlotFile& rPlotFile = GetDocument()->getPlotFile();\r
+       double min, max, mean, mode, median, stddev;\r
+       rPlotFile.statistics (1, min, max, mean, mode, median, stddev);\r
+       DialogAutoScaleParameters dialogAutoScale (m_frame, mean, mode, median, stddev, m_dAutoScaleFactor);\r
+    int iRetVal = dialogAutoScale.ShowModal();\r
+    if (iRetVal == wxID_OK) {\r
+               m_bMinSpecified = true;\r
+               m_bMaxSpecified = true;\r
+               double dMin, dMax;\r
+               if (dialogAutoScale.getMinMax (&dMin, &dMax)) {\r
+                       m_dMinPixel = dMin;\r
+                       m_dMaxPixel = dMax;\r
+                       m_dAutoScaleFactor = dialogAutoScale.getAutoScaleFactor();\r
+                       OnUpdate (this, NULL);\r
+               }\r
+    }\r
+}\r
+\r
+void \r
+PlotFileView::OnScaleMinMax (wxCommandEvent& event)\r
+{\r
+       const PlotFile& rPlotFile = GetDocument()->getPlotFile();\r
+    double min, max;\r
+\r
+    if (! m_bMinSpecified && ! m_bMaxSpecified) {\r
+               if (! rPlotFile.getMinMax (1, min, max)) {\r
+                       *theApp->getLog() << "Error: unable to find Min/Max\n";\r
+                       return;\r
+       }\r
+       }\r
+       \r
+    if (m_bMinSpecified)\r
+               min = m_dMinPixel;\r
+    if (m_bMaxSpecified)\r
+               max = m_dMaxPixel;\r
+       \r
+    DialogGetMinMax dialogMinMax (m_frame, "Set Y-axis Minimum & Maximum", min, max);\r
+    int retVal = dialogMinMax.ShowModal();\r
+    if (retVal == wxID_OK) {\r
+               m_bMinSpecified = true;\r
+               m_bMaxSpecified = true;\r
+               m_dMinPixel = dialogMinMax.getMinimum();\r
+               m_dMaxPixel = dialogMinMax.getMaximum();\r
+               OnUpdate (this, NULL);\r
+    }\r
+}\r
+\r
+\r
 PlotFileCanvas* 
 PlotFileView::CreateCanvas (wxView *view, wxFrame *parent)
 {
@@ -1202,6 +1275,10 @@ PlotFileView::CreateChildFrame(wxDocument *doc, wxView *view)
     file_menu->Append(wxID_PRINT_SETUP, "Print &Setup...");
     file_menu->Append(wxID_PREVIEW, "Print Pre&view");
     
+    wxMenu *view_menu = new wxMenu;\r
+    view_menu->Append(PLOTMENU_VIEW_SCALE_MINMAX, "Display Scale &Set...");\r
+    view_menu->Append(PLOTMENU_VIEW_SCALE_AUTO, "Display Scale &Auto...");\r
+    \r
     wxMenu *help_menu = new wxMenu;
     help_menu->Append(MAINMENU_HELP_CONTENTS, "&Contents");
     help_menu->AppendSeparator();
@@ -1209,7 +1286,8 @@ PlotFileView::CreateChildFrame(wxDocument *doc, wxView *view)
     
     wxMenuBar *menu_bar = new wxMenuBar;
     
-    menu_bar->Append(file_menu, "&File");
+    menu_bar->Append(file_menu, "&File");\r
+       menu_bar->Append(view_menu, "&View");
     menu_bar->Append(help_menu, "&Help");
     
     subframe->SetMenuBar(menu_bar);
@@ -1246,10 +1324,10 @@ PlotFileView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
 void 
 PlotFileView::OnDraw (wxDC* dc)
 {
-    const PlotFile& rPlot = GetDocument()->getPlotFile();\r
-    const int iNColumns = rPlot.getNumColumns();\r
-       const int iNRecords = rPlot.getNumRecords();\r
-\r
+    const PlotFile& rPlotFile = GetDocument()->getPlotFile();\r
+    const int iNColumns = rPlotFile.getNumColumns();\r
+       const int iNRecords = rPlotFile.getNumRecords();\r
+       \r
        if (iNColumns > 0 && iNRecords > 0) {\r
                int xsize, ysize;\r
                m_canvas->GetClientSize (&xsize, &ysize);\r
@@ -1257,38 +1335,50 @@ PlotFileView::OnDraw (wxDC* dc)
                SGP sgp (driver);\r
                const PlotFile& rPhantom = GetDocument()->getPlotFile();\r
                EZPlot plot (sgp);\r
-\r
-               if (! rPlot.getTitle().empty()) {\r
+               \r
+               if (! rPlotFile.getTitle().empty()) {\r
                        std::string s("title ");\r
-                       s += rPlot.getTitle();\r
+                       s += rPlotFile.getTitle();\r
                        plot.ezset (s);\r
                }\r
-               if (! rPlot.getXLabel().empty()) {\r
+               if (! rPlotFile.getXLabel().empty()) {\r
                        std::string s("xlabel ");\r
-                       s += rPlot.getXLabel();\r
+                       s += rPlotFile.getXLabel();\r
                        plot.ezset (s);\r
                }\r
-               if (! rPlot.getYLabel().empty()) {\r
+               if (! rPlotFile.getYLabel().empty()) {\r
                        std::string s("ylabel ");\r
-                       s += rPlot.getYLabel();\r
+                       s += rPlotFile.getYLabel();\r
                        plot.ezset (s);\r
                }\r
+               \r
+               if (m_bMinSpecified) {\r
+                       std::ostringstream os;\r
+                       os << "ymin " << m_dMinPixel;\r
+                       plot.ezset (os.str());\r
+               }\r
 \r
-       plot.ezset("box");\r
-       plot.ezset("grid");\r
+               if (m_bMaxSpecified) {\r
+                       std::ostringstream os;\r
+                       os << "ymax " << m_dMaxPixel;\r
+                       plot.ezset (os.str());\r
+               }\r
 \r
+               plot.ezset("box");\r
+               plot.ezset("grid");\r
+               \r
                double* pdXaxis = new double [iNRecords];\r
-               rPlot.getColumn (0, pdXaxis);\r
-\r
+               rPlotFile.getColumn (0, pdXaxis);\r
+               \r
                double* pdY = new double [iNRecords];\r
                for (int iCol = 1; iCol < iNColumns; iCol++) {\r
-                       rPlot.getColumn (iCol, pdY);\r
+                       rPlotFile.getColumn (iCol, pdY);\r
                        plot.addCurve (pdXaxis, pdY, iNRecords);\r
                }\r
-\r
+               \r
                delete pdXaxis;\r
                delete pdY;\r
-\r
+               \r
                plot.plot();\r
        }\r
 }
@@ -1298,7 +1388,7 @@ void
 PlotFileView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
 {
     if (m_canvas)
-      m_canvas->Refresh();
+               m_canvas->Refresh();
 }
 
 bool 
@@ -1312,14 +1402,14 @@ PlotFileView::OnClose (bool deleteWindow)
     m_canvas = NULL;
     wxString s(wxTheApp->GetAppName());
     if (m_frame)
-      m_frame->SetTitle(s);
+               m_frame->SetTitle(s);
     SetFrame(NULL);
        
     Activate(false);
     
     if (deleteWindow) {
-      delete m_frame;
-      return true;
+               delete m_frame;
+               return true;
     }
     return true;
 }
index 8a9bd79..12daabd 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: views.h,v 1.13 2000/12/20 14:39:09 kevin Exp $
+**  $Id: views.h,v 1.14 2000/12/20 20:08:48 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
@@ -216,6 +216,11 @@ private:
 
     PlotFileCanvas *m_canvas;
     wxFrame *m_frame;
+    bool m_bMinSpecified;\r
+    bool m_bMaxSpecified;\r
+    double m_dMinPixel;\r
+    double m_dMaxPixel;\r
+    double m_dAutoScaleFactor;\r
 
 public:
     PlotFileView(void);
@@ -226,6 +231,8 @@ public:
     void OnUpdate(wxView *sender, wxObject *hint = NULL);
     bool OnClose (bool deleteWindow = true);
     void OnProperties (wxCommandEvent& event);
+    void OnScaleAuto (wxCommandEvent& event);\r
+    void OnScaleMinMax (wxCommandEvent& event);\r
 
        wxFrame* getFrame ()
        { return m_frame; }