r626: no message
authorKevin M. Rosenberg <kevin@rosenberg.net>
Sat, 10 Mar 2001 23:14:16 +0000 (23:14 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Sat, 10 Mar 2001 23:14:16 +0000 (23:14 +0000)
14 files changed:
ChangeLog
NEWS
include/ezplot.h
include/plotfile.h
include/projections.h
libctgraphics/ezplot.cpp
libctgraphics/sgp.cpp
libctsim/projections.cpp
libctsim/scanner.cpp
libctsupport/plotfile.cpp
msvc/ctsim/ctsim.plg
src/ctsim.h
src/views.cpp
src/views.h

index a48e4cefc3500feeba0f4db91679efa87ae0c598..1467907a876c3574e0d7e81c8a0feaf70ce6e64d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,4 @@
-3.1.0 - Released 2//01
+3.5.0 - Released 2//01
 
        * ctsim: Added tips to be displayed at startup and via the help menu.
 
 
        * ctsim: Added tips to be displayed at startup and via the help menu.
 
@@ -17,6 +17,8 @@
 
        * ctsim: Added imagefile export to DICOM files.
 
 
        * ctsim: Added imagefile export to DICOM files.
 
+       * ctsim: Added plot t-theta sampling to projection file menu.
+       
        * ctsim: Added background and SMP processing for reconstructions. 
 
        * ctsim: Added background and SMP processing for scanning.
        * ctsim: Added background and SMP processing for reconstructions. 
 
        * ctsim: Added background and SMP processing for scanning.
diff --git a/NEWS b/NEWS
index 2da1deef76d3f455010eff6694059d53c2a83538..b2837f0cc79ca66e5c3444dad00b3c56dc5fb665 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,23 @@
+Version 3.5 New Features
+
+* Multithreading for running length processes in background. Also
+  takes advantage of multiple-CPU's in SMP systems for speed improvements
+  with parallel processing.
+
+* Import PNG, PPM, and PGM images
+
+* DICOM file import/export
+
+* Can read and reconstruct SIEMENS AR.STAR DICOM raw data files
+
+* Scattergram of T-Theta sampling.
+
+* Added startup-tips to help new users learn features.
+
+* Added ability to place detector at any arbitray position
+
+
+
 Version 3.0 New Features
 
 * Greatly improved dialog boxes
 Version 3.0 New Features
 
 * Greatly improved dialog boxes
index d605f92583e84d974ea416e2e4762d94f95e50bf..797d53cea0d864681736f35bde75d1b7a0a33e34 100644 (file)
@@ -7,7 +7,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: ezplot.h,v 1.25 2001/01/28 19:10:18 kevin Exp $
+**  $Id: ezplot.h,v 1.26 2001/03/10 23:14:15 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
 **
 **  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
@@ -84,6 +84,7 @@ enum {
  SB_BOX,
  SB_CIRCLE,
  SB_ERRORBAR,
  SB_BOX,
  SB_CIRCLE,
  SB_ERRORBAR,
+ SB_POINT,
  MAXSYMBOL,
 };
 
  MAXSYMBOL,
 };
 
index a11c330b25e865f5ba441dc1d14fa0d98fa74b30..ae74b62abc799e526b31113b1866194ee37c8f25 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: plotfile.h,v 1.8 2001/01/28 19:10:18 kevin Exp $
+**  $Id: plotfile.h,v 1.9 2001/03/10 23:14:15 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
 **
 **  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
@@ -60,7 +60,7 @@
 
 class PlotFile 
 {
 
 class PlotFile 
 {
- private:
+private:
   std::string m_strFilename;
   std::string m_strDate;
   std::vector<std::string> m_vecStrDescriptions;
   std::string m_strFilename;
   std::string m_strDate;
   std::vector<std::string> m_vecStrDescriptions;
@@ -68,68 +68,72 @@ class PlotFile
   std::vector<double> m_vecCurves;
   int m_iNumColumns;
   int m_iNumRecords;
   std::vector<double> m_vecCurves;
   int m_iNumColumns;
   int m_iNumRecords;
-
+  bool m_bScatterPlot;
+  
   bool headerRead (std::iostream& os);
   bool headerWrite (std::iostream& os);
   bool columnsRead (std::iostream& os);
   bool columnsWrite (std::iostream& os);
   bool headerRead (std::iostream& os);
   bool headerWrite (std::iostream& os);
   bool columnsRead (std::iostream& os);
   bool columnsWrite (std::iostream& os);
-
+  
   void initHeaders ();
   void initHeaders ();
-
+  
   PlotFile (const PlotFile& rhs);        // copy constructor
   PlotFile& operator= (const PlotFile&); // assignment operator
   PlotFile (const PlotFile& rhs);        // copy constructor
   PlotFile& operator= (const PlotFile&); // assignment operator
-
+  
 public:
   PlotFile (int iNColumns, int iNRecords);
   PlotFile (void);
   ~PlotFile ();
 public:
   PlotFile (int iNColumns, int iNRecords);
   PlotFile (void);
   ~PlotFile ();
-
-  void setCurveSize (int iNCurves, int iNRecords);
-
+  
+  void setCurveSize (int iNCurves, int iNRecords, bool bScatterPlot = false);
+  
   void addDescription (const char* const pszDesc)
   void addDescription (const char* const pszDesc)
-    { m_vecStrDescriptions.push_back (pszDesc); }
-
+  { m_vecStrDescriptions.push_back (pszDesc); }
+  
   void addEzsetCommand (const char* const pszCmd)
   void addEzsetCommand (const char* const pszCmd)
-    { m_vecStrEzsetCommands.push_back (pszCmd); }
+  { m_vecStrEzsetCommands.push_back (pszCmd); }
   
   bool addColumn (int iCol, const double* const pdColumn);
   
   bool addColumn (int iCol, const double* const pdColumn);
-
+  
   bool addColumn (int iCol, const float* const pdColumn);
   bool addColumn (int iCol, const float* const pdColumn);
-
+  
   void getColumn (int iCol, double *pdColumnData) const;
   void getColumn (int iCol, double *pdColumnData) const;
-
+  
   const std::string& getDate () const
   const std::string& getDate () const
-    { return m_strDate; }
-
+  { return m_strDate; }
+  
   int getNumColumns () const
   int getNumColumns () const
-    { return m_iNumColumns; }
-
+  { return m_iNumColumns; }
+  
   int getNumRecords () const
   int getNumRecords () const
-    { return m_iNumRecords; }
-
+  { return m_iNumRecords; }
+  
+  bool getIsScatterPlot() const
+  { return m_bScatterPlot; }
+  
   bool getMinMax (int startingCol, double& min, double& max) const;
   bool getMinMax (int startingCol, double& min, double& max) const;
-
+  
   bool statistics (int startingCol, double& min, double& max, double& mean, double& mode, double& median, double &stddev) const;
   bool statistics (int startingCol, double& min, double& max, double& mean, double& mode, double& median, double &stddev) const;
-
+  
   unsigned int getNumDescriptions (void) const
   unsigned int getNumDescriptions (void) const
-      { return m_vecStrDescriptions.size(); }
-
+  { return m_vecStrDescriptions.size(); }
+  
   const std::string& getDescription (int iDescIndex) const
   const std::string& getDescription (int iDescIndex) const
-    { return m_vecStrDescriptions[iDescIndex]; }
-
+  { return m_vecStrDescriptions[iDescIndex]; }
+  
   unsigned int getNumEzsetCommands (void) const
   unsigned int getNumEzsetCommands (void) const
-      { return m_vecStrEzsetCommands.size(); }
-
+  { return m_vecStrEzsetCommands.size(); }
+  
   const std::string& getEzsetCommand (int iIndex) const
   const std::string& getEzsetCommand (int iIndex) const
-    { return m_vecStrEzsetCommands[iIndex]; }
-
+  { return m_vecStrEzsetCommands[iIndex]; }
+  
   bool fileRead (const char* const filename);
   bool fileRead (const char* const filename);
-
+  
   bool fileWrite (const char* const filename);
   bool fileWrite (const char* const filename);
-
+  
   const std::string& getFilename (void) const 
   const std::string& getFilename (void) const 
-      {  return m_strFilename; }
-
+  {  return m_strFilename; }
+  
   void printHeaders (std::ostream& os) const;
   void printHeaders (std::ostringstream& os) const;
   void printHeadersBrief (std::ostream& os) const;
   void printHeaders (std::ostream& os) const;
   void printHeaders (std::ostringstream& os) const;
   void printHeadersBrief (std::ostream& os) const;
index 610cae76d3dc9b63189fba45a15e65739e3bfc9b..39cb09a7a67446a3723a7cb06a6921bc6ddc68a7 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: projections.h,v 1.27 2001/03/02 02:08:14 kevin Exp $
+**  $Id: projections.h,v 1.28 2001/03/10 23:14:15 kevin Exp $
 **
 **
 **  This program is free software; you can redistribute it and/or modify
 **
 **
 **  This program is free software; you can redistribute it and/or modify
@@ -38,6 +38,36 @@ class fnetorderstream;
 #include "imagefile.h"
 #include <complex>
 
 #include "imagefile.h"
 #include <complex>
 
+//used for rebinning divergent beam projections to parallel
+class ParallelRaysumCoordinate {  
+public:
+  double m_dT;      // Distance from center of origin
+  double m_dTheta;  // perpendicular angle to origin
+  int m_iViewNum;   // View number for this raysum
+  int m_iDetNum;    // Detector number for this raysum
+
+  bool lessThanT (ParallelRaysumCoordinate& rCompare)
+  {return m_dT < rCompare.m_dT; }
+  bool lessThanTheta (ParallelRaysumCoordinate& rCompare)
+  {return m_dTheta < rCompare.m_dTheta; }
+};
+
+class ParallelRaysums {
+private:
+  ParallelRaysumCoordinate** m_ppCoordinates;
+  int m_iNumCoordinates;
+
+public:
+  ParallelRaysums (Projections* pProjections);
+  ~ParallelRaysums ();
+
+  ParallelRaysumCoordinate** getCoordinates() {return m_ppCoordinates;}
+  int getNumCoordinates() const {return m_iNumCoordinates;}
+  void getLimits (double* dMinT, double* dMaxT, double* dMinTheta, double* dMaxTheta) const;
+};
+
+
+
 // Projections
 class Projections
 {
 // Projections
 class Projections
 {
@@ -74,6 +104,8 @@ class Projections
   bool detarrayRead (fnetorderstream& fs, DetectorArray& darray, const int view_num);
   bool detarrayWrite (fnetorderstream& fs, const DetectorArray& darray, const int view_num);
 
   bool detarrayRead (fnetorderstream& fs, DetectorArray& darray, const int view_num);
   bool detarrayWrite (fnetorderstream& fs, const DetectorArray& darray, const int view_num);
 
+  bool interpolateToParallel();
+
   bool convertPolar (ImageFile& rIF, int iInterpolation);
   bool convertFFTPolar (ImageFile& rIF, int iInterpolation, int iZeropad);
   bool calcArrayPolarCoordinates (unsigned int nx, unsigned int ny, double** ppdView, double** ppdDet);
   bool convertPolar (ImageFile& rIF, int iInterpolation);
   bool convertFFTPolar (ImageFile& rIF, int iInterpolation, int iZeropad);
   bool calcArrayPolarCoordinates (unsigned int nx, unsigned int ny, double** ppdView, double** ppdDet);
index ed1ca233d26ef8e8c02e967e78717935a77b64bd..79a4ebbb908c226babb1f72f2e54e03b16d0a328 100644 (file)
@@ -6,7 +6,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: ezplot.cpp,v 1.31 2001/02/20 04:48:45 kevin Exp $
+**  $Id: ezplot.cpp,v 1.32 2001/03/10 23:14:16 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
 **
 **  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
@@ -466,14 +466,11 @@ EZPlot::getLegend (unsigned int iCurve) const
 void
 EZPlot::plot (SGP* pSGP)
 {
 void
 EZPlot::plot (SGP* pSGP)
 {
-
   if (m_vecCurves.size() <= 0)
     return;
   
   if (m_vecCurves.size() <= 0)
     return;
   
-
   m_pSGP = pSGP;
 
   m_pSGP = pSGP;
 
-
   m_pSGP->setWindow (0., 0., 1., 1.);
   
   if (s_textsize == TRUE)
   m_pSGP->setWindow (0., 0., 1., 1.);
   
   if (s_textsize == TRUE)
@@ -481,6 +478,8 @@ EZPlot::plot (SGP* pSGP)
 
   charheight = m_pSGP->getCharHeight();
   charwidth = m_pSGP->getCharWidth();
 
   charheight = m_pSGP->getCharHeight();
   charwidth = m_pSGP->getCharWidth();
+  double symheight = charheight * 0.3;       // size of symbol in NDC 
+  double symwidth = symheight;
  
   const EZPlotCurve& firstCurve = *m_vecCurves[0];
 
  
   const EZPlotCurve& firstCurve = *m_vecCurves[0];
 
@@ -668,7 +667,7 @@ EZPlot::plot (SGP* pSGP)
         m_pSGP->setLineStyle (SGP::LS_SOLID);
         for (int j = 0; j < 5; j++) {
           m_pSGP->moveAbs (xmin + j * xinc, y);
         m_pSGP->setLineStyle (SGP::LS_SOLID);
         for (int j = 0; j < 5; j++) {
           m_pSGP->moveAbs (xmin + j * xinc, y);
-          symbol(iSymbol, 0.5 * charwidth, 0.5 * charheight);
+          symbol (iSymbol, symwidth, symheight);
         }
       }
       ++iLegend;       // move to next legend position 
         }
       }
       ++iLegend;       // move to next legend position 
@@ -816,10 +815,6 @@ EZPlot::plot (SGP* pSGP)
   m_pSGP->setLineStyle (SGP::LS_SOLID);
   drawAxes();
   
   m_pSGP->setLineStyle (SGP::LS_SOLID);
   drawAxes();
   
-  // size of symbol in NDC 
-  double symwidth = charwidth;
-  double symheight = charheight;
-  
 
   double clipRect[4];
 
 
   double clipRect[4];
 
@@ -847,27 +842,18 @@ EZPlot::plot (SGP* pSGP)
       for (int i = 1; i < pCurve->m_iPointCount; i++) {
         double x2 = convertWorldToNDC_X (pCurve->x[i]);
         double y2 = convertWorldToNDC_Y (pCurve->y[i]);
       for (int i = 1; i < pCurve->m_iPointCount; i++) {
         double x2 = convertWorldToNDC_X (pCurve->x[i]);
         double y2 = convertWorldToNDC_Y (pCurve->y[i]);
-
         double x2Clip = x2;
         double x2Clip = x2;
-
         double y2Clip = y2;
 
         if (clip_rect (x1, y1, x2Clip, y2Clip, clipRect)) {
         double y2Clip = y2;
 
         if (clip_rect (x1, y1, x2Clip, y2Clip, clipRect)) {
-
           m_pSGP->moveAbs (x1, y1);
           m_pSGP->moveAbs (x1, y1);
-
           m_pSGP->lineAbs (x2Clip, y2Clip);
           m_pSGP->lineAbs (x2Clip, y2Clip);
-
         }
         }
-
         x1 = x2;
         x1 = x2;
-
         y1 = y2;
         y1 = y2;
-
       } 
     }
     if (iSym > 0) {
       } 
     }
     if (iSym > 0) {
-
       int iSymFreq = getSymbolFreq (iCurve);
       m_pSGP->setLineStyle (SGP::LS_SOLID);
       double x = convertWorldToNDC_X (pCurve->x[0]);
       int iSymFreq = getSymbolFreq (iCurve);
       m_pSGP->setLineStyle (SGP::LS_SOLID);
       double x = convertWorldToNDC_X (pCurve->x[0]);
@@ -1144,6 +1130,8 @@ EZPlot::symbol (int sym, double symwidth, double symheight)
     m_pSGP->moveRel (-0.5 * symwidth, 0.0);
     m_pSGP->lineRel (symwidth, 0.0);
     m_pSGP->moveRel (-0.5 * symwidth, 0.5 * symheight);
     m_pSGP->moveRel (-0.5 * symwidth, 0.0);
     m_pSGP->lineRel (symwidth, 0.0);
     m_pSGP->moveRel (-0.5 * symwidth, 0.5 * symheight);
+  } else if (sym == SB_POINT) {
+    m_pSGP->pointRel (0, 0);
   }
 }
 
   }
 }
 
index 275a955bfbf031b24891351eb25e6e9830d57695..57904a621f9a64120b4c210ef33db6fd84743438 100644 (file)
@@ -7,7 +7,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: sgp.cpp,v 1.29 2001/01/28 19:10:18 kevin Exp $
+**  $Id: sgp.cpp,v 1.30 2001/03/10 23:14:16 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
 **
 **  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
@@ -175,6 +175,17 @@ SGP::markerNDC (double x, double y)
 void
 SGP::pointNDC (double x, double y)
 {
 void
 SGP::pointNDC (double x, double y)
 {
+  int xp = static_cast<int>(x * (m_iPhysicalXSize - 1) + 0.5);
+  int yp = static_cast<int>(y * (m_iPhysicalYSize - 1) + 0.5);
+  if (m_driver.isWX())
+    yp = m_iPhysicalYSize - yp;
+
+#if HAVE_WXWINDOWS
+    if (m_driver.isWX())
+      m_driver.idWX()->DrawPoint (xp, yp);
+#endif
+  m_iCurrentPhysicalX = xp;
+  m_iCurrentPhysicalY = yp;
 }
 
 
 }
 
 
@@ -657,7 +668,6 @@ SGP::pointAbs (double x, double y)
   double xndc = x, yndc = y;
   mc_to_ndc.transformPoint (&xndc, &yndc);
   pointNDC (xndc, yndc);
   double xndc = x, yndc = y;
   mc_to_ndc.transformPoint (&xndc, &yndc);
   pointNDC (xndc, yndc);
-  stylusNDC (xndc, yndc, false);            // move to location 
   m_dCurrentWorldX = x;
   m_dCurrentWorldY = y;
 }
   m_dCurrentWorldX = x;
   m_dCurrentWorldY = y;
 }
@@ -746,31 +756,31 @@ SGP::drawArc (const double r, double start, double stop)
     stop = temp;
   }
 
     stop = temp;
   }
 
-  double x = r * cos ((double) start);
-  double y = r * sin ((double) start);
-  moveRel (x, y);          // move from center to start of arc 
+  double xCent = m_dCurrentWorldX;
+  double yCent = m_dCurrentWorldY;
+
+  double x = r * cos (start);
+  double y = r * sin (start);
+  moveAbs (xCent + x, yCent + y);          // move from center to start of arc 
 
 
-  const double thetaIncrement = (5 * (TWOPI / 360)); 
-  double cosTheta = cos(thetaIncrement);
-  double sinTheta = sin(thetaIncrement);
+  const double thetaIncrement = (5 * (TWOPI / 360));  // 5 degree increments
+  double cosTheta = cos (thetaIncrement);
+  double sinTheta = sin (thetaIncrement);
 
 
-  double angle, xp, yp;
-  for (angle = start; angle < stop - thetaIncrement; angle += thetaIncrement) {
-    xp = cosTheta * x - sinTheta * y; // translate point by thetaIncrement
-    yp = sinTheta * x + cosTheta * y;
-    lineAbs (xp, yp);
+  for (double angle = start; angle < stop; angle += thetaIncrement) {
+    double xp = cosTheta * x - sinTheta * y; // translate point by thetaIncrement
+    double yp = sinTheta * x + cosTheta * y;
+    lineAbs (xCent + xp, yCent + yp);
     x = xp; y = yp;
   }
 
   double c = cos (stop - angle);
   double s = sin (stop - angle);
     x = xp; y = yp;
   }
 
   double c = cos (stop - angle);
   double s = sin (stop - angle);
-  xp = c * x - s * y;
-  yp = s * x + c * y;
-  lineAbs (xp, yp);
+  double xp = c * x - s * y;
+  double yp = s * x + c * y;
+  lineAbs (xCent + xp, yCent + yp);
 
 
-  x = r * cos (stop);
-  y = r * sin (stop);
-  moveRel (-x, -y);            // move back to center of circle 
+  moveAbs (xCent, yCent);              // move back to center of circle 
 }
 
 
 }
 
 
index 627ccb91f11ba32f85e8feabbca0297487f57509..b3d6d35b2df647b5595d60c01bebcf30771af957 100644 (file)
@@ -8,7 +8,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: projections.cpp,v 1.54 2001/03/05 21:59:55 kevin Exp $
+**  $Id: projections.cpp,v 1.55 2001/03/10 23:14:16 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
 **
 **  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
@@ -687,6 +687,11 @@ Projections::convertPolar (ImageFile& rIF, int iInterpolationID)
 
   if (! v || nx == 0 || ny == 0)
     return false;
 
   if (! v || nx == 0 || ny == 0)
     return false;
+
+  if (m_geometry != Scanner::GEOMETRY_PARALLEL) {
+    sys_error (ERR_WARNING, "convertPolar supports Parallel only");
+    return false;
+  }
   
   Array2d<double> adView (nx, ny);
   Array2d<double> adDet (nx, ny);
   
   Array2d<double> adView (nx, ny);
   Array2d<double> adDet (nx, ny);
@@ -727,6 +732,11 @@ Projections::convertFFTPolar (ImageFile& rIF, int iInterpolationID, int iZeropad
   if (! v || nx == 0 || ny == 0)
     return false;
   
   if (! v || nx == 0 || ny == 0)
     return false;
   
+  if (m_geometry != Scanner::GEOMETRY_PARALLEL) {
+    sys_error (ERR_WARNING, "convertFFTPolar supports Parallel only");
+    return false;
+  }
+  
 #ifndef HAVE_FFT
   return false;
 #else
 #ifndef HAVE_FFT
   return false;
 #else
@@ -784,11 +794,6 @@ Projections::calcArrayPolarCoordinates (unsigned int nx, unsigned int ny, double
   
   int iDetCenter = (m_nDet - 1) / 2;   // index refering to L=0 projection 
 
   
   int iDetCenter = (m_nDet - 1) / 2;   // index refering to L=0 projection 
 
-  if (m_geometry != Scanner::GEOMETRY_PARALLEL) {
-    sys_error (ERR_WARNING, "convertPolar supports Parallel only");
-    return false;
-  }
-  
   // Calculates polar coordinates (view#, det#) for each point on phantom grid
   double x = xMin + xInc / 2;  // Rectang coords of center of pixel 
   for (unsigned int ix = 0; ix < nx; x += xInc, ix++) {
   // Calculates polar coordinates (view#, det#) for each point on phantom grid
   double x = xMin + xInc / 2;  // Rectang coords of center of pixel 
   for (unsigned int ix = 0; ix < nx; x += xInc, ix++) {
@@ -952,7 +957,7 @@ Projections::initFromSomatomAR_STAR (int iNViews, int iNDets, unsigned char* pDa
     double dTempScale = 2294.4871 * dEScale;
     for (int id = 0; id < iNDets; id++) {
       int iV = pData[lDataPos+1] + 256 * pData[lDataPos];
     double dTempScale = 2294.4871 * dEScale;
     for (int id = 0; id < iNDets; id++) {
       int iV = pData[lDataPos+1] + 256 * pData[lDataPos];
-      if (iV > 32767)
+      if (iV > 32767)   // two's complement signed conversion
         iV = iV - 65536;
       double dCosScale = cos ((id + 1 - iCenter) * dBetaInc);
       detval[id] = iV / (dTempScale * dCosScale);
         iV = iV - 65536;
       double dCosScale = cos ((id + 1 - iCenter) * dBetaInc);
       detval[id] = iV / (dTempScale * dCosScale);
@@ -963,3 +968,74 @@ Projections::initFromSomatomAR_STAR (int iNViews, int iNDets, unsigned char* pDa
   return true;
 }
 
   return true;
 }
 
+
+ParallelRaysums::ParallelRaysums (Projections* pProjections)
+: m_ppCoordinates(NULL), m_iNumCoordinates(0)
+{
+  int nDet = pProjections->nDet();
+  int nView = pProjections->nView();
+  int iGeometry = pProjections->geometry();
+  double dDetInc = pProjections->detInc();
+  double dDetStart = pProjections->detStart();
+  double dFocalLength = pProjections->focalLength();
+
+  m_iNumCoordinates =  nDet * nView;
+  m_ppCoordinates = new ParallelRaysumCoordinate* [m_iNumCoordinates];
+  for (int i = 0; i < m_iNumCoordinates; i++)
+    m_ppCoordinates[i] = new ParallelRaysumCoordinate;
+
+  ParallelRaysumCoordinate** ppCurrentCoordinate = m_ppCoordinates;
+
+  for (int iV = 0; iV < nView; iV++) {
+    double dViewAngle = pProjections->getDetectorArray(iV).viewAngle();
+    for (int iD = 0; iD < nDet; iD++) {
+      ParallelRaysumCoordinate* pC = *ppCurrentCoordinate;
+      if (iGeometry == Scanner::GEOMETRY_PARALLEL) {
+        pC->m_dTheta = dViewAngle;
+        pC->m_dT = dDetStart + (iD * dDetInc);
+      } else if (iGeometry == Scanner::GEOMETRY_EQUILINEAR) {
+        double dDetPos = dDetStart + (iD * dDetInc);
+        double dFanAngle = atan (dDetPos / pProjections->sourceDetectorLength());
+        pC->m_dTheta = dViewAngle + dFanAngle;
+        pC->m_dT = dFocalLength * sin(dFanAngle);        
+      } else if (iGeometry == Scanner::GEOMETRY_EQUIANGULAR) {
+        double dFanAngle = dDetStart + (iD * dDetInc);
+        pC->m_dTheta = dViewAngle + dFanAngle;
+        pC->m_dT = dFocalLength * sin(dFanAngle);        
+      }
+      ++ppCurrentCoordinate;
+    }
+  }
+}
+
+ParallelRaysums::~ParallelRaysums()
+{
+  for (int i = 0; i < m_iNumCoordinates; i++)
+    delete m_ppCoordinates[i];
+
+  delete m_ppCoordinates;
+}
+
+void
+ParallelRaysums::getLimits (double* dMinT, double* dMaxT, double* dMinTheta, double* dMaxTheta) const
+{
+  if (m_iNumCoordinates <= 0)
+    return;
+
+  *dMinT = *dMaxT = m_ppCoordinates[0]->m_dT;
+  *dMinTheta = *dMaxTheta = m_ppCoordinates[0]->m_dTheta;
+
+  for (int i = 0; i < m_iNumCoordinates; i++) {
+    double dT = m_ppCoordinates[i]->m_dT;
+    double dTheta = m_ppCoordinates[i]->m_dTheta;
+    if (dT < *dMinT)
+      *dMinT = dT;
+    else if (dT > *dMaxT)
+      *dMaxT = dT;
+
+    if (dTheta < *dMinTheta)
+      *dMinTheta = dTheta;
+    else if (dTheta > *dMaxTheta)
+      *dMaxTheta = dTheta;
+  }
+}
index 2314595219d76c45801d1a8dbf8a57f91de10f05..ff3cd9af366833c74a3e7e3e52641aeeaaa43a2b 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: scanner.cpp,v 1.33 2001/03/01 07:30:49 kevin Exp $
+**  $Id: scanner.cpp,v 1.34 2001/03/10 23:14:16 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
 **
 **  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
@@ -188,8 +188,10 @@ Scanner::Scanner (const Phantom& phm, const char* const geometryName,
       m_detInc = m_detLen / (m_nDet - 1); // center detector = (nDet/2)
       dDetectorArrayEndOffset = m_detInc;
     }
       m_detInc = m_detLen / (m_nDet - 1); // center detector = (nDet/2)
       dDetectorArrayEndOffset = m_detInc;
     }
+    // adjust for center-detector length
     double dA1 = acos ((m_dScanDiameter / 2) / m_dCenterDetectorLength);
     double dAngularScale = 2 * (HALFPI + dAngle - dA1) / m_detLen;
     double dA1 = acos ((m_dScanDiameter / 2) / m_dCenterDetectorLength);
     double dAngularScale = 2 * (HALFPI + dAngle - dA1) / m_detLen;
+
     m_dAngularDetLen = dAngularScale * (m_detLen + dDetectorArrayEndOffset);
     m_dAngularDetIncrement = dAngularScale * m_detInc;
     m_initPos.dAngularDet = -m_dAngularDetLen / 2;
     m_dAngularDetLen = dAngularScale * (m_detLen + dDetectorArrayEndOffset);
     m_dAngularDetIncrement = dAngularScale * m_detInc;
     m_initPos.dAngularDet = -m_dAngularDetLen / 2;
index 81682b9187488e1e41dd5bc91ce323a7e7c023bd..a99bf1d80cf356cc3af8be2f05ed363838b2554e 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: plotfile.cpp,v 1.12 2001/01/28 19:10:18 kevin Exp $
+**  $Id: plotfile.cpp,v 1.13 2001/03/10 23:14:16 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
 **
 **  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
@@ -64,17 +64,17 @@ PlotFile::initHeaders ()
 }
 
 void
 }
 
 void
-PlotFile::setCurveSize (int nCols, int nRecords)
+PlotFile::setCurveSize (int nCols, int nRecords, bool bScatterPlot)
 {
   m_iNumColumns = nCols;
   m_iNumRecords = nRecords;
 {
   m_iNumColumns = nCols;
   m_iNumRecords = nRecords;
+  m_bScatterPlot = bScatterPlot;
   m_vecCurves.clear();
   m_vecCurves.reserve (m_iNumColumns * m_iNumRecords);
 }
 
 // Storage format
 //   a Column's records are stored sequentially. It begins at iCol * m_iNumRecords
   m_vecCurves.clear();
   m_vecCurves.reserve (m_iNumColumns * m_iNumRecords);
 }
 
 // Storage format
 //   a Column's records are stored sequentially. It begins at iCol * m_iNumRecords
-
 bool
 PlotFile::addColumn (int iCol, const double* const pdColData)
 {
 bool
 PlotFile::addColumn (int iCol, const double* const pdColData)
 {
index c45df02db374f62570e74020ecd874ae6a2aad56..375e1028b16f6ac93a1e1020eb1323356cc4e647 100644 (file)
@@ -3,30 +3,67 @@
 <pre>
 <h1>Build Log</h1>
 <h3>
 <pre>
 <h1>Build Log</h1>
 <h3>
---------------------Configuration: ctsim - Win32 Debug--------------------
+--------------------Configuration: libctsim - Win32 Debug--------------------
 </h3>
 <h3>Command Lines</h3>
 </h3>
 <h3>Command Lines</h3>
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP49.tmp" with contents
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1B8.tmp" with contents
+[
+/nologo /G6 /MTd /W3 /Gm /Gi /GR /GX /Zi /Od /Gy /I "..\..\..\wx2.2.5\src\png" /I "..\..\..\wx2.2.5\src\zlib" /I "..\..\INCLUDE" /I "..\..\getopt" /I "..\..\..\fftw-2.1.3\fftw" /I "..\..\..\fftw-2.1.3\rfftw" /I "..\..\..\wx2.2.5\include" /I "\dicom\ctn\include" /D "_DEBUG" /D "HAVE_WXWIN" /D "HAVE_STRING_H" /D "HAVE_GETOPT_H" /D "WIN32" /D "_MBCS" /D "_LIB" /D "MSVC" /D "HAVE_FFTW" /D "HAVE_PNG" /D "HAVE_SGP" /D "HAVE_WXWINDOWS" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "HAVE_CTN_DICOM" /D VERSION=\"3.1.0\" /FR"Debug/" /Fp"Debug/libctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 
+"C:\ctsim\libctgraphics\ezplot.cpp"
+]
+Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1B8.tmp" 
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1B9.tmp" with contents
 [
 [
-/nologo /G6 /MTd /W3 /Gm /Gi /GR /GX /Zi /Od /Gy /I "\wx2.2.5\include" /I "..\..\..\fftw-2.1.3\fftw" /I "\wx2.2.5\src\png" /I "\wx2.2.5\src\zlib" /I "..\..\include" /I "..\..\getopt" /I "..\..\..\fftw-2.1.3\rfftw" /I "\dicom\ctn\include" /D VERSION=\"3.0.0beta1\" /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=\"3.1.0\" /D "HAVE_CTN_DICOM" /FR"Debug/" /Fp"Debug/ctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 
-"C:\ctsim\src\backgroundmgr.cpp"
-"C:\ctsim\src\backgroundsupr.cpp"
-"C:\ctsim\src\graph3dview.cpp"
-"C:\ctsim\src\threadproj.cpp"
-"C:\ctsim\src\threadraster.cpp"
-"C:\ctsim\src\threadrecon.cpp"
+/nologo /out:"Debug\libctsim.lib" 
+.\Debug\array2dfile.obj
+.\Debug\backprojectors.obj
+.\Debug\clip.obj
+.\Debug\consoleio.obj
+.\Debug\ctndicom.obj
+.\Debug\dlgezplot.obj
+.\Debug\ezplot.obj
+.\Debug\ezset.obj
+.\Debug\ezsupport.obj
+.\Debug\filter.obj
+.\Debug\fnetorderstream.obj
+.\Debug\fourier.obj
+.\Debug\getopt.obj
+.\Debug\getopt1.obj
+.\Debug\globalvars.obj
+.\Debug\hashtable.obj
+.\Debug\imagefile.obj
+.\Debug\interpolator.obj
+.\Debug\mathfuncs.obj
+.\Debug\phantom.obj
+.\Debug\plotfile.obj
+.\Debug\pol.obj
+.\Debug\procsignal.obj
+.\Debug\projections.obj
+.\Debug\reconstruct.obj
+.\Debug\scanner.obj
+.\Debug\sgp.obj
+.\Debug\strfuncs.obj
+.\Debug\syserror.obj
+.\Debug\trace.obj
+.\Debug\transformmatrix.obj
+.\Debug\xform.obj
 ]
 ]
-Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP49.tmp" 
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP4A.tmp" with contents
+Creating command line "link.exe -lib @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1B9.tmp"
+<h3>Output Window</h3>
+Compiling...
+ezplot.cpp
+Creating library...
+<h3>
+--------------------Configuration: ctsim - Win32 Debug--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1BA.tmp" with contents
 [
 /nologo /G6 /MTd /W3 /Gm /Gi /GR /GX /Zi /Od /Gy /I "\wx2.2.5\include" /I "..\..\..\fftw-2.1.3\fftw" /I "\wx2.2.5\src\png" /I "\wx2.2.5\src\zlib" /I "..\..\include" /I "..\..\getopt" /I "..\..\..\fftw-2.1.3\rfftw" /I "\dicom\ctn\include" /D VERSION=\"3.0.0beta1\" /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=\"3.1.0\" /D "HAVE_CTN_DICOM" /D CTSIMVERSION=\"3.0.0alpha5\" /FR"Debug/" /Fp"Debug/ctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 
 [
 /nologo /G6 /MTd /W3 /Gm /Gi /GR /GX /Zi /Od /Gy /I "\wx2.2.5\include" /I "..\..\..\fftw-2.1.3\fftw" /I "\wx2.2.5\src\png" /I "\wx2.2.5\src\zlib" /I "..\..\include" /I "..\..\getopt" /I "..\..\..\fftw-2.1.3\rfftw" /I "\dicom\ctn\include" /D VERSION=\"3.0.0beta1\" /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=\"3.1.0\" /D "HAVE_CTN_DICOM" /D CTSIMVERSION=\"3.0.0alpha5\" /FR"Debug/" /Fp"Debug/ctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 
-"C:\ctsim\src\ctsim.cpp"
-"C:\ctsim\src\dialogs.cpp"
-"C:\ctsim\src\docs.cpp"
 "C:\ctsim\src\views.cpp"
 ]
 "C:\ctsim\src\views.cpp"
 ]
-Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP4A.tmp" 
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP4B.tmp" with contents
+Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1BA.tmp" 
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1BB.tmp" with contents
 [
 winmm.lib rpcrt4.lib ws2_32.lib ../libctsim/Debug/libctsim.lib libcmtd.lib ..\..\..\fftw-2.1.3\Win32\FFTW2st\Debug\FFTW2st.lib ..\..\..\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib wxd.lib xpmd.lib tiffd.lib zlibd.lib pngd.lib comctl32.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 opengl32.lib glu32.lib htmlhelp.lib ctn_lib.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/ctsim.pdb" /debug /machine:I386 /out:"Debug/ctsim.exe" /pdbtype:sept /libpath:"\wx2.2.5\lib" /libpath:"\dicom\ctn\winctn\ctn_lib\Debug" 
 .\Debug\backgroundmgr.obj
 [
 winmm.lib rpcrt4.lib ws2_32.lib ../libctsim/Debug/libctsim.lib libcmtd.lib ..\..\..\fftw-2.1.3\Win32\FFTW2st\Debug\FFTW2st.lib ..\..\..\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib wxd.lib xpmd.lib tiffd.lib zlibd.lib pngd.lib comctl32.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 opengl32.lib glu32.lib htmlhelp.lib ctn_lib.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/ctsim.pdb" /debug /machine:I386 /out:"Debug/ctsim.exe" /pdbtype:sept /libpath:"\wx2.2.5\lib" /libpath:"\dicom\ctn\winctn\ctn_lib\Debug" 
 .\Debug\backgroundmgr.obj
@@ -53,19 +90,9 @@ winmm.lib rpcrt4.lib ws2_32.lib ../libctsim/Debug/libctsim.lib libcmtd.lib ..\..
 \wx2.2.5\lib\zlibd.lib
 \wx2.2.5\lib\tiffd.lib
 ]
 \wx2.2.5\lib\zlibd.lib
 \wx2.2.5\lib\tiffd.lib
 ]
-Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP4B.tmp"
+Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1BB.tmp"
 <h3>Output Window</h3>
 Compiling...
 <h3>Output Window</h3>
 Compiling...
-backgroundmgr.cpp
-backgroundsupr.cpp
-threadraster.cpp
-graph3dview.cpp
-threadproj.cpp
-threadrecon.cpp
-Compiling...
-ctsim.cpp
-dialogs.cpp
-docs.cpp
 views.cpp
 Linking...
 
 views.cpp
 Linking...
 
index ee871cbf3e4d794a7f090174d0e73cd1d2d4c558..7ced875d3c5ab3ab044b2d6d8633c5f90c7aafee 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: ctsim.h,v 1.55 2001/03/04 03:14:47 kevin Exp $
+**  $Id: ctsim.h,v 1.56 2001/03/10 23:14:16 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
 **
 **  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
@@ -309,6 +309,7 @@ enum {
     PJMENU_RECONSTRUCT_FOURIER,
     PJMENU_CONVERT_POLAR,
     PJMENU_CONVERT_FFT_POLAR,
     PJMENU_RECONSTRUCT_FOURIER,
     PJMENU_CONVERT_POLAR,
     PJMENU_CONVERT_FFT_POLAR,
+    PJMENU_PLOT_TTHETA_SAMPLING,
     
     IFMENU_FILE_EXPORT,
     IFMENU_FILE_PROPERTIES,
     
     IFMENU_FILE_EXPORT,
     IFMENU_FILE_PROPERTIES,
index 54a12b8d764ea05f6d96d71015de8215fe3283cb..6f55604e11f4c69ee725b19455e897d1c148c66a 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: views.cpp,v 1.129 2001/03/07 22:30:16 kevin Exp $
+**  $Id: views.cpp,v 1.130 2001/03/10 23:14:16 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
 **
 **  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
@@ -2277,6 +2277,7 @@ EVT_MENU(PJMENU_RECONSTRUCT_FBP, ProjectionFileView::OnReconstructFBP)
 EVT_MENU(PJMENU_RECONSTRUCT_FOURIER, ProjectionFileView::OnReconstructFourier)
 EVT_MENU(PJMENU_CONVERT_POLAR, ProjectionFileView::OnConvertPolar)
 EVT_MENU(PJMENU_CONVERT_FFT_POLAR, ProjectionFileView::OnConvertFFTPolar)
 EVT_MENU(PJMENU_RECONSTRUCT_FOURIER, ProjectionFileView::OnReconstructFourier)
 EVT_MENU(PJMENU_CONVERT_POLAR, ProjectionFileView::OnConvertPolar)
 EVT_MENU(PJMENU_CONVERT_FFT_POLAR, ProjectionFileView::OnConvertFFTPolar)
+EVT_MENU(PJMENU_PLOT_TTHETA_SAMPLING, ProjectionFileView::OnPlotTThetaSampling)
 END_EVENT_TABLE()
 
 ProjectionFileView::ProjectionFileView() 
 END_EVENT_TABLE()
 
 ProjectionFileView::ProjectionFileView() 
@@ -2342,11 +2343,14 @@ ProjectionFileView::OnConvertPolar (wxCommandEvent& event)
     ImageFileDocument* pPolarDoc = theApp->newImageDoc();
     ImageFile* pIF = new ImageFile (m_iDefaultPolarNX, m_iDefaultPolarNY);
     m_iDefaultPolarInterpolation = Projections::convertInterpNameToID (strInterpolation.c_str());
     ImageFileDocument* pPolarDoc = theApp->newImageDoc();
     ImageFile* pIF = new ImageFile (m_iDefaultPolarNX, m_iDefaultPolarNY);
     m_iDefaultPolarInterpolation = Projections::convertInterpNameToID (strInterpolation.c_str());
-    if (! rProj.convertPolar (*pIF, m_iDefaultPolarInterpolation)) {
+    
+  if (! rProj.convertPolar (*pIF, m_iDefaultPolarInterpolation)) {
       delete pIF;
       *theApp->getLog() << "Error converting to Polar\n";
       return;
     }
       delete pIF;
       *theApp->getLog() << "Error converting to Polar\n";
       return;
     }
+
+
     pPolarDoc = theApp->newImageDoc ();
     if (! pPolarDoc) {
       sys_error (ERR_SEVERE, "Unable to create image file");
     pPolarDoc = theApp->newImageDoc ();
     if (! pPolarDoc) {
       sys_error (ERR_SEVERE, "Unable to create image file");
@@ -2408,6 +2412,43 @@ ProjectionFileView::OnConvertFFTPolar (wxCommandEvent& event)
   }
 }
 
   }
 }
 
+void
+ProjectionFileView::OnPlotTThetaSampling (wxCommandEvent& event)
+{
+  Projections& rProj = GetDocument()->getProjections();
+    ParallelRaysums parallel (&rProj);
+    PlotFileDocument* pPlotDoc = theApp->newPlotDoc();
+    PlotFile& rPlot = pPlotDoc->getPlotFile();
+    ParallelRaysumCoordinate** ppCoord = parallel.getCoordinates();
+    double* pdT = new double [parallel.getNumCoordinates()];
+    double* pdTheta = new double [parallel.getNumCoordinates()];
+    for (int i = 0; i < parallel.getNumCoordinates(); i++) {
+      pdT[i] = (*ppCoord)->m_dT;
+      pdTheta[i] = (*ppCoord)->m_dTheta;
+      ++ppCoord;
+    }
+    rPlot.setCurveSize (2, parallel.getNumCoordinates(), true);
+    rPlot.addEzsetCommand ("title T-Theta Sampling");
+    rPlot.addEzsetCommand ("xlabel T");
+    rPlot.addEzsetCommand ("ylabel Theta");
+    rPlot.addEzsetCommand ("curve 1");
+    if (rProj.nDet() < 50 && rProj.nView() < 50)
+      rPlot.addEzsetCommand ("symbol 1"); // x symbol
+    else
+      rPlot.addEzsetCommand ("symbol 6"); // point symbol
+    rPlot.addEzsetCommand ("noline");
+    rPlot.addColumn (0, pdT);
+    rPlot.addColumn (1, pdTheta);
+    delete pdT;
+    delete pdTheta;
+    if (theApp->getAskDeleteNewDocs())
+      pPlotDoc->Modify (true);
+    pPlotDoc->UpdateAllViews ();
+    pPlotDoc->getView()->OnUpdate (this, NULL);
+    pPlotDoc->getView()->getFrame()->Show(true);
+    return;
+}
+
 void
 ProjectionFileView::OnReconstructFourier (wxCommandEvent& event)
 {
 void
 ProjectionFileView::OnReconstructFourier (wxCommandEvent& event)
 {
@@ -2590,7 +2631,10 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   wxMenu *convert_menu = new wxMenu;
   convert_menu->Append (PJMENU_CONVERT_POLAR, "&Polar Image...\tCtrl-L");
   convert_menu->Append (PJMENU_CONVERT_FFT_POLAR, "&FFT->Polar Image...\tCtrl-M");
   wxMenu *convert_menu = new wxMenu;
   convert_menu->Append (PJMENU_CONVERT_POLAR, "&Polar Image...\tCtrl-L");
   convert_menu->Append (PJMENU_CONVERT_FFT_POLAR, "&FFT->Polar Image...\tCtrl-M");
-  
+
+  wxMenu* analyze_menu = new wxMenu;
+  analyze_menu->Append (PJMENU_PLOT_TTHETA_SAMPLING, "&Plot T-Theta Sampling\tCtrl-T");
+
   wxMenu *reconstruct_menu = new wxMenu;
   reconstruct_menu->Append (PJMENU_RECONSTRUCT_FBP, "&Filtered Backprojection...\tCtrl-R", "Reconstruct image using filtered backprojection");
   reconstruct_menu->Append (PJMENU_RECONSTRUCT_FOURIER, "&Fourier...\tCtrl-E", "Reconstruct image using inverse Fourier");
   wxMenu *reconstruct_menu = new wxMenu;
   reconstruct_menu->Append (PJMENU_RECONSTRUCT_FBP, "&Filtered Backprojection...\tCtrl-R", "Reconstruct image using filtered backprojection");
   reconstruct_menu->Append (PJMENU_RECONSTRUCT_FOURIER, "&Fourier...\tCtrl-E", "Reconstruct image using inverse Fourier");
@@ -2606,19 +2650,21 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   
   menu_bar->Append (m_pFileMenu, "&File");
   menu_bar->Append (convert_menu, "&Convert");
   
   menu_bar->Append (m_pFileMenu, "&File");
   menu_bar->Append (convert_menu, "&Convert");
+  menu_bar->Append (analyze_menu, "&Analyze");
   menu_bar->Append (reconstruct_menu, "&Reconstruct");
   menu_bar->Append (help_menu, "&Help");
   
   subframe->SetMenuBar(menu_bar);  
   subframe->Centre(wxBOTH);
   
   menu_bar->Append (reconstruct_menu, "&Reconstruct");
   menu_bar->Append (help_menu, "&Help");
   
   subframe->SetMenuBar(menu_bar);  
   subframe->Centre(wxBOTH);
   
-  wxAcceleratorEntry accelEntries[5];
+  wxAcceleratorEntry accelEntries[6];
   accelEntries[0].Set (wxACCEL_CTRL, static_cast<int>('L'), PJMENU_CONVERT_POLAR);
   accelEntries[1].Set (wxACCEL_CTRL, static_cast<int>('M'), PJMENU_CONVERT_FFT_POLAR);
   accelEntries[2].Set (wxACCEL_CTRL, static_cast<int>('R'), PJMENU_RECONSTRUCT_FBP);
   accelEntries[3].Set (wxACCEL_CTRL, static_cast<int>('E'), PJMENU_RECONSTRUCT_FOURIER);
   accelEntries[4].Set (wxACCEL_CTRL, static_cast<int>('I'), PJMENU_FILE_PROPERTIES);
   accelEntries[0].Set (wxACCEL_CTRL, static_cast<int>('L'), PJMENU_CONVERT_POLAR);
   accelEntries[1].Set (wxACCEL_CTRL, static_cast<int>('M'), PJMENU_CONVERT_FFT_POLAR);
   accelEntries[2].Set (wxACCEL_CTRL, static_cast<int>('R'), PJMENU_RECONSTRUCT_FBP);
   accelEntries[3].Set (wxACCEL_CTRL, static_cast<int>('E'), PJMENU_RECONSTRUCT_FOURIER);
   accelEntries[4].Set (wxACCEL_CTRL, static_cast<int>('I'), PJMENU_FILE_PROPERTIES);
-  wxAcceleratorTable accelTable (5, accelEntries);
+  accelEntries[5].Set (wxACCEL_CTRL, static_cast<int>('T'), PJMENU_PLOT_TTHETA_SAMPLING);
+  wxAcceleratorTable accelTable (6, accelEntries);
   subframe->SetAcceleratorTable (accelTable);
   
   return subframe;
   subframe->SetAcceleratorTable (accelTable);
   
   return subframe;
@@ -3002,7 +3048,8 @@ PlotFileView::OnUpdate (wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
   const PlotFile& rPlotFile = GetDocument()->getPlotFile();
   const int iNColumns = rPlotFile.getNumColumns();
   const int iNRecords = rPlotFile.getNumRecords();
   const PlotFile& rPlotFile = GetDocument()->getPlotFile();
   const int iNColumns = rPlotFile.getNumColumns();
   const int iNRecords = rPlotFile.getNumRecords();
-  
+  const bool bScatterPlot = rPlotFile.getIsScatterPlot();
+
   if (iNColumns > 0 && iNRecords > 0) {
     if (m_pEZPlot)
       delete m_pEZPlot;
   if (iNColumns > 0 && iNRecords > 0) {
     if (m_pEZPlot)
       delete m_pEZPlot;
@@ -3025,17 +3072,22 @@ PlotFileView::OnUpdate (wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
     
     m_pEZPlot->ezset("box");
     m_pEZPlot->ezset("grid");
     
     m_pEZPlot->ezset("box");
     m_pEZPlot->ezset("grid");
-    
-    double* pdXaxis = new double [iNRecords];
-    rPlotFile.getColumn (0, pdXaxis);
-    
+  
+    double* pdX = new double [iNRecords];
     double* pdY = new double [iNRecords];
     double* pdY = new double [iNRecords];
-    for (int iCol = 1; iCol < iNColumns; iCol++) {
-      rPlotFile.getColumn (iCol, pdY);
-      m_pEZPlot->addCurve (pdXaxis, pdY, iNRecords);
-    }
+    if (! bScatterPlot) {
+      rPlotFile.getColumn (0, pdX);
     
     
-    delete pdXaxis;
+      for (int iCol = 1; iCol < iNColumns; iCol++) {
+        rPlotFile.getColumn (iCol, pdY);
+        m_pEZPlot->addCurve (pdX, pdY, iNRecords);
+      }
+    } else {
+      rPlotFile.getColumn (0, pdX);
+      rPlotFile.getColumn (1, pdY);
+      m_pEZPlot->addCurve (pdX, pdY, iNRecords);
+    }
+    delete pdX;
     delete pdY;
   }
   
     delete pdY;
   }
   
index 8a4a78a33a8e710cf592c51f09faaee2057a7a4b..38ea68519962de6a43f4eda0c4d117fe2c8b6bf3 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: views.h,v 1.47 2001/03/01 07:30:49 kevin Exp $
+**  $Id: views.h,v 1.48 2001/03/10 23:14:16 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
 **
 **  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
@@ -240,6 +240,7 @@ public:
   void OnReconstructFourier (wxCommandEvent& event);
   void OnConvertPolar (wxCommandEvent& event);
   void OnConvertFFTPolar (wxCommandEvent& event);
   void OnReconstructFourier (wxCommandEvent& event);
   void OnConvertPolar (wxCommandEvent& event);
   void OnConvertFFTPolar (wxCommandEvent& event);
+  void OnPlotTThetaSampling (wxCommandEvent& event);
   
 #if CTSIM_MDI
   wxDocMDIChildFrame* getFrame() { return m_pFrame; }
   
 #if CTSIM_MDI
   wxDocMDIChildFrame* getFrame() { return m_pFrame; }