r499: no message
authorKevin M. Rosenberg <kevin@rosenberg.net>
Thu, 8 Feb 2001 06:25:07 +0000 (06:25 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Thu, 8 Feb 2001 06:25:07 +0000 (06:25 +0000)
15 files changed:
ChangeLog
doc/ctsim-concepts.tex
include/phantom.h
include/projections.h
include/scanner.h
libctsim/phantom.cpp
libctsim/projections.cpp
libctsim/scanner.cpp
msvc/ctsim/ctsim.plg
src/dialogs.cpp
src/dialogs.h
src/views.cpp
src/views.h
tools/phm2if.cpp
tools/phm2pj.cpp

index a1e199f5eb14941db1056098783d69b5d27fc6ee..71f6deee69af8fba2f6ac4a9ff483977144b7fa3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 3.0.0beta1 - Released
 
+       * global: Projection files are not compatible with previous version
+       due to new scanner definitions.
+       
+       * global: deleted concept of field-of-view and added
+         view ratio and scan ratio concepts.
+       
        * ctsim: Added most-recently-used files to File menu with
        registry storage between executions.
 
@@ -28,6 +34,8 @@
        
        * pjinfo: Fixed bug when doing --dump and not specifing --endview
 
+       * phm2pj: Fixed MPI bug with broadcasting of variables
+       
        * ctsimtext-lam: Changes for first version to compile under lam
        
 3.0.0alpha5 - Released 1/12/00
index 17071df05b8de8ebc70bd971b918a4ec20ed9a53..aa976159d95e0a10af58d7ca3d49b4f1c0e25e8f 100644 (file)
@@ -21,20 +21,18 @@ the 'scanner'.
 describe the object being scanned. A phantom is composed a one or more
 phantom elements. These elements are simple geometric shapes,
 specifically, rectangles, triangles, ellipses, sectors and segments.
-With these the standard phantoms used in the CT literature (the Herman
-and the Shepp-Logan) can be constructed.  In fact
-\ctsim\ provides a shortcut to construct those phantoms for you.  It also
-allows you to write a file in which the composition of your own phantom is
-described.
+With these elements, standard phantoms used in the CT literature (Herman
+Shepp-Logan) can be constructed.  In fact, \ctsim\ provides a shortcut to construct those published phantoms.  \ctsim\ also
+reads text files of user-defined phantoms.
 
-The types of phantom elements and their definitions are taken from Herman's 1980
-book\cite{HERMAN80}.
+The types of phantom elements and their definitions are taken from
+Herman's 1980 book\cite{HERMAN80}.
 
 \subsection{Phantom File}\label{phantomfile}\index{Concepts,Phantoms,File}
 Each line in the text file describes an element of the
 phantom.  Each line contains seven entries, in the following form:
 \begin{verbatim}
-item cx cy dx dy r a
+element-type cx cy dx dy r a
 \end{verbatim}
 The first entry defines the type of the element, one
 of {\tt rectangle}, {\tt ellipse}, {\tt triangle}, {\tt sector}, or {\tt segment}.
@@ -45,53 +43,61 @@ and {\tt a} is the X-ray attenuation coefficient of the object.
 Where objects overlap, the attenuations of the overlapped objects are summed.
 
 
-
 \subsection{Phantom Elements}\label{phantomelements}\index{Concepts,Phantoms,Elements}
 
 \subsubsection{ellipse}
 Ellipses use dx and dy to define the semi-major and semi-minor axis lengths,
-with the centre of the ellipse at cx and cy.  Of note, the commonly used
+with the center of the ellipse at cx and cy.  Of note, the commonly used
 phantom described by Shepp and Logan\cite{SHEPP74} uses only ellipses.
 
 \subsubsection{rectangle}
 Rectangles use
-cx  and cy to define the position of the centre of the rectangle with respect
+cx  and cy to define the position of the center of the rectangle with respect
 to the origin.  dx and dy  are the half-width and half-height of the
 rectangle.
 
 \subsubsection{triangle}
-Triangles are drawn with the centre of the base at cx,cy, with a base
-width of 2*dx in x direction, and a height of dy.  Rotations are then
-applied about the origin.
-
-\subsubsection{sector}
-It appears that dx and dy
-define the end points of a radius of the sector, from which the radius and
-the angle of the two arms of the sector are calculated.  But then
-orientation and centering of the sector don't make much sense yet.
+Triangles are drawn with the center of the base at cx,cy, with a base
+half-width of dx and a height of dy.  Rotations are then
+applied about the center of the base.
 
 \subsubsection{segment}
-Segments are the segments of a circle between a chord and the
-perimeter of the circle.  This also isn't clear to me, but it appears that
-perhaps the distance from chord to circle perimeter, and circle radius is
-defined by dx and dy. Chord is always horizontal through the origin, then
-translated and then rotated (???).
+Segments are complex. They are the portion of an circle between a
+chord and the perimeter of the circle.  \texttt{dy} sets the radius of
+the circle. Segments start with the center of the chord located at
+\texttt{(0,0)} and the chord horizontal. The half-width of the chord
+is set by \texttt{dx}.  The portion of an circle lying below the chord
+is then added. The imaginary center of this circle is located at
+\texttt{(0,-dy)}. The segment is then rotated by \texttt{r} and then
+translated by \texttt{cx,cy}.
+
+\subsubsection{sector}
+Sectors are the like a ``pie slice'' from a circle. The radius of the
+circle is set by \texttt{dy}. Sectors are
+defined similarly to segments. In this case, though, a chord is not
+drawn.  Instead, the lines are drawn from the origin of the circle
+\texttt{(0,-dy)} to the points \texttt{(-dx,0)} and \texttt{(dx,0)}.
+The perimeter of the circle is then draw between those two points
+below the x-axis. The sector is then rotated and translated the same
+as a segment.
 
 \subsection{Phantom Size}
-Also note that the overall dimensions of the phantom are increased by 1\%
-above the specified sizes to avoid clipping due to round-off errors.  
-So, if the phantom is defined as
-a rectangle of size 0.1 by 0.1, the actual phantom has extent 0.101
-in each direction.
+Also note that the overall dimensions of the phantom are increased by
+1\% above the specified sizes to avoid clipping due to round-off
+errors from polygonal sampling.  So, if the phantom is defined as a
+rectangle of size 0.1 by 0.1, the actual phantom has extent 0.101 in
+each direction.
 
 \section{Scanner}\label{conceptscanner}\index{Concepts,Scanner}%
 \subsection{Sizes}
-Understanding the scanning geometry is the most complicated aspect
-of using \ctsim. For our real-world CT simulators, this is actually
-quite simple. The geometry is fixed by the manufacturer during
-the construction of the scanner and can not be changed. 
+Understanding the scanning geometry is the most complicated aspect of
+using \ctsim. For real-world CT simulators, this is actually quite
+simple. The geometry is fixed by the manufacturer during the
+construction of the scanner and can not be changed. Conversely,
+real-world CT scanners can only take objects up to a fixed size.
+
 \ctsim, being a very flexible simulator,
-gives tremendous options is setting up the geometry for a scan.
+gives tremendous options in setting up the geometry for a scan.
 
 In general, the geometry for a scan all starts from the size of the
 phantom being scanned. This is because \ctsim\ allows for statistical
@@ -131,13 +137,13 @@ well as during rasterization of phantoms. By default, the \emph{view diameter}
 is set equal to the \emph{phantom diameter}. It may be useful, especially for 
 experimental reasons, to process an area larger (and maybe even smaller) than
 the phantom. Thus, during rasterization or during projections, \ctsim\ will
-ask for a \emph{view diameter ratio},
-\latexonly{$V_{dR}$.}\latexignore{\emph{VdR}.}
+ask for a \emph{view ratio},
+\latexonly{$V_{R}$.}\latexignore{\emph{VR}.}
 The \emph{view diameter} is then set as
-\latexonly{$$V_d = P_d V_{dR}$$}\latexignore{\\$$\emph{Vd = Pd x VdR}$$}
+\latexonly{$$V_d = P_d V_{R}$$}\latexignore{\\$$\emph{Vd = Pd x VR}$$}
 
 By using a 
-\latexonly{$V_{dR}$}\latexignore{\emph{VdR}}
+\latexonly{$V_{R}$}\latexignore{\emph{VR}}
 less than 1, \ctsim\ will allow
 for a \emph{view diameter} less than 
 \emph{phantom diameter}.
@@ -148,24 +154,25 @@ scanner that is larger than the scanner itself!
 \subsubsection{Scan Diameter}
 By default, the entire \emph{view diameter} is scanned. For experimental
 purposes, it may be desirable to scan an area either larger or smaller than
-the \emph{view diameter}. Thus, the concept of \emph{scan diameter}
-\latexonly{$S_{dR}$}\latexignore{\emph{SdR}}
+the \emph{view diameter}. Thus, the concept of \emph{scan ratio}
+\latexonly{$S_{R}$}\latexignore{\emph{SR}}
 is born. The scan diameter
 \latexonly{$S_d$}\latexignore{\emph{Sd}}
-is defined as
-\latexonly{$$S_d = V_d S_{dR}$$}\latexignore{\\$$\emph{Sd = Vd x SdR}$$\\}
-By default and for all ordinary scanning, the \emph{scan diameter ratio} is to \texttt{1}. If the \emph{scan diameter ratio} is less than \texttt{1}, you
-can plan on significant artifacts.
+is the diameter over which x-rays are collected and is defined as
+\latexonly{$$S_d = V_d S_{R}$$}\latexignore{\\$$\emph{Sd = Vd x SR}$$\\}
+By default and for all ordinary scanning, the \emph{scan ratio} is to
+\texttt{1}. If the \emph{scan ratio} is less than \texttt{1},
+you can expect significant artifacts.
 
 \subsubsection{Focal Length}
 The \emph{focal length},
 \latexonly{$F_l$,}\latexignore{\emph{Fl},}
 is the distance of the X-ray source to the center of
 the phantom. The focal length is set as a ratio,
-\latexonly{$F_{lR}$,}\latexignore{\emph{FlR},}
+\latexonly{$F_{lR}$,}\latexignore{\emph{FllR},}
 of the view radius. Focal length is
 calculated as
-\latexonly{$$F_l = F_{lR} (V_d / 2)$$}\latexignore{\\$$\emph{Fl = FlR x (Vd / 2)}$$}
+\latexonly{$$F_l = (V_d / 2) F_R$$}\latexignore{\\$$\emph{Fl = (Vd / 2) x FlR}$$}
 
 For parallel geometry scanning, the focal length doesn't matter. However, 
 divergent geometry scanning (equilinear and equiangular), the \emph{focal
@@ -244,7 +251,7 @@ Consider increasing the focal length ratio to two leaving the
 field of view ratio as 1,  as in  Figure 4.  Now the detectors array is
 denser, and the real field of view is closer to that specified, but note
 again that the field of view is not used. Instead, the focal length is
-used to give a distance from the centre of the phantom to the source, and
+used to give a distance from the center of the phantom to the source, and
 the detector array is adjusted to give an angular coverage to include the
 whole phantom.
 \begin{figure}
index f67679c6f1ee1315685353b9f28836c58edf7972..5769b258610f162d2e0b49545cb943551be135a2 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: phantom.h,v 1.21 2001/01/28 19:10:18 kevin Exp $
+**  $Id: phantom.h,v 1.22 2001/02/08 06:25:07 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
@@ -69,7 +69,6 @@ class PhantomElement
     double* const xOutline() const {return m_xOutline;}
     double* const yOutline() const {return m_yOutline;}
     const double atten() const {return m_atten;}
-    const double diameter() const {return m_diameter;}
     const double xmin() const {return m_xmin;}
     const double xmax() const {return m_xmax;}
     const double ymin() const {return m_ymin;}
@@ -92,7 +91,6 @@ class PhantomElement
     double *m_x, *m_y;      // ptr to array of points in obj world coord 
     int m_nPoints;                  // number of points in outline arrays 
     double m_xmin, m_xmax, m_ymin, m_ymax;  // pelem limits 
-    double m_diameter;      
     GRFMTX_2D m_xformPhmToObj;        // map from phantom to normalized pelem coords
     GRFMTX_2D m_xformObjToPhm;        // map from normalized pelem coords to phantom coords 
     double* m_xOutline;
@@ -166,9 +164,9 @@ class Phantom
 
     void addPElem (const char* const composition, const double cx, const double cy, const double u, const double v, const double rot, const double atten);
 
-    void convertToImagefile (ImageFile& im, const int in_nsample, const int trace, const int colStart, const int colCount, bool bStoreAtColumnPos) const;
+    void convertToImagefile (ImageFile& im, double dViewRatio, const int in_nsample, const int trace, const int colStart, const int colCount, bool bStoreAtColumnPos) const;
 
-    void convertToImagefile (ImageFile& im, const int in_nsample, const int trace) const;
+    void convertToImagefile (ImageFile& im, double dViewRatio, const int in_nsample, const int trace) const;
 
     void printDefinitions (std::ostream& os) const;
     void printDefinitions (std::ostringstream& os) const;
@@ -192,9 +190,12 @@ class Phantom
     void print (std::ostream& os) const;
     void print (std::ostringstream& os) const;
 
-    const double maxAxisLength () const {return (((m_xmax - m_xmin) > (m_ymax - m_ymin)) ? (m_xmax - m_xmin) : (m_ymax - m_ymin));}
+    double maxAxisLength () const 
+    {  return maxValue<double> (m_xmax - m_xmin, m_ymax - m_ymin); }
+
+    double getDiameterBoundaryCircle() const 
+    { return SQRT2 * maxAxisLength(); }
 
-    const double diameter() const {return m_diameter;}
     const double xmin() const {return m_xmin;}
     const double xmax() const {return m_xmax;}
     const double ymin() const {return m_ymin;}
@@ -214,13 +215,11 @@ class Phantom
     PhantomComposition m_composition;
     int m_nPElem;                          // number of pelems in phantom 
     double m_xmin, m_xmax, m_ymin, m_ymax;  // extent of pelems in pelem coordinates
-    double m_diameter;                        // diameter of object
     mutable std::list<PhantomElement*> m_listPElem;      // pelem lists
     std::string m_name;
     int m_id;
     bool m_fail;
     std::string m_failMessage;
-
     static const char* s_aszPhantomName[];
     static const char* s_aszPhantomTitle[];
     static const int s_iPhantomCount;
index a09f481c351db0006168b1743b6a83a2b1ad89ce..48ca0f44710f737b2e4bbfe950bd086bfa1e2c9d 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: projections.h,v 1.21 2001/01/28 19:10:18 kevin Exp $
+**  $Id: projections.h,v 1.22 2001/02/08 06:25:07 kevin Exp $
 **
 **
 **  This program is free software; you can redistribute it and/or modify
@@ -84,7 +84,6 @@ class Projections
   void setNView (int nView);  // used in MPI to restrict # of views
   void setRotInc (double rotInc) { m_rotInc = rotInc;}
   void setDetInc (double detInc) { m_detInc = detInc;}
-  void setPhmLen (double phmLen) { m_phmLen = phmLen;}
   void setCalcTime (double calcTime) {m_calcTime = calcTime;}
   void setRemark (const char* remark) {m_remark = remark; m_label.setLabelString(remark);}
   void setRemark (const std::string& remark) {setRemark(remark.c_str());}
@@ -92,15 +91,15 @@ class Projections
   double detStart() const {return m_detStart;}
   double rotStart() const {return m_rotStart;}
   double calcTime() const {return m_calcTime;}
-  double phmLen() const {return m_phmLen;}
+  double viewLen() const {return m_dViewDiameter / SQRT2;}
   const char*  remark() const {return m_remark.c_str();}
   double detInc() const {return m_detInc;}
   double rotInc() const {return m_rotInc;}
   int nDet() const {return m_nDet;}
   int nView() const {return m_nView;}
   int geometry() const {return m_geometry;}
-  double focalLength() const {return m_focalLength;}
-  double fieldOfView() const {return m_fieldOfView;}
+  double focalLength() const {return m_dFocalLength;}
+  double phmLen() const { return m_dViewDiameter / SQRT2; }
 
   const std::string& getFilename() const {return m_filename;}
   Array2dFileLabel& getLabel() {return m_label;}
@@ -130,9 +129,9 @@ class Projections
   double m_rotInc;             // angle between rotations 
   double m_detStart;           // distance of beginning detector to center phantom
   double m_detInc;             // increment between detectors 
-  double m_phmLen;             // Length of phantom edge (phm is square) 
-  double m_focalLength;
-  double m_fieldOfView;
+  double m_dFocalLength;
+  double m_dViewDiameter;
+  double m_dFanBeamAngle;
   kuint32 m_year;                   // Creation date & time
   kuint32 m_month;
   kuint32 m_day;
index f0b498b72844e5d90ed223f243455b884d0cb985..162e89686744e2a34a9f04374e3333ea0fe7f007 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: scanner.h,v 1.16 2000/12/16 03:29:02 kevin Exp $
+**  $Id: scanner.h,v 1.17 2001/02/08 06:25:07 kevin Exp $
 **
 **
 **  This program is free software; you can redistribute it and/or modify
@@ -74,7 +74,9 @@ class Scanner
   static const int Scanner::GEOMETRY_EQUIANGULAR;
 
   
-  Scanner (const Phantom& phm, const char* const geometryName, int nDet, int nView, int nSample, const double rot_anglen, double dFieldOfView, double dFocalLength);
+  Scanner (const Phantom& phm, const char* const geometryName, int nDet, 
+    int nView, int nSample, const double rot_anglen, 
+    double dFocalLengthRatio, double dViewRatio, double dScanRatio);
   ~Scanner();
   
   void collectProjections (Projections& proj, const Phantom& phm, const int trace = Trace::TRACE_NONE, SGP* pSGP = NULL);
@@ -87,12 +89,15 @@ class Scanner
   const std::string& failMessage() const {return m_failMessage;}
   unsigned int nDet() const {return m_nDet;}
   unsigned int nView() const {return m_nView;}
-  double phmLen() const {return m_phmLen;}
   double rotInc() const {return m_rotInc;}
   double detInc() const {return m_detInc;}
   double detLen() const {return m_detLen;}
   double focalLength() const {return m_dFocalLength;}
-  double fieldOfView() const {return m_dFieldOfView;}
+  double viewDiameter() const {return m_dViewDiameter;}
+  double scanDiameter() const {return m_dScanDiameter;}
+  double fanBeamAngle() const {return m_dFanBeamAngle;}
+
   int geometry() const {return m_idGeometry;}
 
   static int getGeometryCount() {return s_iGeometryCount;}
@@ -109,15 +114,17 @@ class Scanner
   unsigned int m_nDet;         /* Number of detectors in array */
   unsigned int m_nView;                /* Number of rotated views */
   unsigned int m_nSample;      /* Number of rays per detector */
-  double m_dFieldOfView;        // Field of View
   double m_dFocalLength;        // Focal Length
-  double m_dFieldOfViewRatio;   // Field of View Ratio to diameter phmLen
-  double m_dFocalLengthRatio;   // Focal Length ratio to radius phmLen
+  double m_dViewDiameter; // Diameter of area being processed
+  double m_dScanDiameter; // Diamer of area being scanned
+  double m_dViewRatio;   // View Ratio to diameter phantom
+  double m_dFocalLengthRatio;   // Focal Length ratio to radius phantom
+  double m_dScanRatio;       // Scan length to view length ratio
+  double m_dFanBeamAngle;
   double m_detLen;             // Total length of detector array 
   double m_rotLen;             // Rotation angle length in radians (norm 2PI)
   double m_detInc;             // Increment between centers of detectors 
   double m_rotInc;             // Increment in rotation angle between views 
-  double m_phmLen;              // Maximum Length of phantom or area of interest
   double m_dXCenter;            // Center of Phantom
   double m_dYCenter;            
   double m_dAngularDetIncrement;
index 0a9f53ecce76d2456079aeb9a100763894552ed0..fea8e6e55aa1b7790a8d4eb9ad9a2b0d9df2803b 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: phantom.cpp,v 1.27 2001/01/28 19:10:18 kevin Exp $
+**  $Id: phantom.cpp,v 1.28 2001/02/08 06:25:07 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
@@ -82,7 +82,6 @@ Phantom::init ()
   m_xmax = -1E30;
   m_ymin = 1E30;
   m_ymax = -1E30;
-  m_diameter = 0;
   m_composition = P_PELEMS;
   m_fail = false;
   m_id = PHM_INVALID;
@@ -261,11 +260,6 @@ Phantom::addPElem (const char *type, const double cx, const double cy, const dou
   if (m_ymin > pelem->ymin())    m_ymin = pelem->ymin();
   if (m_ymax < pelem->ymax())    m_ymax = pelem->ymax();
 
-  if (m_diameter < pelem->diameter())
-    m_diameter = pelem->diameter();
-
-  //  m_diameter = lineLength(m_xmin, m_ymin, m_xmax, m_ymax);
-
   m_nPElem++;
 }
 
@@ -472,13 +466,13 @@ Phantom::addStdHermanBordered ()
  */
 
 void
-Phantom::convertToImagefile (ImageFile& im, const int in_nsample, const int trace) const
+Phantom::convertToImagefile (ImageFile& im, double dViewRatio, const int in_nsample, const int trace) const
 {
-  convertToImagefile (im, in_nsample, trace, 0, im.nx(), true);
+  convertToImagefile (im, dViewRatio, in_nsample, trace, 0, im.nx(), true);
 }
 
 void 
-Phantom::convertToImagefile (ImageFile& im, const int in_nsample, const int trace, const int colStart, const int colCount, bool bStoreAtColumnPos) const
+Phantom::convertToImagefile (ImageFile& im, const double dViewRatio, const int in_nsample, const int trace, const int colStart, const int colCount, bool bStoreAtColumnPos) const
 {
   int nx = im.nx();
   int ny = im.ny();
@@ -493,14 +487,12 @@ Phantom::convertToImagefile (ImageFile& im, const int in_nsample, const int trac
   double dy = m_ymax - m_ymin;
   double xcent = m_xmin + dx / 2;
   double ycent = m_ymin + dy / 2;
-  double phmlen = (dx > dy ? dx : dy);
-
-  double phmradius = phmlen / 2;
+  double dHalflen = dViewRatio * (getDiameterBoundaryCircle() / SQRT2 / 2);
 
-  double xmin = xcent - phmradius;
-  double xmax = xcent + phmradius;
-  double ymin = ycent - phmradius;
-  double ymax = ycent + phmradius;
+  double xmin = xcent - dHalflen;
+  double xmax = xcent + dHalflen;
+  double ymin = ycent - dHalflen;
+  double ymax = ycent + dHalflen;
 
   // Each pixel holds the average of the intensity of the cell with (ix,iy) at the center of the pixel
   // Set major increments so that the last cell v[nx-1][ny-1] will start at xmax - xinc, ymax - yinc).
@@ -581,15 +573,6 @@ PhantomElement::PhantomElement (const char *type, const double cx, const double
   makeTransformMatrices ();     // calc transform matrices between phantom and normalized phantomelement
   makeVectorOutline ();                // calculate vector outline of pelem 
 
-  // Find maximum diameter of Object
-  double r2Max = 0;
-  for (int i = 0; i < m_nPoints; i++) {
-    double r2 = (m_xOutline[i] * m_xOutline[i]) + (m_yOutline[i] * m_yOutline[i]);
-    if (r2 > r2Max)
-      r2Max = r2;
-  }
-  m_diameter = 2 * sqrt( r2Max );
-
   m_rectLimits[0] = m_xmin;   m_rectLimits[1] = m_ymin;
   m_rectLimits[2] = m_xmax;   m_rectLimits[3] = m_ymax;
 }
index f6b8cb15a48fd3b3362d79b89505de4740b96271..970b437f6552143074786c921ccfd106ed7e8874 100644 (file)
@@ -8,7 +8,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: projections.cpp,v 1.46 2001/01/28 19:10:18 kevin Exp $
+**  $Id: projections.cpp,v 1.47 2001/02/08 06:25:07 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
@@ -148,14 +148,14 @@ Projections::initFromScanner (const Scanner& scanner)
   deleteProjData();
   init (scanner.nView(), scanner.nDet());
   
-  m_phmLen = scanner.phmLen();
   m_rotInc = scanner.rotInc();
   m_detInc = scanner.detInc();
   m_geometry = scanner.geometry();
-  m_focalLength = scanner.focalLength();
-  m_fieldOfView = scanner.fieldOfView();
+  m_dFocalLength = scanner.focalLength();
+  m_dViewDiameter = scanner.viewDiameter();
   m_rotStart = 0;
   m_detStart =  -(scanner.detLen() / 2);
+  m_dFanBeamAngle = scanner.fanBeamAngle();
 }
 
 void
@@ -230,10 +230,10 @@ Projections::headerWrite (fnetorderstream& fs)
   kfloat64 _rotInc = m_rotInc;
   kfloat64 _detStart = m_detStart;
   kfloat64 _detInc = m_detInc;
-  kfloat64 _phmLen = m_phmLen;
-  kfloat64 _fieldOfView = m_fieldOfView;
-  kfloat64 _focalLength = m_focalLength;
-  
+  kfloat64 _viewDiameter = m_dViewDiameter;
+  kfloat64 _focalLength = m_dFocalLength;
+  kfloat64 _fanBeamAngle = m_dFanBeamAngle;
+
   fs.seekp(0);
   if (! fs)
     return false;
@@ -248,9 +248,9 @@ Projections::headerWrite (fnetorderstream& fs)
   fs.writeFloat64 (_rotInc);
   fs.writeFloat64 (_detStart);
   fs.writeFloat64 (_detInc);
-  fs.writeFloat64 (_phmLen);
+  fs.writeFloat64 (_viewDiameter);
   fs.writeFloat64 (_focalLength);
-  fs.writeFloat64 (_fieldOfView);
+  fs.writeFloat64 (_fanBeamAngle);
   fs.writeInt16 (_year);
   fs.writeInt16 (_month);
   fs.writeInt16 (_day);
@@ -279,7 +279,7 @@ Projections::headerRead (fnetorderstream& fs)
 {
   kuint16 _hsize, _signature, _year, _month, _day, _hour, _minute, _second, _remarksize = 0;
   kuint32 _nView, _nDet, _geom;
-  kfloat64 _calcTime, _rotStart, _rotInc, _detStart, _detInc, _phmLen, _focalLength, _fieldOfView;
+  kfloat64 _calcTime, _rotStart, _rotInc, _detStart, _detInc, _focalLength, _viewDiameter, _fanBeamAngle;
   
   fs.seekg(0);
   if (! fs)
@@ -295,9 +295,9 @@ Projections::headerRead (fnetorderstream& fs)
   fs.readFloat64 (_rotInc);
   fs.readFloat64 (_detStart);
   fs.readFloat64 (_detInc);
-  fs.readFloat64 (_phmLen);
+  fs.readFloat64 (_viewDiameter);
   fs.readFloat64 (_focalLength);
-  fs.readFloat64 (_fieldOfView);
+  fs.readFloat64 (_fanBeamAngle);
   fs.readInt16 (_year);
   fs.readInt16 (_month);
   fs.readInt16 (_day);
@@ -341,9 +341,9 @@ Projections::headerRead (fnetorderstream& fs)
   m_rotInc = _rotInc;
   m_detStart = _detStart;
   m_detInc = _detInc;
-  m_phmLen = _phmLen;
-  m_focalLength = _focalLength;
-  m_fieldOfView = _fieldOfView;
+  m_dFocalLength = _focalLength;
+  m_dViewDiameter = _viewDiameter;
+  m_dFanBeamAngle = _fanBeamAngle;
   m_year = _year;
   m_month = _month;
   m_day = _day;
@@ -631,7 +631,8 @@ Projections::printProjectionData (int startView, int endView)
   printf("Description: %s\n", m_remark.c_str());
   printf("Geometry: %s\n", Scanner::convertGeometryIDToName (m_geometry));
   printf("nView       = %8d           nDet = %8d\n", m_nView, m_nDet);
-  printf("focalLength = %8.4f  fieldOfView = %8.4f\n", m_focalLength, m_fieldOfView);
+  printf("focalLength = %8.4f ViewDiameter = %8.4f\n", m_dFocalLength, m_dViewDiameter);
+  printf("fanBeamAngle= %8.4f\n", convertRadiansToDegrees(m_dFanBeamAngle));
   printf("rotStart    = %8.4f       rotInc = %8.4f\n", m_rotStart, m_rotInc);
   printf("detStart    = %8.4f       detInc = %8.4f\n", m_detStart, m_detInc);
   if (m_projData != NULL) {
@@ -657,16 +658,16 @@ void
 Projections::printScanInfo (std::ostringstream& os) const
 {
   os << "Number of detectors: " << m_nDet << "\n";
-  os << "    Number of views: " << m_nView<< "\n";
-  os << "             Remark: " << m_remark.c_str()<< "\n";
-  os << "           Geometry: " << Scanner::convertGeometryIDToName (m_geometry)<< "\n";
-  os << "       Focal Length: " << m_focalLength<< "\n";
-  os << "      Field Of View: " << m_fieldOfView<< "\n";
-  os << "             phmLen: " << m_phmLen<< "\n";
-  os << "           detStart: " << m_detStart<< "\n";
-  os << "             detInc: " << m_detInc<< "\n";
-  os << "           rotStart: " << m_rotStart<< "\n";
-  os << "             rotInc: " << m_rotInc<< "\n";
+  os << "Number of views: " << m_nView<< "\n";
+  os << "Description: " << m_remark.c_str()<< "\n";
+  os << "Geometry: " << Scanner::convertGeometryIDToName (m_geometry)<< "\n";
+  os << "Focal Length: " << m_dFocalLength<< "\n";
+  os << "View Diameter: " << m_dViewDiameter<< "\n";
+  os << "Fan Beam Angle: " << convertRadiansToDegrees(m_dFanBeamAngle) << "\n";
+  os << "detStart: " << m_detStart<< "\n";
+  os << "detInc: " << m_detInc<< "\n";
+  os << "rotStart: " << m_rotStart<< "\n";
+  os << "rotInc: " << m_rotInc<< "\n";
 }
 
 
@@ -765,10 +766,10 @@ Projections::convertFFTPolar (ImageFile& rIF, int iInterpolationID, int iZeropad
 void
 Projections::calcArrayPolarCoordinates (unsigned int nx, unsigned int ny, double** ppdView, double** ppdDet)
 {
-  double xMin = -m_phmLen / 2;
-  double xMax = xMin + m_phmLen;
-  double yMin = -m_phmLen / 2;
-  double yMax = yMin + m_phmLen;
+  double xMin = -phmLen() / 2;
+  double xMax = xMin + phmLen();
+  double yMin = -phmLen() / 2;
+  double yMax = yMin + phmLen();
   
   double xInc = (xMax - xMin) / nx;    // size of cells
   double yInc = (yMax - yMin) / ny;
index 6e2e57ad48bf962af80a9219c9638947f21bc713..7081903f71b7984b17723c905a29c2b810826efc 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: scanner.cpp,v 1.29 2001/02/04 21:28:19 kevin Exp $
+**  $Id: scanner.cpp,v 1.30 2001/02/08 06:25:07 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
@@ -82,10 +82,11 @@ DetectorArray::~DetectorArray (void)
 *   int nSample                Number of rays per detector
 */
 
-Scanner::Scanner (const Phantom& phm, const char* const geometryName, int nDet, int nView, int nSample, const double rot_anglen, const double dFocalLengthRatio, const double dFieldOfViewRatio)
+Scanner::Scanner (const Phantom& phm, const char* const geometryName, 
+                  int nDet, int nView, int nSample, const double rot_anglen, 
+                  const double dFocalLengthRatio, const double dViewRatio,
+                  double dScanRatio)
 {
-  m_phmLen = phm.maxAxisLength();      // maximal length along an axis
-  
   m_fail = false;
   m_idGeometry = convertGeometryNameToID (geometryName);
   if (m_idGeometry == GEOMETRY_INVALID) {
@@ -107,20 +108,23 @@ Scanner::Scanner (const Phantom& phm, const char* const geometryName, int nDet,
   m_nView    = nView;
   m_nSample  = nSample;
   m_dFocalLengthRatio = dFocalLengthRatio;
-  m_dFieldOfViewRatio = dFieldOfViewRatio;
-  m_dFocalLength = (m_phmLen * SQRT2 / 2) * dFocalLengthRatio;
-  m_dFieldOfView = m_phmLen * SQRT2 * dFieldOfViewRatio;
+  m_dViewRatio = dViewRatio;
+  m_dScanRatio = dScanRatio;
+  m_dViewDiameter = phm.getDiameterBoundaryCircle() * m_dViewRatio;
+  m_dFocalLength = (m_dViewDiameter / 2) * dFocalLengthRatio;
+  m_dScanDiameter = m_dViewDiameter * m_dScanRatio;
   
   m_dXCenter = phm.xmin() + (phm.xmax() - phm.xmin()) / 2;
   m_dYCenter = phm.ymin() + (phm.ymax() - phm.ymin()) / 2;
   m_rotLen  = rot_anglen;
   m_rotInc  = m_rotLen / m_nView;
   if (m_idGeometry == GEOMETRY_PARALLEL) {
-    m_detLen   = m_dFieldOfView;
+    m_detLen   = m_dScanDiameter;
     m_detInc  = m_detLen / m_nDet;
     if (m_nDet % 2 == 0) // Adjust for Even number of detectors
       m_detInc = m_detLen / (m_nDet - 1); // center detector = (nDet/2)-1
     
+    m_dFanBeamAngle = 0;
     double dHalfDetLen = m_detLen / 2;
     m_initPos.xs1 = m_dXCenter - dHalfDetLen;
     m_initPos.ys1 = m_dYCenter + m_dFocalLength;
@@ -132,34 +136,20 @@ Scanner::Scanner (const Phantom& phm, const char* const geometryName, int nDet,
     m_initPos.yd2 = m_dYCenter - m_dFocalLength;
     m_initPos.angle = 0.0;
   } else if (m_idGeometry == GEOMETRY_EQUILINEAR) {
-#if 0
-    double dAngle1 = atan ((m_dFieldOfView / 2) / m_dFocalLength);
-    double dHalfSquare = m_dFieldOfView / SQRT2 / 2;
-    double dFocalPastPhm = m_dFocalLength - dHalfSquare;
-    if (dFocalPastPhm <= 0.) {
-      m_fail = true;
-      m_failMessage = "Focal Point inside of phantom";
-      return;
-    }
-    double dAngle2 = atan( dHalfSquare / dFocalPastPhm );
-    double dAngle = maxValue<double> (dAngle1, dAngle2);
-    //double dAngle = (m_dFieldOfView / 2) / cos (asin (m_dFieldOfView / 2 / m_dFocalLength));
-#else
-    if (m_dFieldOfView/2 >= m_dFocalLength) {
+  if (m_dScanDiameter / 2 >= m_dFocalLength) {
       m_fail = true;
-      m_failMessage = "Invalid geometry: Focal length must be larger than field of view";
+      m_failMessage = "Invalid geometry: Focal length must be larger than scan length";
       return;
     }
-    double dAngle = asin ((m_dFieldOfView/2) / m_dFocalLength);
-#endif    
-
-    double dHalfDetLen = 2 * m_dFocalLength * tan (dAngle);
+    const double dAngle = asin ((m_dScanDiameter / 2) / m_dFocalLength);
+    const double dHalfDetLen = 2 * m_dFocalLength * tan (dAngle);
     
     m_detLen = dHalfDetLen * 2;
     m_detInc  = m_detLen / m_nDet;
     if (m_nDet % 2 == 0) // Adjust for Even number of detectors
       m_detInc = m_detLen / (m_nDet - 1); // center detector = (nDet/2)-1
-    
+  
+    m_dFanBeamAngle = dAngle * 2;
     m_initPos.angle = 0.0;
     m_initPos.xs1 = m_dXCenter;
     m_initPos.ys1 = m_dYCenter + m_dFocalLength;
@@ -171,12 +161,12 @@ Scanner::Scanner (const Phantom& phm, const char* const geometryName, int nDet,
     m_initPos.yd2 = m_dYCenter - m_dFocalLength;
     m_initPos.angle = 0.0;
   } else if (m_idGeometry == GEOMETRY_EQUIANGULAR) {
-    if (m_dFieldOfView/2 > m_dFocalLength) {
+    if (m_dScanDiameter / 2 > m_dFocalLength) {
       m_fail = true;
-      m_failMessage = "Invalid geometry: Focal length must be larger than field of view";
+      m_failMessage = "Invalid geometry: Focal length must be larger than scan length";
       return;
     }
-    double dAngle = asin ((m_dFieldOfView/2) / m_dFocalLength);
+    const double dAngle = asin ((m_dScanDiameter / 2) / m_dFocalLength);
 
     m_detLen = 2 * dAngle;
     m_detInc = m_detLen / m_nDet;
@@ -186,6 +176,7 @@ Scanner::Scanner (const Phantom& phm, const char* const geometryName, int nDet,
     m_dAngularDetLen = m_detLen * 2;
     m_initPos.dAngularDet = -m_dAngularDetLen / 2;
     
+    m_dFanBeamAngle = dAngle * 2;
     m_initPos.angle = 0;
     m_initPos.xs1 = m_dXCenter;
     m_initPos.ys1 = m_dYCenter + m_dFocalLength;;
@@ -312,14 +303,16 @@ Scanner::collectProjections (Projections& proj, const Phantom& phm, const int iS
       m_dXMaxWin = m_dXCenter + dHalfWindowSize;
       m_dYMinWin = m_dYCenter - dHalfWindowSize;
       m_dYMaxWin = m_dYCenter + dHalfWindowSize;
-      double dHalfPhmLen = m_phmLen /  2;
       
       m_pSGP->setWindow (m_dXMinWin, m_dYMinWin, m_dXMaxWin, m_dYMaxWin);
       m_pSGP->setRasterOp (RO_COPY);
+
       m_pSGP->setColor (C_RED);
       m_pSGP->moveAbs (0., 0.);
-      m_pSGP->drawRect (m_dXCenter - dHalfPhmLen, m_dYCenter - dHalfPhmLen, m_dXCenter + dHalfPhmLen, m_dYCenter + dHalfPhmLen);
+      m_pSGP->drawCircle (m_dViewDiameter / 2);
+
       m_pSGP->moveAbs (0., 0.);
+      m_pSGP->setColor (C_GREEN);
       m_pSGP->drawCircle (m_dFocalLength);
       m_pSGP->setColor (C_BLUE);
       m_pSGP->setTextPointSize (9);
@@ -329,7 +322,7 @@ Scanner::collectProjections (Projections& proj, const Phantom& phm, const int iS
       traceShowParam ("Phantom:",       "%s", PROJECTION_TRACE_ROW_PHANT_ID, C_BLACK, phm.name().c_str());
       traceShowParam ("Geometry:", "%s", PROJECTION_TRACE_ROW_GEOMETRY, C_BLUE, convertGeometryIDToName(m_idGeometry));
       traceShowParam ("Focal Length Ratio:", "%.2f", PROJECTION_TRACE_ROW_FOCAL_LENGTH, C_BLUE, m_dFocalLengthRatio);
-      traceShowParam ("Field Of View Ratio:", "%.2f", PROJECTION_TRACE_ROW_FIELD_OF_VIEW, C_BLUE, m_dFieldOfViewRatio);
+//      traceShowParam ("Field Of View Ratio:", "%.2f", PROJECTION_TRACE_ROW_FIELD_OF_VIEW, C_BLUE, m_dFieldOfViewRatio);
       traceShowParam ("Num Detectors:", "%d", PROJECTION_TRACE_ROW_NDET, C_BLUE, proj.nDet());
       traceShowParam ("Num Views:", "%d", PROJECTION_TRACE_ROW_NVIEW, C_BLUE, proj.nView());
       traceShowParam ("Samples / Ray:", "%d", PROJECTION_TRACE_ROW_SAMPLES, C_BLUE, m_nSample);
index 0222fe4823c093531088be30e466d68f467d9311..c131702410dc6cf2a26f8bc18c37f3a1d474c2f2 100644 (file)
@@ -6,13 +6,13 @@
 --------------------Configuration: ctsim - Win32 Debug--------------------
 </h3>
 <h3>Command Lines</h3>
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP5B.tmp" with contents
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP10B.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" /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.0.0alpha5\" /FR"Debug/" /Fp"Debug/ctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 
-"C:\ctsim\src\ctsim.cpp"
+"C:\ctsim\src\views.cpp"
 ]
-Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP5B.tmp" 
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP5C.tmp" with contents
+Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP10B.tmp" 
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP10C.tmp" with contents
 [
 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 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 opengl32.lib glu32.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/ctsim.pdb" /debug /machine:I386 /out:"Debug/ctsim.exe" /pdbtype:sept /libpath:"\wx2.2.5\lib" 
 .\Debug\ctsim.obj
@@ -33,10 +33,10 @@ comctl32.lib winmm.lib rpcrt4.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib w
 \wx2.2.5\lib\zlibd.lib
 \wx2.2.5\lib\tiffd.lib
 ]
-Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP5C.tmp"
+Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP10C.tmp"
 <h3>Output Window</h3>
 Compiling...
-ctsim.cpp
+views.cpp
 Linking...
 
 
index d1526e7ce1d219b2fa1ddb5ac96b9529054ac5d4..c120591a2e7b5930f425f0de6a714ffc851217f7 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: dialogs.cpp,v 1.27 2001/01/28 19:10:18 kevin Exp $
+**  $Id: dialogs.cpp,v 1.28 2001/02/08 06:25:07 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
@@ -357,7 +357,8 @@ DialogAutoScaleParameters::getAutoScaleFactor ()
 // DialogGetRasterParameters
 /////////////////////////////////////////////////////////////////////
 
-DialogGetRasterParameters::DialogGetRasterParameters (wxWindow* pParent, int iDefaultXSize, int iDefaultYSize, int iDefaultNSamples)
+DialogGetRasterParameters::DialogGetRasterParameters 
+   (wxWindow* pParent, int iDefaultXSize, int iDefaultYSize, int iDefaultNSamples, double dDefaultViewRatio)
 : wxDialog (pParent, -1, "Set Rasterization Parameters", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxCAPTION)
 {
   wxBoxSizer* pTopSizer = new wxBoxSizer (wxVERTICAL);
@@ -365,24 +366,29 @@ DialogGetRasterParameters::DialogGetRasterParameters (wxWindow* pParent, int iDe
   pTopSizer->Add (new wxStaticText (this, -1, "Set Rasterization Parameters"), 0, wxALIGN_CENTER | wxTOP | wxLEFT | wxRIGHT, 5);
   
   pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5);
-  
+    
+  wxFlexGridSizer *pGridSizer = new wxFlexGridSizer (2);
   std::ostringstream os;
   os << iDefaultXSize;
   m_pTextCtrlXSize = new wxTextCtrl (this, -1, os.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
+  pGridSizer->Add (new wxStaticText (this, -1, "X Size"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  pGridSizer->Add (m_pTextCtrlXSize, 0, wxALIGN_CENTER_VERTICAL);
   std::ostringstream osYSize;
   osYSize << iDefaultYSize;
   m_pTextCtrlYSize = new wxTextCtrl (this, -1, osYSize.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
+  pGridSizer->Add (new wxStaticText (this, -1, "Y Size"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  pGridSizer->Add (m_pTextCtrlYSize, 0, wxALIGN_CENTER_VERTICAL);
+  std::ostringstream osViewRatio;
+  osViewRatio << dDefaultViewRatio;
+  m_pTextCtrlViewRatio = new wxTextCtrl (this, -1, osViewRatio.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
+  pGridSizer->Add (new wxStaticText (this, -1, "View Ratio"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  pGridSizer->Add (m_pTextCtrlViewRatio, 0, wxALIGN_CENTER_VERTICAL);
   std::ostringstream osNSamples;
   osNSamples << iDefaultNSamples;
   m_pTextCtrlNSamples = new wxTextCtrl (this, -1, osNSamples.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
-  
-  wxFlexGridSizer *pGridSizer = new wxFlexGridSizer (2);
-  pGridSizer->Add (new wxStaticText (this, -1, "X Size"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (m_pTextCtrlXSize, 0, wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (new wxStaticText (this, -1, "Y Size"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (m_pTextCtrlYSize, 0, wxALIGN_CENTER_VERTICAL);
   pGridSizer->Add (new wxStaticText (this, -1, "Samples per Pixel"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
   pGridSizer->Add (m_pTextCtrlNSamples, 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);
@@ -428,7 +434,6 @@ DialogGetRasterParameters::getYSize ()
     return (m_iDefaultYSize);
 }
 
-
 unsigned int
 DialogGetRasterParameters::getNSamples ()
 {
@@ -440,6 +445,16 @@ DialogGetRasterParameters::getNSamples ()
     return (m_iDefaultNSamples);
 }
 
+double
+DialogGetRasterParameters::getViewRatio ()
+{
+  wxString strCtrl = m_pTextCtrlViewRatio->GetValue();
+  double dValue;
+  if (strCtrl.ToDouble (&dValue))
+    return dValue;
+  else
+    return (m_dDefaultViewRatio);
+}
 
 
 /////////////////////////////////////////////////////////////////////
@@ -449,14 +464,18 @@ DialogGetRasterParameters::getNSamples ()
 /////////////////////////////////////////////////////////////////////
 
 
-DialogGetProjectionParameters::DialogGetProjectionParameters (wxWindow* pParent, int iDefaultNDet, int iDefaultNView, int iDefaultNSamples, double dDefaultRotAngle, double dDefaultFocalLength, double dDefaultFieldOfView, int iDefaultGeometry, int iDefaultTrace)
+DialogGetProjectionParameters::DialogGetProjectionParameters 
+   (wxWindow* pParent, int iDefaultNDet, int iDefaultNView, int iDefaultNSamples, 
+    double dDefaultRotAngle, double dDefaultFocalLength, double dDefaultViewRatio,
+    double dDefaultScanRatio, int iDefaultGeometry, int iDefaultTrace)
 : wxDialog (pParent, -1, "Set Projection Parameters", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxCAPTION)
 {
   wxBoxSizer* pTopSizer = new wxBoxSizer (wxVERTICAL);
   
   m_dDefaultRotAngle = dDefaultRotAngle;
   m_dDefaultFocalLength = dDefaultFocalLength;
-  m_dDefaultFieldOfView = dDefaultFieldOfView;
+  m_dDefaultViewRatio = dDefaultViewRatio;
+  m_dDefaultScanRatio = dDefaultScanRatio;
   m_iDefaultNSamples = iDefaultNSamples;
   m_iDefaultNView = iDefaultNView;
   m_iDefaultNDet = iDefaultNDet;
@@ -466,45 +485,49 @@ DialogGetProjectionParameters::DialogGetProjectionParameters (wxWindow* pParent,
   pTopSizer->Add (new wxStaticText (this, -1, "Set Projection Parameters"), 0, wxALIGN_CENTER | wxTOP | wxLEFT | wxRIGHT, 5);
   
   pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5);
+    
+  wxFlexGridSizer* pGridSizer = new wxFlexGridSizer (2);
+  pGridSizer->Add (new wxStaticText (this, -1, "Scanner Geometry"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  m_pListBoxGeometry = new StringValueAndTitleListBox (this, Scanner::getGeometryCount(), Scanner::getGeometryTitleArray(), Scanner::getGeometryNameArray());
+  m_pListBoxGeometry->SetSelection (iDefaultGeometry);
+  
+  pGridSizer->Add (m_pListBoxGeometry, 0, wxALL | wxALIGN_CENTER | wxEXPAND);
   
   std::ostringstream os;
   os << iDefaultNDet;
   m_pTextCtrlNDet = new wxTextCtrl (this, -1, os.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
+  pGridSizer->Add (new wxStaticText (this, -1, "Detectors"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  pGridSizer->Add (m_pTextCtrlNDet, 0, wxALIGN_CENTER_VERTICAL);
   std::ostringstream osNView;
   osNView << iDefaultNView;
   m_pTextCtrlNView = new wxTextCtrl (this, -1, osNView.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
+  pGridSizer->Add (new wxStaticText (this, -1, "Views"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  pGridSizer->Add (m_pTextCtrlNView, 0, wxALIGN_CENTER_VERTICAL);
   std::ostringstream osNSamples;
   osNSamples << iDefaultNSamples;
   m_pTextCtrlNSamples = new wxTextCtrl (this, -1, osNSamples.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
+  pGridSizer->Add (new wxStaticText (this, -1, "Samples per Detector"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  pGridSizer->Add (m_pTextCtrlNSamples, 0, wxALIGN_CENTER_VERTICAL);
   std::ostringstream osRotAngle;
   osRotAngle << dDefaultRotAngle;
   m_pTextCtrlRotAngle = new wxTextCtrl (this, -1, osRotAngle.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
+  pGridSizer->Add (new wxStaticText (this, -1, "Rotation Angle (PI units)"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  pGridSizer->Add (m_pTextCtrlRotAngle, 0, wxALIGN_CENTER_VERTICAL);
   std::ostringstream osFocalLength;
   osFocalLength << dDefaultFocalLength;
   m_pTextCtrlFocalLength = new wxTextCtrl (this, -1, osFocalLength.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
-  std::ostringstream osFieldOfView;
-  osFieldOfView << dDefaultFieldOfView;
-  m_pTextCtrlFieldOfView = new wxTextCtrl (this, -1, osFieldOfView.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
-  
-  wxFlexGridSizer* pGridSizer = new wxFlexGridSizer (2);
-  pGridSizer->Add (new wxStaticText (this, -1, "Scanner Geometry"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
-  m_pListBoxGeometry = new StringValueAndTitleListBox (this, Scanner::getGeometryCount(), Scanner::getGeometryTitleArray(), Scanner::getGeometryNameArray());
-  m_pListBoxGeometry->SetSelection (iDefaultGeometry);
-  
-  pGridSizer->Add (m_pListBoxGeometry, 0, wxALL | wxALIGN_CENTER | wxEXPAND);
-  
-  pGridSizer->Add (new wxStaticText (this, -1, "Detectors"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (m_pTextCtrlNDet, 0, wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (new wxStaticText (this, -1, "Views"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (m_pTextCtrlNView, 0, wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (new wxStaticText (this, -1, "Samples per Detector"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (m_pTextCtrlNSamples, 0, wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (new wxStaticText (this, -1, "Rotation Angle (PI units)"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (m_pTextCtrlRotAngle, 0, wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (new wxStaticText (this, -1, "Focal Length Ratio (phantom radius units)"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  pGridSizer->Add (new wxStaticText (this, -1, "Focal Length Ratio"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
   pGridSizer->Add (m_pTextCtrlFocalLength, 0, wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (new wxStaticText (this, -1, "Field of View (phantom diameter units)"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (m_pTextCtrlFieldOfView, 0, wxALIGN_CENTER_VERTICAL);
+  std::ostringstream osViewRatio;
+  osViewRatio << dDefaultViewRatio;
+  m_pTextCtrlViewRatio = new wxTextCtrl (this, -1, osViewRatio.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
+  pGridSizer->Add (new wxStaticText (this, -1, "View Ratio"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  pGridSizer->Add (m_pTextCtrlViewRatio, 0, wxALIGN_CENTER_VERTICAL);
+  std::ostringstream osScanRatio;
+  osScanRatio << dDefaultScanRatio;
+  m_pTextCtrlScanRatio = new wxTextCtrl (this, -1, osScanRatio.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
+  pGridSizer->Add (new wxStaticText (this, -1, "Scan Ratio"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  pGridSizer->Add (m_pTextCtrlScanRatio, 0, wxALIGN_CENTER_VERTICAL);
   
   m_pListBoxTrace = new StringValueAndTitleListBox (this, Trace::getTraceCount(), Trace::getTraceTitleArray(), Trace::getTraceNameArray());
   m_pListBoxTrace->SetSelection (iDefaultTrace);
@@ -591,14 +614,25 @@ DialogGetProjectionParameters::getFocalLengthRatio ()
 }
 
 double
-DialogGetProjectionParameters::getFieldOfViewRatio ()
+DialogGetProjectionParameters::getViewRatio ()
+{
+  wxString strCtrl = m_pTextCtrlViewRatio->GetValue();
+  double dValue;
+  if (strCtrl.ToDouble (&dValue))
+    return (dValue);
+  else
+    return (m_dDefaultViewRatio);
+}
+
+double
+DialogGetProjectionParameters::getScanRatio ()
 {
-  wxString strCtrl = m_pTextCtrlFieldOfView->GetValue();
+  wxString strCtrl = m_pTextCtrlScanRatio->GetValue();
   double dValue;
   if (strCtrl.ToDouble (&dValue))
     return (dValue);
   else
-    return (m_dDefaultFieldOfView);
+    return (m_dDefaultScanRatio);
 }
 
 const char*
index 8bdada08368d8c990afdd59f6bb898742c1330cc..0284924aeed4dfc119ca829212367da84b2a306f 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: dialogs.h,v 1.22 2001/01/28 19:10:18 kevin Exp $
+**  $Id: dialogs.h,v 1.23 2001/02/08 06:25:07 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
@@ -110,28 +110,35 @@ class DialogGetMinMax : public wxDialog
 class DialogGetRasterParameters : public wxDialog
 {
  public:
-    DialogGetRasterParameters (wxWindow* pParent, int iDefaultXSize = 0, int iDefaultYSize = 0, int iDefaultNSamples = 1);
+    DialogGetRasterParameters (wxWindow* pParent, int iDefaultXSize = 0, int iDefaultYSize = 0, 
+      int iDefaultNSamples = 1, double dDefaultViewRatio = 1);
     virtual ~DialogGetRasterParameters ();
 
     unsigned int getXSize ();
     unsigned int getYSize ();
     unsigned int getNSamples ();
+    double getViewRatio();
 
  private:
     wxTextCtrl* m_pTextCtrlXSize;
     wxTextCtrl* m_pTextCtrlYSize;
     wxTextCtrl* m_pTextCtrlNSamples;
+    wxTextCtrl* m_pTextCtrlViewRatio;
 
     int m_iDefaultXSize;
     int m_iDefaultYSize;
     int m_iDefaultNSamples;
+    double m_dDefaultViewRatio;
 };
 
 
 class DialogGetProjectionParameters : public wxDialog
 {
  public:
-    DialogGetProjectionParameters (wxWindow* pParent, int iDefaultNDet = 0, int iDefaultNView = 0, int iDefaultNSamples = 1, double dDefaultRotAngle = 1., double dDefaultFocalLength = 1, double dDefaultFieldOfView = 1., int iDefaultGeometry = Scanner::GEOMETRY_PARALLEL, int iDefaultTrace = Trace::TRACE_NONE);
+    DialogGetProjectionParameters (wxWindow* pParent, int iDefaultNDet = 0, 
+      int iDefaultNView = 0, int iDefaultNSamples = 1, double dDefaultRotAngle = 1., 
+      double dDefaultFocalLength = 1, double dDefaultViewRatio = 1., 
+      double dDefaultScanRatio = 1., int iDefaultGeometry = Scanner::GEOMETRY_PARALLEL, int iDefaultTrace = Trace::TRACE_NONE);
     ~DialogGetProjectionParameters ();
 
     unsigned int getNDet ();
@@ -140,7 +147,8 @@ class DialogGetProjectionParameters : public wxDialog
     int getTrace ();
 
     double getRotAngle ();
-    double getFieldOfViewRatio ();
+    double getViewRatio ();
+    double getScanRatio ();
     double getFocalLengthRatio ();
     const char* getGeometry();
 
@@ -150,8 +158,8 @@ class DialogGetProjectionParameters : public wxDialog
     wxTextCtrl* m_pTextCtrlNSamples;
     wxTextCtrl* m_pTextCtrlRotAngle;
     wxTextCtrl* m_pTextCtrlFocalLength;
-    wxTextCtrl* m_pTextCtrlFieldOfView;
-
+    wxTextCtrl* m_pTextCtrlViewRatio;
+    wxTextCtrl* m_pTextCtrlScanRatio;
     StringValueAndTitleListBox* m_pListBoxGeometry;
     StringValueAndTitleListBox* m_pListBoxTrace;
 
@@ -162,7 +170,8 @@ class DialogGetProjectionParameters : public wxDialog
     int m_iDefaultGeometry;
     double m_dDefaultRotAngle;
     double m_dDefaultFocalLength;
-    double m_dDefaultFieldOfView;
+    double m_dDefaultViewRatio;
+    double m_dDefaultScanRatio;
 };
 
 
index 9d2af66574be0219347e110b2edd811c2e2489d5..c1debac9f66427f8f1718f5113e8791f75876840 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: views.cpp,v 1.98 2001/02/04 21:28:19 kevin Exp $
+**  $Id: views.cpp,v 1.99 2001/02/08 06:25:07 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
@@ -1766,6 +1766,20 @@ PhantomCanvas::OnDraw (wxDC& dc)
     m_pView->OnDraw(& dc);
 }
 
+wxSize
+PhantomCanvas::GetBestSize() const
+{
+  if (! m_pView)
+    return wxSize(0,0);
+
+  int xSize, ySize;
+  theApp->getMainFrame()->GetClientSize (&xSize, &ySize);
+  xSize = maxValue<int> (xSize, ySize);
+  ySize = xSize = (xSize / 3);
+  return wxSize (xSize, ySize);
+}
+
+
 
 // PhantomFileView
 
@@ -1790,7 +1804,8 @@ PhantomFileView::PhantomFileView()
   m_iDefaultNSample = 1;
   m_dDefaultRotation = 1;
   m_dDefaultFocalLength = 2;
-  m_dDefaultFieldOfView = 1;
+  m_dDefaultViewRatio = 1;
+  m_dDefaultScanRatio = 1;
   m_iDefaultGeometry = Scanner::GEOMETRY_PARALLEL;
   m_iDefaultTrace = Trace::TRACE_NONE;
   
@@ -1803,6 +1818,7 @@ PhantomFileView::PhantomFileView()
   m_iDefaultRasterNY = 256;
   m_iDefaultRasterNSamples = 2;
 #endif
+  m_dDefaultRasterViewRatio = 1;
 }
 
 PhantomFileView::~PhantomFileView()
@@ -1831,7 +1847,10 @@ PhantomFileView::OnProperties (wxCommandEvent& event)
 void
 PhantomFileView::OnProjections (wxCommandEvent& event)
 {
-  DialogGetProjectionParameters dialogProjection (getFrameForChild(), m_iDefaultNDet, m_iDefaultNView, m_iDefaultNSample, m_dDefaultRotation, m_dDefaultFocalLength, m_dDefaultFieldOfView, m_iDefaultGeometry, m_iDefaultTrace);
+  DialogGetProjectionParameters dialogProjection (getFrameForChild(), 
+    m_iDefaultNDet, m_iDefaultNView, m_iDefaultNSample, m_dDefaultRotation, 
+    m_dDefaultFocalLength, m_dDefaultViewRatio, m_dDefaultScanRatio, m_iDefaultGeometry, 
+    m_iDefaultTrace);
   int retVal = dialogProjection.ShowModal();
   if (retVal == wxID_OK) {
     m_iDefaultNDet = dialogProjection.getNDet();
@@ -1840,7 +1859,8 @@ PhantomFileView::OnProjections (wxCommandEvent& event)
     m_iDefaultTrace = dialogProjection.getTrace();
     m_dDefaultRotation = dialogProjection.getRotAngle();
     m_dDefaultFocalLength = dialogProjection.getFocalLengthRatio();
-    m_dDefaultFieldOfView = dialogProjection.getFieldOfViewRatio();
+    m_dDefaultViewRatio = dialogProjection.getViewRatio();
+    m_dDefaultScanRatio = dialogProjection.getScanRatio();
     wxString sGeometry = dialogProjection.getGeometry();
     m_iDefaultGeometry = Scanner::convertGeometryNameToID (sGeometry.c_str());
     
@@ -1848,7 +1868,7 @@ PhantomFileView::OnProjections (wxCommandEvent& event)
       const Phantom& rPhantom = GetDocument()->getPhantom();
       Projections* pProj = new Projections;
       Scanner theScanner (rPhantom, sGeometry.c_str(), m_iDefaultNDet, m_iDefaultNView, m_iDefaultNSample, 
-                          m_dDefaultRotation, m_dDefaultFocalLength, m_dDefaultFieldOfView);
+                          m_dDefaultRotation, m_dDefaultFocalLength, m_dDefaultViewRatio, m_dDefaultScanRatio);
       if (theScanner.fail()) {
         wxString msg = "Failed making scanner\n";
         msg += theScanner.failMessage().c_str();
@@ -1886,7 +1906,12 @@ PhantomFileView::OnProjections (wxCommandEvent& event)
       }
       
       std::ostringstream os;
-      os << "Projections for " << rPhantom.name() << ": nDet=" << m_iDefaultNDet << ", nView=" << m_iDefaultNView << ", nSamples=" << m_iDefaultNSample << ", RotAngle=" << m_dDefaultRotation << ", FocalLengthRatio=" << m_dDefaultFocalLength << ", FieldOfViewRatio=" << m_dDefaultFieldOfView << ", Geometry=" << sGeometry.c_str();
+      os << "Projections for " << rPhantom.name() << ": nDet=" << m_iDefaultNDet 
+        << ", nView=" << m_iDefaultNView << ", nSamples=" << m_iDefaultNSample 
+        << ", RotAngle=" << m_dDefaultRotation << ", FocalLengthRatio=" << m_dDefaultFocalLength 
+        << ", ViewRatio=" << m_dDefaultViewRatio << ", ScanRatio=" << m_dDefaultScanRatio 
+        << ", Geometry=" << sGeometry.c_str() << ", FanBeamAngle=" << 
+        convertRadiansToDegrees (theScanner.fanBeamAngle());
       pProj->setCalcTime (timer.timerEnd());
       pProj->setRemark (os.str());
       *theApp->getLog() << os.str().c_str() << "\n";
@@ -1921,14 +1946,18 @@ PhantomFileView::OnProjections (wxCommandEvent& event)
 void
 PhantomFileView::OnRasterize (wxCommandEvent& event)
 {
-  DialogGetRasterParameters dialogRaster (getFrameForChild(), m_iDefaultRasterNX, m_iDefaultRasterNY, m_iDefaultRasterNSamples);
+  DialogGetRasterParameters dialogRaster (getFrameForChild(), m_iDefaultRasterNX, m_iDefaultRasterNY, 
+    m_iDefaultRasterNSamples, m_dDefaultRasterViewRatio);
   int retVal = dialogRaster.ShowModal();
   if (retVal == wxID_OK) {
     m_iDefaultRasterNX = dialogRaster.getXSize();
     m_iDefaultRasterNY  = dialogRaster.getYSize();
     m_iDefaultRasterNSamples = dialogRaster.getNSamples();
+    m_dDefaultRasterViewRatio = dialogRaster.getViewRatio();
     if (m_iDefaultRasterNSamples < 1)
       m_iDefaultRasterNSamples = 1;
+    if (m_dDefaultRasterViewRatio < 0)
+      m_dDefaultRasterViewRatio = 0;
     if (m_iDefaultRasterNX > 0 && m_iDefaultRasterNY > 0) {
       const Phantom& rPhantom = GetDocument()->getPhantom();
 
@@ -1939,7 +1968,8 @@ PhantomFileView::OnRasterize (wxCommandEvent& event)
                                     pImageFile->nx() + 1, getFrameForChild(), wxPD_CAN_ABORT);
       Timer timer;
       for (unsigned int i = 0; i < pImageFile->nx(); i++) {
-        rPhantom.convertToImagefile (*pImageFile, m_iDefaultRasterNSamples, Trace::TRACE_NONE, i, 1, true);
+        rPhantom.convertToImagefile (*pImageFile, m_dDefaultRasterViewRatio, m_iDefaultRasterNSamples, 
+          Trace::TRACE_NONE, i, 1, true);
         if (! dlgProgress.Update (i+1)) {
           delete pImageFile;
           return;
@@ -1958,7 +1988,8 @@ PhantomFileView::OnRasterize (wxCommandEvent& event)
       pRasterDoc->getView()->getFrame()->Show(true);
       std::ostringstream os;
       os << "Rasterize Phantom " << rPhantom.name() << ": XSize=" << m_iDefaultRasterNX << ", YSize=" 
-        << m_iDefaultRasterNY << ", nSamples=" << m_iDefaultRasterNSamples;
+        << m_iDefaultRasterNY << ", ViewRatio=" << m_dDefaultRasterViewRatio << ", nSamples=" 
+        << m_iDefaultRasterNSamples;;
       *theApp->getLog() << os.str().c_str() << "\n";
       pImageFile->labelAdd (os.str().c_str(), timer.timerEnd());
       ImageFileView* rasterView = pRasterDoc->getView();
@@ -1976,11 +2007,8 @@ PhantomCanvas*
 PhantomFileView::CreateCanvas (wxFrame *parent)
 {
   PhantomCanvas* pCanvas;
-  int width, height;
-  parent->GetClientSize(&width, &height);
-  
-  pCanvas = new PhantomCanvas (this, parent, wxPoint(0, 0), wxSize(width, height), 0);
   
+  pCanvas = new PhantomCanvas (this, parent, wxPoint(0, 0), wxSize(0,0), 0);
   pCanvas->SetBackgroundColour(*wxWHITE);
   pCanvas->Clear();
   
@@ -1995,9 +2023,9 @@ wxDocChildFrame*
 PhantomFileView::CreateChildFrame(wxDocument *doc, wxView *view)
 {
 #if CTSIM_MDI
-  wxDocMDIChildFrame *subframe = new wxDocMDIChildFrame (doc, view, theApp->getMainFrame(), -1, "Phantom Frame", wxPoint(10, 10), wxSize(256, 256), wxDEFAULT_FRAME_STYLE);
+  wxDocMDIChildFrame *subframe = new wxDocMDIChildFrame (doc, view, theApp->getMainFrame(), -1, "Phantom Frame", wxPoint(10, 10), wxSize(0, 0), wxDEFAULT_FRAME_STYLE);
 #else
-  wxDocChildFrame *subframe = new wxDocChildFrame (doc, view, theApp->getMainFrame(), -1, "Phantom Frame", wxPoint(10, 10), wxSize(256, 256), wxDEFAULT_FRAME_STYLE);
+  wxDocChildFrame *subframe = new wxDocChildFrame (doc, view, theApp->getMainFrame(), -1, "Phantom Frame", wxPoint(10, 10), wxSize(0, 0), wxDEFAULT_FRAME_STYLE);
 #endif
   theApp->setIconForFrame (subframe);
   
@@ -2062,11 +2090,11 @@ PhantomFileView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
 {
   m_pFrame = CreateChildFrame(doc, this);
   SetFrame(m_pFrame);
-  
-  int width, height;
-  m_pFrame->GetClientSize(&width, &height);
-  m_pFrame->SetTitle("PhantomFileView");
   m_pCanvas = CreateCanvas (m_pFrame);
+  m_pFrame->SetClientSize (m_pCanvas->GetBestSize());
+  m_pCanvas->SetClientSize (m_pCanvas->GetBestSize());
+  
+  m_pFrame->SetTitle ("PhantomFileView");
   
 #ifdef __X__
   int x, y;  // X requires a forced resize
index e3eb560f7b2a28c97370f4461ad0fe09e4dea311..14a7e0c93913d80b271d0391408b722c42231c7d 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: views.h,v 1.44 2001/01/31 01:01:22 kevin Exp $
+**  $Id: views.h,v 1.45 2001/02/08 06:25:07 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
@@ -296,11 +296,13 @@ private:
   int m_iDefaultTrace;
   double m_dDefaultRotation;
   double m_dDefaultFocalLength;
-  double m_dDefaultFieldOfView;
+  double m_dDefaultViewRatio;
+  double m_dDefaultScanRatio;
   
   int m_iDefaultRasterNX;
   int m_iDefaultRasterNY;
   int m_iDefaultRasterNSamples;
+  double m_dDefaultRasterViewRatio;
 
   wxWindow* getFrameForChild() 
 #if CTSIM_MDI
@@ -343,6 +345,7 @@ public:
   PhantomCanvas (PhantomFileView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style);
   virtual ~PhantomCanvas();
 
+  virtual wxSize GetBestSize() const;
   void setView(PhantomFileView* pView)
   { m_pView = pView; }
   virtual void OnDraw(wxDC& dc);
index edcdba43cad1d9e4345fc53362e8524d35791646..1dfa39d3aaa327e5ba6149cac5ebf5bc7b978683 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: phm2if.cpp,v 1.21 2001/01/09 22:31:47 kevin Exp $
+**  $Id: phm2if.cpp,v 1.22 2001/02/08 06:25:07 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
@@ -29,7 +29,7 @@
 #include "timer.h"
 
 
-enum { O_PHANTOM, O_DESC, O_NSAMPLE, O_FILTER, O_TRACE, O_VERBOSE, O_HELP, 
+enum { O_PHANTOM, O_DESC, O_NSAMPLE, O_FILTER, O_VIEW_RATIO, O_TRACE, O_VERBOSE, O_HELP, 
 O_PHMFILE, O_FILTER_DOMAIN, O_FILTER_BW, O_FILTER_PARAM, O_DEBUG, O_VERSION };
 
 static struct option my_options[] = 
@@ -43,6 +43,7 @@ static struct option my_options[] =
   {"filter-bw", 1, 0, O_FILTER_BW},
   {"filter-param", 1, 0, O_FILTER_PARAM},
   {"trace", 1, 0, O_TRACE},
+  {"view-ratio", 1, 0, O_VIEW_RATIO},
   {"verbose", 0, 0, O_VERBOSE},
   {"debug", 0, 0, O_DEBUG},
   {"help", 0, 0, O_HELP},
@@ -50,7 +51,7 @@ static struct option my_options[] =
   {0, 0, 0, 0}
 };
 
-static const char* g_szIdStr = "$Id: phm2if.cpp,v 1.21 2001/01/09 22:31:47 kevin Exp $";
+static const char* g_szIdStr = "$Id: phm2if.cpp,v 1.22 2001/02/08 06:25:07 kevin Exp $";
 
 void 
 phm2if_usage (const char *program)
@@ -61,6 +62,7 @@ phm2if_usage (const char *program)
   std::cout << "     outfile         Name of output file for image\n";
   std::cout << "     nx              Number of pixels X-axis\n";
   std::cout << "     ny              Number of pixels Y-axis\n";
+  std::cout << "     --view-ratio    View diameter to phantom diameter ratio (default = 1)\n";
   std::cout << "     --phantom       Phantom to use for projection\n";
   std::cout << "        herman       Herman head phantom\n";
   std::cout << "        herman-b     Herman head phantom (Bordered)\n";
@@ -117,6 +119,7 @@ phm2if_main (int argc, char* const argv[])
   int opt_nx = 0;
   int opt_ny = 0;
   int opt_nsample = 1;
+  double optViewRatio = 1.;
   double optFilterParam = 1.;
   double optFilterBW = 1.;
   int optTrace = Trace::TRACE_NONE;
@@ -173,6 +176,15 @@ phm2if_main (int argc, char* const argv[])
           return (1);
         }
         break;
+      case O_VIEW_RATIO:
+        optViewRatio = strtod(optarg, &endptr);
+        endstr = optarg + strlen(optarg);
+        if (endptr != endstr) {
+          sys_error(ERR_SEVERE,"Error setting --view-ratio to %s\n", optarg);
+          phm2if_usage(argv[0]);
+          return (1);
+        }
+        break;
       case O_FILTER_PARAM:
         optFilterParam = strtod(optarg, &endptr);
         endstr = optarg + strlen(optarg);
@@ -234,7 +246,7 @@ phm2if_main (int argc, char* const argv[])
     }
     
     std::ostringstream oss;
-    oss << "phm2if: nx=" << opt_nx << ", ny=" << opt_ny << ", nsample=" << opt_nsample << ", ";
+    oss << "phm2if: nx=" << opt_nx << ", ny=" << opt_ny << ", viewRatio=" << optViewRatio << ", nsample=" << opt_nsample << ", ";
     if (optPhmFilename != "")
       oss << "phantomFile=" << optPhmFilename;
     else if (optPhmName != "")
@@ -279,6 +291,7 @@ phm2if_main (int argc, char* const argv[])
   mpiWorld.getComm().Bcast (&opt_nx, 1, MPI::INT, 0);
   mpiWorld.getComm().Bcast (&opt_ny, 1, MPI::INT, 0);
   mpiWorld.getComm().Bcast (&opt_nsample, 1, MPI::INT, 0);
+  mpiWorld.getComm().Bcast *&optViewRatio, 1, MPI::DOUBLE, 0);
   mpiWorld.getComm().Bcast (&optFilterParam, 1, MPI::DOUBLE, 0);
   mpiWorld.getComm().Bcast (&optFilterBW, 1, MPI::DOUBLE, 0);
   
@@ -316,7 +329,7 @@ phm2if_main (int argc, char* const argv[])
     }
   } else {
     TimerCollectiveMPI timerRasterize (mpiWorld.getComm());
-    phm.convertToImagefile (*pImLocal, opt_nsample, optTrace, mpiWorld.getMyStartWorkUnit(), mpiWorld.getMyLocalWorkUnits(), false);
+    phm.convertToImagefile (*pImLocal, optViewRatio, opt_nsample, optTrace, mpiWorld.getMyStartWorkUnit(), mpiWorld.getMyLocalWorkUnits(), false);
     if (optVerbose)
       timerRasterize.timerEndAndReport ("Time to rasterize phantom");
     
@@ -332,7 +345,7 @@ phm2if_main (int argc, char* const argv[])
   } else if (optFilterName != "") {
     pImGlobal->filterResponse (optDomainName.c_str(), optFilterBW, optFilterName.c_str(), optFilterParam);
   } else {
-    phm.convertToImagefile (*pImGlobal, opt_nsample, optTrace);
+    phm.convertToImagefile (*pImGlobal, optViewRatio, opt_nsample, optTrace);
   }
 #endif
   
@@ -345,19 +358,6 @@ phm2if_main (int argc, char* const argv[])
     pImGlobal->fileWrite (optOutFilename.c_str());
     if (optVerbose)
       std::cout << "Time to rasterize phantom: " << calctime << " seconds\n";
-    
-    if (optTrace >= Trace::TRACE_PHANTOM) {
-      double dmin, dmax;
-      int nscale;
-      
-      std::cout << "Enter display size scale (nominal = 1): ";
-      std::cin >> nscale;
-      std::cout << "Enter minimum and maximum densities (min, max): ";
-      std::cin >> dmin;
-      
-      std::cin >> dmax;
-      pImGlobal->displayScaling (nscale, dmin, dmax);
-    }
   }
   
   delete pImGlobal;
index 34557af8a08e0ca40b331b4a53fa335bb9648a7c..f32f5c57cb7422c4273a6a940242dda9483464f6 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: phm2pj.cpp,v 1.23 2001/01/17 06:25:15 kevin Exp $
+**  $Id: phm2pj.cpp,v 1.24 2001/02/08 06:25:07 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
@@ -29,7 +29,7 @@
 #include "timer.h"
 
 
-enum { O_PHANTOM, O_DESC, O_NRAY, O_ROTANGLE, O_PHMFILE, O_GEOMETRY, O_FOCAL_LENGTH, O_FIELD_OF_VIEW,
+enum { O_PHANTOM, O_DESC, O_NRAY, O_ROTANGLE, O_PHMFILE, O_GEOMETRY, O_FOCAL_LENGTH, O_VIEW_RATIO, O_SCAN_RATIO,
        O_TRACE, O_VERBOSE, O_HELP, O_DEBUG, O_VERSION };
 
 static struct option phm2pj_options[] = 
@@ -41,7 +41,8 @@ static struct option phm2pj_options[] =
   {"rotangle", 1, 0, O_ROTANGLE},
   {"geometry", 1, 0, O_GEOMETRY},
   {"focal-length", 1, 0, O_FOCAL_LENGTH},
-  {"field-of-view", 1, 0, O_FIELD_OF_VIEW},
+  {"view-ratio", 1, 0, O_VIEW_RATIO},
+  {"scan-ratio", 1, 0, O_SCAN_RATIO},
   {"trace", 1, 0, O_TRACE},
   {"verbose", 0, 0, O_VERBOSE},
   {"help", 0, 0, O_HELP},
@@ -50,7 +51,7 @@ static struct option phm2pj_options[] =
   {0, 0, 0, 0}
 };
 
-static const char* g_szIdStr = "$Id: phm2pj.cpp,v 1.23 2001/01/17 06:25:15 kevin Exp $";
+static const char* g_szIdStr = "$Id: phm2pj.cpp,v 1.24 2001/02/08 06:25:07 kevin Exp $";
 
 
 void 
@@ -78,7 +79,9 @@ phm2pj_usage (const char *program)
   std::cout << "        equiangular   Equiangular divergent scan beams\n";
   std::cout << "     --focal-length   Focal length ratio (ratio to radius of phantom)\n";
   std::cout << "                      (default = 1)\n";
-  std::cout << "     --field-of-view  Field of view (ratio to diameter of phantom square)\n";
+  std::cout << "     --view-ratio     Length to view (view diameter to phantom diameter)\n";
+  std::cout << "                      (default = 1)\n";
+  std::cout << "     --scan-ratio     Length to scan (scan diameter to view diameter)\n";
   std::cout << "                      (default = 1)\n";
   std::cout << "     --trace          Trace level to use\n";
   std::cout << "        none          No tracing (default)\n";
@@ -110,7 +113,8 @@ phm2pj_main (int argc, char* const argv[])
   int opt_nview;
   int opt_nray = 1;
   double dOptFocalLength = 1.;
-  double dOptFieldOfView = 1.;
+  double dOptViewRatio = 1.;
+  double dOptScanRatio = 1.;
   int opt_trace = Trace::TRACE_NONE;
   int opt_verbose = 0;
   int opt_debug = 0;
@@ -177,11 +181,20 @@ phm2pj_main (int argc, char* const argv[])
          return (1);
        }
        break;
-      case O_FIELD_OF_VIEW:
-       dOptFieldOfView = strtod(optarg, &endptr);
+  case O_VIEW_RATIO:
+       dOptViewRatio = strtod(optarg, &endptr);
+       endstr = optarg + strlen(optarg);
+       if (endptr != endstr) {
+         std::cerr << "Error setting --view-ratio to " << optarg << std::endl;
+         phm2pj_usage(argv[0]);
+         return (1);
+       }
+       break;
+  case O_SCAN_RATIO:
+       dOptScanRatio = strtod(optarg, &endptr);
        endstr = optarg + strlen(optarg);
        if (endptr != endstr) {
-         std::cerr << "Error setting --field-of-view to " << optarg << std::endl;
+         std::cerr << "Error setting --scan-ratio to " << optarg << std::endl;
          phm2pj_usage(argv[0]);
          return (1);
        }
@@ -275,6 +288,9 @@ phm2pj_main (int argc, char* const argv[])
   TimerCollectiveMPI timerBcast(mpiWorld.getComm());
   mpiWorld.BcastString (optPhmName);
   mpiWorld.getComm().Bcast (&opt_rotangle, 1, MPI::DOUBLE, 0);
+  mpiWorld.getComm().Bcast (&dOptFocalLength, 1, MPI::DOUBLE, 0);
+  mpiWorld.getComm().Bcast (&dOptViewRatio, 1, MPI::DOUBLE, 0);
+  mpiWorld.getComm().Bcast (&dOptScanRatio, 1, MPI::DOUBLE, 0);
   mpiWorld.getComm().Bcast (&opt_nview, 1, MPI::INT, 0);
   mpiWorld.getComm().Bcast (&opt_ndet, 1, MPI::INT, 0);
   mpiWorld.getComm().Bcast (&opt_nray, 1, MPI::INT, 0);
@@ -289,7 +305,7 @@ phm2pj_main (int argc, char* const argv[])
 #endif
 
   opt_rotangle *= PI;
-  Scanner scanner (phm, optGeometryName.c_str(), opt_ndet, opt_nview, opt_nray, opt_rotangle, dOptFocalLength, dOptFieldOfView);
+  Scanner scanner (phm, optGeometryName.c_str(), opt_ndet, opt_nview, opt_nray, opt_rotangle, dOptFocalLength, dOptViewRatio, dOptScanRatio);
   if (scanner.fail()) {
     std::cout << "Scanner Creation Error: " << scanner.failMessage() << std::endl;
     return (1);