r583: no message
authorKevin M. Rosenberg <kevin@rosenberg.net>
Sun, 25 Feb 2001 15:27:28 +0000 (15:27 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Sun, 25 Feb 2001 15:27:28 +0000 (15:27 +0000)
ChangeLog
msvc/ctsim/ctsim.dsp
msvc/ctsim/ctsim.plg
src/backgroundsupr.cpp
src/threadproj.cpp
src/threadproj.h
src/views.cpp

index 5ebfd0ec6fa18d10c508d3accc236d40ca3bbbaa..e4044e85952aefc194b275bcd4b82faae25dc0aa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,4 @@
-3.1.0 - Released
+3.1.0 - Released 2//01
 
        * ctsim: Added tips to be displayed at startup and via the help menu.
 
@@ -7,6 +7,8 @@
        on SMP systems.
 
        * ctsim: Added background and SMP processing for reconstructions. 
+
+       * ctsim: Added background and SMP processing for scanning.
        
        * ctsim: Added "Verbose Logging", "Startup Tips", and
        "Background processes" options  to Preferences dialog.
index 47a647291fcfb3d062c2ada38e7cb7aba516098c..f59a03bef601ea240fa4f9090e26c3cea19dfdc5 100644 (file)
@@ -140,6 +140,10 @@ SOURCE=..\..\src\graph3dview.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\src\threadproj.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\src\threadrecon.cpp
 # End Source File
 # Begin Source File
@@ -197,6 +201,10 @@ SOURCE=..\..\src\splash.xpm
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\src\threadproj.h
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\src\threadrecon.h
 # End Source File
 # Begin Source File
index 93645342b0937e8a30b2f5ab96199197eb63e007..0c5966844e85993d175890b173ece6b0f53fb67f 100644 (file)
@@ -3,43 +3,81 @@
 <pre>
 <h1>Build Log</h1>
 <h3>
+--------------------Configuration: libctsim - Win32 Debug--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP310.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" /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 /FR"Debug/" /Fp"Debug/libctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c 
+"C:\ctsim\libctsim\scanner.cpp"
+]
+Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP310.tmp" 
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP311.tmp" with contents
+[
+/nologo /out:"Debug\libctsim.lib" 
+.\Debug\array2dfile.obj
+.\Debug\backprojectors.obj
+.\Debug\clip.obj
+.\Debug\consoleio.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 "link.exe -lib @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP311.tmp"
+<h3>Output Window</h3>
+Compiling...
+scanner.cpp
+Creating library...
+<h3>
 --------------------Configuration: ctsim - Win32 Debug--------------------
 </h3>
 <h3>Command Lines</h3>
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP2E5.tmp" with contents
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP312.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"
-"C:\ctsim\src\graph3dview.cpp"
-"C:\ctsim\src\threadrecon.cpp"
 "C:\ctsim\src\backgroundsupr.cpp"
 ]
-Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP2E5.tmp" 
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP2E6.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\" /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\RSP2E6.tmp" 
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP2E7.tmp" with contents
+Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP312.tmp" 
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP313.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\backgroundsupr.obj
 .\Debug\ctsim.obj
 .\Debug\dialogs.obj
 .\Debug\dlgprojections.obj
 .\Debug\dlgreconstruct.obj
 .\Debug\docs.obj
 .\Debug\graph3dview.obj
+.\Debug\threadproj.obj
 .\Debug\threadrecon.obj
 .\Debug\tips.obj
 .\Debug\views.obj
 .\Debug\ctsim.res
-.\Debug\backgroundsupr.obj
-.\Debug\threadproj.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"
@@ -50,20 +88,10 @@ 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\RSP2E7.tmp"
+Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP313.tmp"
 <h3>Output Window</h3>
 Compiling...
-threadrecon.cpp
-Skipping... (no relevant changes detected)
-backgroundmgr.cpp
-graph3dview.cpp
 backgroundsupr.cpp
-Compiling...
-views.cpp
-Skipping... (no relevant changes detected)
-ctsim.cpp
-dialogs.cpp
-docs.cpp
 Linking...
 
 
index da2120db352c8b13c0bb3454f653527de7fdce74..0a09ef8614cec93ac83c1b9c14ba75b40a4bac35 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2001 Kevin Rosenberg
 **
-**  $Id: backgroundsupr.cpp,v 1.4 2001/02/25 08:43:03 kevin Exp $
+**  $Id: backgroundsupr.cpp,v 1.5 2001/02/25 15:27:28 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
@@ -74,7 +74,7 @@ BackgroundSupervisor::BackgroundSupervisor (wxFrame* pParentFrame, wxDocument* p
     wxEvtHandler()
 {
   m_iNumThreads = theApp->getNumberCPU();
-  //  ++m_iNumThreads;
+    ++m_iNumThreads;
 
   m_vecpThreads.reserve (m_iNumThreads);
   for (int iThread = 0; iThread < m_iNumThreads; iThread++)
index dc96cee4b31b5c5ddb8a6c0392c77cd467284f8b..2978c61c342ebb6b98cc63c366449e366ecaa6ef 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2001 Kevin Rosenberg
 **
-**  $Id: threadproj.cpp,v 1.1 2001/02/25 10:52:55 kevin Exp $
+**  $Id: threadproj.cpp,v 1.2 2001/02/25 15:27:28 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
@@ -111,11 +111,16 @@ ProjectorSupervisor::ProjectorSupervisor (PhantomFileView* pPhantomView, int iND
       m_dViewRatio(dViewRatio), m_dScanRatio(dScanRatio), m_pszLabel(pszLabel), 
       BackgroundSupervisor (pPhantomView->GetFrame(), pPhantomView->GetDocument(), "Projecting", iNView)
 {
+  m_pScanner = new Scanner (m_pPhantomDoc->getPhantom(), m_pszGeometry, m_iNDet,
+                  m_iNView, m_iNSample, m_dRotation, m_dFocalLength, m_dViewRatio, m_dScanRatio);
+
   m_vecpChildProjections.reserve (getNumWorkers());
   for (unsigned int iThread = 0; iThread < getNumWorkers(); iThread++) {
-    m_vecpChildProjections[iThread] = new Projections (m_iNDet, m_iNView);    
+    m_vecpChildProjections[iThread] = new Projections (*m_pScanner);    
   }
 
+
+
 }
 
 ProjectorSupervisor::~ProjectorSupervisor()
@@ -124,13 +129,16 @@ ProjectorSupervisor::~ProjectorSupervisor()
       delete m_vecpChildProjections[i];
       m_vecpChildProjections[i] = NULL;
     }
+
+  delete m_pScanner;
 }
 
 BackgroundWorkerThread*
 ProjectorSupervisor::createWorker (int iThread, int iStartUnit, int iNumUnits)
 {
    ProjectorWorker* pThread = new ProjectorWorker (this, iThread, iStartUnit, iNumUnits);
-   pThread->SetParameters (m_pPhantomView, m_vecpChildProjections[iThread], m_iNDet, m_iNView, 
+   m_vecpChildProjections[iThread]->setNView (iNumUnits);
+   pThread->SetParameters (m_pPhantomView, m_vecpChildProjections[iThread], m_pScanner, m_iNDet, m_iNView, 
      m_pszGeometry, m_iNSample, m_dRotation, m_dFocalLength, m_dViewRatio, m_dScanRatio);
 
    return pThread;
@@ -169,18 +177,22 @@ ProjectorSupervisor::onDone()
 Projections*
 ProjectorSupervisor::getProjections()
 {
-  Projections* pProjections = new Projections (m_iNDet, m_iNView);
-#if 0
-  ImageFileArray pArray = pImageFile->getArray();
-  
-  int i;
-  for (i = 0; i < getNumWorkers(); i++) {
-    ImageFileArrayConst pChildArray = m_vecpChildImageFile[i]->getArray();
-    for (int ix = 0; ix < m_iImageNX; ix++)
-      for (int iy = 0; iy < m_iImageNY; iy++)
-        pArray[ix][iy] += pChildArray[ix][iy];
+  Projections* pProjections = new Projections (*m_pScanner);
+
+  int iGlobalView = 0;
+  size_t detArraySize = pProjections->nDet() * sizeof (DetectorValue);
+  for (int iw = 0; iw < getNumWorkers(); iw++) {
+    for (int iView = 0; iView < m_vecpChildProjections[iw]->nView(); iView++) {
+      DetectorArray& childDetArray = m_vecpChildProjections[iw]->getDetectorArray(iView);
+      DetectorArray& globalDetArray = pProjections->getDetectorArray(iGlobalView);
+      globalDetArray.setViewAngle (childDetArray.viewAngle());
+      DetectorValue* childDetval = childDetArray.detValues();
+      DetectorValue* globalDetval = globalDetArray.detValues();
+      memcpy (globalDetval, childDetval, detArraySize);
+      iGlobalView++;
+    }
   }
-#endif
+
   return (pProjections);
 }
 
@@ -192,10 +204,12 @@ ProjectorSupervisor::getProjections()
 /////////////////////////////////////////////////////////////////////
 
 void
-ProjectorWorker::SetParameters (PhantomFileView* pPhantomView, Projections* pProjections, int iNDet, int iView,
+ProjectorWorker::SetParameters (PhantomFileView* pPhantomView, Projections* pProjections, Scanner* pScanner,
+ int iNDet, int iView,
  const char* pszGeometry, int iNSample, double dRotation, double dFocalLength, double dViewRatio,
  double dScanRatio)
 {
+   m_pScanner = pScanner;
    m_pPhantomView = pPhantomView;
    m_pProjections = pProjections;
    m_pszGeometry = pszGeometry;
@@ -209,14 +223,11 @@ wxThread::ExitCode
 ProjectorWorker::Entry ()
 {
   const Phantom& rPhantom = m_pPhantomView->GetDocument()->getPhantom();
-  Scanner* pScanner = new Scanner (rPhantom, m_pszGeometry, m_iNDet,
-    m_iNView, m_iNSample, m_dRotation, m_dFocalLength, m_dViewRatio, m_dScanRatio);
-
-  bool bFail = pScanner->fail();
+  bool bFail = m_pScanner->fail();
   wxString failMsg;
   if (bFail) {
       failMsg = "Unable to make Projector: ";
-      failMsg += pScanner->failMessage().c_str();  
+      failMsg += m_pScanner->failMessage().c_str();  
       wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT );
       event.SetString( failMsg );
       wxPostEvent( theApp->getMainFrame(), event );
@@ -237,11 +248,10 @@ ProjectorWorker::Entry ()
 #endif
         break;
       }
-      pScanner->collectProjections (*m_pProjections, rPhantom, iUnit + m_iStartUnit, 1, true, Trace::TRACE_NONE);
+      m_pScanner->collectProjections (*m_pProjections, rPhantom, iUnit + m_iStartUnit, 1, true, Trace::TRACE_NONE);
       wxPostEvent (m_pSupervisor, eventProgress);
     }
   }
-  delete pScanner;
 
   if (bFail) {
     wxCommandEvent eventFail (wxEVT_COMMAND_MENU_SELECTED, BackgroundSupervisor::MSG_WORKER_THREAD_FAIL);
index 02afffde2225af8e4e4486d33bd350ce6f5ac156..6bb16f5e3d6ba605d649ad0d153ffcbff436adbd 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2001 Kevin Rosenberg
 **
-**  $Id: threadproj.h,v 1.1 2001/02/25 10:52:55 kevin Exp $
+**  $Id: threadproj.h,v 1.2 2001/02/25 15:27:28 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
@@ -72,7 +72,8 @@ private:
   std::vector<Projections*> m_vecpChildProjections;
   PhantomFileDocument* m_pPhantomDoc;
   PhantomFileView* m_pPhantomView;
-    
+  Scanner* m_pScanner;
+  
   const int m_iNDet;
   const int m_iNView;
   const char* const m_pszGeometry;
@@ -106,6 +107,7 @@ class ProjectorWorker : public BackgroundWorkerThread {
 private:
   PhantomFileView* m_pPhantomView;
   Projections* m_pProjections;
+  Scanner* m_pScanner;
   int m_iNDet;
   int m_iNView;
   const char* m_pszGeometry;
@@ -121,7 +123,8 @@ public:
     : BackgroundWorkerThread (pSupervisor, iThread, iStartView, iNumViews)
   {}
   
-  void SetParameters (PhantomFileView* pPhantomFile, Projections* pProjections, int iNDet, int iView, 
+  void SetParameters (PhantomFileView* pPhantomFile, Projections* pProjections, Scanner* pScanner, 
+   int iNDet, int iView, 
    const char* const pszGeometry, int iNSample, double dRotation, double dFocalLength, double dViewRatio,
    double dScanRatio);
 
index a4826e0292c0d7137c6ae94144788f9f64ab5335..ae7ea2094b4189c17de31c96eca6b1ed038fb850 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: views.cpp,v 1.118 2001/02/25 10:52:55 kevin Exp $
+**  $Id: views.cpp,v 1.119 2001/02/25 15:27:28 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
@@ -47,6 +47,7 @@
 #include "backprojectors.h"
 #include "reconstruct.h"
 #include "timer.h"
+#include "threadproj.h"
 #include "threadrecon.h"
 
 #if defined(MSVC) || HAVE_SSTREAM
@@ -113,7 +114,7 @@ ImageFileCanvas::OnMouseEvent(wxMouseEvent& event)
 {
   if (! m_pView)
     return;
-
+  
   
   wxClientDC dc(this);
   PrepareDC(dc);
@@ -1878,95 +1879,115 @@ PhantomFileView::OnProjections (wxCommandEvent& event)
     m_dDefaultFocalLength, m_dDefaultViewRatio, m_dDefaultScanRatio, m_iDefaultGeometry, 
     m_iDefaultTrace);
   int retVal = dialogProjection.ShowModal();
-  if (retVal == wxID_OK) {
-    m_iDefaultNDet = dialogProjection.getNDet();
-    m_iDefaultNView = dialogProjection.getNView();
-    m_iDefaultNSample = dialogProjection.getNSamples();
-    m_iDefaultTrace = dialogProjection.getTrace();
-    m_dDefaultRotation = dialogProjection.getRotAngle();
-    m_dDefaultFocalLength = dialogProjection.getFocalLengthRatio();
-    m_dDefaultViewRatio = dialogProjection.getViewRatio();
-    m_dDefaultScanRatio = dialogProjection.getScanRatio();
-    wxString sGeometry = dialogProjection.getGeometry();
-    m_iDefaultGeometry = Scanner::convertGeometryNameToID (sGeometry.c_str());
+  if (retVal != wxID_OK) 
+    return;
+  
+  m_iDefaultNDet = dialogProjection.getNDet();
+  m_iDefaultNView = dialogProjection.getNView();
+  m_iDefaultNSample = dialogProjection.getNSamples();
+  m_iDefaultTrace = dialogProjection.getTrace();
+  m_dDefaultRotation = dialogProjection.getRotAngle();
+  m_dDefaultFocalLength = dialogProjection.getFocalLengthRatio();
+  m_dDefaultViewRatio = dialogProjection.getViewRatio();
+  m_dDefaultScanRatio = dialogProjection.getScanRatio();
+  wxString sGeometry = dialogProjection.getGeometry();
+  m_iDefaultGeometry = Scanner::convertGeometryNameToID (sGeometry.c_str());
+  double dRotationRadians = m_dDefaultRotation;
+  m_dDefaultRotation /= TWOPI;  // convert back to fraction of a circle
+  
+  if (m_iDefaultNDet <= 0 || m_iDefaultNView <= 0 || sGeometry == "")
+    return;
+  
+  const Phantom& rPhantom = GetDocument()->getPhantom();
+  Scanner theScanner (rPhantom, sGeometry.c_str(), m_iDefaultNDet, m_iDefaultNView, m_iDefaultNSample, 
+    dRotationRadians, m_dDefaultFocalLength, m_dDefaultViewRatio, m_dDefaultScanRatio);
+  if (theScanner.fail()) {
+    wxString msg = "Failed making scanner\n";
+    msg += theScanner.failMessage().c_str();
+    *theApp->getLog() << msg << "\n";
+    wxMessageBox (msg, "Error");
+    return;
+  }
+  
+  std::ostringstream os;
+  os << "Projections for " << rPhantom.name() << ": nDet=" << m_iDefaultNDet 
+    << ", nView=" << m_iDefaultNView << ", nSamples=" << m_iDefaultNSample 
+    << ", RotAngle=" << m_dDefaultRotation << ", FocalLengthRatio=" << m_dDefaultFocalLength 
+    << ", ViewRatio=" << m_dDefaultViewRatio << ", ScanRatio=" << m_dDefaultScanRatio 
+    << ", Geometry=" << sGeometry.c_str() << ", FanBeamAngle=" << 
+    convertRadiansToDegrees (theScanner.fanBeamAngle());
+  
+  Timer timer;
+  Projections* pProj = NULL;
+  if (m_iDefaultTrace > Trace::TRACE_CONSOLE) {
+    pProj = new Projections;
+    pProj->initFromScanner (theScanner);
     
-    if (m_iDefaultNDet > 0 && m_iDefaultNView > 0 && sGeometry != "") {
-      const Phantom& rPhantom = GetDocument()->getPhantom();
-      Projections* pProj = new Projections;
-      Scanner theScanner (rPhantom, sGeometry.c_str(), m_iDefaultNDet, m_iDefaultNView, m_iDefaultNSample, 
-        m_dDefaultRotation, m_dDefaultFocalLength, m_dDefaultViewRatio, m_dDefaultScanRatio);
-      if (theScanner.fail()) {
-        wxString msg = "Failed making scanner\n";
-        msg += theScanner.failMessage().c_str();
-        *theApp->getLog() << msg << "\n";
-        wxMessageBox (msg, "Error");
+    ProjectionsDialog dialogProjections (theScanner, *pProj, rPhantom, m_iDefaultTrace, dynamic_cast<wxWindow*>(getFrameForChild()));
+    for (int iView = 0; iView < pProj->nView(); iView++) {
+      ::wxYield();
+      if (dialogProjections.isCancelled() || ! dialogProjections.projectView (iView)) {
+        delete pProj;
         return;
       }
-      std::ostringstream os;
-      os << "Projections for " << rPhantom.name() << ": nDet=" << m_iDefaultNDet 
-        << ", nView=" << m_iDefaultNView << ", nSamples=" << m_iDefaultNSample 
-        << ", RotAngle=" << m_dDefaultRotation << ", FocalLengthRatio=" << m_dDefaultFocalLength 
-        << ", ViewRatio=" << m_dDefaultViewRatio << ", ScanRatio=" << m_dDefaultScanRatio 
-        << ", Geometry=" << sGeometry.c_str() << ", FanBeamAngle=" << 
-        convertRadiansToDegrees (theScanner.fanBeamAngle());
-      pProj->initFromScanner (theScanner);
-      m_dDefaultRotation /= TWOPI;  // convert back to fraction of a circle
-      
-      Timer timer;
-      if (m_iDefaultTrace > Trace::TRACE_CONSOLE) {
-        ProjectionsDialog dialogProjections (theScanner, *pProj, rPhantom, m_iDefaultTrace, dynamic_cast<wxWindow*>(getFrameForChild()));
-        for (int iView = 0; iView < pProj->nView(); iView++) {
-          ::wxYield();
-          if (dialogProjections.isCancelled() || ! dialogProjections.projectView (iView)) {
-            delete pProj;
-            return;
-          }
-          ::wxYield();
-          while (dialogProjections.isPaused()) {
-            ::wxYield();
-            ::wxUsleep(50);
-          }
-        }
-      } else {
-        wxProgressDialog dlgProgress (wxString("Projection"), wxString("Projection Progress"), pProj->nView() + 1, getFrameForChild(), wxPD_CAN_ABORT );
-        for (int i = 0; i < pProj->nView(); i++) {
-          theScanner.collectProjections (*pProj, rPhantom, i, 1, true, m_iDefaultTrace);
-          if (! dlgProgress.Update (i+1)) {
-            delete pProj;
-            return;
-          }
-        }
-      }
-      
-      pProj->setRemark (os.str());
-      pProj->setCalcTime (timer.timerEnd());
-      *theApp->getLog() << os.str().c_str() << "\n";
-      
       ::wxYield();
-      ProjectionFileDocument* pProjectionDoc = theApp->newProjectionDoc();
-      if (! pProjectionDoc) {
-        sys_error (ERR_SEVERE, "Unable to create projection document");
+      while (dialogProjections.isPaused()) {
+        ::wxYield();
+        ::wxUsleep(50);
+      }
+    }
+  } else {
+    if (theApp->getUseBackgroundTasks() || theApp->getNumberCPU() > 1) {
+      ProjectorSupervisorThread* pProjector = new ProjectorSupervisorThread (this, m_iDefaultNDet,
+        m_iDefaultNView, sGeometry.c_str(), m_iDefaultNSample, dRotationRadians,
+        m_dDefaultFocalLength, m_dDefaultViewRatio, m_dDefaultScanRatio, os.str().c_str());
+      if (pProjector->Create() != wxTHREAD_NO_ERROR) {
+        sys_error (ERR_SEVERE, "Error creating projector thread");
+        delete pProjector;
         return;
       }
-      pProjectionDoc->setProjections (pProj);
-      ProjectionFileView* projView = pProjectionDoc->getView();
-      if (projView) {
-        projView->OnUpdate (projView, NULL);
-        if (projView->getCanvas())
-             projView->getCanvas()->SetClientSize (m_iDefaultNDet, m_iDefaultNView);
-        if (wxFrame* pFrame = projView->getFrame()) {
-          pFrame->Show(true);
-          pFrame->SetFocus();
-          pFrame->Raise();
+      pProjector->SetPriority(60);
+      pProjector->Run();
+      return;
+    } else {
+      pProj = new Projections;
+      pProj->initFromScanner (theScanner);
+      wxProgressDialog dlgProgress (wxString("Projection"), wxString("Projection Progress"), pProj->nView() + 1, getFrameForChild(), wxPD_CAN_ABORT );
+      for (int i = 0; i < pProj->nView(); i++) {
+        theScanner.collectProjections (*pProj, rPhantom, i, 1, true, m_iDefaultTrace);
+        if (! dlgProgress.Update (i+1)) {
+          delete pProj;
+          return;
         }
-        GetDocumentManager()->ActivateView (projView, true, false);
       }
-      ::wxYield();
-      if (theApp->getAskDeleteNewDocs())
-        pProjectionDoc-> Modify(true);
-      pProjectionDoc->UpdateAllViews (this);
     }
   }
+  
+  *theApp->getLog() << os.str().c_str() << "\n";
+  pProj->setRemark (os.str());
+  pProj->setCalcTime (timer.timerEnd());
+  
+  ProjectionFileDocument* pProjectionDoc = theApp->newProjectionDoc();
+  if (! pProjectionDoc) {
+    sys_error (ERR_SEVERE, "Unable to create projection document");
+    return;
+  }
+  pProjectionDoc->setProjections (pProj);
+  ProjectionFileView* projView = pProjectionDoc->getView();
+  if (projView) {
+    projView->OnUpdate (projView, NULL);
+    if (projView->getCanvas())
+      projView->getCanvas()->SetClientSize (m_iDefaultNDet, m_iDefaultNView);
+    if (wxFrame* pFrame = projView->getFrame()) {
+      pFrame->Show(true);
+      pFrame->SetFocus();
+      pFrame->Raise();
+    }
+    GetDocumentManager()->ActivateView (projView, true, false);
+  }
+  if (theApp->getAskDeleteNewDocs())
+    pProjectionDoc-> Modify(true);
+  pProjectionDoc->UpdateAllViews (this);
 }
 
 
@@ -2369,124 +2390,126 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
     m_iDefaultTrace);
   
   int retVal = dialogReconstruction.ShowModal();
-  if (retVal == wxID_OK) {
-    m_iDefaultNX = dialogReconstruction.getXSize();
-    m_iDefaultNY = dialogReconstruction.getYSize();
-    wxString optFilterName = dialogReconstruction.getFilterName();
-    m_iDefaultFilter = SignalFilter::convertFilterNameToID (optFilterName.c_str());
-    m_dDefaultFilterParam = dialogReconstruction.getFilterParam();
-    wxString optFilterMethodName = dialogReconstruction.getFilterMethodName();
-    m_iDefaultFilterMethod = ProcessSignal::convertFilterMethodNameToID(optFilterMethodName.c_str());
-    m_iDefaultZeropad = dialogReconstruction.getZeropad();
-    wxString optFilterGenerationName = dialogReconstruction.getFilterGenerationName();
-    m_iDefaultFilterGeneration = ProcessSignal::convertFilterGenerationNameToID (optFilterGenerationName.c_str());
-    wxString optInterpName = dialogReconstruction.getInterpName();
-    m_iDefaultInterpolation = Backprojector::convertInterpNameToID (optInterpName.c_str());
-    m_iDefaultInterpParam = dialogReconstruction.getInterpParam();
-    wxString optBackprojectName = dialogReconstruction.getBackprojectName();
-    m_iDefaultBackprojector = Backprojector::convertBackprojectNameToID (optBackprojectName.c_str());
-    m_iDefaultTrace = dialogReconstruction.getTrace();
+  if (retVal != wxID_OK)
+    return;
+  
+  m_iDefaultNX = dialogReconstruction.getXSize();
+  m_iDefaultNY = dialogReconstruction.getYSize();
+  wxString optFilterName = dialogReconstruction.getFilterName();
+  m_iDefaultFilter = SignalFilter::convertFilterNameToID (optFilterName.c_str());
+  m_dDefaultFilterParam = dialogReconstruction.getFilterParam();
+  wxString optFilterMethodName = dialogReconstruction.getFilterMethodName();
+  m_iDefaultFilterMethod = ProcessSignal::convertFilterMethodNameToID(optFilterMethodName.c_str());
+  m_iDefaultZeropad = dialogReconstruction.getZeropad();
+  wxString optFilterGenerationName = dialogReconstruction.getFilterGenerationName();
+  m_iDefaultFilterGeneration = ProcessSignal::convertFilterGenerationNameToID (optFilterGenerationName.c_str());
+  wxString optInterpName = dialogReconstruction.getInterpName();
+  m_iDefaultInterpolation = Backprojector::convertInterpNameToID (optInterpName.c_str());
+  m_iDefaultInterpParam = dialogReconstruction.getInterpParam();
+  wxString optBackprojectName = dialogReconstruction.getBackprojectName();
+  m_iDefaultBackprojector = Backprojector::convertBackprojectNameToID (optBackprojectName.c_str());
+  m_iDefaultTrace = dialogReconstruction.getTrace();
+  
+  if (m_iDefaultNX <= 0 && m_iDefaultNY <= 0) 
+    return;
+  
+  const Projections& rProj = GetDocument()->getProjections();
+  std::ostringstream os;
+  os << "Reconstruct " << rProj.getFilename() << ": xSize=" << m_iDefaultNX << ", ySize=" << m_iDefaultNY << ", Filter=" << optFilterName.c_str() << ", FilterParam=" << m_dDefaultFilterParam << ", FilterMethod=" << optFilterMethodName.c_str() << ", FilterGeneration=" << optFilterGenerationName.c_str() << ", Zeropad=" << m_iDefaultZeropad << ", Interpolation=" << optInterpName.c_str() << ", InterpolationParam=" << m_iDefaultInterpParam << ", Backprojection=" << optBackprojectName.c_str();
+  
+  Timer timerRecon;
+  if (m_iDefaultTrace > Trace::TRACE_CONSOLE) {
+    ImageFile* pImageFile = new ImageFile;
+    pImageFile->setArraySize (m_iDefaultNX, m_iDefaultNY);
+    Reconstructor* pReconstructor = new Reconstructor (rProj, *pImageFile, optFilterName.c_str(), 
+      m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), 
+      optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), m_iDefaultTrace);
     
-    if (m_iDefaultNX > 0 && m_iDefaultNY > 0) {
-      const Projections& rProj = GetDocument()->getProjections();
-      std::ostringstream os;
-      os << "Reconstruct " << rProj.getFilename() << ": xSize=" << m_iDefaultNX << ", ySize=" << m_iDefaultNY << ", Filter=" << optFilterName.c_str() << ", FilterParam=" << m_dDefaultFilterParam << ", FilterMethod=" << optFilterMethodName.c_str() << ", FilterGeneration=" << optFilterGenerationName.c_str() << ", Zeropad=" << m_iDefaultZeropad << ", Interpolation=" << optInterpName.c_str() << ", InterpolationParam=" << m_iDefaultInterpParam << ", Backprojection=" << optBackprojectName.c_str();
-      
-      Timer timerRecon;
-      if (m_iDefaultTrace > Trace::TRACE_CONSOLE) {
-        ImageFile* pImageFile = new ImageFile;
-        pImageFile->setArraySize (m_iDefaultNX, m_iDefaultNY);
-        Reconstructor* pReconstructor = new Reconstructor (rProj, *pImageFile, optFilterName.c_str(), 
-          m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), 
-          optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), m_iDefaultTrace);
-        
-        ReconstructDialog* pDlgReconstruct = new ReconstructDialog (*pReconstructor, rProj, *pImageFile, m_iDefaultTrace, getFrameForChild());
-        for (int iView = 0; iView < rProj.nView(); iView++) {
-          ::wxYield();
-          if (pDlgReconstruct->isCancelled() || ! pDlgReconstruct->reconstructView (iView, true)) {
-            delete pDlgReconstruct;
-            delete pReconstructor;
-            delete pImageFile;
-            return;
-          }
-          ::wxYield();
-          ::wxYield();
-          while (pDlgReconstruct->isPaused()) {
-            ::wxYield();
-            ::wxUsleep(50);
-          }
-        }
-        pReconstructor->postProcessing();
+    ReconstructDialog* pDlgReconstruct = new ReconstructDialog (*pReconstructor, rProj, *pImageFile, m_iDefaultTrace, getFrameForChild());
+    for (int iView = 0; iView < rProj.nView(); iView++) {
+      ::wxYield();
+      if (pDlgReconstruct->isCancelled() || ! pDlgReconstruct->reconstructView (iView, true)) {
         delete pDlgReconstruct;
         delete pReconstructor;
-        ImageFileDocument* pReconDoc = theApp->newImageDoc();
-        if (! pReconDoc) {
-          sys_error (ERR_SEVERE, "Unable to create image file");
-          return;
-        }
-        pReconDoc->setImageFile (pImageFile);
-        if (theApp->getAskDeleteNewDocs())
-          pReconDoc->Modify (true);
-        pReconDoc->UpdateAllViews (this);
-        if (ImageFileView* rasterView = pReconDoc->getView()) {
-          rasterView->OnUpdate (rasterView, NULL);
-          rasterView->getFrame()->SetFocus();
-          rasterView->getFrame()->Show(true);
-        }
-        *theApp->getLog() << os.str().c_str() << "\n";
-        pImageFile->labelAdd (rProj.getLabel());
-        pImageFile->labelAdd (os.str().c_str(), timerRecon.timerEnd());
-        
-      } else {
-        if (theApp->getUseBackgroundTasks() || theApp->getNumberCPU() > 1) {
-          ReconstructorSupervisorThread* pReconstructor = new ReconstructorSupervisorThread (this, 
-            m_iDefaultNX, m_iDefaultNY, optFilterName.c_str(), 
-            m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), 
-            optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), os.str().c_str());
-          if (pReconstructor->Create() != wxTHREAD_NO_ERROR) {
-            sys_error (ERR_SEVERE, "Error creating reconstructor thread");
-            delete pReconstructor;
-            return;
-          }
-//          pReconstructor->SetPriority (60);
-          pReconstructor->Run();
-        } else {
-          ImageFile* pImageFile = new ImageFile;
-          pImageFile->setArraySize (m_iDefaultNX, m_iDefaultNY);
-          Reconstructor* pReconstructor = new Reconstructor (rProj, *pImageFile, optFilterName.c_str(), 
-            m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), 
-            optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), m_iDefaultTrace);
-          
-          wxProgressDialog dlgProgress (wxString("Reconstruction"), wxString("Reconstruction Progress"), rProj.nView() + 1, getFrameForChild(), wxPD_CAN_ABORT );
-          for (int iView = 0; iView < rProj.nView(); iView++) {
-            pReconstructor->reconstructView (iView, 1);
-            if (! dlgProgress.Update (iView + 1)) {
-              delete pReconstructor;
-              delete pImageFile;
-              return;
-            }
-          }
-          pReconstructor->postProcessing();
+        delete pImageFile;
+        return;
+      }
+      ::wxYield();
+      ::wxYield();
+      while (pDlgReconstruct->isPaused()) {
+        ::wxYield();
+        ::wxUsleep(50);
+      }
+    }
+    pReconstructor->postProcessing();
+    delete pDlgReconstruct;
+    delete pReconstructor;
+    ImageFileDocument* pReconDoc = theApp->newImageDoc();
+    if (! pReconDoc) {
+      sys_error (ERR_SEVERE, "Unable to create image file");
+      return;
+    }
+    pReconDoc->setImageFile (pImageFile);
+    if (theApp->getAskDeleteNewDocs())
+      pReconDoc->Modify (true);
+    pReconDoc->UpdateAllViews (this);
+    if (ImageFileView* rasterView = pReconDoc->getView()) {
+      rasterView->OnUpdate (rasterView, NULL);
+      rasterView->getFrame()->SetFocus();
+      rasterView->getFrame()->Show(true);
+    }
+    *theApp->getLog() << os.str().c_str() << "\n";
+    pImageFile->labelAdd (rProj.getLabel());
+    pImageFile->labelAdd (os.str().c_str(), timerRecon.timerEnd());
+    
+  } else {
+    if (theApp->getUseBackgroundTasks() || theApp->getNumberCPU() > 1) {
+      ReconstructorSupervisorThread* pReconstructor = new ReconstructorSupervisorThread (this, 
+        m_iDefaultNX, m_iDefaultNY, optFilterName.c_str(), 
+        m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), 
+        optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), os.str().c_str());
+      if (pReconstructor->Create() != wxTHREAD_NO_ERROR) {
+        sys_error (ERR_SEVERE, "Error creating reconstructor thread");
+        delete pReconstructor;
+        return;
+      }
+      pReconstructor->SetPriority (60);
+      pReconstructor->Run();
+    } else {
+      ImageFile* pImageFile = new ImageFile;
+      pImageFile->setArraySize (m_iDefaultNX, m_iDefaultNY);
+      Reconstructor* pReconstructor = new Reconstructor (rProj, *pImageFile, optFilterName.c_str(), 
+        m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), 
+        optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), m_iDefaultTrace);
+      
+      wxProgressDialog dlgProgress (wxString("Reconstruction"), wxString("Reconstruction Progress"), rProj.nView() + 1, getFrameForChild(), wxPD_CAN_ABORT );
+      for (int iView = 0; iView < rProj.nView(); iView++) {
+        pReconstructor->reconstructView (iView, 1);
+        if (! dlgProgress.Update (iView + 1)) {
           delete pReconstructor;
-          ImageFileDocument* pReconDoc = theApp->newImageDoc();
-          if (! pReconDoc) {
-            sys_error (ERR_SEVERE, "Unable to create image file");
-            return;
-          }
-          pReconDoc->setImageFile (pImageFile);
-          if (theApp->getAskDeleteNewDocs())
-            pReconDoc->Modify (true);
-          pReconDoc->UpdateAllViews (this);
-          if (ImageFileView* rasterView = pReconDoc->getView()) {
-            rasterView->OnUpdate (rasterView, NULL);
-            rasterView->getFrame()->SetFocus();
-            rasterView->getFrame()->Show(true);
-          }
-          *theApp->getLog() << os.str().c_str() << "\n";
-          pImageFile->labelAdd (rProj.getLabel());
-          pImageFile->labelAdd (os.str().c_str(), timerRecon.timerEnd());
+          delete pImageFile;
+          return;
         }
       }
+      pReconstructor->postProcessing();
+      delete pReconstructor;
+      ImageFileDocument* pReconDoc = theApp->newImageDoc();
+      if (! pReconDoc) {
+        sys_error (ERR_SEVERE, "Unable to create image file");
+        return;
+      }
+      pReconDoc->setImageFile (pImageFile);
+      if (theApp->getAskDeleteNewDocs())
+        pReconDoc->Modify (true);
+      pReconDoc->UpdateAllViews (this);
+      if (ImageFileView* rasterView = pReconDoc->getView()) {
+        rasterView->OnUpdate (rasterView, NULL);
+        rasterView->getFrame()->SetFocus();
+        rasterView->getFrame()->Show(true);
+      }
+      *theApp->getLog() << os.str().c_str() << "\n";
+      pImageFile->labelAdd (rProj.getLabel());
+      pImageFile->labelAdd (os.str().c_str(), timerRecon.timerEnd());
     }
   }
 }