-3.0.0beta1 - Released
+3.0.0alpha4
* ctsim: Fixed initialization of min/max for PlotFiles
* ctsim: Added reset to full-intensity scale menu item
- * ctsim: Add convert projections to polar plot
+ * ctsim: Add conversion of projections to polar plot
+ * ctsim: improve bilinear scaling of image size
+
* ezplot: Cleaned up y-tick label placement
* sgp: Added better support for projection/reconstruction animation
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: imagefile.h,v 1.29 2001/01/04 21:28:41 kevin Exp $
+** $Id: imagefile.h,v 1.30 2001/01/06 15:33: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
#ifdef HAVE_FFTW
bool fft (ImageFile& result) const;
bool ifft (ImageFile& result) const;
+ bool fftRows (ImageFile& result) const;
+ bool ifftRows (ImageFile& result) const;
+ bool fftCols (ImageFile& result) const;
+ bool ifftCols (ImageFile& result) const;
#endif
bool magnitude (ImageFile& result) const;
bool phase (ImageFile& result) const;
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: imagefile.cpp,v 1.34 2001/01/04 21:28:41 kevin Exp $
+** $Id: imagefile.cpp,v 1.35 2001/01/06 15:33: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
vResultImag[ix][iy] = 0;
}
} else {
- vResult[ix][iy] = vReal[scaleNX][scaleNY] +
- dXFrac * (vReal[scaleNX+1][scaleNY] - vReal[scaleNX][scaleNY]) +
- dYFrac * (vReal[scaleNX][scaleNY+1] - vReal[scaleNX][scaleNY]);
+ vResult[ix][iy] = (1 - dXFrac) * (1 - dYFrac) * vReal[scaleNX][scaleNY] +
+ dXFrac * (1 - dYFrac) * vReal[scaleNX+1][scaleNY] +
+ dYFrac * (1 - dXFrac) * vReal[scaleNX][scaleNY+1] +
+ dXFrac * dYFrac * vReal[scaleNX+1][scaleNY+1];
if (result.isComplex()) {
if (isComplex())
- vResultImag[ix][iy] = vImag[scaleNX][scaleNY] +
- dXFrac * (vImag[scaleNX+1][scaleNY] - vImag[scaleNX][scaleNY]) +
- dYFrac * (vImag[scaleNX][scaleNY+1] - vImag[scaleNX][scaleNY]);
+ vResultImag[ix][iy] = (1 - dXFrac) * (1 - dYFrac) * vImag[scaleNX][scaleNY] +
+ dXFrac * (1 - dYFrac) * vImag[scaleNX+1][scaleNY] +
+ dYFrac * (1 - dXFrac) * vImag[scaleNX][scaleNY+1] +
+ dXFrac * dYFrac * vImag[scaleNX+1][scaleNY+1];
else
vResultImag[ix][iy] = 0;
}
return true;
}
+
+bool
+ImageFile::fftRows (ImageFile& result) const
+{
+ if (m_nx != result.nx() || m_ny != result.ny()) {
+ sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::fftRows]");
+ return false;
+ }
+
+ if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {
+ if (! result.convertRealToComplex ())
+ return false;
+ }
+
+ fftw_complex* in = new fftw_complex [m_nx];
+
+ ImageFileArrayConst vReal = getArray();
+ ImageFileArrayConst vImag = getImaginaryArray();
+
+ fftw_plan plan = fftw_create_plan (m_nx, FFTW_FORWARD, FFTW_IN_PLACE);
+ std::complex<double>* pcRow = new std::complex<double> [m_nx];
+
+ unsigned int ix, iy;
+ unsigned int iArray = 0;
+ for (iy = 0; iy < m_ny; iy++) {
+ for (ix = 0; ix < m_nx; ix++) {
+ in[ix].re = vReal[ix][iy];
+ if (isComplex())
+ in[ix].im = vImag[ix][iy];
+ else
+ in[ix].im = 0;
+ }
+
+ fftw_one (plan, in, NULL);
+
+ for (ix = 0; ix < m_nx; ix++)
+ pcRow[ix] = std::complex<double>(in[ix].re, in[ix].im);
+
+ Fourier::shuffleFourierToNaturalOrder (pcRow, m_nx);
+ for (ix = 0; ix < m_nx; ix++) {
+ vReal[ix][iy] = pcRow[ix].real();
+ vImag[ix][iy] = pcRow[ix].imag();
+ }
+ }
+ delete [] pcRow;
+
+ fftw_destroy_plan (plan);
+ delete in;
+
+ return true;
+}
+
+bool
+ImageFile::ifftRows (ImageFile& result) const
+{
+ if (m_nx != result.nx() || m_ny != result.ny()) {
+ sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::fftRows]");
+ return false;
+ }
+
+ if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {
+ if (! result.convertRealToComplex ())
+ return false;
+ }
+
+ fftw_complex* in = new fftw_complex [m_nx];
+
+ ImageFileArrayConst vReal = getArray();
+ ImageFileArrayConst vImag = getImaginaryArray();
+
+ fftw_plan plan = fftw_create_plan (m_nx, FFTW_BACKWARD, FFTW_IN_PLACE);
+ std::complex<double>* pcRow = new std::complex<double> [m_nx];
+
+ unsigned int ix, iy;
+ unsigned int iArray = 0;
+ for (iy = 0; iy < m_ny; iy++) {
+ for (ix = 0; ix < m_nx; ix++) {
+ double dImag = 0;
+ if (isComplex())
+ dImag = vImag[ix][iy];
+ pcRow[ix] = std::complex<double> (vReal[ix][iy], dImag);
+ }
+
+ Fourier::shuffleNaturalToFourierOrder (pcRow, m_nx);
+
+ for (ix = 0; ix < m_nx; ix++) {
+ in[ix].re = pcRow[ix].real();
+ in[ix].im = pcRow[ix].imag();
+ }
+
+ fftw_one (plan, in, NULL);
+
+ for (ix = 0; ix < m_nx; ix++) {
+ vReal[ix][iy] = in[ix].re;
+ vImag[ix][iy] = in[ix].im;
+ }
+ }
+ delete [] pcRow;
+
+ fftw_destroy_plan (plan);
+ delete in;
+
+ return true;
+}
+
+bool
+ImageFile::fftCols (ImageFile& result) const
+{
+ return false;
+}
+
+bool
+ImageFile::ifftCols (ImageFile& result) const
+{
+ return false;
+}
+
#endif // HAVE_FFTW
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: projections.cpp,v 1.37 2001/01/04 21:28:41 kevin Exp $
+** $Id: projections.cpp,v 1.38 2001/01/06 15:33: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
{
{"nearest"},
{"bilinear"},
- {"bicubic"},
+// {"bicubic"},
};
const char* Projections::s_aszInterpTitle[] =
{
{"Nearest"},
{"Bilinear"},
- {"Bicubic"},
+// {"Bicubic"},
};
const int Projections::s_iInterpCount = sizeof(s_aszInterpName) / sizeof(char*);
return true;
}
+
+bool
+Projections::convertFFTPolar (ImageFile& rIF, int iInterpolationID, int iZeropad)
+{
+ unsigned int nx = rIF.nx();
+ unsigned int ny = rIF.ny();
+ ImageFileArray v = rIF.getArray();
+ if (! rIF.isComplex())
+ rIF.convertRealToComplex();
+ ImageFileArray vImag = rIF.getImaginaryArray();
+
+ if (! v || nx == 0 || ny == 0)
+ return false;
+
+ Array2d<double> adView (nx, ny);
+ Array2d<double> adDet (nx, ny);
+ double** ppdView = adView.getArray();
+ double** ppdDet = adDet.getArray();
+
+ std::complex<double>** ppcDetValue = new std::complex<double>* [m_nView];
+ unsigned int iView;
+ double* pdDet = new double [m_nDet];
+ fftw_complex* pcIn = new fftw_complex [m_nDet];
+ fftw_plan plan = fftw_create_plan (m_nDet, FFTW_FORWARD, FFTW_IN_PLACE);
+
+ for (iView = 0; iView < m_nView; iView++) {
+ ppcDetValue[iView] = new std::complex<double> [m_nDet];
+ unsigned int iDet;
+ for (iDet = 0; iDet < m_nDet; iDet++) {
+ pcIn[iDet].re = getDetectorArray(iView).detValues()[iDet];
+ pcIn[iDet].im = 0;
+ }
+ fftw_one (plan, pcIn, NULL);
+ for (iDet = 0; iDet < m_nDet; iDet++)
+ ppcDetValue[iView][iDet] = std::complex<double> (pcIn[iDet].re, pcIn[iDet].im);
+ Fourier::shuffleFourierToNaturalOrder (ppcDetValue[iView], m_nDet);
+ }
+
+ fftw_destroy_plan (plan);
+ delete [] pcIn;
+
+ calcArrayPolarCoordinates (nx, ny, ppdView, ppdDet);
+
+ interpolatePolar (v, vImag, nx, ny, ppcDetValue, ppdView, ppdDet, m_nView, m_nDet, iInterpolationID);
+
+ for (iView = 0; iView < m_nView; iView++)
+ delete [] ppcDetValue[iView];
+ delete [] ppcDetValue;
+
+ return true;
+}
+
void
Projections::calcArrayPolarCoordinates (unsigned int nx, unsigned int ny, double** ppdView, double** ppdDet)
{
if (iInterpolationID == POLAR_INTERP_NEAREST) {
int iView = nearest<int> (ppdView[ix][iy]);
int iDet = nearest<int> (ppdDet[ix][iy]);
- if (iView == nView)
- iView = nView - 1;
+ if (iView == nView) {
+ iView = 0;
+ // iDet = m_nDet - iDet;
+ }
if (iDet >= 0 && iDet < nDet && iView >= 0 && iView < nView) {
v[ix][iy] = ppcDetValue[iView][iDet].real();
if (vImag)
if (iFloorView < nView - 1)
v2 = ppcDetValue[iFloorView + 1][iFloorDet];
else
- v2 = v1;
+ v2 = ppcDetValue[0][iFloorDet];
if (iFloorDet < nDet - 1)
v4 = ppcDetValue[iFloorView][iFloorDet+1];
else
if (iFloorView < nView - 1 && iFloorDet < nDet - 1)
v3 = ppcDetValue [iFloorView+1][iFloorDet+1];
else if (iFloorView < nView - 1)
- v4 = v2;
+ v3 = v2;
else
- v4 = v1;
- std::complex<double> vInterp = v1 + dFracView * (v2 - v1) + dFracDet * (v4 - v1);
+ v3 = ppcDetValue[0][iFloorDet+1];
+ std::complex<double> vInterp = (1 - dFracView) * (1 - dFracDet) * v1 +
+ dFracView * (1 - dFracDet) * v2 + dFracView * dFracDet * v3 +
+ dFracDet * (1 - dFracView) * v4;
v[ix][iy] = vInterp.real();
if (vImag)
vImag[ix][iy] = vInterp.imag();
}
}
-bool
-Projections::convertFFTPolar (ImageFile& rIF, int iInterpolationID, int iZeropad)
-{
- unsigned int nx = rIF.nx();
- unsigned int ny = rIF.ny();
- ImageFileArray v = rIF.getArray();
- if (! rIF.isComplex())
- rIF.convertRealToComplex();
- ImageFileArray vImag = rIF.getImaginaryArray();
-
- if (! v || nx == 0 || ny == 0)
- return false;
-
- Array2d<double> adView (nx, ny);
- Array2d<double> adDet (nx, ny);
- double** ppdView = adView.getArray();
- double** ppdDet = adDet.getArray();
-
- std::complex<double>** ppcDetValue = new std::complex<double>* [m_nView];
- unsigned int iView;
- double* pdDet = new double [m_nDet];
- fftw_complex* pcIn = new fftw_complex [m_nDet];
- fftw_plan plan = fftw_create_plan (m_nDet, FFTW_FORWARD, FFTW_IN_PLACE);
-
- for (iView = 0; iView < m_nView; iView++) {
- ppcDetValue[iView] = new std::complex<double> [m_nDet];
- unsigned int iDet;
- for (iDet = 0; iDet < m_nDet; iDet++) {
- pcIn[iDet].re = getDetectorArray(iView).detValues()[iDet];
- pcIn[iDet].im = 0;
- }
- fftw_one (plan, pcIn, NULL);
- for (iDet = 0; iDet < m_nDet; iDet++)
- ppcDetValue[iView][iDet] = std::complex<double> (pcIn[iDet].re, pcIn[iDet].im);
- Fourier::shuffleFourierToNaturalOrder (ppcDetValue[iView], m_nDet);
- }
-
- fftw_destroy_plan (plan);
-
- delete [] pcIn;
-
- calcArrayPolarCoordinates (nx, ny, ppdView, ppdDet);
-
- interpolatePolar (v, vImag, nx, ny, ppcDetValue, ppdView, ppdDet, m_nView, m_nDet, iInterpolationID);
-
- for (iView = 0; iView < m_nView; iView++)
- delete [] ppcDetValue[iView];
- delete [] ppcDetValue;
-
- return true;
-}
-
-
# End Source File
# Begin Source File
-SOURCE=.\ctsim.rc
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
SOURCE=.\wx\msw\error.ico
# End Source File
# Begin Source File
SOURCE=..\..\..\wx2\include\wx\msw\wx\msw\watch1.cur
# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\wx2\include\wx\msw\wx.rc
+# End Source File
# End Group
# End Target
# End Project
--------------------Configuration: ctsim - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1A0.tmp" with contents
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP12.tmp" with contents
[
/nologo /G6 /MTd /W3 /Gm /GR /GX /ZI /Od /I "\wx2\include" /I "." /I "..\..\include" /I "..\..\getopt" /I "..\..\..\lpng108" /I "..\..\..\zlib" /I "..\..\..\fftw-2.1.3\fftw" /I "..\..\..\fftw-2.1.3\rfftw" /D VERSION=\"2.5.0\" /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.0beta1\" /FR"Debug/" /Fp"Debug/ctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
-"C:\ctsim\src\dialogs.cpp"
+"C:\ctsim\src\views.cpp"
]
-Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1A0.tmp"
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1A1.tmp" with contents
+Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP12.tmp"
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP13.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 ..\..\..\lpng108\msvc\win32\libpng\lib_dbg\libpng.lib ..\..\..\lpng108\msvc\win32\zlib\lib_dbg\zlib.lib libcmtd.lib ..\..\..\fftw-2.1.3\Win32\FFTW2st\Debug\FFTW2st.lib ..\..\..\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib ../../../wx2/lib/wxd.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/ctsim.pdb" /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrtd.lib" /out:"Debug/ctsim.exe" /pdbtype:sept /libpath:"..\..\..\lpng108\msvc\win32\libpng\lib" /libpath:"..\..\..\lpng108\msvc\win32\zlib\lib"
.\Debug\ctsim.obj
"\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib"
\wx2\lib\wxd.lib
]
-Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP1A1.tmp"
+Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP13.tmp"
<h3>Output Window</h3>
Compiling...
-dialogs.cpp
+views.cpp
Linking...
-Creating command line "bscmake.exe /nologo /o"Debug/ctsim.bsc" .\Debug\ctsim.sbr .\Debug\dialogs.sbr .\Debug\dlgprojections.sbr .\Debug\dlgreconstruct.sbr .\Debug\docs.sbr .\Debug\views.sbr"
-Creating browse info file...
-BSCMAKE: warning BK4503 : minor error in .SBR file '.\Debug\dialogs.sbr' ignored
-<h3>Output Window</h3>
<h3>Results</h3>
-ctsim.exe - 0 error(s), 1 warning(s)
+ctsim.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: ctsim.cpp,v 1.25 2001/01/02 16:02:13 kevin Exp $
+** $Id: ctsim.cpp,v 1.26 2001/01/06 15:33: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
#endif
#endif
-static const char* rcsindent = "$Id: ctsim.cpp,v 1.25 2001/01/02 16:02:13 kevin Exp $";
+static const char* rcsindent = "$Id: ctsim.cpp,v 1.26 2001/01/06 15:33:15 kevin Exp $";
class CTSimApp* theApp = NULL;
//// Create the main frame window
m_pFrame = new MainFrame(m_docManager, (wxFrame *) NULL, -1, "CTSim", wxPoint(0, 0), wxSize(500, 400), wxDEFAULT_FRAME_STYLE);
-
+
SetTopWindow (m_pFrame);
m_pFrame->Centre(wxBOTH);
// Top-level window for CTSim
+#if CTSIM_MDI
+IMPLEMENT_CLASS(MainFrame, wxMDIParentFrame)
+
+BEGIN_EVENT_TABLE(MainFrame, wxMDIParentFrame)
+#else
IMPLEMENT_CLASS(MainFrame, wxDocParentFrame)
BEGIN_EVENT_TABLE(MainFrame, wxDocParentFrame)
+#endif
+
EVT_MENU(MAINMENU_HELP_ABOUT, MainFrame::OnAbout)
EVT_MENU(MAINMENU_HELP_CONTENTS, MainFrame::OnHelpContents)
EVT_MENU(MAINMENU_FILE_CREATE_PHANTOM, MainFrame::OnCreatePhantom)
+#if CTSIM_MDI
+MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long type)
+: wxMDIParentFrame(NULL, id, title, pos, size, type), m_pLog(NULL)
+#else
MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long type)
: wxDocParentFrame(manager, frame, id, title, pos, size, type), m_pLog(NULL)
+#endif
{
m_pLog = new wxTextCtrl (this, -1, "Log Window\n", wxPoint(0, 250), wxSize(100,50), wxTE_MULTILINE | wxTE_READONLY);
wxLog::SetActiveTarget(new wxLogTextCtrl(m_pLog));
file_menu->Append(MAINMENU_FILE_EXIT, "E&xit");
// history of files visited
- m_docManager->FileHistoryUseMenu(file_menu);
+ theApp->getDocManager()->FileHistoryUseMenu(file_menu);
m_pWindowMenu = new wxMenu;
m_pWindowMenu->UpdateUI (this);
MainFrame::OnUpdateUI (wxUpdateUIEvent& rEvent)
{
int iPos = 0;
- wxList& rListDocs = m_docManager->GetDocuments();
+ wxList& rListDocs = theApp->getDocManager()->GetDocuments();
wxNode* pNode = rListDocs.GetFirst();
while (iPos < MAX_WINDOW_MENUITEMS && pNode != NULL) {
wxDocument* pDoc = static_cast<wxDocument*>(pNode->GetData());
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: ctsim.h,v 1.21 2001/01/04 21:28:41 kevin Exp $
+** $Id: ctsim.h,v 1.22 2001/01/06 15:33: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
#include <dmalloc.h>
#endif
+#ifdef MSVC
+// #define CTSIM_MDI 1
+#endif
+
+
class wxMenu;
class wxDocument;
// Define a new frame for main window
+#if CTSIM_MDI
+class MainFrame: public wxMDIParentFrame
+#else
class MainFrame: public wxDocParentFrame
+#endif
{
DECLARE_CLASS(MainFrame)
private:
enum {
MAINMENU_HELP_ABOUT = 500,
+ MAINMENU_WINDOW_BASE,
MAINMENU_HELP_CONTENTS,
MAINMENU_FILE_CREATE_PHANTOM,
MAINMENU_FILE_CREATE_FILTER,
MAINMENU_FILE_EXIT,
- IFMENU_FILE_PROPERTIES,
-
PJMENU_FILE_PROPERTIES,
PJMENU_RECONSTRUCT_FBP,
PJMENU_RECONSTRUCT_FOURIER,
PJMENU_CONVERT_FFT_POLAR,
IFMENU_FILE_EXPORT,
+ IFMENU_FILE_PROPERTIES,
IFMENU_PLOT_ROW,
IFMENU_PLOT_COL,
+ IFMENU_PLOT_FFT_ROW,
+ IFMENU_PLOT_FFT_COL,
IFMENU_PLOT_HISTOGRAM,
IFMENU_VIEW_SCALE_AUTO,
IFMENU_FILTER_INVERSE_FOURIER,
IFMENU_FILTER_FFT,
IFMENU_FILTER_IFFT,
+ IFMENU_FILTER_FFT_ROWS,
+ IFMENU_FILTER_FFT_COLS,
+ IFMENU_FILTER_IFFT_ROWS,
+ IFMENU_FILTER_IFFT_COLS,
IFMENU_FILTER_MAGNITUDE,
IFMENU_FILTER_PHASE,
IFMENU_FILTER_SHUFFLENATURALTOFOURIERORDER,
PLOTMENU_VIEW_SCALE_MINMAX,
PLOTMENU_VIEW_SCALE_AUTO,
PLOTMENU_VIEW_SCALE_FULL,
- MAINMENU_WINDOW_BASE,
+
};
#endif
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: docs.cpp,v 1.11 2001/01/02 16:02:13 kevin Exp $
+** $Id: docs.cpp,v 1.12 2001/01/06 15:33: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
}
Modify(false);
UpdateAllViews();
+ GetFirstView()->OnUpdate (GetFirstView(), NULL);
return true;
}
m_idPhantom = m_phantom.id();
Modify(false);
UpdateAllViews();
+ GetFirstView()->OnUpdate (GetFirstView(), NULL);
return true;
}
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: views.cpp,v 1.51 2001/01/04 21:28:41 kevin Exp $
+** $Id: views.cpp,v 1.52 2001/01/06 15:33: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
EVT_MENU(IFMENU_IMAGE_MULTIPLY, ImageFileView::OnMultiply)
EVT_MENU(IFMENU_IMAGE_DIVIDE, ImageFileView::OnDivide)
EVT_MENU(IFMENU_IMAGE_SCALESIZE, ImageFileView::OnScaleSize)
-#ifdef HAVE_FFTW
+#ifdef HAVE_FFT
EVT_MENU(IFMENU_FILTER_FFT, ImageFileView::OnFFT)
EVT_MENU(IFMENU_FILTER_IFFT, ImageFileView::OnIFFT)
+EVT_MENU(IFMENU_FILTER_FFT_ROWS, ImageFileView::OnFFTRows)
+EVT_MENU(IFMENU_FILTER_IFFT_ROWS, ImageFileView::OnIFFTRows)
+EVT_MENU(IFMENU_FILTER_FFT_COLS, ImageFileView::OnFFTCols)
+EVT_MENU(IFMENU_FILTER_IFFT_COLS, ImageFileView::OnIFFTCols)
#endif
EVT_MENU(IFMENU_FILTER_MAGNITUDE, ImageFileView::OnMagnitude)
EVT_MENU(IFMENU_FILTER_PHASE, ImageFileView::OnPhase)
EVT_MENU(IFMENU_PLOT_ROW, ImageFileView::OnPlotRow)
EVT_MENU(IFMENU_PLOT_COL, ImageFileView::OnPlotCol)
+#ifdef HAVE_FFT
+EVT_MENU(IFMENU_PLOT_FFT_ROW, ImageFileView::OnPlotFFTRow)
+EVT_MENU(IFMENU_PLOT_FFT_COL, ImageFileView::OnPlotFFTCol)
+#endif
EVT_MENU(IFMENU_PLOT_HISTOGRAM, ImageFileView::OnPlotHistogram)
END_EVENT_TABLE()
ImageFileView::OnFFT (wxCommandEvent& event)
{
ImageFile& rIF = GetDocument()->getImageFile();
- wxProgressDialog dlgProgress (wxString("FFT"), wxString("FFT Progress"), 1, m_frame, wxPD_APP_MODAL);
rIF.fft (rIF);
rIF.labelAdd ("FFT Image");
m_bMinSpecified = false;
ImageFileView::OnIFFT (wxCommandEvent& event)
{
ImageFile& rIF = GetDocument()->getImageFile();
- wxProgressDialog dlgProgress (wxString("IFFT"), wxString("IFFT Progress"), 1, m_frame, wxPD_APP_MODAL);
rIF.ifft (rIF);
rIF.labelAdd ("IFFT Image");
m_bMinSpecified = false;
GetDocument()->Modify(TRUE);
GetDocument()->UpdateAllViews(this);
}
+
+void
+ImageFileView::OnFFTRows (wxCommandEvent& event)
+{
+ ImageFile& rIF = GetDocument()->getImageFile();
+ rIF.fftRows (rIF);
+ rIF.labelAdd ("FFT Rows");
+ m_bMinSpecified = false;
+ m_bMaxSpecified = false;
+ if (theApp->getSetModifyNewDocs())
+ GetDocument()->Modify(TRUE);
+ GetDocument()->UpdateAllViews(this);
+}
+
+void
+ImageFileView::OnIFFTRows (wxCommandEvent& event)
+{
+ ImageFile& rIF = GetDocument()->getImageFile();
+ rIF.ifftRows (rIF);
+ rIF.labelAdd ("IFFT Rows");
+ m_bMinSpecified = false;
+ m_bMaxSpecified = false;
+ if (theApp->getSetModifyNewDocs())
+ GetDocument()->Modify(TRUE);
+ GetDocument()->UpdateAllViews(this);
+}
+
+void
+ImageFileView::OnFFTCols (wxCommandEvent& event)
+{
+ ImageFile& rIF = GetDocument()->getImageFile();
+ rIF.fftCols (rIF);
+ rIF.labelAdd ("FFT Columns");
+ m_bMinSpecified = false;
+ m_bMaxSpecified = false;
+ if (theApp->getSetModifyNewDocs())
+ GetDocument()->Modify(TRUE);
+ GetDocument()->UpdateAllViews(this);
+}
+
+void
+ImageFileView::OnIFFTCols (wxCommandEvent& event)
+{
+ ImageFile& rIF = GetDocument()->getImageFile();
+ rIF.ifftCols (rIF);
+ rIF.labelAdd ("IFFT Columns");
+ m_bMinSpecified = false;
+ m_bMaxSpecified = false;
+ if (theApp->getSetModifyNewDocs())
+ GetDocument()->Modify(TRUE);
+ GetDocument()->UpdateAllViews(this);
+}
#endif
void
wxFrame*
ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
{
+#if CTSIM_MDI
+ wxMDIChildFrame *subframe = new wxMDIChildFrame(theApp->getMainFrame(), -1, "ImageFile Frame", wxPoint(-1, -1), wxSize(0, 0), wxDEFAULT_FRAME_STYLE);
+#else
wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "ImageFile Frame", wxPoint(-1, -1), wxSize(0, 0), wxDEFAULT_FRAME_STYLE);
+#endif
wxMenu *file_menu = new wxMenu;
filter_menu->Append (IFMENU_FILTER_EXP, "&Exp");
filter_menu->AppendSeparator();
#ifdef HAVE_FFT
- filter_menu->Append (IFMENU_FILTER_FFT, "&FFT");
- filter_menu->Append (IFMENU_FILTER_IFFT, "&IFFT");
+ filter_menu->Append (IFMENU_FILTER_FFT, "2D &FFT");
+ filter_menu->Append (IFMENU_FILTER_IFFT, "2D &IFFT");
+ filter_menu->Append (IFMENU_FILTER_FFT_ROWS, "FFT Rows");
+ filter_menu->Append (IFMENU_FILTER_IFFT_ROWS, "IFFT Rows");
+ filter_menu->Append (IFMENU_FILTER_FFT_COLS, "FFT Columns");
+ filter_menu->Append (IFMENU_FILTER_IFFT_COLS, "IFFT Columns");
filter_menu->Append (IFMENU_FILTER_FOURIER, "F&ourier");
filter_menu->Append (IFMENU_FILTER_INVERSE_FOURIER, "Inverse Fo&urier");
#else
analyze_menu->Append (IFMENU_PLOT_COL, "Plot &Column");
analyze_menu->Append (IFMENU_PLOT_HISTOGRAM, "Plot &Histogram");
analyze_menu->AppendSeparator();
+ analyze_menu->Append (IFMENU_PLOT_FFT_ROW, "Plot FFT Row");
+ analyze_menu->Append (IFMENU_PLOT_FFT_COL, "Plot FFT Column");
+ analyze_menu->AppendSeparator();
analyze_menu->Append (IFMENU_COMPARE_IMAGES, "Compare &Images...");
analyze_menu->Append (IFMENU_COMPARE_ROW, "Compare &Row");
analyze_menu->Append (IFMENU_COMPARE_COL, "Compare &Column");
if (!GetDocument()->Close())
return false;
- m_canvas->Clear();
+ // m_canvas->Clear();
m_canvas->m_pView = NULL;
m_canvas = NULL;
wxString s(theApp->GetAppName());
}
ImageFile& rScaledIF = pScaledDoc->getImageFile();
rScaledIF.setArraySize (iNewNX, iNewNY);
+ rScaledIF.labelsCopy (rIF);
rScaledIF.labelAdd (os.str().c_str());
rIF.scaleImage (rScaledIF);
*theApp->getLog() << os.str().c_str() << "\n";
}
}
+#ifdef HAVE_FFT
+void
+ImageFileView::OnPlotFFTRow (wxCommandEvent& event)
+{
+ int xCursor, yCursor;
+ if (! m_canvas->GetCurrentCursor (xCursor, yCursor)) {
+ wxMessageBox ("No row selected. Please use left mouse button on image to select column","Error");
+ return;
+ }
+
+ const ImageFile& rIF = dynamic_cast<ImageFileDocument*>(GetDocument())->getImageFile();
+ ImageFileArrayConst v = rIF.getArray();
+ ImageFileArrayConst vImag = rIF.getImaginaryArray();
+ int nx = rIF.nx();
+ int ny = rIF.ny();
+
+ if (v != NULL && yCursor < ny) {
+ fftw_complex* pcIn = new fftw_complex [nx];
+
+ int i;
+ for (i = 0; i < nx; i++) {
+ pcIn[i].re = v[i][yCursor];
+ if (rIF.isComplex())
+ pcIn[i].im = vImag[i][yCursor];
+ else
+ pcIn[i].im = 0;
+ }
+
+ fftw_plan plan = fftw_create_plan (nx, FFTW_FORWARD, FFTW_IN_PLACE);
+ fftw_one (plan, pcIn, NULL);
+ fftw_destroy_plan (plan);
+
+ double* pX = new double [nx];
+ double* pYReal = new double [nx];
+ double* pYImag = new double [nx];
+ double* pYMag = new double [nx];
+ for (i = 0; i < nx; i++) {
+ pX[i] = i;
+ pYReal[i] = pcIn[i].re;
+ pYImag[i] = pcIn[i].im;
+ pYMag[i] = ::sqrt (pcIn[i].re * pcIn[i].re + pcIn[i].im * pcIn[i].im);
+ }
+ Fourier::shuffleFourierToNaturalOrder (pYReal, nx);
+ Fourier::shuffleFourierToNaturalOrder (pYImag, nx);
+ Fourier::shuffleFourierToNaturalOrder (pYMag, nx);
+
+ PlotFileDocument* pPlotDoc = dynamic_cast<PlotFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.plt", wxDOC_SILENT));
+ if (! pPlotDoc) {
+ sys_error (ERR_SEVERE, "Internal error: unable to create Plot file");
+ } else {
+ PlotFile& rPlotFile = pPlotDoc->getPlotFile();
+ std::ostringstream os;
+ os << "Row " << yCursor;
+ std::string title("title ");
+ title += os.str();
+ rPlotFile.addEzsetCommand (title.c_str());
+ rPlotFile.addEzsetCommand ("xlabel Column");
+ rPlotFile.addEzsetCommand ("ylabel Pixel Value");
+ rPlotFile.addEzsetCommand ("lxfrac 0");
+ rPlotFile.addEzsetCommand ("curve 1");
+ rPlotFile.addEzsetCommand ("color 1");
+ rPlotFile.addEzsetCommand ("curve 2");
+ rPlotFile.addEzsetCommand ("color 2");
+ rPlotFile.addEzsetCommand ("dash 1");
+ rPlotFile.addEzsetCommand ("curve 3");
+ rPlotFile.addEzsetCommand ("dash 2");
+ rPlotFile.addEzsetCommand ("color 3");
+ rPlotFile.addEzsetCommand ("box");
+ rPlotFile.addEzsetCommand ("grid");
+ rPlotFile.setCurveSize (2, nx);
+ rPlotFile.addColumn (0, pX);
+ rPlotFile.addColumn (1, pYReal);
+ rPlotFile.addColumn (2, pYImag);
+ rPlotFile.addColumn (3, pYMag);
+ }
+ delete pX;
+ delete pYReal;
+ delete pYImag;
+ delete pYMag;
+ delete [] pcIn;
+
+ if (theApp->getSetModifyNewDocs())
+ pPlotDoc->Modify(true);
+ pPlotDoc->UpdateAllViews();
+ }
+}
+
+void
+ImageFileView::OnPlotFFTCol (wxCommandEvent& event)
+{
+ int xCursor, yCursor;
+ if (! m_canvas->GetCurrentCursor (xCursor, yCursor)) {
+ wxMessageBox ("No column selected. Please use left mouse button on image to select column","Error");
+ return;
+ }
+
+ const ImageFile& rIF = dynamic_cast<ImageFileDocument*>(GetDocument())->getImageFile();
+ ImageFileArrayConst v = rIF.getArray();
+ int nx = rIF.nx();
+ int ny = rIF.ny();
+
+ if (v != NULL && xCursor < nx) {
+ double* pX = new double [ny];
+ double* pY = new double [ny];
+ for (int i = 0; i < ny; i++) {
+ pX[i] = i;
+ pY[i] = v[xCursor][i];
+ }
+ PlotFileDocument* pPlotDoc = dynamic_cast<PlotFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.plt", wxDOC_SILENT));
+ if (! pPlotDoc) {
+ sys_error (ERR_SEVERE, "Internal error: unable to create Plot file");
+ } else {
+ PlotFile& rPlotFile = pPlotDoc->getPlotFile();
+ std::ostringstream os;
+ os << "Column " << xCursor;
+ std::string title("title ");
+ title += os.str();
+ rPlotFile.addEzsetCommand (title.c_str());
+ rPlotFile.addEzsetCommand ("xlabel Row");
+ rPlotFile.addEzsetCommand ("ylabel Pixel Value");
+ rPlotFile.addEzsetCommand ("lxfrac 0");
+ rPlotFile.addEzsetCommand ("box");
+ rPlotFile.addEzsetCommand ("grid");
+ rPlotFile.setCurveSize (2, nx);
+ rPlotFile.addColumn (0, pX);
+ rPlotFile.addColumn (1, pY);
+ }
+ delete pX;
+ delete pY;
+ if (theApp->getSetModifyNewDocs())
+ pPlotDoc->Modify(true);
+ pPlotDoc->UpdateAllViews();
+ }
+}
+#endif
+
void
ImageFileView::OnCompareCol (wxCommandEvent& event)
{
m_dDefaultFieldOfView = 1;
m_iDefaultGeometry = Scanner::GEOMETRY_PARALLEL;
m_iDefaultTrace = Trace::TRACE_NONE;
+
+ m_iDefaultRasterNX = 256;
+ m_iDefaultRasterNY = 256;
+ m_iDefaultRasterNSamples = 2;
}
PhantomView::~PhantomView(void)
void
PhantomView::OnRasterize (wxCommandEvent& event)
{
- DialogGetRasterParameters dialogRaster (m_frame, 256, 256, 1);
+ DialogGetRasterParameters dialogRaster (m_frame, m_iDefaultRasterNX, m_iDefaultRasterNY, m_iDefaultRasterNSamples);
int retVal = dialogRaster.ShowModal();
if (retVal == wxID_OK) {
- int xSize = dialogRaster.getXSize();
- int ySize = dialogRaster.getYSize();
- int nSamples = dialogRaster.getNSamples();
- if (nSamples < 1)
- nSamples = 1;
- if (xSize > 0 && ySize > 0) {
+ m_iDefaultRasterNX = dialogRaster.getXSize();
+ m_iDefaultRasterNY = dialogRaster.getYSize();
+ m_iDefaultRasterNSamples = dialogRaster.getNSamples();
+ if (m_iDefaultRasterNSamples < 1)
+ m_iDefaultRasterNSamples = 1;
+ if (m_iDefaultRasterNX > 0 && m_iDefaultRasterNY > 0) {
const Phantom& rPhantom = GetDocument()->getPhantom();
ImageFileDocument* pRasterDoc = dynamic_cast<ImageFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.if", wxDOC_SILENT));
if (! pRasterDoc) {
}
ImageFile& imageFile = pRasterDoc->getImageFile();
- imageFile.setArraySize (xSize, ySize);
+ imageFile.setArraySize (m_iDefaultRasterNX, m_iDefaultRasterNX);
wxProgressDialog dlgProgress (wxString("Rasterize"), wxString("Rasterization Progress"), imageFile.nx() + 1, m_frame, wxPD_CAN_ABORT);
Timer timer;
for (unsigned int i = 0; i < imageFile.nx(); i++) {
- rPhantom.convertToImagefile (imageFile, nSamples, Trace::TRACE_NONE, i, 1, true);
+ rPhantom.convertToImagefile (imageFile, m_iDefaultRasterNSamples, Trace::TRACE_NONE, i, 1, true);
if (! dlgProgress.Update(i+1)) {
pRasterDoc->DeleteAllViews();
return;
pRasterDoc->Modify(true);
pRasterDoc->UpdateAllViews(this);
std::ostringstream os;
- os << "Rasterize Phantom " << rPhantom.name() << ": XSize=" << xSize << ", YSize=" << ySize << ", nSamples=" << nSamples;
+ os << "Rasterize Phantom " << rPhantom.name() << ": XSize=" << m_iDefaultRasterNX << ", YSize="
+ << m_iDefaultRasterNY << ", nSamples=" << m_iDefaultRasterNSamples;
*theApp->getLog() << os.str().c_str() << "\n";
imageFile.labelAdd (os.str().c_str(), timer.timerEnd());
ImageFileView* rasterView = dynamic_cast<ImageFileView*>(pRasterDoc->GetFirstView());
wxFrame*
PhantomView::CreateChildFrame(wxDocument *doc, wxView *view)
{
+#if CTSIM_MDI
+ wxMDIChildFrame *subframe = new wxMDIChildFrame(theApp->getMainFrame(), -1, "Phantom Frame", wxPoint(10, 10), wxSize(256, 256), wxDEFAULT_FRAME_STYLE);
+#else
wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "Phantom Frame", wxPoint(10, 10), wxSize(256, 256), wxDEFAULT_FRAME_STYLE);
-
+#endif
+
wxMenu *file_menu = new wxMenu;
file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom...");
if (!GetDocument()->Close())
return false;
- m_canvas->Clear();
+// m_canvas->Clear();
m_canvas->m_pView = NULL;
m_canvas = NULL;
- wxString s(wxTheApp->GetAppName());
- if (m_frame)
- m_frame->SetTitle(s);
+// wxString s(wxTheApp->GetAppName());
+// if (m_frame)
+// m_frame->SetTitle(s);
SetFrame(NULL);
Activate(false);
if (deleteWindow) {
+
delete m_frame;
return true;
}
wxFrame*
ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view)
{
+#ifdef CTSIM_MDI
+ wxMDIChildFrame *subframe = new wxMDIChildFrame (theApp->getMainFrame(), -1, "Projection Frame", wxPoint(10, 10), wxSize(0, 0), wxDEFAULT_FRAME_STYLE);
+#else
wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "Projection Frame", wxPoint(10, 10), wxSize(0, 0), wxDEFAULT_FRAME_STYLE);
-
+#endif
+
wxMenu *file_menu = new wxMenu;
file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom...");
if (!GetDocument()->Close())
return false;
- m_canvas->Clear();
+ // m_canvas->Clear();
m_canvas->m_pView = NULL;
m_canvas = NULL;
wxString s(wxTheApp->GetAppName());
wxFrame*
PlotFileView::CreateChildFrame(wxDocument *doc, wxView *view)
{
+#ifdef CTSIM_MDI
+ wxMDIChildFrame *subframe = new wxMDIChildFrame (theApp->getMainFrame(), -1, "Plot Frame", wxPoint(10, 10), wxSize(500, 300), wxDEFAULT_FRAME_STYLE);
+#else
wxDocChildFrame *subframe = new wxDocChildFrame(doc, view, theApp->getMainFrame(), -1, "Plot Frame", wxPoint(10, 10), wxSize(500, 300), wxDEFAULT_FRAME_STYLE);
-
+#endif
+
wxMenu *file_menu = new wxMenu;
file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom...");
if (!GetDocument()->Close())
return false;
- m_canvas->Clear();
+ // m_canvas->Clear();
m_canvas->m_pView = NULL;
m_canvas = NULL;
wxString s(wxTheApp->GetAppName());
** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: views.h,v 1.25 2001/01/04 21:28:41 kevin Exp $
+** $Id: views.h,v 1.26 2001/01/06 15:33: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
#ifdef HAVE_FFT
void OnFFT (wxCommandEvent& event);
void OnIFFT (wxCommandEvent& event);
+ void OnFFTRows (wxCommandEvent& event);
+ void OnIFFTRows (wxCommandEvent& event);
+ void OnFFTCols (wxCommandEvent& event);
+ void OnIFFTCols (wxCommandEvent& event);
#endif
void OnMagnitude (wxCommandEvent& event);
void OnScaleFull (wxCommandEvent& event);
void OnPlotRow (wxCommandEvent& event);
void OnPlotCol (wxCommandEvent& event);
+#if HAVE_FFT
+ void OnPlotFFTRow (wxCommandEvent& event);
+ void OnPlotFFTCol (wxCommandEvent& event);
+#endif
void OnPlotHistogram (wxCommandEvent& event);
void OnCompareRow (wxCommandEvent& event);
void OnCompareCol (wxCommandEvent& event);
double m_dDefaultFocalLength;
double m_dDefaultFieldOfView;
+ int m_iDefaultRasterNX;
+ int m_iDefaultRasterNY;
+ int m_iDefaultRasterNSamples;
+
public:
PhantomView(void);
virtual ~PhantomView(void);