r520: no message
authorKevin M. Rosenberg <kevin@rosenberg.net>
Sun, 11 Feb 2001 04:56:38 +0000 (04:56 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Sun, 11 Feb 2001 04:56:38 +0000 (04:56 +0000)
23 files changed:
doc/ctsim-concepts.tex
doc/ctsim-gui.tex
doc/ctsim-install.tex
doc/ctsim-textui.tex
doc/ctsim-web.tex
doc/ctsim.tex
doc/mytitle.sty
include/Makefile.am
include/backprojectors.h
include/ct.h
include/filter.h
libctsim/backprojectors.cpp
libctsim/filter.cpp
libctsim/procsignal.cpp
libctsim/reconstruct.cpp
libctsupport/Makefile.am
msvc/ctsim/ctsim.plg
src/ctsim.cpp
src/ctsim.h
src/dialogs.cpp
src/dialogs.h
src/views.cpp
tools/phm2pj.cpp

index 81dbf42..ddf6bed 100644 (file)
@@ -1,14 +1,15 @@
 \chapter{Concepts}\index{Concepts}%
 \setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
-\setfooter{\thepage}{}{}{}{}{\thepage}%
+\setfooter{\thepage}{}{}{}{\small Version 0.2}{\thepage}%
 
 \section{Overview}\label{conceptoverview}\index{Concepts,Overview}%
-The operation of \ctsim\ begins with the phantom object.  A phantom
-object consists of geometric elements.  A scanner is specified and the
-projection data simulated.  Finally that projection data can be
-reconstructed using various user controlled algorithms producing an
-image of the phantom object. This reconstruction can then be
-statistically compared to the original phantom object.
+The operation of \ctsim\ begins with the phantom object.  A
+phantom object consists of geometric elements.  A scanner is
+specified and the collection of x-ray data, or projections, is
+simulated. That projection data can be reconstructed using various
+user-controlled algorithms producing an image of the phantom
+object. This reconstruction can then be statistically compared to
+the original phantom object.
 
 In order to use \ctsim\ effectively, some knowledge of how \ctsim\ works
 and the approach taken is required. \ctsim\ deals with a variety of
@@ -18,14 +19,15 @@ object, but the two objects we need to be concerned with are the
 \section{Phantoms}\label{conceptphantom}\index{Concepts,Phantoms}%
 \subsection{Overview}\label{phantomoverview}\index{Concepts,Phantoms,Overview}%
 
-\ctsim\ uses geometrical objects to
-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 elements, standard phantoms used in the CT literature can
-be constructed.  In fact, \ctsim\ provides a shortcut to load the
-published phantoms of Herman and Shepp-Logan.  \ctsim\ also reads text
-files of user-defined phantoms.
+\ctsim\ uses geometrical objects to 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
+elements, standard phantoms used in the CT literature can be
+constructed.  In fact, \ctsim\ provides a shortcut to load the
+published phantoms of Herman\cite{HERMAN80} and
+Shepp-Logan\cite{SHEPP74}. \ctsim\ also reads text files of
+user-defined phantoms.
 
 The types of phantom elements and their definitions are taken with
 permission from G.T. Herman's 1980 book\cite{HERMAN80}.
@@ -36,7 +38,7 @@ phantom.  Each line contains seven entries, in the following form:
 \begin{verbatim}
 element-type cx cy dx dy r a
 \end{verbatim}
-The first entry defines the type of the element, one of
+The first entry defines the type of the element, either
 \rtfsp\texttt{rectangle}, \texttt{}, \texttt{triangle},
 \rtfsp\texttt{sector}, or \texttt{segment}. \texttt{cx},
 \rtfsp\texttt{cy}, \texttt{dx} and \texttt{dy} have different
@@ -138,15 +140,16 @@ square
 These relationships are diagrammed in figure 2.1.
 
 \subsubsection{View Diameter}
-The \emph{view diameter} is the area that is being processed during scanning of phantoms as
-well as during rasterization of phantoms. By default, the \emph{view diameter}
-\rtfsp 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 ratio},
-\latexonly{$v_r$.}\latexignore{\rtfsp \emph{VR}.}
-The \emph{view diameter} is then set as
-\latexonly{$$v_d = p_d v_r$$}\latexignore{\\$$\emph{Vd = Pd x VR}$$}
+The \emph{view diameter} is the area that is being processed
+during scanning of phantoms as well as during rasterization of
+phantoms. By default, the \emph{view diameter} \rtfsp 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 ratio},
+\latexonly{$v_r$.}\latexignore{\rtfsp \emph{VR}.} The \emph{view
+diameter} is then calculated as \latexonly{$$v_d = p_d
+v_r$$}\latexignore{\\$$\emph{Vd = Pd x VR}$$}
 
 By using a
 \latexonly{$v_r$}\latexignore{\emph{VR}}
@@ -158,17 +161,17 @@ be impossible and is analagous to inserting an object into the CT
 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 ratio}
-\latexonly{$s_r$}\latexignore{\emph{SR}}
+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 ratio}, \latexonly{$s_r$,}\latexignore{\emph{SR},}
 is born. The scan diameter
-\latexonly{$s_d$}\latexignore{\emph{Sd}}
-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.
+\latexonly{$s_d$}\latexignore{\emph{Sd}} 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},
@@ -180,9 +183,13 @@ of the view radius. Focal length is
 calculated as
 \latexonly{$$f = (v_d / 2) f_r$$}\latexignore{\\$$\emph{F = (Vd / 2) x FR}$$}
 
-For parallel geometry scanning, the focal length doesn't matter. However,
-divergent geometry scanning (equilinear and equiangular), the \emph{focal
-length ratio} should be set at \texttt{2} or more to avoid artifacts.
+For parallel geometry scanning, the focal length doesn't matter.
+However, divergent geometry scanning (equilinear and equiangular),
+the \emph{focal length ratio} should be set at \texttt{2} or more
+to avoid artifacts. Moreover, a value of less than \texttt{1},
+though it can be given to \ctsim, is physically impossible and it
+analagous to have having the x-ray source with the \emph{view
+diameter}.
 
 
 \subsection{Parallel Geometry}\label{geometryparallel}\index{Concepts,Scanner,Geometries,Parallel}
@@ -213,13 +220,14 @@ See figure 2.2.
 
 
 \subsubsection{Fan Beam Angle}
-For these divergent beam geometries, the \emph{fan beam angle} needs
-to be calculated. For real-world CT scanners, this is fixed at the
-time of manufacture. \ctsim, however, calculates the \emph{fan beam angle},
-$\alpha$ from the \emph{scan diameter} and the \emph{focal length}
-\latexignore{\\$$\emph{alpha = 2 x asin ( (Sd / 2) / f)}$$\\}
-\latexonly{\begin{equation}\label{alphacalc}\alpha = 2 \sin^{-1} ((s_d / 2) / f)\end{equation}}
-This is illustrated in figure 2.3.
+For these divergent beam geometries, the \emph{fan beam angle}
+needs to be calculated. For real-world CT scanners, this is fixed
+at the time of manufacture. \ctsim, however, calculates the
+\emph{fan beam angle}, $\alpha$, from the \emph{scan diameter} and
+the \emph{focal length} \latexignore{\\$$\emph{alpha = 2 x asin (
+(Sd / 2) / f)}$$\\}
+\latexonly{\begin{equation}\label{alphacalc}\alpha = 2 \sin^{-1}
+((s_d / 2) / f)\end{equation}} This is illustrated in figure 2.3.
 \begin{figure}
 \image{10cm;0cm}{alphacalc.eps}
 \caption{Calculation of $\alpha$}
@@ -236,37 +244,39 @@ there are significant artifacts. The primary way to manage the
 To illustrate, the \emph{scan diameter} can be defined as
 \latexonly{$$s_d = s_r v_r p_d$$}\latexignore{\\$$Sd = Sr x Vr x Pd$$\\}
 
-Further, $f$ can be defined as
-\latexonly{$$f = f_r (v_r p_d / 2)$$}
-Plugging these equations into
-\latexignore{the above equation,}\latexonly{equation~\ref{alphacalc},}
-We have,
+Further, $f$ can be defined as \latexonly{$$f = f_r (v_r p_d /
+2)$$}\latexignore{\\$$F = FR x (VR x Pd)$$\\}
+
+Substituting these equations into \latexignore{the above
+equation,}\latexonly{equation~\ref{alphacalc},} We have,
 \latexonly{
 \begin{eqnarray}
 \alpha &= 2\,\sin^{-1} \frac{s_r v_r p_d / 2}{f_r v_r (p_d / 2)} \nonumber \\
 &= 2\,\sin^{-1} (s_r / f_r)
 \end{eqnarray}
-}
+} \latexignore{\\$$\alpha = 2 sin (Sr / Fr$$\\}
 
-Since in normal scanning $s_r = 1$, $\alpha$ depends only upon the \emph{focal length ratio}.
+Since in normal scanning $s_r$ = 1, $\alpha$ depends only upon the
+\emph{focal length ratio}.
 
 \subsubsection{Detector Array Size}
-In general, you do not need to be concerned with the detector array
-size. It is automatically calculated by \ctsim.
+In general, you do not need to be concerned with the detector
+array size. It is automatically calculated by \ctsim. For those
+interested, this section explains how the detector array size is
+calculated.
 
 For parallel geometry, the detector length is equal to the scan
 diameter.
 
-For divergent beam geometrys, the size of the
-detector array also depends upon the \emph{focal length}.
-Increasing the \emph{focal length}
-decreases the size of the detector array while increasing the \emph{scan
-diameter} increases the detector array size.
+For divergent beam geometries, the size of the detector array also
+depends upon the \emph{focal length}. Increasing the \emph{focal
+length} decreases the size of the detector array while increasing
+the \emph{scan diameter} increases the detector array size.
 
-For equiangular geometry, the detectors are spaced around a
-circle covering an angular distance of
-\latexonly{$\alpha$.}\latexignore{\emph{alpha}.}
-The dotted circle in
+For equiangular geometry, the detectors are spaced around a circle
+covering an angular distance of
+\latexonly{$2\,\alpha$.}\latexignore{\emph{2 \alpha}.} The dotted
+circle in
 \begin{figure}
 \image{10cm;0cm}{equiangular.eps}
 \caption{Equiangluar geometry}
@@ -275,10 +285,9 @@ figure 2.4 indicates the positions of the detectors in this case.
 
 For equilinear geometry, the detectors are space along a straight
 line. The length of the line depends upon
-\latexonly{$\alpha$}\latexignore{\emph{alpha}}
-and the \emph{focal length}. It is calculated as
-\latexonly{$$\mathrm{detLengh} = 4\,f \tan (\alpha / 2)$$}
-\latexignore{\\$$\emph{detLength} = 4 x F x tan(alpha/2)$$\\}
+\latexonly{$\alpha$}\latexignore{\emph{alpha}} and the \emph{focal
+length}. It is calculated as \latexonly{$4\,f \tan (\alpha / 2)$}
+\latexignore{\emph{4 x F x tan(\alpha/2)}}
 \begin{figure}
 \image{10cm;0cm}{equilinear.eps}
 \caption{Equilinear geometry}
@@ -320,12 +329,12 @@ transform of the projection data and multiply that by the $|w|$ filter and
 then perform an inverse fourier transform.
 
 Though multiplying by $|w|$ gives the sharpest reconstructions, in
-practice, superior results are obtained by mutiplying the $|w|$ filter
-by another filter that attenuates the higher frequencies. \ctsim\ has
+practice, superior results are obtained by reducing the higher
+frequencies. This is performed by mutiplying the $|w|$ filter by
+another filter that attenuates the higher frequencies. \ctsim\ has
 multiple filters for this purpose.
 
 \subsubsection{Backprojection of filtered projections}
-Backprojection is the process of ``smearing'' the filtered projections
-over the reconstructing image. Various levels of interpolation can be
-specified.  In general, the trade-off is between quality and execution
-time.
+Backprojection is the process of ``smearing'' the filtered
+projections over the reconstructing image. Various levels of
+interpolation can be specified.
index 420e56d..8d675de 100644 (file)
@@ -1,54 +1,72 @@
-\chapter{ctsim - the Graphical User Interface}\label{ctsim}\index{ctsim}% 
+\chapter{The Graphical User Interface}\label{ctsim}\index{ctsim}%
 \setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
 \setfooter{\thepage}{}{}{}{}{\thepage}%
 
 \section{Overview}
-\ctsim\ is the graphical shell for the CTSim project. It is
-written using the wxLibrary for cross-platform compatibility with GTK,
-Motif, and Microsoft Windows. It includes all of the functionality of
-the command-line tool \ctsimtext\ as well as image processing and visualization features.
+\ctsim\ is the graphical shell for the CTSim project. It utilizes
+using the \urlref{wxWindows}{http://www.wxwindows.org} library for
+cross-platform compatibility. The graphical shell is compatible
+with Microsoft Windows, \urlref{GTK}{http://www.gtk.org}, and
+\urlref{Motif}{http://www.openmotif.org} graphical environments.
+This graphical includes all of the functionality of the
+command-line interface \helprefn{\ctsimtext}{ctsimtext} as well as
+great image processing and visualization features.
 
-\ctsim\ can open projection files, image files, phantom definition files, and plotfiles.
+\ctsim\ can open projection files, image files, phantom files, and
+plotfiles.
 
-\usage
-ctsim [OPTIONS] [files to open...]
+\usage \texttt{ctsim [files to open...]
+
+You can invoke \ctsim\ by itself on the command line, or include
+any number of files that you want \ctsim\ to automatically open.
+
+\section{File Types Support}
+
+Phantom and plot files are stored as ASCII text. In contrast,
+image and projection files are stored in binary format. \ctsim\
+incorporates logic so that binary files are cross-platform
+compatible between both little and big endian architectures.
 
-\section{Files Supported}
 \subsection{Phantom}
-Phantom files are supported. Besides loading phantom files from
-the disk, the Herman and Shepp-Logan phantoms are built-in to CTSim.
-Phantom files can be read and stored on the disk. However, a text
-editor is required to create and edit these files.
-\subsection{Image}
-Image files are 2-dimensional files stored a 4-byte floating point values.
-They are stored in little-endian format and \ctsim\ incorporates routines
-to read and write files correctly on both big and little endian architextures.
+Besides loading phantom files from the disk, the Herman and
+Shepp-Logan phantoms are built-in to \ctsim. Phantom files can be
+read and stored on the disk. However, a text editor is required to
+create and edit these files.
 
-Images files can be either real or complex valued. Typically, all images
-are real except for images that have been processed by Fourier transforms.
+\subsection{Image}
+Image files are 2-dimensional files that store 4-byte floating
+point values. Images files can be either real or complex valued.
+Typically, all images are real except for images that have been
+processed by Fourier transforms. As you might expect,
+complex-valued images are twice the size of real-valued images
+since both a real and imaginary component need to be store.
 
 \subsection{Projection}
 Projection files are created from Phantom files during the projection process.
 Numerous options are available for creation of the these files.
 
 \subsection{Plot}
-Plot files are created by CTSim during analysis of image files. They can be
-read and stored on the disk. They are stored as ASCII files for easy
-cross-platform support.
+Plot files are created by \ctsim\ during analysis of image files.
+They can be read and stored on the disk. They are stored as ASCII
+files for easy cross-platform support.
 
 \section{Phantom Menus}
 
 \subsection{Rasterize Dialog}
-This creates an image file from a phantom. Technically, it converts
-the phantom from a vector (infinite resolution) object into defined resolution
-image. The parameters to set are:
-
-x-size   Number of columns in image file
-y-size   Number of rows in image file
-samples  Numbers of samples taken per pixel in the x and y directions.
-         For example, if the nsamples is set to \texttt{3}, then for every
-         pixel in the image file, 9 samples (3 x 3) are averaged.
+This creates an image file from a phantom. Technically, it
+converts the phantom from a vector (infinite resolution) object
+into a 2-dimension array of floating-point pixels. The parameters
+to set are:
+
+\begin{twocollist}
+%\twocolitemruled{\textbf{Parameter}}{\textbf{Options}}
+\twocolitem{\texttt{X size}}{Number of columns in image file}
+\twocolitem{\texttt{Y size}}{Number of rows in image file}
+\twocolitem{\texttt{Samples per pixel}}{Numbers of samples taken
+per pixel in both the x and y directions. For example, if the
+\texttt{Samples per pixel} is set to \texttt{3}, then for every
+pixel in the image file 9 samples (3 x 3) are averaged.}
+\end{twocollist}
 
 \subsection{Projection Dialog}
 This creates a projection file from a phantom.
@@ -56,11 +74,11 @@ This creates a projection file from a phantom.
 \section{Image Menus}
 \subsection{File - Properties}
 Properties of image files include
-%\begin{itemize}\itemsep=0
-%\item Whether the image is real or complex valued
-%\item Numeric statistics
-%\item Image file labels
-%\end{itemize}
+\begin{itemize}\itemsep=0pt
+  \item Whether the image is real or complex valued
+  \item Numeric statistics
+  \item Image file labels
+\end{itemize}
 
 \subsection{View}
 These options are for change the intensity scale for viewing the image.
@@ -79,16 +97,16 @@ These commands are used for analyzing an image.
 \section{Projection Menus}
 \subsection{Process - Convert Polar Dialog}\label{convertpolardialog}
 The parameters are \texttt{xsize}, \texttt{ysize}, and \texttt{interpolation}.
-The \texttt{xsize} and \texttt{ysize} parameters set the size of the 
+The \texttt{xsize} and \texttt{ysize} parameters set the size of the
 resulting image file. The \texttt{interpolation} parameter selects the
 interpolation method. Currently, the \texttt{bilinear} option provides
 the highest quality interpolation.
 
 \subsection{Process - Convert FFT Polar Dialog}
-The paramters for this option are the same as 
-\helprefn{convertpolardialog}{Convert Polar Dialog}. For this command,
-though, the projections are Fourier transformed prior to conversion to
-polar image.
+The parameters for this option are the same as
+\helprefn{convertpolardialog}{Convert Polar Dialog}. For this
+command, though, the projections are Fourier transformed prior to
+conversion to polar image.
 
 \subsection{Reconstruct - Filtered Backprojection Dialog}
 This dialog sets the parameters for reconstructing an image from projections
@@ -106,4 +124,3 @@ These commands set the scaling for the y-axis.
 \subsubsection{Set}
 \subsubsection{Auto}
 \subsubsection{Full}
-
index 77bf5ee..bb4a942 100644 (file)
@@ -11,7 +11,16 @@ http://www.ctsim.org
 ftp://ftp.ctsim.org
 \end{verbatim}
 
-It is available in Windows 95/NT/2000 and Linux GUI versions and non-GUI versions.
+\section{Installing Windows Binary}\index{Installation,Windows}%
+
+Download the Windows executable file as helprefn{shown}{download}.
+Simply execute this program to unpack \ctsim\ and begin the
+installation program. \ctsim\ will then be accessible from the
+\texttt{Start} Menu under the \texttt{Programs} submenu.
+
+\ctsim\ is compatible with Windows 98, Windows Me, Windows NT 4.0,
+and Windows 2000. Due to use of the OpenGL and htmlhelp libraries,
+\ctsim\ is not compatible with the stock Windows 95 system.
 
 \section{Installing Linux RPM}\index{Installation,Linux}%
 Download the RPM file from as \helprefn{shown}{download}. Then use
@@ -21,12 +30,6 @@ the \texttt{rpm} manager program:\\
 \ctsim will then be installed in the \texttt{/usr/local/bin}
 directory.
 
-\section{Installing Windows Binary}\index{Installation,Windows}%
-
-Download the Windows executable file as helprefn{shown}{download}.
-Simply execute this program to unpack \ctsim\ and begin the
-installation program.
-
 \section{Build From Sources}\label{build}\index{Installation,Build}%
 
 Refer to the INSTALL file included in the source distribution for
index 85174f2..5a7976f 100644 (file)
@@ -1,11 +1,11 @@
-\chapter{ctsimtext}\label{ctsimtext}\index{ctsimtext}%
+\chapter{The Command Line Interface}\label{ctsimtext}\index{ctsimtext}%
 \setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
 \setfooter{\thepage}{}{}{}{}{\thepage}%
 
-\ctsimtext\ is a master shell for all of the command-line utilities. 
+\ctsimtext\ is a master shell for all of the command-line utilities.
 
 \usage
-\ctsimtext\ can be executed without any parameters. In that case, \ctsimtext\ 
+\ctsimtext\ can be executed without any parameters. In that case, \ctsimtext\
 offers a command-line to enter the function-names and their parameters. The output of the command is displayed. Further commands may be given to \ctsimtext. The shell is exited by the \texttt{quit} command.
 
 \ctsimtext\ can also be called to execute a single command. This is especially useful for batch files containing multiple \ctsimtext\ commands. This is invoked by calling \par
@@ -18,11 +18,11 @@ Perfoms math functions on a single image.
 
 \usage
 \begin{itemize}\itemsep=0pt
-  \item --invert
-  \item --log
-  \item --exp
-  \item --sqr
-  \item --sqrt
+  \item -\,-invert
+  \item -\,-log
+  \item -\,-exp
+  \item -\,-sqr
+  \item -\,-sqrt
 \end{itemize}
 
 \section{if2}\label{if2}\index{ctsimtext,if2}%
@@ -30,12 +30,12 @@ Perfoms math functions on a two images.
 
 \usage
 \begin{itemize}\itemsep=0pt
-  \item --add
-  \item --sub
-  \item --mul
-  \item --comp
-  \item --column-plot
-  \item --row-plot
+  \item -\,-add
+  \item -\,-sub
+  \item -\,-mul
+  \item -\,-comp
+  \item -\,-column-plot
+  \item -\,-row-plot
 \end{itemize}
 
 \section{ifexport}\label{ifexport}\index{ctsimtext,ifexport}%
@@ -45,29 +45,29 @@ Export an imagefile to a standard graphics file.
 \begin{itemize}\itemsep=0pt
   \item --format
   \begin{itemize}\itemsep=0pt
-    \item --pgm
-    \item --pgmasc
-    \item --png
-    \item --png16
+    \item -\,-pgm
+    \item -\,-pgmasc
+    \item -\,-png
+    \item -\,-png16
   \end{itemize}
-  \item --center
+  \item -\,-center
   \begin{itemize}\itemsep=0pt
     \item median
     \item mode
     \item mean
   \end{itemize}
-  \item --auto
+  \item -\,-auto
   \begin{itemize}\itemsep=0pt
-     \item --full
-     \item --std0.1
-     \item --std0.5
-     \item --std1
-     \item --std2
-     \item --std3
+     \item -\,-full
+     \item -\,-std0.1
+     \item -\,-std0.5
+     \item -\,-std1
+     \item -\,-std2
+     \item -\,-std3
   \end{itemize}
-  \item --scale
-  \item --min
-  \item --max
+  \item -\,-scale
+  \item -\,-min
+  \item -\,-max
 \end{itemize}
 
 \section{ifinfo}\label{ifinfo}\index{ctsimtext,ifinfo}%
@@ -76,11 +76,11 @@ Displays information about an imagefile.
 
 \usage
 \begin{itemize}\itemsep=0pt
-  \item --labels
-  \item --no-labels
-  \item --stats
-  \item --no-stats
-  \item --help
+  \item -\,-labels
+  \item -\,-no-labels
+  \item -\,-stats
+  \item -\,-no-stats
+  \item -\,-help
 \end{itemize}
 
 \section{phm2pj}\label{phm2pj}\index{ctsimtext,phm2pj}%
@@ -89,35 +89,35 @@ Simulates collection of X-rays data (projections) around a phantom object.
 \usage
 phm2pj projection-file-name number-of-detectors number-of-views [options...]
 \begin{itemize}\itemsep=0pt
-  \item --phantom
-  Select a standard phantom 
+  \item -\,-phantom
+  Select a standard phantom
   \begin{itemize}\itemsep=0pt
     \item herman
     \item shepp-logan
     \item unit-pulse
   \end{itemize}
 
-  \item --phmfile
+  \item -\,-phmfile
   Load a phantom definition definition
 
-  \item --geometry
+  \item -\,-geometry
   \begin{itemize}\itemsep=0pt
     \item parallel
     \item equiangular
     \item equilinear
   \end{itemize}
 
-  \item --nray
+  \item -\,-nray
     Number of samples per each detector
 
-  \item --rotangle
+  \item -\,-rotangle
     Sets the rotation amount as a multiple of pi. For parallel geometries use
 a rotation angle of 1 and for equilinear and equiangular geometries use a rotation angle of 2.
 
-  \item --field-of-view
+  \item -\,-field-of-view
     Sets the field of view as a ratio of the diameter of the phantom. For parallel geometries, using a value of 1.0 is fine. For other geometies, this should be at least 1.3 to avoid artifacts.
 
-  \item --focal-length
+  \item -\,-focal-length
     Sets the distance of the radiation source and detectors from the center of the object as a ratio of the radius of the object. For parallel geometries, a value of 1.0 is fine. For other geometries, this should be at least 2.0 to avoid artifacts.
 \end{itemize}
 
@@ -130,7 +130,7 @@ to average per pixel.
 
 \usage
 \begin{itemize}\itemsep=0pt
-  \item --nsamples
+  \item -\,-nsamples
 \end{itemize}
 
 \section{pj2if}\label{pj2if}\index{ctsimtext,pj2if}%
@@ -138,7 +138,7 @@ Convert a projection file into an imagefile.
 
 \usage
 \begin{itemize}\itemsep=0pt
-\item --help    Print brief online help
+\item -\,-help    Print brief online help
 \end{itemize}
 
 \section{pjinfo}\label{pjinfo}\index{ctsimtext,pjinfo}%
@@ -146,11 +146,11 @@ Displays information about a projection file.
 
 \usage
 \begin{itemize}\itemsep=0pt
-  \item --binaryheader
-  \item --binaryview
-  \item --startview
-  \item --endview
-  \item --dump
+  \item -\,-binaryheader
+  \item -\,-binaryview
+  \item -\,-startview
+  \item -\,-endview
+  \item -\,-dump
 \end{itemize}
 
 \section{pjrec}\label{pjrec}\index{ctsimtext,pjrec}%
@@ -159,18 +159,23 @@ Reconstructs the interior of an object from a projection file.
 \usage
 \begin{twocollist}
 \twocolitemruled{\textbf{Parameter}}{\textbf{Options}}
-\twocolitem{\textbf{--filter}}{Selects which filter to apply to each projection. To properly reconstruct an image, this filter should be multiplied 
-by the absolute value of distance from zero frequency.
+\twocolitem{\textbf{-\,-filter}}{Selects which filter to apply to
+each projection. To properly reconstruct an image, this filter
+should be multiplied by the absolute value of distance from zero
+frequency.
 \begin{itemize}\itemsep=0pt
 \item abs\_bandlimit
 \item abs\_cosine
 \item abs\_hamming
 \end{itemize}
-}
-\twocolitem{\textbf{\-\-filter-parameter}}{Sets the alpha level for Hamming
+} \twocolitem{\textbf{-\,-filter-parameter}}{Sets the alpha level
+for Hamming
   window. At setting of 0.54, this equals the Hanning window.}
 
-\twocolitem{\textbf{\-\-filter-method}}{Selects the filtering method. For large numbers of detectors, \texttt{rfftw} is optimal. For smaller numbers of detectors, \texttt{convolution} might be a bit faster. 
+\twocolitem{\textbf{-\,-filter-method}}{Selects the filtering
+method. For large numbers of detectors, \texttt{rfftw} is optimal.
+For smaller numbers of detectors, \texttt{convolution} might be a
+bit faster.
 \begin{itemize}\itemsep=0pt
 \item convolution
 \item fourier
@@ -178,31 +183,43 @@ by the absolute value of distance from zero frequency.
 \item fftw
 \item rfftw
 \end{itemize}
-}
-\twocolitem{\textbf{\-\-filter-generation}}{Selects the filter generation. With convolution, \texttt{direct} is the proper method to select. With any of the frequency methods, \texttt{inverse-fourier} is the best method.
-\begin{itemize}\itemsep=0pt
-\item direct
-\item inverse-fourier
-\end{itemize}
-}
-\twocolitem{\textbf{--interpolation}}{Interpolation technique. \texttt{linear} is optimal.
+} \twocolitem{\textbf{-\,-interpolation}}{Interpolation technique.
+\texttt{linear} is optimal.
 \begin{itemize}\itemsep=0pt
 \item nearest
 \item linear
+\item cubic
 \end{itemize}
 }
-\twocolitem{\textbf{-backprojection}}{Selects the backprojection technique. A setting of \texttt{idiff3} is optimal.
+\end{twocollist}
+
+\subsection{Advanced Options}
+
+These options are only visible if \emph{Advanced Options} has been
+selected in the \texttt{File/Preferences} dialog.
+
+\begin{twocollist}
+\twocolitem{\textbf{-\,-backprojection}}{Selects the
+backprojection technique. A setting of \texttt{idiff} is optimal.
 \begin{itemize}\itemsep=0pt
 \item trig
 \item table
 \item diff
-\item diff2
-\item idiff2
-\item idiff3
+\item idiff
 \end{itemize}
 }
-\twocolitem{\textbf{--zeropad}}{Zeropad factor. A setting of \texttt{1} is optimal.}
 
-\twocolitem{\textbf{--preinterpolate}}{Selects preinterpolation interpolation technique and sets the preinterpolation factor. Currently, this is experimental and does not work well.}
-\end{twocollist}
+\twocolitem{\textbf{-\,-zeropad}}{Zeropad factor. A setting of
+\texttt{1} is optimal.}
+
+\twocolitem{\textbf{-\,-filter-generation}}{Selects the filter
+generation. With convolution, \texttt{direct} is the proper method
+to select. With any of the frequency methods,
+\texttt{inverse-fourier} is the best method.
+\begin{itemize}\itemsep=0pt
+\item direct
+\item inverse-fourier
+\end{itemize}
 
+\end{twocollist}
+}
index de856c5..42c2d6a 100644 (file)
@@ -1,4 +1,4 @@
-\chapter{The Web Browser CGI Interface}\label{webinterface}\index{Web Interface}%
+\chapter{The Web Interface}\label{webinterface}\index{Web Interface}%
 \setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
 \setfooter{\thepage}{}{}{}{}{\thepage}%
 
index fadc1ac..73deaf4 100644 (file)
 \parskip=10pt%
 \parindent=0pt%
 %\backgroundcolour{255;255;255}\textcolour{0;0;0}% Has an effect in HTML only
-\winhelpignore{\title{CTSim 3.0 User Manual}%
+\title{CTSim 3.0 User Manual}%
 \author{Kevin Rosenberg, M.D.}%
-\date{February 2001}%
-}%
-\winhelponly{\title{CTSim 3.0 User Manual}%
-\author{by Kevin Rosenberg, M.D.\\$$\image{3cm;3cm}{logo-huge.bmp}$$}%
-}%
+\date{February 9, 2001}%
 \makeindex%
+
 \begin{document}%
 \maketitle%
 \pagestyle{fancyplain}%
 
 \setheader{{\it CONTENTS}}{}{}{}{}{{\it CONTENTS}}%
 \setfooter{\thepage}{}{}{}{}{\thepage}%
+\parskip=2pt
 \tableofcontents%
 
+\parskip=10pt
 \chapter*{Copyright notice}%
 \setheader{{\it COPYRIGHT}}{}{}{}{}{{\it COPYRIGHT}}%
 \setfooter{\thepage}{}{}{}{}{\thepage}%
index 5ab1d58..0a1756b 100644 (file)
@@ -9,7 +9,7 @@
 {\sf\@author}
 \par
 {\sf With documentation contributions by Ian Kay, Ph.D.}}
-\vskip 1.5em {\large\sf \@date \par} \end{flushleft} \par
+\vskip 3em {\large\sf Manual Version 0.2\\\@date \par} \end{flushleft} \par
 \@thanks
 \vfill
 {\sf\small\begin{flushright}%
index 965756b..88079cc 100644 (file)
@@ -1,4 +1,4 @@
-noinst_HEADERS=ct.h ezplot.h pol.h sgp.h array2d.h imagefile.h backprojectors.h mpiworld.h fnetorderstream.h phantom.h timer.h sstream_subst scanner.h projections.h ctsupport.h filter.h array2dfile.h trace.h transformmatrix.h procsignal.h reconstruct.h plotfile.h hashtable.h fourier.h ctglobals.h dlgezplot.h cubicinterp.h
+noinst_HEADERS=ct.h ezplot.h pol.h sgp.h array2d.h imagefile.h backprojectors.h mpiworld.h fnetorderstream.h phantom.h timer.h sstream_subst scanner.h projections.h ctsupport.h filter.h array2dfile.h trace.h transformmatrix.h procsignal.h reconstruct.h plotfile.h hashtable.h fourier.h ctglobals.h dlgezplot.h interpolator.h
 
 
 
index d9144de..8fbb06b 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: backprojectors.h,v 1.20 2001/02/09 01:54:20 kevin Exp $
+**  $Id: backprojectors.h,v 1.21 2001/02/11 04:56:37 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
@@ -45,9 +45,7 @@ class Backprojector
   static const int BPROJ_TRIG;
   static const int BPROJ_TABLE;
   static const int BPROJ_DIFF;
-  static const int BPROJ_DIFF2;
-  static const int BPROJ_IDIFF2;
-  static const int BPROJ_IDIFF3;
+  static const int BPROJ_IDIFF;
 
   static const int INTERP_INVALID;
   static const int INTERP_NEAREST;
@@ -182,31 +180,11 @@ class BackprojectDiff : public Backproject
   double im_xinc, im_yinc;
 };
 
-class BackprojectDiff2 : public BackprojectDiff
-{
- public:
-  BackprojectDiff2 (const Projections& proj, ImageFile& im, int interpID, const int interpFactor)
-    :  BackprojectDiff (proj, im, interpID, interpFactor)
-    {}
-
-  void BackprojectView (const double* const t, const double view_angle);
-};
-
-class BackprojectIntDiff2 : public BackprojectDiff
-{
- public:
-  BackprojectIntDiff2 (const Projections& proj, ImageFile& im, int interpID, const int interpFactor)
-    :  BackprojectDiff (proj, im, interpID, interpFactor)
-    {}
-  
-  void BackprojectView (const double* const t, const double view_angle);
-};
-
 
-class BackprojectIntDiff3 : public BackprojectDiff
+class BackprojectIntDiff : public BackprojectDiff
 {
  public:
-  BackprojectIntDiff3 (const Projections& proj, ImageFile& im, int interpID, const int interpFactor)
+  BackprojectIntDiff (const Projections& proj, ImageFile& im, int interpID, const int interpFactor)
     :  BackprojectDiff (proj, im, interpID, interpFactor)
     {}
   
index 25082ca..9be0e7f 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: ct.h,v 1.56 2001/02/08 23:08:10 kevin Exp $
+**  $Id: ct.h,v 1.57 2001/02/11 04:56:37 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
@@ -164,7 +164,7 @@ extern "C" {
 #endif
 
 #include "ctsupport.h"
-#include "cubicinterp.h"
+#include "interpolator.h"
 #include "fnetorderstream.h"
 
 #ifdef HAVE_SGP
index 0a610d6..2dd5ed5 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: filter.h,v 1.24 2001/01/28 19:10:18 kevin Exp $
+**  $Id: filter.h,v 1.25 2001/02/11 04:56:37 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
@@ -103,6 +103,8 @@ class SignalFilter {
     static void setNumIntegral(int nIntegral) {N_INTEGRAL = nIntegral;}
 
   static const int getFilterCount() {return s_iFilterCount;}
+  static const int getReconstructFilterCount() { return s_iReconstructFilterCount; }
+
   static const char** getFilterNameArray() {return s_aszFilterName;}
   static const char** getFilterTitleArray() {return s_aszFilterTitle;}
   static int convertFilterNameToID (const char* const filterName);
@@ -142,6 +144,7 @@ class SignalFilter {
     static const char* s_aszFilterName[];
     static const char* s_aszFilterTitle[];
     static const int s_iFilterCount;
+    static const int s_iReconstructFilterCount;
     static const char* s_aszDomainName[];
     static const char* s_aszDomainTitle[];
     static const int s_iDomainCount;
index 8afe189..c7a8f27 100644 (file)
@@ -8,7 +8,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: backprojectors.cpp,v 1.25 2001/02/09 01:54:20 kevin Exp $
+**  $Id: backprojectors.cpp,v 1.26 2001/02/11 04:56:37 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
@@ -30,18 +30,14 @@ const int Backprojector::BPROJ_INVALID = -1;
 const int Backprojector::BPROJ_TRIG = 0;
 const int Backprojector::BPROJ_TABLE = 1;
 const int Backprojector::BPROJ_DIFF = 2;
-const int Backprojector::BPROJ_DIFF2 = 3;
-const int Backprojector::BPROJ_IDIFF2 = 4;
-const int Backprojector::BPROJ_IDIFF3 = 5;
+const int Backprojector::BPROJ_IDIFF = 3;
 
 const char* Backprojector::s_aszBackprojectName[] = 
 {
   {"trig"},
   {"table"},
   {"diff"},
-  {"diff2"},
-  {"idiff2"},
-  {"idiff3"},
+  {"idiff"},
 };
 
 const char* Backprojector::s_aszBackprojectTitle[] = 
@@ -49,9 +45,7 @@ const char* Backprojector::s_aszBackprojectTitle[] =
   {"Direct Trigometric"},
   {"Trigometric Table"},
   {"Difference Iteration"},
-  {"Difference Iteration Optimized"},
-  {"Integer Difference Iteration Optimized"},
-  {"Integer Difference Iteration Highly-Optimized"},
+  {"Integer Difference Iteration"},
 };
 
 const int Backprojector::s_iBackprojectCount = sizeof(s_aszBackprojectName) / sizeof(const char*);
@@ -73,7 +67,9 @@ const char* Backprojector::s_aszInterpName[] =
   {"nearest"},
   {"linear"},
   {"cubic"},
+#if HAVE_FREQ_PREINTERP
   {"freq_preinterpolationj"},
+#endif
 #if HAVE_BSPLINE_INTERP
   {"bspline"},
   {"1bspline"},
@@ -87,7 +83,9 @@ const char* Backprojector::s_aszInterpTitle[] =
   {"Nearest"},
   {"Linear"},
   {"Cubic"},
+#if HAVE_FREQ_PREINTERP
   {"Frequency Preinterpolation"},
+#endif
 #if HAVE_BSPLINE_INTERP
   {"B-Spline"},
   {"B-Spline 1st Order"},
@@ -162,12 +160,8 @@ Backprojector::initBackprojector (const Projections& proj, ImageFile& im, const
       m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectTable (proj, im, m_idInterpolation, interpFactor));
     else if (m_idBackproject == BPROJ_DIFF)
       m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectDiff (proj, im, m_idInterpolation, interpFactor));
-    else if (m_idBackproject == BPROJ_DIFF2)
-      m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectDiff2 (proj, im, m_idInterpolation, interpFactor));
-    else if (m_idBackproject == BPROJ_IDIFF2)
-      m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectIntDiff2 (proj, im, m_idInterpolation, interpFactor));
-    else if (m_idBackproject == BPROJ_IDIFF3)
-      m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectIntDiff3 (proj, im, m_idInterpolation, interpFactor));
+    else if (m_idBackproject == BPROJ_IDIFF)
+      m_pBackprojectImplem = static_cast<Backproject*>(new BackprojectIntDiff (proj, im, m_idInterpolation, interpFactor));
   } else {
     m_fail = true;
     m_failMessage = "Unable to select a backprojection method [Backprojector::initBackprojector]";
@@ -333,9 +327,9 @@ BackprojectTrig::BackprojectView (const double* const filteredProj, const double
 {
   double theta = view_angle;
   
-  CubicInterpolator* pCubicInterp = NULL;
+  CubicPolyInterpolator* pCubicInterp = NULL;
   if (interpType == Backprojector::INTERP_CUBIC)
-    pCubicInterp = new CubicInterpolator (filteredProj, nDet);
+    pCubicInterp = new CubicPolyInterpolator (filteredProj, nDet);
   
   double x = xMin + xInc / 2;  // Rectang coords of center of pixel 
   for (int ix = 0; ix < nx; x += xInc, ix++) {
@@ -403,9 +397,9 @@ BackprojectTable::BackprojectView (const double* const filteredProj, const doubl
 {
   double theta = view_angle;
   
-  CubicInterpolator* pCubicInterp = NULL;
+  CubicPolyInterpolator* pCubicInterp = NULL;
   if (interpType == Backprojector::INTERP_CUBIC)
-    pCubicInterp = new CubicInterpolator (filteredProj, nDet);
+    pCubicInterp = new CubicPolyInterpolator (filteredProj, nDet);
   
   for (int ix = 0; ix < nx; ix++) {
     ImageFileColumn pImCol = v[ix];
@@ -462,84 +456,28 @@ BackprojectDiff::~BackprojectDiff()
   ScaleImageByRotIncrement();
 }
 
-void
-BackprojectDiff::BackprojectView (const double* const filteredProj, const double view_angle)
-{
-  double theta = view_angle;  // add half PI to view angle to get perpendicular theta angle
-  double det_dx = xInc * cos (theta);
-  double det_dy = yInc * sin (theta);
-  double lColStart = start_r * cos (theta - start_phi);  // calculate L for first point in image
-  
-  CubicInterpolator* pCubicInterp = NULL;
-  if (interpType == Backprojector::INTERP_CUBIC)
-    pCubicInterp = new CubicInterpolator (filteredProj, nDet);
-  
-  for (int ix = 0; ix < nx; ix++, lColStart += det_dx) {
-    double curDetPos = lColStart;
-    ImageFileColumn pImCol = v[ix];
-    
-    for (int iy = 0; iy < ny; iy++, curDetPos += det_dy) {
-#ifdef DEBUG
-      printf ("[%2d,%2d]:  %8.5f  ", ix, iy, curDetPos);
-#endif
-      if (interpType == Backprojector::INTERP_NEAREST) {
-        int iDetPos = iDetCenter + nearest<int>(curDetPos / detInc);   // calc index in the filtered raysum vector 
-        
-        if (iDetPos >= 0 && iDetPos < nDet)
-          pImCol[iy] += filteredProj[iDetPos];
-      } else if (interpType == Backprojector::INTERP_LINEAR) {
-        double detPos = curDetPos / detInc;            // position along detector 
-        double detPosFloor = floor (detPos);
-        int iDetPos = iDetCenter + static_cast<int>(detPosFloor);
-        double frac = detPos - detPosFloor;    // fraction distance from det 
-        if (iDetPos >= 0 && iDetPos < nDet - 1)
-          pImCol[iy] += ((1-frac) * filteredProj[iDetPos] + frac * filteredProj[iDetPos+1]);
-      } else if (interpType = Backprojector::INTERP_CUBIC) {
-        double p = iDetCenter + (curDetPos / detInc);  // position along detector
-        if (p >= 0 && p < nDet)
-          pImCol[iy] += pCubicInterp->interpolate (p);
-      }
-    }  // end for y 
-  }    // end for x 
-
-  if (interpType == Backprojector::INTERP_CUBIC)
-    delete pCubicInterp;
-}
-
-
-// CLASS IDENTICATION
-//   BackprojectDiff2
-//
-// PURPOSE
-//   Optimized version of BackprojectDiff
 
 void
-BackprojectDiff2::BackprojectView (const double* const filteredProj, const double view_angle)
+BackprojectDiff::BackprojectView (const double* const filteredProj, const double view_angle)
 {
   double theta = view_angle;
   
-  CubicInterpolator* pCubicInterp = NULL;
-  if (interpType == Backprojector::INTERP_CUBIC)
-    pCubicInterp = new CubicInterpolator (filteredProj, nDet);
-  
-  // Distance betw. detectors for an angle given in units of detectors 
+  // Distance between detectors for an angle given in units of detectors 
   double det_dx = xInc * cos (theta) / detInc;
   double det_dy = yInc * sin (theta) / detInc;
   
   // calculate detPosition for first point in image (ix=0, iy=0) 
   double detPosColStart = start_r * cos (theta - start_phi) / detInc;
   
-#ifdef DEBUG
-  printf ("start_r=%8.5f, start_phi=%8.5f, rotScale=%8.5f\n", start_r, start_phi, rotScale);
-#endif
+  CubicPolyInterpolator* pCubicInterp = NULL;
+  if (interpType == Backprojector::INTERP_CUBIC)
+    pCubicInterp = new CubicPolyInterpolator (filteredProj, nDet);
+  
   for (int ix = 0; ix < nx; ix++, detPosColStart += det_dx) {
     double curDetPos = detPosColStart;
     ImageFileColumn pImCol = v[ix];
     
     for (int iy = 0; iy < ny; iy++, curDetPos += det_dy) {
-#ifdef DEBUG
-      printf ("[%2d,%2d]: %8.5f %8.5f\n", ix, iy, curDetPos, filteredProj[iDetCenter + nearest<int>(curDetPos)]);
-#endif
       if (interpType == Backprojector::INTERP_NEAREST) {
         int iDetPos = iDetCenter + nearest<int> (curDetPos);   // calc index in the filtered raysum vector 
         
@@ -563,77 +501,15 @@ BackprojectDiff2::BackprojectView (const double* const filteredProj, const doubl
     delete pCubicInterp;
 }
 
-// CLASS IDENTICATION
-//   BackprojectIntDiff2
-//
-// PURPOSE
-//   Integer version of BackprojectDiff2
-
-void
-BackprojectIntDiff2::BackprojectView (const double* const filteredProj, const double view_angle)
-{
-  double theta = view_angle;
-  
-  CubicInterpolator* pCubicInterp = NULL;
-  if (interpType == Backprojector::INTERP_CUBIC)
-    pCubicInterp = new CubicInterpolator (filteredProj, nDet);
-  
-  static const kint32 scale = 1 << 16;
-  static const double dScale = scale;
-  static const kint32 halfScale = scale / 2;
-  
-  const kint32 det_dx = nearest<kint32> (xInc * cos (theta) / detInc * scale);
-  const kint32 det_dy = nearest<kint32> (yInc * sin (theta) / detInc * scale);
-  
-  // calculate L for first point in image (0, 0) 
-  kint32 detPosColStart = nearest<kint32> (start_r * cos (theta - start_phi) / detInc * scale);
-  
-  for (int ix = 0; ix < nx; ix++, detPosColStart += det_dx) {
-    kint32 curDetPos = detPosColStart;
-    ImageFileColumn pImCol = v[ix];
-    
-    for (int iy = 0; iy < ny; iy++, curDetPos += det_dy) {
-      if (interpType == Backprojector::INTERP_NEAREST) {
-        int detPosNearest = (curDetPos >= 0 ? ((curDetPos + halfScale) / scale) : ((curDetPos - halfScale) / scale));
-        int iDetPos = iDetCenter + detPosNearest;      // calc index in the filtered raysum vector 
-        
-        if (iDetPos < 0 || iDetPos >= nDet)  // check for index outside of raysum pos 
-          errorIndexOutsideDetector (ix, iy, theta, curDetPos, iDetPos);
-        else
-          *pImCol++ += filteredProj[iDetPos];
-      } else if (interpType == Backprojector::INTERP_LINEAR) {
-        kint32 detPosFloor = curDetPos / scale;
-        kint32 detPosRemainder = curDetPos % scale;
-        if (detPosRemainder < 0) {
-          detPosFloor--;
-          detPosRemainder += scale;
-        }
-        int iDetPos = iDetCenter + detPosFloor;
-        double frac = detPosRemainder / dScale;
-        if (iDetPos < 0 || iDetPos >= nDet - 1)
-          errorIndexOutsideDetector (ix, iy, theta, curDetPos, iDetPos);
-        else
-          *pImCol++ += ((1.-frac) * filteredProj[iDetPos] + frac * filteredProj[iDetPos+1]);
-      } else if (interpType = Backprojector::INTERP_CUBIC) {
-        double p = iDetCenter + (static_cast<double>(curDetPos) / scale);      // position along detector
-        if (p >= 0 && p < nDet)
-          *pImCol++  += pCubicInterp->interpolate (p);
-      }
-    }  // end for y
-  }    // end for x
-
-  if (interpType == Backprojector::INTERP_CUBIC)
-    delete pCubicInterp;
-}
 
 // CLASS IDENTICATION
-//   BackprojectIntDiff3
+//   BackprojectIntDiff
 //
 // PURPOSE
-//   Highly optimized version of BackprojectIntDiff2
+//   Highly optimized and integer version of BackprojectDiff
 
 void
-BackprojectIntDiff3::BackprojectView (const double* const filteredProj, const double view_angle)
+BackprojectIntDiff::BackprojectView (const double* const filteredProj, const double view_angle)
 {
   double theta = view_angle;  // add half PI to view angle to get perpendicular theta angle
   static const int scaleShift = 16;
@@ -649,7 +525,7 @@ BackprojectIntDiff3::BackprojectView (const double* const filteredProj, const do
   kint32 detPosColStart = nearest<kint32> ((start_r * cos (theta - start_phi) / detInc + iDetCenter) * scale);
   
   double* deltaFilteredProj = NULL;  
-  CubicInterpolator* pCubicInterp = NULL;
+  CubicPolyInterpolator* pCubicInterp = NULL;
   if (interpType == Backprojector::INTERP_LINEAR) {
     // precalculate scaled difference for linear interpolation
     deltaFilteredProj = new double [nDet];
@@ -657,7 +533,7 @@ BackprojectIntDiff3::BackprojectView (const double* const filteredProj, const do
       deltaFilteredProj[i] = (filteredProj[i+1] - filteredProj[i]) * dInvScale;
     deltaFilteredProj[nDet - 1] = 0;  // last detector
   } else if (interpType == Backprojector::INTERP_CUBIC) {
-    pCubicInterp = new CubicInterpolator (filteredProj, nDet);
+    pCubicInterp = new CubicPolyInterpolator (filteredProj, nDet);
   }
   
   int iLastDet = nDet - 1;
@@ -688,7 +564,7 @@ BackprojectIntDiff3::BackprojectView (const double* const filteredProj, const do
       for (int iy = 0; iy < ny; iy++, curDetPos += det_dy) {
         *pImCol++ += pCubicInterp->interpolate (static_cast<double>(curDetPos) / 65536);
       }
-    } // end cubic
+    } // end Cubic
   } // end for ix
   
   if (interpType == Backprojector::INTERP_LINEAR)
@@ -703,9 +579,9 @@ BackprojectEquiangular::BackprojectView (const double* const filteredProj, const
 {
   double beta = view_angle;
   
-  CubicInterpolator* pCubicInterp = NULL;
+  CubicPolyInterpolator* pCubicInterp = NULL;
   if (interpType == Backprojector::INTERP_CUBIC)
-    pCubicInterp = new CubicInterpolator (filteredProj, nDet);
+    pCubicInterp = new CubicPolyInterpolator (filteredProj, nDet);
   
   for (int ix = 0; ix < nx; ix++) {
     ImageFileColumn pImCol = v[ix];
@@ -746,9 +622,9 @@ BackprojectEquilinear::BackprojectView (const double* const filteredProj, const
 {
   double beta = view_angle;
   
-  CubicInterpolator* pCubicInterp = NULL;
+  CubicPolyInterpolator* pCubicInterp = NULL;
   if (interpType == Backprojector::INTERP_CUBIC)
-    pCubicInterp = new CubicInterpolator (filteredProj, nDet);
+    pCubicInterp = new CubicPolyInterpolator (filteredProj, nDet);
   
   for (int ix = 0; ix < nx; ix++) {
     ImageFileColumn pImCol = v[ix];
index 4ac9017..f4a10f3 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2000 Kevin Rosenberg
 **
-**  $Id: filter.cpp,v 1.35 2001/01/28 19:10:18 kevin Exp $
+**  $Id: filter.cpp,v 1.36 2001/02/11 04:56:37 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
@@ -30,7 +30,7 @@
 int SignalFilter::N_INTEGRAL=500;  //static member
 
 const int SignalFilter::FILTER_INVALID = -1 ;
-const int SignalFilter::FILTER_ABS_BANDLIMIT = 0;      // filter times |x = |
+const int SignalFilter::FILTER_ABS_BANDLIMIT = 0;      // filter times |x|
 const int SignalFilter::FILTER_ABS_G_HAMMING = 1;
 const int SignalFilter::FILTER_ABS_COSINE = 2;
 const int SignalFilter::FILTER_ABS_SINC = 3;
@@ -41,6 +41,8 @@ const int SignalFilter::FILTER_G_HAMMING = 7;
 const int SignalFilter::FILTER_COSINE = 8;
 const int SignalFilter::FILTER_TRIANGLE = 9;
 
+const int SignalFilter::s_iReconstructFilterCount = 5;
+
 const char* SignalFilter::s_aszFilterName[] = {
   {"abs_bandlimit"},
   {"abs_hamming"},
index 32af552..707ee38 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: procsignal.cpp,v 1.24 2001/01/28 19:10:18 kevin Exp $
+**  $Id: procsignal.cpp,v 1.25 2001/02/11 04:56:37 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
@@ -44,7 +44,7 @@ const int ProcessSignal::FILTER_METHOD_RFFTW =5 ;
 const char* ProcessSignal::s_aszFilterMethodName[] = {
   {"convolution"},
   {"fourier"},
-  {"fouier_table"},
+  {"fouier-table"},
   {"fft"},
 #if HAVE_FFTW
   {"fftw"},
@@ -69,7 +69,7 @@ const int ProcessSignal::FILTER_GENERATION_DIRECT = 0;
 const int ProcessSignal::FILTER_GENERATION_INVERSE_FOURIER = 1;
 const char* ProcessSignal::s_aszFilterGenerationName[] = {
   {"direct"},
-  {"inverse_fourier"},
+  {"inverse-fourier"},
 };
 const char* ProcessSignal::s_aszFilterGenerationTitle[] = {
   {"Direct"},
index da99f59..e80cc4f 100644 (file)
@@ -8,7 +8,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: reconstruct.cpp,v 1.11 2001/01/30 05:05:41 kevin Exp $
+**  $Id: reconstruct.cpp,v 1.12 2001/02/11 04:56:37 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
  */
 
 
-Reconstructor::Reconstructor (const Projections& rProj, ImageFile& rIF, const char* const filterName, double filt_param, const char* const filterMethodName, const int zeropad, const char* filterGenerationName, const char* const interpName, int interpFactor, const char* const backprojectName, const int iTrace, SGP* pSGP)
-  : m_rProj(rProj), m_rImagefile(rIF), m_pProcessSignal(0), m_pBackprojector(0), m_iTrace(iTrace), m_bFail(false), m_adPlotXAxis(0)
+Reconstructor::Reconstructor (const Projections& rProj, ImageFile& rIF, const char* const filterName, 
+                              double filt_param, const char* const filterMethodName, const int zeropad, 
+                              const char* filterGenerationName, const char* const interpName, 
+                              int interpFactor, const char* const backprojectName, const int iTrace, SGP* pSGP)
+  : m_rProj(rProj), m_rImagefile(rIF), m_pProcessSignal(0), m_pBackprojector(0), m_iTrace(iTrace), 
+    m_bFail(false), m_adPlotXAxis(0)
 {
   m_nFilteredProjections = m_rProj.nDet() * interpFactor;
 
@@ -65,7 +69,9 @@ Reconstructor::Reconstructor (const Projections& rProj, ImageFile& rIF, const ch
 #endif
 
   double filterBW = 1. / m_rProj.detInc();
-  m_pProcessSignal = new ProcessSignal (filterName, filterMethodName, filterBW, m_rProj.detInc(), m_rProj.nDet(), filt_param, "spatial", filterGenerationName, zeropad, interpFactor, iTrace, m_rProj.geometry(), m_rProj.focalLength(), pSGP);
+  m_pProcessSignal = new ProcessSignal (filterName, filterMethodName, filterBW, m_rProj.detInc(), 
+    m_rProj.nDet(), filt_param, "spatial", filterGenerationName, zeropad, interpFactor, iTrace, 
+    m_rProj.geometry(), m_rProj.focalLength(), pSGP);
 
   if (m_pProcessSignal->fail()) {
     m_bFail = true;
index 308f252..9f279ec 100644 (file)
@@ -1,6 +1,6 @@
 noinst_LIBRARIES = libctsupport.a
 INCLUDES=@my_includes@
-libctsupport_a_SOURCES= strfuncs.cpp syserror.cpp fnetorderstream.cpp consoleio.cpp mathfuncs.cpp xform.cpp clip.cpp plotfile.cpp hashtable.cpp cubicinterp.cpp
+libctsupport_a_SOURCES= strfuncs.cpp syserror.cpp fnetorderstream.cpp consoleio.cpp mathfuncs.cpp xform.cpp clip.cpp plotfile.cpp hashtable.cpp interpolator.cpp
 EXTRA_DIST=Makefile.nt
 
 
index ae08e1e..d9390b5 100644 (file)
@@ -6,15 +6,15 @@
 --------------------Configuration: ctsim - Win32 Debug--------------------
 </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\RSP299.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 
-"D:\ctsim\src\ctsim.cpp"
+"C:\ctsim\src\dialogs.cpp"
 ]
-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 "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP299.tmp" 
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP29A.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" 
+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 /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
 .\Debug\dialogs.obj
 .\Debug\dlgprojections.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\RSP4A.tmp"
+Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP29A.tmp"
 <h3>Output Window</h3>
 Compiling...
-ctsim.cpp
+dialogs.cpp
 Linking...
 
 
index a2fede7..b08db82 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: ctsim.cpp,v 1.73 2001/02/09 22:22:04 kevin Exp $
+**  $Id: ctsim.cpp,v 1.74 2001/02/11 04:56:38 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
@@ -43,6 +43,7 @@
 #include "wx/image.h"
 #include "wx/filesys.h"
 #include "wx/fs_zip.h"
+#include "wx/msw/helpchm.h"
 
 #if !wxUSE_DOC_VIEW_ARCHITECTURE
 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
@@ -70,7 +71,7 @@
 #endif
 #endif
 
-static const char* rcsindent = "$Id: ctsim.cpp,v 1.73 2001/02/09 22:22:04 kevin Exp $";
+static const char* rcsindent = "$Id: ctsim.cpp,v 1.74 2001/02/11 04:56:38 kevin Exp $";
 
 struct option CTSimApp::ctsimOptions[] = 
 {
@@ -82,7 +83,7 @@ struct option CTSimApp::ctsimOptions[] =
 IMPLEMENT_APP(CTSimApp)
 
 CTSimApp::CTSimApp()
-: m_docManager(NULL), m_pFrame(NULL), m_pLog(0), m_pLogDoc(0)
+: m_docManager(NULL), m_pFrame(NULL), m_pLog(0), m_pLogDoc(0), m_bAdvancedOptions(false)
 {
        theApp = this;
 }
@@ -262,6 +263,7 @@ IMPLEMENT_CLASS(MainFrame, wxDocParentFrame)
 BEGIN_EVENT_TABLE(MainFrame, wxDocParentFrame)
 #endif
 
+EVT_MENU(MAINMENU_FILE_PREFERENCES, MainFrame::OnPreferences)
 EVT_MENU(MAINMENU_HELP_ABOUT, MainFrame::OnAbout)
 EVT_MENU(MAINMENU_HELP_CONTENTS, MainFrame::OnHelpContents)
 EVT_MENU(MAINMENU_HELP_TOPICS, MainFrame::OnHelpTopics)
@@ -317,6 +319,7 @@ MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const
        file_menu->Append(wxID_OPEN, "&Open...\tCtrl-O");
        
        file_menu->AppendSeparator();
+  file_menu->Append (MAINMENU_FILE_PREFERENCES, "Pr&eferences...");
        file_menu->Append(MAINMENU_FILE_EXIT, "E&xit");
        
        //  history of files visited
@@ -521,12 +524,6 @@ MainFrame::OnHelpSecondary (wxCommandEvent& event)
 void
 MainFrame::showHelp (int commandID)
 {
-#ifdef CTSIM_WINHELP
-       m_winHelp.LoadFile();
-#else
-       m_htmlHelp.LoadFile();
-#endif
-       
        switch (commandID) {
                
        case MAINMENU_HELP_CONTENTS:
@@ -766,6 +763,13 @@ BitmapDialog::~BitmapDialog()
 {}
 
 
+void 
+MainFrame::OnPreferences (wxCommandEvent& WXUNUSED(event) )
+{
+  theApp->setAdvancedOptions (! theApp->getAdvancedOptions());
+}
+
+
 #include "./splash.xpm"
 void 
 MainFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
index 63316b4..c878803 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: ctsim.h,v 1.42 2001/02/06 06:57:46 kevin Exp $
+**  $Id: ctsim.h,v 1.43 2001/02/11 04:56:38 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
@@ -39,6 +39,7 @@
 #include "wx/wx.h"
 #endif
 #include "wx/config.h"
+#include "wx/msw/helpchm.h"
 
 #ifdef MSVC
 #define CTSIM_MDI 1
@@ -108,7 +109,7 @@ private:
   bool m_bShuttingDown;
 
 #if CTSIM_WINHELP
-  wxWinHelpController      m_winHelp;
+  wxCHMHelpController      m_winHelp;
 #endif
   wxHtmlHelpController     m_htmlHelp;
   
@@ -122,7 +123,7 @@ public:
   void OnSize (wxSizeEvent& event);
 
 #if CTSIM_WINHELP
-  wxWinHelpController&   getWinHelpController()
+  wxCHMHelpController&   getWinHelpController()
   {return m_winHelp; }
 #endif
   wxHtmlHelpController&  getHtmlHelpController()
@@ -134,6 +135,7 @@ public:
   void OnHelpTopics (wxCommandEvent& event);
   void OnHelpContents (wxCommandEvent& event);
   void OnCreatePhantom (wxCommandEvent& event);
+  void OnPreferences (wxCommandEvent& event);
   
 #if defined(CTSIM_WINHELP) && (defined(DEBUG) || defined(_DEBUG))
   void OnHelpSecondary (wxCommandEvent& event);
@@ -177,7 +179,8 @@ class CTSimApp: public wxApp
 private:
   enum { O_HELP, O_VERSION };
   static struct option ctsimOptions[];
-  
+
+  bool m_bAdvancedOptions;
   wxDocManager* m_docManager;
   MainFrame* m_pFrame;
   wxConfig* m_pConfig;
@@ -214,7 +217,9 @@ public:
   { return new EZPlotDialog (m_pFrame); }
   
   void getCompatibleImages (const ImageFileDocument* pIFDoc, std::vector<ImageFileDocument*>& vecIF);
-  
+  bool getAdvancedOptions() const { return m_bAdvancedOptions; }
+  void setAdvancedOptions (bool bAdv) { m_bAdvancedOptions = bAdv; }
+
   void setIconForFrame (wxFrame* pFrame);
   wxConfig* getConfig()
   { return m_pConfig; }
@@ -255,6 +260,7 @@ enum {
     
     MAINMENU_FILE_CREATE_FILTER,
     MAINMENU_FILE_EXIT,
+    MAINMENU_FILE_PREFERENCES,
     
     PJMENU_FILE_PROPERTIES,
     PJMENU_RECONSTRUCT_FBP,
index c120591..0afae26 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: dialogs.cpp,v 1.28 2001/02/08 06:25:07 kevin Exp $
+**  $Id: dialogs.cpp,v 1.29 2001/02/11 04:56:38 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
@@ -508,11 +508,13 @@ DialogGetProjectionParameters::DialogGetProjectionParameters
   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);
+  if (theApp->getAdvancedOptions()) {
+    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);
@@ -594,12 +596,20 @@ DialogGetProjectionParameters::getNSamples ()
 double
 DialogGetProjectionParameters::getRotAngle ()
 {
-  wxString strCtrl = m_pTextCtrlRotAngle->GetValue();
-  double dValue;
-  if (strCtrl.ToDouble (&dValue))
-    return (dValue * PI);
-  else
-    return (m_dDefaultRotAngle);
+  if (theApp->getAdvancedOptions()) {
+    wxString strCtrl = m_pTextCtrlRotAngle->GetValue();
+    double dValue;
+    if (strCtrl.ToDouble (&dValue))
+      return (dValue * PI);
+    else
+      return (m_dDefaultRotAngle);
+  } else {
+    if (Scanner::convertGeometryNameToID (m_pListBoxGeometry->getSelectionStringValue()) == 
+          Scanner::GEOMETRY_PARALLEL)
+      return (PI);
+    else
+      return (2 * PI);
+  }
 }
 
 double
@@ -656,7 +666,10 @@ DialogGetProjectionParameters::getTrace ()
 /////////////////////////////////////////////////////////////////////
 
 
-DialogGetReconstructionParameters::DialogGetReconstructionParameters (wxWindow* pParent, int iDefaultXSize, int iDefaultYSize, int iDefaultFilterID, double dDefaultFilterParam,  int iDefaultFilterMethodID, int iDefaultFilterGenerationID, int iDefaultZeropad, int iDefaultInterpID, int iDefaultInterpParam, int iDefaultBackprojectID, int iTrace)
+DialogGetReconstructionParameters::DialogGetReconstructionParameters (wxWindow* pParent, int iDefaultXSize, 
+                     int iDefaultYSize, int iDefaultFilterID, double dDefaultFilterParam,  
+                     int iDefaultFilterMethodID, int iDefaultFilterGenerationID, int iDefaultZeropad, 
+                     int iDefaultInterpID, int iDefaultInterpParam, int iDefaultBackprojectID, int iTrace)
 : wxDialog (pParent, -1, "Set Reconstruction Parameters", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxCAPTION)
 {
   wxBoxSizer* pTopSizer = new wxBoxSizer (wxVERTICAL);
@@ -665,25 +678,13 @@ DialogGetReconstructionParameters::DialogGetReconstructionParameters (wxWindow*
   
   pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5);
   
-  std::ostringstream os;
-  os << iDefaultXSize;
-  m_pTextCtrlXSize = new wxTextCtrl (this, -1, os.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
-  std::ostringstream osYSize;
-  osYSize << iDefaultYSize;
-  m_pTextCtrlYSize = new wxTextCtrl (this, -1, osYSize.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
-  std::ostringstream osFilterParam;
-  osFilterParam << dDefaultFilterParam;
-  m_pTextCtrlFilterParam = new wxTextCtrl (this, -1, osFilterParam.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
-  std::ostringstream osZeropad;
-  osZeropad << iDefaultZeropad;
-  m_pTextCtrlZeropad = new wxTextCtrl (this, -1, osZeropad.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
-  std::ostringstream osInterpParam;
-  osInterpParam << iDefaultInterpParam;
-  m_pTextCtrlInterpParam = new wxTextCtrl (this, -1, osInterpParam.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
-  
   wxFlexGridSizer* pGridSizer = new wxFlexGridSizer (6);
   pGridSizer->Add (new wxStaticText (this, -1, "Filter"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
-  m_pListBoxFilter = new StringValueAndTitleListBox (this, SignalFilter::getFilterCount(), SignalFilter::getFilterTitleArray(), SignalFilter::getFilterNameArray());
+
+  if (theApp->getAdvancedOptions())
+    m_pListBoxFilter = new StringValueAndTitleListBox (this, SignalFilter::getFilterCount(), SignalFilter::getFilterTitleArray(), SignalFilter::getFilterNameArray());
+  else
+    m_pListBoxFilter = new StringValueAndTitleListBox (this, SignalFilter::getReconstructFilterCount(), SignalFilter::getFilterTitleArray(), SignalFilter::getFilterNameArray());
   m_pListBoxFilter->SetSelection (iDefaultFilterID);
   pGridSizer->Add (m_pListBoxFilter, 0, wxALL | wxALIGN_LEFT | wxEXPAND);
   
@@ -692,17 +693,18 @@ DialogGetReconstructionParameters::DialogGetReconstructionParameters (wxWindow*
   pGridSizer->Add (new wxStaticText (this, -1, "Filter Method"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
   pGridSizer->Add (m_pListBoxFilterMethod, 0, wxALL | wxALIGN_LEFT | wxEXPAND);
   
-  m_pListBoxFilterGeneration = new StringValueAndTitleListBox (this, ProcessSignal::getFilterGenerationCount(), ProcessSignal::getFilterGenerationTitleArray(), ProcessSignal::getFilterGenerationNameArray());
-  m_pListBoxFilterGeneration->SetSelection (iDefaultFilterGenerationID);
-  pGridSizer->Add (new wxStaticText (this, -1, "Filter Generation"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
-  pGridSizer->Add (m_pListBoxFilterGeneration, 0, wxALL | wxALIGN_LEFT | wxEXPAND);
-  
-  
-  m_pListBoxBackproject = new StringValueAndTitleListBox (this, Backprojector::getBackprojectCount(), Backprojector::getBackprojectTitleArray(), Backprojector::getBackprojectNameArray());
-  m_pListBoxBackproject->SetSelection (iDefaultBackprojectID);
-  pGridSizer->Add (new wxStaticText (this, -1, "Backprojection"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
-  pGridSizer->Add (m_pListBoxBackproject, 0, wxALL | wxALIGN_RIGHT | wxEXPAND);
+  if (theApp->getAdvancedOptions()) {
+    m_pListBoxFilterGeneration = new StringValueAndTitleListBox (this, ProcessSignal::getFilterGenerationCount(), ProcessSignal::getFilterGenerationTitleArray(), ProcessSignal::getFilterGenerationNameArray());
+    m_pListBoxFilterGeneration->SetSelection (iDefaultFilterGenerationID);
+    pGridSizer->Add (new wxStaticText (this, -1, "Filter Generation"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
+    pGridSizer->Add (m_pListBoxFilterGeneration, 0, wxALL | wxALIGN_LEFT | wxEXPAND);
   
+    m_pListBoxBackproject = new StringValueAndTitleListBox (this, Backprojector::getBackprojectCount(), Backprojector::getBackprojectTitleArray(), Backprojector::getBackprojectNameArray());
+    m_pListBoxBackproject->SetSelection (iDefaultBackprojectID);
+    pGridSizer->Add (new wxStaticText (this, -1, "Backprojection"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
+    pGridSizer->Add (m_pListBoxBackproject, 0, wxALL | wxALIGN_RIGHT | wxEXPAND);
+  }
+
   m_pListBoxInterp = new StringValueAndTitleListBox (this, Backprojector::getInterpCount(), Backprojector::getInterpTitleArray(), Backprojector::getInterpNameArray());
   m_pListBoxInterp->SetSelection (iDefaultInterpID);
   pGridSizer->Add (new wxStaticText (this, -1, "Interpolation"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);
@@ -717,16 +719,37 @@ DialogGetReconstructionParameters::DialogGetReconstructionParameters (wxWindow*
   m_pListBoxTrace->SetSelection (iTrace);
   pGridSizer->Add (m_pListBoxTrace);
   
+  std::ostringstream osHammingParam;
+  osHammingParam << dDefaultFilterParam;
+  m_pTextCtrlFilterParam = new wxTextCtrl (this, -1, osHammingParam.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
+  pGridSizer->Add (new wxStaticText (this, -1, "Hamming Parameter"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+  pGridSizer->Add (m_pTextCtrlFilterParam, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+  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_LEFT | 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_LEFT | wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (new wxStaticText (this, -1, "Filter Parameter"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (m_pTextCtrlFilterParam, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (new wxStaticText (this, -1, "Zeropad"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
-  pGridSizer->Add (m_pTextCtrlZeropad, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+
+  if (theApp->getAdvancedOptions()) {
+    std::ostringstream osZeropad;
+    osZeropad << iDefaultZeropad;
+    m_pTextCtrlZeropad = new wxTextCtrl (this, -1, osZeropad.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
+    pGridSizer->Add (new wxStaticText (this, -1, "Zeropad"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+    pGridSizer->Add (m_pTextCtrlZeropad, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+  }
+
+#if HAVE_FREQ_PREINTERP
+  std::ostringstream osInterpParam;
+  osInterpParam << iDefaultInterpParam;
+  m_pTextCtrlInterpParam = new wxTextCtrl (this, -1, osInterpParam.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);
   pGridSizer->Add (new wxStaticText (this, -1, "Interpolation Parameter"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
   pGridSizer->Add (m_pTextCtrlInterpParam, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+#endif  
   
   pTopSizer->Add (pGridSizer, 1, wxALL, 3);
   
@@ -777,24 +800,31 @@ DialogGetReconstructionParameters::getYSize ()
 unsigned int
 DialogGetReconstructionParameters::getZeropad ()
 {
-  wxString strCtrl = m_pTextCtrlZeropad->GetValue();
-  unsigned long lValue;
-  if (strCtrl.ToULong (&lValue))
-    return lValue;
-  else
-    return (m_iDefaultZeropad);
+  if (theApp->getAdvancedOptions()) {
+    wxString strCtrl = m_pTextCtrlZeropad->GetValue();
+    unsigned long lValue;
+    if (strCtrl.ToULong (&lValue))
+      return lValue;
+    else
+      return (m_iDefaultZeropad);
+  } else
+    return 1;
 }
 
 
 unsigned int
 DialogGetReconstructionParameters::getInterpParam ()
 {
+#if HAVE_FREQ_PREINTERP
   wxString strCtrl = m_pTextCtrlInterpParam->GetValue();
   unsigned long lValue;
   if (strCtrl.ToULong (&lValue))
     return lValue;
   else
     return (m_iDefaultInterpParam);
+#else
+  return 1;
+#endif
 }
 
 double
@@ -838,13 +868,24 @@ DialogGetReconstructionParameters::getTrace ()
 const char*
 DialogGetReconstructionParameters::getBackprojectName ()
 {
-  return m_pListBoxBackproject->getSelectionStringValue();
+  if (theApp->getAdvancedOptions()) {
+    return m_pListBoxBackproject->getSelectionStringValue();
+  } else
+    return "idiff";
 }
 
 const char*
 DialogGetReconstructionParameters::getFilterGenerationName ()
 {
-  return m_pListBoxFilterGeneration->getSelectionStringValue();
+  if (theApp->getAdvancedOptions()) {
+    return m_pListBoxFilterGeneration->getSelectionStringValue();
+  } else {
+    if (ProcessSignal::convertFilterMethodNameToID(m_pListBoxFilterMethod->getSelectionStringValue())
+        == ProcessSignal::FILTER_METHOD_CONVOLUTION)
+      return "direct";
+    else
+      return "inverse-fourier";
+  }
 }
 
 
index 0284924..8311bb2 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: dialogs.h,v 1.23 2001/02/08 06:25:07 kevin Exp $
+**  $Id: dialogs.h,v 1.24 2001/02/11 04:56:38 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
@@ -179,7 +179,13 @@ class DialogGetProjectionParameters : public wxDialog
 class DialogGetReconstructionParameters : public wxDialog
 {
  public:
-    DialogGetReconstructionParameters (wxWindow* pParent, int iDefaultXSize = 0, int iDefaultYSize = 0, int iDefaultFilterID = SignalFilter::FILTER_ABS_BANDLIMIT, double dDefaultFilterParam = 1., int iDefaultFilterMethodID = ProcessSignal::FILTER_METHOD_CONVOLUTION, int iDefaultFilterGeneration = ProcessSignal::FILTER_GENERATION_INVALID, int iDefaultZeropad = 3, int iDefaultInterpID = Backprojector::INTERP_LINEAR, int iDefaultInterpParam = 1, int iDefaultBackprojectID = Backprojector::BPROJ_IDIFF3, int iDefaultTrace = Trace::TRACE_NONE);
+    DialogGetReconstructionParameters (wxWindow* pParent, int iDefaultXSize = 0, int iDefaultYSize = 0, 
+      int iDefaultFilterID = SignalFilter::FILTER_ABS_BANDLIMIT, double dDefaultFilterParam = 1., 
+      int iDefaultFilterMethodID = ProcessSignal::FILTER_METHOD_CONVOLUTION, 
+      int iDefaultFilterGeneration = ProcessSignal::FILTER_GENERATION_DIRECT, 
+      int iDefaultZeropad = 3, int iDefaultInterpID = Backprojector::INTERP_LINEAR, 
+      int iDefaultInterpParam = 1, int iDefaultBackprojectID = Backprojector::BPROJ_IDIFF, 
+      int iDefaultTrace = Trace::TRACE_NONE);
     virtual ~DialogGetReconstructionParameters ();
 
     unsigned int getXSize();
index 6a77ba3..ce66ec1 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: views.cpp,v 1.101 2001/02/09 14:34:16 kevin Exp $
+**  $Id: views.cpp,v 1.102 2001/02/11 04:56:38 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
@@ -822,6 +822,7 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   m_pFileMenu->Append(wxID_PREVIEW, "Print Preview");
 #ifdef CTSIM_MDI
   m_pFileMenu->AppendSeparator();
+  m_pFileMenu->Append (MAINMENU_FILE_PREFERENCES, "Pr&eferences...");
   m_pFileMenu->Append(MAINMENU_FILE_EXIT, "E&xit");
 #endif
   GetDocumentManager()->FileHistoryAddFilesToMenu(m_pFileMenu);
@@ -2046,6 +2047,7 @@ PhantomFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   m_pFileMenu->Append(wxID_PREVIEW, "Print Pre&view");
 #ifdef CTSIM_MDI
   m_pFileMenu->AppendSeparator();
+  m_pFileMenu->Append (MAINMENU_FILE_PREFERENCES, "Pr&eferences...");
   m_pFileMenu->Append(MAINMENU_FILE_EXIT, "E&xit");
 #endif
   GetDocumentManager()->FileHistoryAddFilesToMenu(m_pFileMenu);
@@ -2220,7 +2222,7 @@ ProjectionFileView::ProjectionFileView()
   m_iDefaultFilterGeneration = ProcessSignal::FILTER_GENERATION_DIRECT;
 #endif
   m_iDefaultZeropad = 1;
-  m_iDefaultBackprojector = Backprojector::BPROJ_IDIFF3;
+  m_iDefaultBackprojector = Backprojector::BPROJ_IDIFF;
   m_iDefaultInterpolation = Backprojector::INTERP_LINEAR;
   m_iDefaultInterpParam = 1;
   m_iDefaultTrace = Trace::TRACE_NONE;
@@ -2325,7 +2327,10 @@ ProjectionFileView::OnReconstructFourier (wxCommandEvent& event)
 void
 ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
 {
-  DialogGetReconstructionParameters dialogReconstruction (getFrameForChild(), m_iDefaultNX, m_iDefaultNY, m_iDefaultFilter, m_dDefaultFilterParam, m_iDefaultFilterMethod, m_iDefaultFilterGeneration, m_iDefaultZeropad, m_iDefaultInterpolation, m_iDefaultInterpParam, m_iDefaultBackprojector, m_iDefaultTrace);
+  DialogGetReconstructionParameters dialogReconstruction (getFrameForChild(), m_iDefaultNX, m_iDefaultNY, 
+    m_iDefaultFilter, m_dDefaultFilterParam, m_iDefaultFilterMethod, m_iDefaultFilterGeneration, 
+    m_iDefaultZeropad, m_iDefaultInterpolation, m_iDefaultInterpParam, m_iDefaultBackprojector, 
+    m_iDefaultTrace);
   
   int retVal = dialogReconstruction.ShowModal();
   if (retVal == wxID_OK) {
@@ -2454,6 +2459,7 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   m_pFileMenu->Append(wxID_PREVIEW, "Print Pre&view");
 #ifdef CTSIM_MDI
   m_pFileMenu->AppendSeparator();
+  m_pFileMenu->Append (MAINMENU_FILE_PREFERENCES, "Pr&eferences...");
   m_pFileMenu->Append(MAINMENU_FILE_EXIT, "E&xit");
 #endif
   GetDocumentManager()->FileHistoryAddFilesToMenu(m_pFileMenu);
@@ -2784,6 +2790,7 @@ PlotFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   m_pFileMenu->Append(wxID_PREVIEW, "Print Pre&view");
 #ifdef CTSIM_MDI
   m_pFileMenu->AppendSeparator();
+  m_pFileMenu->Append (MAINMENU_FILE_PREFERENCES, "Pr&eferences...");
   m_pFileMenu->Append(MAINMENU_FILE_EXIT, "E&xit");
 #endif
   GetDocumentManager()->FileHistoryAddFilesToMenu(m_pFileMenu);
@@ -3041,6 +3048,7 @@ TextFileView::CreateChildFrame (wxDocument *doc, wxView *view)
   m_pFileMenu->Append(wxID_PREVIEW, "Print Pre&view");
 #ifdef CTSIM_MDI
   m_pFileMenu->AppendSeparator();
+  m_pFileMenu->Append (MAINMENU_FILE_PREFERENCES, "Pr&eferences...");
   m_pFileMenu->Append(MAINMENU_FILE_EXIT, "E&xit");
 #endif
   GetDocumentManager()->FileHistoryAddFilesToMenu(m_pFileMenu);
index f32f5c5..687c290 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: phm2pj.cpp,v 1.24 2001/02/08 06:25:07 kevin Exp $
+**  $Id: phm2pj.cpp,v 1.25 2001/02/11 04:56:38 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
@@ -51,7 +51,7 @@ static struct option phm2pj_options[] =
   {0, 0, 0, 0}
 };
 
-static const char* g_szIdStr = "$Id: phm2pj.cpp,v 1.24 2001/02/08 06:25:07 kevin Exp $";
+static const char* g_szIdStr = "$Id: phm2pj.cpp,v 1.25 2001/02/11 04:56:38 kevin Exp $";
 
 
 void 
@@ -72,7 +72,7 @@ phm2pj_usage (const char *program)
   std::cout << "     --desc           Description of raysum\n";
   std::cout << "     --nray           Number of rays per detector (default = 1)\n";
   std::cout << "     --rotangle       Degrees to rotate view through (multiple of PI)\n";
-  std::cout << "                      (default = 1)\n";
+  std::cout << "                      (default = select appropriate for geometry)\n";
   std::cout << "     --geometry       Geometry of scanning\n";
   std::cout << "        parallel      Parallel scan beams (default)\n";
   std::cout << "        equilinear    Equilinear divergent scan beams\n";
@@ -118,7 +118,7 @@ phm2pj_main (int argc, char* const argv[])
   int opt_trace = Trace::TRACE_NONE;
   int opt_verbose = 0;
   int opt_debug = 0;
-  double opt_rotangle = 1;
+  double opt_rotangle = -1;
   char* endptr = NULL;
   char* endstr;
 
@@ -251,6 +251,13 @@ phm2pj_main (int argc, char* const argv[])
       return (1);
     }
 
+    if (opt_rotangle < 0) {
+      if (optGeometryName.compare ("parallel") == 0)
+        opt_rotangle = 1;
+      else
+        opt_rotangle = 2;
+    }
+
     std::ostringstream desc;
     desc << "phm2pj: NDet=" << opt_ndet << ", Nview=" << opt_nview << ", NRay=" << opt_nray << ", RotAngle=" << opt_rotangle << ", Geometry=" << optGeometryName << ", ";
     if (optPhmFileName.length()) {