r583: no message
[ctsim.git] / src / views.cpp
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());
     }
   }
 }