From 7df269f65639c1a862a58649c48331824029128a Mon Sep 17 00:00:00 2001 From: "Kevin M. Rosenberg" Date: Fri, 23 Feb 2001 02:06:02 +0000 Subject: [PATCH] r574: no message --- doc/ctsim-concepts.tex | 17 ++++++--- doc/ctsim-gui.tex | 6 ++++ doc/ctsim-textui.tex | 2 +- include/backprojectors.h | 14 +++++--- include/reconstruct.h | 3 +- libctsim/backprojectors.cpp | 38 +++++++++++++++++--- libctsim/reconstruct.cpp | 10 ++++-- msvc/ctsim/ctsim.plg | 14 ++++---- src/backgroundmgr.cpp | 70 ++++++++++++++++++++++++++++++------- src/backgroundmgr.h | 16 +++++++-- src/threadrecon.cpp | 10 ++++-- src/threadrecon.h | 21 ++++++++--- src/views.cpp | 4 ++- tools/pjrec.cpp | 6 ++-- 14 files changed, 181 insertions(+), 50 deletions(-) diff --git a/doc/ctsim-concepts.tex b/doc/ctsim-concepts.tex index 1b53d60..bacfd4b 100644 --- a/doc/ctsim-concepts.tex +++ b/doc/ctsim-concepts.tex @@ -316,7 +316,7 @@ accurate as filtered backprojection. This is due primarily to interpolation occurring in the frequency domain rather than the spatial domain. -\subsection{Filtered Backprojection}\index{Filtered backprojection} +\subsection{Filtered Backprojection}\index{Filtered backprojection}\index{Symmetric multiprocessing}\index{SMP} The technique is comprised of two sequential steps: filtering projections followed by backprojecting the filtered projections. Though these two steps are sequential, each view position can be processed independently. @@ -324,9 +324,18 @@ these two steps are sequential, each view position can be processed independentl \subsubsection{Parallel Computer Processing}\index{Parallel processing} Since each view can be processed independently, filtered backprojection is amendable to parallel processing. Indeed, this has been used in commercial scanners to speed reconstruction. -This parallelism is exploited in the MPI versions of \ctsim\ where the -data from all the views are spread about amongst all of the -processors. This has been testing in a cluster of 16 computers with excellent +This parallelism is exploited both in the \ctsim\ graphical shell and +in the \helpref{LAM}{ctsimtextlam} version of \ctsimtext. \ctsim\ can distribute it's workload +amongst multiple processors working in parallel. + +The graphical shell will automatically take advantage of multiple CPU's when +running on a \emph{Symmetric Multiprocessing} +computer. Dual-CPU computers are commonly available which provide a near doubling +in reconstruction speeds. \ctsim, though, has no limits on the number of CPU's +that can be used in parallel. The \emph{LAM} version +of \ctsimtext\ is designed to work in a cluster of computers. +This has been testing with a cluster of 16 computers in a +\urlref{Beowulf-class}{http://www.beowulf.org} cluster with excellent results. \subsubsection{Filter projections} diff --git a/doc/ctsim-gui.tex b/doc/ctsim-gui.tex index 2168702..923554a 100644 --- a/doc/ctsim-gui.tex +++ b/doc/ctsim-gui.tex @@ -180,6 +180,12 @@ usual. There extra events are not important for viewing with typical operation o new installations. With this option set, \ctsim\ will display helpful tips when \ctsim\ is started.} +\twocolitem{\textbf{Run background tasks}}{This option is initially turned off in +new installations. With this option set, \ctsim\ execute lengthy calculations in the +background. A background window will appear when processes are running in the background +and will disappear when no background processes are executing. This background window shows +the status and progress of all background processes.} + \end{twocollist} \subsection{File - Open} diff --git a/doc/ctsim-textui.tex b/doc/ctsim-textui.tex index 07e73c3..f926e02 100644 --- a/doc/ctsim-textui.tex +++ b/doc/ctsim-textui.tex @@ -36,7 +36,7 @@ as a shortcut to the equivalent command \\ \end{enumerate} -\section{Parallel Processing}\index{Parallel processing} +\section{Parallel Processing}\label{ctsimtextlam}\index{Parallel processing}\index{MPI}\index{LAM} \ctsimtext\ can distribute it's processing over a cluster. Specifically, \ctsimtext\ supports the \urlref{LAM}{http://www.mpi.nd.edu/lam} version of the MPI environment. On platforms with LAM installed, a parallel version of diff --git a/include/backprojectors.h b/include/backprojectors.h index bd30b9c..ce5b108 100644 --- a/include/backprojectors.h +++ b/include/backprojectors.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: backprojectors.h,v 1.22 2001/02/22 18:22:40 kevin Exp $ +** $Id: backprojectors.h,v 1.23 2001/02/23 02:06:01 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 @@ -64,6 +64,7 @@ class Backprojector ~Backprojector (); void BackprojectView (const double* const viewData, const double viewAngle); + void PostProcessing(); bool fail() const {return m_fail;} const std::string& failMessage() const {return m_failMessage;} @@ -111,13 +112,13 @@ class Backproject virtual ~Backproject (); - virtual void BackprojectView (const double* const viewData, const double viewAngle) {}; + virtual void BackprojectView (const double* const viewData, const double viewAngle) = 0; + virtual void PostProcessing (); // call after backprojecting all views protected: void ScaleImageByRotIncrement (); void Backproject::errorIndexOutsideDetector (int ix, int iy, double theta, double r, double phi, double L, int ni); void Backproject::errorIndexOutsideDetector (int ix, int iy, double theta, double L, int ni); - const Projections& proj; ImageFile& im; int interpType; @@ -132,6 +133,7 @@ class Backproject double xInc, yInc; // size of cells int m_interpFactor; double m_dFocalLength; + bool m_bPostProcessingDone; private: Backproject (const Backproject& rhs); @@ -156,7 +158,8 @@ class BackprojectTable : public Backproject BackprojectTable (const Projections& proj, ImageFile& im, int interpID, const int interpFactor); virtual ~BackprojectTable (); - void BackprojectView (const double* const t, const double view_angle); + virtual void BackprojectView (const double* const t, const double view_angle); + virtual void PostProcessing (); // call after backprojecting all views protected: Array2d arrayR; @@ -172,7 +175,8 @@ class BackprojectDiff : public Backproject BackprojectDiff (const Projections& proj, ImageFile& im, int interpID, const int interpFactor); ~BackprojectDiff (); - void BackprojectView (const double* const t, const double view_angle); + virtual void BackprojectView (const double* const t, const double view_angle); + virtual void PostProcessing (); // call after backprojecting all views protected: double start_r; diff --git a/include/reconstruct.h b/include/reconstruct.h index 54f19f0..1e232e5 100644 --- a/include/reconstruct.h +++ b/include/reconstruct.h @@ -8,7 +8,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: reconstruct.h,v 1.6 2001/02/20 04:48:45 kevin Exp $ +** $Id: reconstruct.h,v 1.7 2001/02/23 02:06:01 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 @@ -63,6 +63,7 @@ class Reconstructor void reconstructAllViews (); void reconstructView (int iStartView = 0, int iViewCount = -1, SGP* pSGP = NULL, bool bBackprojectView = true, double dGraphWidth = 1.); + void postProcessing (); }; #endif diff --git a/libctsim/backprojectors.cpp b/libctsim/backprojectors.cpp index ebfe2a4..fc3c958 100644 --- a/libctsim/backprojectors.cpp +++ b/libctsim/backprojectors.cpp @@ -8,7 +8,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: backprojectors.cpp,v 1.27 2001/02/22 18:22:40 kevin Exp $ +** $Id: backprojectors.cpp,v 1.28 2001/02/23 02:06:01 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 @@ -113,6 +113,13 @@ Backprojector::BackprojectView (const double* const viewData, const double viewA m_pBackprojectImplem->BackprojectView (viewData, viewAngle); } +void +Backprojector::PostProcessing() +{ + if (m_pBackprojectImplem != NULL) + m_pBackprojectImplem->PostProcessing(); +} + Backprojector::~Backprojector () { delete m_pBackprojectImplem; @@ -254,7 +261,7 @@ Backprojector::convertInterpIDToTitle (const int interpID) // Pure virtual base class for all backprojectors. Backproject::Backproject (const Projections& proj, ImageFile& im, int interpType, const int interpFactor) -: proj(proj), im(im), interpType(interpType), m_interpFactor(interpFactor) +: proj(proj), im(im), interpType(interpType), m_interpFactor(interpFactor), m_bPostProcessingDone(false) { detInc = proj.detInc(); nDet = proj.nDet(); @@ -287,6 +294,12 @@ Backproject::Backproject (const Projections& proj, ImageFile& im, int interpType Backproject::~Backproject () {} +void +Backproject::PostProcessing() +{ + m_bPostProcessingDone = true; +} + void Backproject::ScaleImageByRotIncrement () { @@ -389,7 +402,15 @@ BackprojectTable::BackprojectTable (const Projections& proj, ImageFile& im, int BackprojectTable::~BackprojectTable () { - ScaleImageByRotIncrement(); +} + +void +BackprojectTable::PostProcessing() +{ + if (! m_bPostProcessingDone) { + ScaleImageByRotIncrement(); + m_bPostProcessingDone = true; + } } void @@ -451,11 +472,18 @@ BackprojectDiff::BackprojectDiff (const Projections& proj, ImageFile& im, int in im.arrayDataClear(); } -BackprojectDiff::~BackprojectDiff() +BackprojectDiff::~BackprojectDiff () { - ScaleImageByRotIncrement(); } +void +BackprojectDiff::PostProcessing() +{ + if (! m_bPostProcessingDone) { + ScaleImageByRotIncrement(); + m_bPostProcessingDone = true; + } +} void BackprojectDiff::BackprojectView (const double* const filteredProj, const double view_angle) diff --git a/libctsim/reconstruct.cpp b/libctsim/reconstruct.cpp index 7bc6a83..c11820f 100644 --- a/libctsim/reconstruct.cpp +++ b/libctsim/reconstruct.cpp @@ -8,7 +8,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: reconstruct.cpp,v 1.13 2001/02/20 04:48:45 kevin Exp $ +** $Id: reconstruct.cpp,v 1.14 2001/02/23 02:06:01 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 @@ -139,7 +139,13 @@ void Reconstructor::reconstructAllViews () { reconstructView (0, m_rProj.nView()); - delete m_pBackprojector; m_pBackprojector = NULL; + postProcessing(); +} + +void +Reconstructor::postProcessing() +{ + m_pBackprojector->PostProcessing(); } diff --git a/msvc/ctsim/ctsim.plg b/msvc/ctsim/ctsim.plg index 7e652fc..5b1d868 100644 --- a/msvc/ctsim/ctsim.plg +++ b/msvc/ctsim/ctsim.plg @@ -6,26 +6,26 @@ --------------------Configuration: ctsim - Win32 Debug--------------------

Command Lines

-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP84D.tmp" with contents +Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP58.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.4\" /FR"Debug/" /Fp"Debug/ctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c "C:\ctsim\src\backgroundmgr.cpp" ] -Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP84D.tmp" -Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP84E.tmp" with contents +Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP58.tmp" +Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP59.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 /nologo /subsystem:windows /incremental:yes /pdb:"Debug/ctsim.pdb" /debug /machine:I386 /out:"Debug/ctsim.exe" /pdbtype:sept /libpath:"\wx2.2.5\lib" +.\Debug\backgroundmgr.obj .\Debug\ctsim.obj .\Debug\dialogs.obj .\Debug\dlgprojections.obj .\Debug\dlgreconstruct.obj .\Debug\docs.obj .\Debug\graph3dview.obj +.\Debug\threadrecon.obj +.\Debug\tips.obj .\Debug\views.obj .\Debug\ctsim.res -.\Debug\tips.obj -.\Debug\threadrecon.obj -.\Debug\backgroundmgr.obj \ctsim\msvc\libctsim\Debug\libctsim.lib "\fftw-2.1.3\Win32\FFTW2st\Debug\FFTW2st.lib" "\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib" @@ -36,7 +36,7 @@ winmm.lib rpcrt4.lib ws2_32.lib ../libctsim/Debug/libctsim.lib libcmtd.lib ..\.. \wx2.2.5\lib\zlibd.lib \wx2.2.5\lib\tiffd.lib ] -Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP84E.tmp" +Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP59.tmp"

Output Window

Compiling... backgroundmgr.cpp diff --git a/src/backgroundmgr.cpp b/src/backgroundmgr.cpp index 32c32a6..e915624 100644 --- a/src/backgroundmgr.cpp +++ b/src/backgroundmgr.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2001 Kevin Rosenberg ** -** $Id: backgroundmgr.cpp,v 1.2 2001/02/22 18:22:40 kevin Exp $ +** $Id: backgroundmgr.cpp,v 1.3 2001/02/23 02:06:02 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 @@ -50,13 +50,18 @@ EVT_CLOSE(BackgroundManager::OnCloseWindow) END_EVENT_TABLE() BackgroundManager::BackgroundManager () - : wxMiniFrame (theApp->getMainFrame(), -1, _T("Background Tasks"), wxPoint(0,0), wxSize(200, 100)) //, wxTHICK_FRAME) + : wxMiniFrame (theApp->getMainFrame(), -1, _T("Background Tasks"), wxPoint(0,0), wxSize(210, 50)) //, wxTHICK_FRAME) { m_iNumTasks = 0; m_pCanvas = new BackgroundManagerCanvas (this); theApp->setIconForFrame (this); - Show(false); + m_sizeGauge.Set (50, 15); + m_sizeLabel.Set (140, 15); + m_sizeCell.Set (200, 25); + m_sizeBorder.Set (4, 4); + + Show(false); } @@ -75,16 +80,37 @@ BackgroundManager::addTask (BackgroundTask* pTask, int iNumUnits, const char* co { wxCriticalSectionLocker locker (m_criticalSection); int iNumTasks = m_vecpBackgroundTasks.size(); - int iTaskHeight = 20; - wxSize size (50, 10); - wxPoint pos (4, 5 + iNumTasks * iTaskHeight); + std::vector vecPositionUsed (iNumTasks); + int i; + for (i = 0; i < iNumTasks; i++) + vecPositionUsed[i] = false; + + for (i = 0; i < iNumTasks; i++) { + int iPosUsed = m_vecpPositions[i]; + if (iPosUsed < iNumTasks) + vecPositionUsed[iPosUsed] = true; + } + + int iFirstUnusedPos = iNumTasks; // default is just past current number of tasks + for (i = 0; i < iNumTasks; i++) + if (! vecPositionUsed[i]) { + iFirstUnusedPos = i; + break; + } + + wxPoint posGauge (m_sizeBorder.x, m_sizeBorder.y + iFirstUnusedPos * m_sizeCell.y); + wxPoint posLabel (m_sizeBorder.x + m_sizeGauge.x, m_sizeBorder.y + iFirstUnusedPos * m_sizeCell.y); + wxGauge* pGauge = new wxGauge (m_pCanvas, -1, iNumUnits, posGauge, m_sizeGauge); + wxStaticText* pLabel = new wxStaticText (m_pCanvas, -1, pszTaskName, posLabel, m_sizeLabel); - wxGauge* pGauge = new wxGauge (m_pCanvas, -1, iNumUnits, pos, size); m_vecpBackgroundTasks.push_back (pTask); m_vecpGauges.push_back (pGauge); m_vecpNames.push_back (new std::string (pszTaskName)); + m_vecpPositions.push_back (iFirstUnusedPos); + m_vecpLabels.push_back (pLabel); m_iNumTasks++; + resizeWindow(); Show(true); return (pGauge); } @@ -93,32 +119,52 @@ BackgroundManager::addTask (BackgroundTask* pTask, int iNumUnits, const char* co void BackgroundManager::taskDone (BackgroundTask* pTask) { - wxCriticalSection doneSection; - doneSection.Enter(); + wxCriticalSectionLocker locker (m_criticalSection); StringContainer::iterator iName = m_vecpNames.begin(); GaugeContainer::iterator iGauge = m_vecpGauges.begin(); + PositionContainer::iterator iPosition = m_vecpPositions.begin(); + LabelContainer::iterator iLabel = m_vecpLabels.begin(); for (TaskContainer::iterator iTask = m_vecpBackgroundTasks.begin(); iTask != m_vecpBackgroundTasks.end(); iTask++) { if (*iTask == pTask) { delete *iName; delete *iGauge; + delete *iLabel; m_vecpBackgroundTasks.erase (iTask); m_vecpGauges.erase (iGauge); m_vecpNames.erase (iName); + m_vecpPositions.erase (iPosition); + m_vecpLabels.erase (iLabel); m_iNumTasks--; break; } - iTask++; + iName++; iGauge++; + iPosition++; + iLabel++; } - doneSection.Leave(); + resizeWindow(); if (m_iNumTasks <= 0) Show(false); + // delete pTask; +} + +void +BackgroundManager::resizeWindow() +{ + int iHighestPosition = -1; + + for (int i = 0; i < m_vecpPositions.size(); i++) + if (iHighestPosition < m_vecpPositions[i]) + iHighestPosition = m_vecpPositions[i]; + + wxSize sizeWindow (m_sizeCell.x, m_sizeCell.y * (iHighestPosition + 1)); + SetClientSize (sizeWindow); m_pCanvas->Refresh(); - // delete pTask; } + bool BackgroundManager::isCancelling (BackgroundTask* pTask) { diff --git a/src/backgroundmgr.h b/src/backgroundmgr.h index 3a91537..d3f49a1 100644 --- a/src/backgroundmgr.h +++ b/src/backgroundmgr.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2001 Kevin Rosenberg ** -** $Id: backgroundmgr.h,v 1.2 2001/02/22 18:22:40 kevin Exp $ +** $Id: backgroundmgr.h,v 1.3 2001/02/23 02:06:02 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 @@ -66,11 +66,19 @@ private: typedef std::vector TaskContainer; typedef std::vector GaugeContainer; typedef std::vector StringContainer; + typedef std::vector PositionContainer; + typedef std::vector LabelContainer; TaskContainer m_vecpBackgroundTasks; GaugeContainer m_vecpGauges; StringContainer m_vecpNames; + PositionContainer m_vecpPositions; + LabelContainer m_vecpLabels; + wxSize m_sizeGauge; + wxSize m_sizeLabel; + wxSize m_sizeCell; + wxSize m_sizeBorder; - void OnCloseWindow(wxCloseEvent& event); + void resizeWindow(); public: BackgroundManager (); @@ -82,7 +90,11 @@ public: TaskContainer& getTasks() { return m_vecpBackgroundTasks;} GaugeContainer& getGauges() { return m_vecpGauges;} StringContainer& getNames() { return m_vecpNames;} + PositionContainer& getPositions() { return m_vecpPositions;} + LabelContainer& getLabels() { return m_vecpLabels;} + void OnCloseWindow(wxCloseEvent& event); + DECLARE_EVENT_TABLE() }; diff --git a/src/threadrecon.cpp b/src/threadrecon.cpp index e53daac..f973c68 100644 --- a/src/threadrecon.cpp +++ b/src/threadrecon.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2001 Kevin Rosenberg ** -** $Id: threadrecon.cpp,v 1.3 2001/02/22 18:22:40 kevin Exp $ +** $Id: threadrecon.cpp,v 1.4 2001/02/23 02:06:02 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 @@ -102,8 +102,11 @@ ThreadedReconstructor::start() m_pProjView->GetDocument()->addReconstructor (this); if (! theApp->getUseBackgroundTasks()) m_pDialogProgress = new wxProgressDialog (_T("Filtered Backprojection"), _T("Reconstruction Progress"), m_iTotalViews, m_pProjView->getFrame(), wxPD_CAN_ABORT | wxPD_AUTO_HIDE); - else - m_pGauge = theApp->getBackgroundManager()->addTask (this, m_iTotalViews, m_pProjView->GetFrame()->GetTitle()); + else { + std::string strLabel ("Reconstructing "); + strLabel += m_pProjView->GetFrame()->GetTitle(); + m_pGauge = theApp->getBackgroundManager()->addTask (this, m_iTotalViews, strLabel.c_str()); + } m_iRunning = m_iNumThreads; m_iViewsDone = 0; @@ -307,6 +310,7 @@ ReconstructionThread::Entry () eventProgress.SetInt (RTHREAD_UNIT_COMPLETE); wxPostEvent (m_pSupervisor, eventProgress); } + m_pReconstructor->postProcessing(); eventProgress.SetInt (m_iThread); // Send back thread# that has finished wxPostEvent (m_pSupervisor, eventProgress); diff --git a/src/threadrecon.h b/src/threadrecon.h index ae6f0d2..e9ab35e 100644 --- a/src/threadrecon.h +++ b/src/threadrecon.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2001 Kevin Rosenberg ** -** $Id: threadrecon.h,v 1.3 2001/02/22 18:22:40 kevin Exp $ +** $Id: threadrecon.h,v 1.4 2001/02/23 02:06:02 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 @@ -33,6 +33,20 @@ #include #include "timer.h" +// This thread creates a BackgroundTask event handler object +// The thread is detached and terminates when BackgroundTask terminates +class BackgroundTaskThread : public wxThread { +private: + +public: + BackgroundTaskThread(); + + virtual wxThread::ExitCode Entry(); + + // called when the thread exits - whether it terminates normally or is stopped with Delete() + virtual void OnExit(); +}; + class BackgroundTask : public wxEvtHandler { private: @@ -126,9 +140,8 @@ public: virtual wxThread::ExitCode Entry(); // thread execution starts here - // called when the thread exits - whether it terminates normally or is - // stopped with Delete() (but not when it is Kill()ed!) - virtual void OnExit(); + // called when the thread exits - whether it terminates normally or is stopped with Delete() + virtual void OnExit(); }; diff --git a/src/views.cpp b/src/views.cpp index b8404bd..d8c0984 100644 --- a/src/views.cpp +++ b/src/views.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: views.cpp,v 1.113 2001/02/22 15:00:20 kevin Exp $ +** $Id: views.cpp,v 1.114 2001/02/23 02:06:02 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 @@ -2411,6 +2411,7 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event) ::wxUsleep(50); } } + pReconstructor->postProcessing(); delete pDlgReconstruct; delete pReconstructor; ImageFileDocument* pReconDoc = theApp->newImageDoc(); @@ -2458,6 +2459,7 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event) return; } } + pReconstructor->postProcessing(); delete pReconstructor; ImageFileDocument* pReconDoc = theApp->newImageDoc(); if (! pReconDoc) { diff --git a/tools/pjrec.cpp b/tools/pjrec.cpp index 542f7f2..bc21b48 100644 --- a/tools/pjrec.cpp +++ b/tools/pjrec.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: pjrec.cpp,v 1.24 2001/02/16 00:28:42 kevin Exp $ +** $Id: pjrec.cpp,v 1.25 2001/02/23 02:06:02 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 @@ -48,7 +48,7 @@ static struct option my_options[] = {0, 0, 0, 0} }; -static const char* g_szIdStr = "$Id: pjrec.cpp,v 1.24 2001/02/16 00:28:42 kevin Exp $"; +static const char* g_szIdStr = "$Id: pjrec.cpp,v 1.25 2001/02/23 02:06:02 kevin Exp $"; void pjrec_usage (const char *program) @@ -333,7 +333,7 @@ pjrec_main (int argc, char * const argv[]) return (1); } reconstruct.reconstructAllViews(); - + if (bOptVerbose) timerReconstruct.timerEndAndReport ("Time to reconstruct"); -- 2.34.1