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