\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
\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}.
\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
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}}
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},
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}
\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$}
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}
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}
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.
-\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.
\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.
\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
\subsubsection{Set}
\subsubsection{Auto}
\subsubsection{Full}
-
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
\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
-\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
\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}%
\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}%
\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}%
\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}%
\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}
\usage
\begin{itemize}\itemsep=0pt
- \item --nsamples
+ \item -\,-nsamples
\end{itemize}
\section{pj2if}\label{pj2if}\index{ctsimtext,pj2if}%
\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}%
\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}%
\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
\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}
+}
-\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}%
\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}%
{\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}%
-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
** 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
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;
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)
{}
** 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
#endif
#include "ctsupport.h"
-#include "cubicinterp.h"
+#include "interpolator.h"
#include "fnetorderstream.h"
#ifdef HAVE_SGP
** 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
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);
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;
** 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
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[] =
{"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*);
{"nearest"},
{"linear"},
{"cubic"},
+#if HAVE_FREQ_PREINTERP
{"freq_preinterpolationj"},
+#endif
#if HAVE_BSPLINE_INTERP
{"bspline"},
{"1bspline"},
{"Nearest"},
{"Linear"},
{"Cubic"},
+#if HAVE_FREQ_PREINTERP
{"Frequency Preinterpolation"},
+#endif
#if HAVE_BSPLINE_INTERP
{"B-Spline"},
{"B-Spline 1st Order"},
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]";
{
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++) {
{
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];
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
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;
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];
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;
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)
{
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];
{
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];
** 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
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;
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"},
** 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
const char* ProcessSignal::s_aszFilterMethodName[] = {
{"convolution"},
{"fourier"},
- {"fouier_table"},
+ {"fouier-table"},
{"fft"},
#if HAVE_FFTW
{"fftw"},
const int ProcessSignal::FILTER_GENERATION_INVERSE_FOURIER = 1;
const char* ProcessSignal::s_aszFilterGenerationName[] = {
{"direct"},
- {"inverse_fourier"},
+ {"inverse-fourier"},
};
const char* ProcessSignal::s_aszFilterGenerationTitle[] = {
{"Direct"},
** 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;
#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;
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
--------------------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
\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...
** 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
#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!
#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[] =
{
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;
}
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)
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
void
MainFrame::showHelp (int commandID)
{
-#ifdef CTSIM_WINHELP
- m_winHelp.LoadFile();
-#else
- m_htmlHelp.LoadFile();
-#endif
-
switch (commandID) {
case MAINMENU_HELP_CONTENTS:
{}
+void
+MainFrame::OnPreferences (wxCommandEvent& WXUNUSED(event) )
+{
+ theApp->setAdvancedOptions (! theApp->getAdvancedOptions());
+}
+
+
#include "./splash.xpm"
void
MainFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
** 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
#include "wx/wx.h"
#endif
#include "wx/config.h"
+#include "wx/msw/helpchm.h"
#ifdef MSVC
#define CTSIM_MDI 1
bool m_bShuttingDown;
#if CTSIM_WINHELP
- wxWinHelpController m_winHelp;
+ wxCHMHelpController m_winHelp;
#endif
wxHtmlHelpController m_htmlHelp;
void OnSize (wxSizeEvent& event);
#if CTSIM_WINHELP
- wxWinHelpController& getWinHelpController()
+ wxCHMHelpController& getWinHelpController()
{return m_winHelp; }
#endif
wxHtmlHelpController& getHtmlHelpController()
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);
private:
enum { O_HELP, O_VERSION };
static struct option ctsimOptions[];
-
+
+ bool m_bAdvancedOptions;
wxDocManager* m_docManager;
MainFrame* m_pFrame;
wxConfig* m_pConfig;
{ 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; }
MAINMENU_FILE_CREATE_FILTER,
MAINMENU_FILE_EXIT,
+ MAINMENU_FILE_PREFERENCES,
PJMENU_FILE_PROPERTIES,
PJMENU_RECONSTRUCT_FBP,
** 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
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);
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
/////////////////////////////////////////////////////////////////////
-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);
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);
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);
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);
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
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";
+ }
}
** 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
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();
** 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
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);
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);
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;
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) {
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);
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);
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);
** 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
{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
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";
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;
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()) {