r631: no message
[ctsim.git] / src / views.cpp
index e7d35027f374777a8ff396ec817118cd6bf17ceb..c9689bfab866a05e6b81b901f2d697b0198d2a07 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: views.cpp,v 1.128 2001/03/07 16:34:47 kevin Exp $
+**  $Id: views.cpp,v 1.133 2001/03/11 15:27:30 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
@@ -1414,7 +1414,7 @@ ImageFileView::OnPlotFFTRow (wxCommandEvent& event)
       rPlotFile.addColumn (1, pYReal);
       rPlotFile.addColumn (2, pYImag);
       rPlotFile.addColumn (3, pYMag);
-      for (int iL = 0; iL < rIF.nLabels(); iL++)
+      for (unsigned int iL = 0; iL < rIF.nLabels(); iL++)
         rPlotFile.addDescription (rIF.labelGet(iL).getLabelString().c_str());
       os << " FFT Plot of " << GetDocument()->GetFirstView()->GetFrame()->GetTitle().c_str();
       *theApp->getLog() << os.str().c_str() << "\n";
@@ -1514,7 +1514,7 @@ ImageFileView::OnPlotFFTCol (wxCommandEvent& event)
       rPlotFile.addColumn (1, pYReal);
       rPlotFile.addColumn (2, pYImag);
       rPlotFile.addColumn (3, pYMag);
-      for (int iL = 0; iL < rIF.nLabels(); iL++)
+      for (unsigned int iL = 0; iL < rIF.nLabels(); iL++)
         rPlotFile.addDescription (rIF.labelGet(iL).getLabelString().c_str());
       os << " FFT Plot of " << GetDocument()->GetFirstView()->GetFrame()->GetTitle().c_str();
       *theApp->getLog() << os.str().c_str() << "\n";
@@ -2277,8 +2277,12 @@ EVT_MENU(PJMENU_RECONSTRUCT_FBP, ProjectionFileView::OnReconstructFBP)
 EVT_MENU(PJMENU_RECONSTRUCT_FOURIER, ProjectionFileView::OnReconstructFourier)
 EVT_MENU(PJMENU_CONVERT_POLAR, ProjectionFileView::OnConvertPolar)
 EVT_MENU(PJMENU_CONVERT_FFT_POLAR, ProjectionFileView::OnConvertFFTPolar)
+EVT_MENU(PJMENU_CONVERT_PARALLEL, ProjectionFileView::OnConvertParallel)
+EVT_MENU(PJMENU_PLOT_TTHETA_SAMPLING, ProjectionFileView::OnPlotTThetaSampling)
+EVT_MENU(PJMENU_ARTIFACT_REDUCTION, ProjectionFileView::OnArtifactReduction)
 END_EVENT_TABLE()
 
+
 ProjectionFileView::ProjectionFileView() 
 : wxView(), m_pFrame(0), m_pCanvas(0), m_pFileMenu(0)
 {
@@ -2342,11 +2346,13 @@ ProjectionFileView::OnConvertPolar (wxCommandEvent& event)
     ImageFileDocument* pPolarDoc = theApp->newImageDoc();
     ImageFile* pIF = new ImageFile (m_iDefaultPolarNX, m_iDefaultPolarNY);
     m_iDefaultPolarInterpolation = Projections::convertInterpNameToID (strInterpolation.c_str());
+    
     if (! rProj.convertPolar (*pIF, m_iDefaultPolarInterpolation)) {
       delete pIF;
       *theApp->getLog() << "Error converting to Polar\n";
       return;
     }
+
     pPolarDoc = theApp->newImageDoc ();
     if (! pPolarDoc) {
       sys_error (ERR_SEVERE, "Unable to create image file");
@@ -2408,6 +2414,72 @@ ProjectionFileView::OnConvertFFTPolar (wxCommandEvent& event)
   }
 }
 
+void
+ProjectionFileView::OnPlotTThetaSampling (wxCommandEvent& event)
+{
+  Projections& rProj = GetDocument()->getProjections();
+    ParallelRaysums parallel (&rProj);
+    PlotFileDocument* pPlotDoc = theApp->newPlotDoc();
+    PlotFile& rPlot = pPlotDoc->getPlotFile();
+    ParallelRaysums::CoordinateContainer& coordContainer = parallel.getCoordinates();
+    double* pdT = new double [parallel.getNumCoordinates()];
+    double* pdTheta = new double [parallel.getNumCoordinates()];
+
+    for (int i = 0; i < parallel.getNumCoordinates(); i++) {
+      pdT[i] = coordContainer[i]->m_dT;
+      pdTheta[i] = coordContainer[i]->m_dTheta;
+    }
+    rPlot.setCurveSize (2, parallel.getNumCoordinates(), true);
+    rPlot.addEzsetCommand ("title T-Theta Sampling");
+    rPlot.addEzsetCommand ("xlabel T");
+    rPlot.addEzsetCommand ("ylabel Theta");
+    rPlot.addEzsetCommand ("curve 1");
+    if (rProj.nDet() < 50 && rProj.nView() < 50)
+      rPlot.addEzsetCommand ("symbol 1"); // x symbol
+    else
+      rPlot.addEzsetCommand ("symbol 6"); // point symbol
+    rPlot.addEzsetCommand ("noline");
+    rPlot.addColumn (0, pdT);
+    rPlot.addColumn (1, pdTheta);
+    delete pdT;
+    delete pdTheta;
+    if (theApp->getAskDeleteNewDocs())
+      pPlotDoc->Modify (true);
+    pPlotDoc->UpdateAllViews ();
+    pPlotDoc->getView()->OnUpdate (this, NULL);
+    pPlotDoc->getView()->getFrame()->Show(true);
+    return;
+}
+
+void
+ProjectionFileView::OnConvertParallel (wxCommandEvent& event)
+{
+  Projections& rProj = GetDocument()->getProjections();
+  if (rProj.geometry() == Scanner::GEOMETRY_PARALLEL) {
+    wxMessageBox ("Projections are already parallel", "Error");
+    return;
+  }
+  wxProgressDialog dlgProgress (wxString("Convert to Parallel"), wxString("Conversion Progress"), 1, getFrameForChild(), wxPD_APP_MODAL);
+  Projections* pProjNew = rProj.interpolateToParallel();
+  ProjectionFileDocument* pProjDocNew = theApp->newProjectionDoc();
+  pProjDocNew->setProjections (pProjNew);  
+
+  if (ProjectionFileView* projView = pProjDocNew->getView()) {
+    projView->OnUpdate (projView, NULL);
+    if (projView->getCanvas())
+      projView->getCanvas()->SetClientSize (pProjNew->nDet(), pProjNew->nView());
+    if (wxFrame* pFrame = projView->getFrame()) {
+      pFrame->Show(true);
+      pFrame->SetFocus();
+      pFrame->Raise();
+    }
+    GetDocumentManager()->ActivateView (projView, true, false);
+  }
+  if (theApp->getAskDeleteNewDocs())
+    pProjDocNew-> Modify(true);
+  pProjDocNew->UpdateAllViews (this);
+}
+
 void
 ProjectionFileView::OnReconstructFourier (wxCommandEvent& event)
 {
@@ -2417,10 +2489,17 @@ ProjectionFileView::OnReconstructFourier (wxCommandEvent& event)
 void
 ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
 {
+  const Projections& rProj = GetDocument()->getProjections();
+  ReconstructionROI defaultROI;
+  defaultROI.m_dXMin = -rProj.phmLen() / 2;
+  defaultROI.m_dXMax = defaultROI.m_dXMin + rProj.phmLen();
+  defaultROI.m_dYMin = -rProj.phmLen() / 2;
+  defaultROI.m_dYMax = defaultROI.m_dYMin + rProj.phmLen();
+
   DialogGetReconstructionParameters dialogReconstruction (getFrameForChild(), m_iDefaultNX, m_iDefaultNY, 
     m_iDefaultFilter, m_dDefaultFilterParam, m_iDefaultFilterMethod, m_iDefaultFilterGeneration, 
     m_iDefaultZeropad, m_iDefaultInterpolation, m_iDefaultInterpParam, m_iDefaultBackprojector, 
-    m_iDefaultTrace);
+    m_iDefaultTrace,  &defaultROI);
   
   int retVal = dialogReconstruction.ShowModal();
   if (retVal != wxID_OK)
@@ -2442,11 +2521,11 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
   wxString optBackprojectName = dialogReconstruction.getBackprojectName();
   m_iDefaultBackprojector = Backprojector::convertBackprojectNameToID (optBackprojectName.c_str());
   m_iDefaultTrace = dialogReconstruction.getTrace();
-  
+  dialogReconstruction.getROI (&defaultROI);
+
   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();
   
@@ -2456,7 +2535,7 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
     pImageFile = new ImageFile (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);
+      optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), m_iDefaultTrace, &defaultROI);
     
     ReconstructDialog* pDlgReconstruct = new ReconstructDialog (*pReconstructor, rProj, *pImageFile, m_iDefaultTrace, getFrameForChild());
     for (int iView = 0; iView < rProj.nView(); iView++) {
@@ -2482,7 +2561,7 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
       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());
+        optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), os.str().c_str(), &defaultROI);
       if (pReconstructor->Create() != wxTHREAD_NO_ERROR) {
         sys_error (ERR_SEVERE, "Error creating reconstructor thread");
         delete pReconstructor;
@@ -2497,7 +2576,7 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
       pImageFile = new ImageFile (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);
+        optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), m_iDefaultTrace, &defaultROI);
       
       wxProgressDialog dlgProgress (wxString("Reconstruction"), wxString("Reconstruction Progress"), rProj.nView() + 1, getFrameForChild(), wxPD_CAN_ABORT );
       for (int iView = 0; iView < rProj.nView(); iView++) {
@@ -2531,6 +2610,12 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event)
 }
 
 
+void
+ProjectionFileView::OnArtifactReduction (wxCommandEvent& event)
+{
+}
+
+
 ProjectionFileCanvas* 
 ProjectionFileView::CreateCanvas (wxFrame *parent)
 {
@@ -2590,7 +2675,15 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   wxMenu *convert_menu = new wxMenu;
   convert_menu->Append (PJMENU_CONVERT_POLAR, "&Polar Image...\tCtrl-L");
   convert_menu->Append (PJMENU_CONVERT_FFT_POLAR, "&FFT->Polar Image...\tCtrl-M");
-  
+  convert_menu->AppendSeparator();
+  convert_menu->Append (PJMENU_CONVERT_PARALLEL, "&Interpolate to Parallel");
+
+  wxMenu* filter_menu = new wxMenu;
+  filter_menu->Append (PJMENU_ARTIFACT_REDUCTION, "&Artifact Reduction");
+
+  wxMenu* analyze_menu = new wxMenu;
+  analyze_menu->Append (PJMENU_PLOT_TTHETA_SAMPLING, "&Plot T-Theta Sampling\tCtrl-T");
+
   wxMenu *reconstruct_menu = new wxMenu;
   reconstruct_menu->Append (PJMENU_RECONSTRUCT_FBP, "&Filtered Backprojection...\tCtrl-R", "Reconstruct image using filtered backprojection");
   reconstruct_menu->Append (PJMENU_RECONSTRUCT_FOURIER, "&Fourier...\tCtrl-E", "Reconstruct image using inverse Fourier");
@@ -2606,19 +2699,22 @@ ProjectionFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   
   menu_bar->Append (m_pFileMenu, "&File");
   menu_bar->Append (convert_menu, "&Convert");
+  menu_bar->Append (filter_menu, "Fi&lter");
+  menu_bar->Append (analyze_menu, "&Analyze");
   menu_bar->Append (reconstruct_menu, "&Reconstruct");
   menu_bar->Append (help_menu, "&Help");
   
   subframe->SetMenuBar(menu_bar);  
   subframe->Centre(wxBOTH);
   
-  wxAcceleratorEntry accelEntries[5];
+  wxAcceleratorEntry accelEntries[6];
   accelEntries[0].Set (wxACCEL_CTRL, static_cast<int>('L'), PJMENU_CONVERT_POLAR);
   accelEntries[1].Set (wxACCEL_CTRL, static_cast<int>('M'), PJMENU_CONVERT_FFT_POLAR);
   accelEntries[2].Set (wxACCEL_CTRL, static_cast<int>('R'), PJMENU_RECONSTRUCT_FBP);
   accelEntries[3].Set (wxACCEL_CTRL, static_cast<int>('E'), PJMENU_RECONSTRUCT_FOURIER);
   accelEntries[4].Set (wxACCEL_CTRL, static_cast<int>('I'), PJMENU_FILE_PROPERTIES);
-  wxAcceleratorTable accelTable (5, accelEntries);
+  accelEntries[5].Set (wxACCEL_CTRL, static_cast<int>('T'), PJMENU_PLOT_TTHETA_SAMPLING);
+  wxAcceleratorTable accelTable (6, accelEntries);
   subframe->SetAcceleratorTable (accelTable);
   
   return subframe;
@@ -3002,7 +3098,8 @@ PlotFileView::OnUpdate (wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
   const PlotFile& rPlotFile = GetDocument()->getPlotFile();
   const int iNColumns = rPlotFile.getNumColumns();
   const int iNRecords = rPlotFile.getNumRecords();
-  
+  const bool bScatterPlot = rPlotFile.getIsScatterPlot();
+
   if (iNColumns > 0 && iNRecords > 0) {
     if (m_pEZPlot)
       delete m_pEZPlot;
@@ -3025,17 +3122,22 @@ PlotFileView::OnUpdate (wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
     
     m_pEZPlot->ezset("box");
     m_pEZPlot->ezset("grid");
-    
-    double* pdXaxis = new double [iNRecords];
-    rPlotFile.getColumn (0, pdXaxis);
-    
+  
+    double* pdX = new double [iNRecords];
     double* pdY = new double [iNRecords];
-    for (int iCol = 1; iCol < iNColumns; iCol++) {
-      rPlotFile.getColumn (iCol, pdY);
-      m_pEZPlot->addCurve (pdXaxis, pdY, iNRecords);
-    }
+    if (! bScatterPlot) {
+      rPlotFile.getColumn (0, pdX);
     
-    delete pdXaxis;
+      for (int iCol = 1; iCol < iNColumns; iCol++) {
+        rPlotFile.getColumn (iCol, pdY);
+        m_pEZPlot->addCurve (pdX, pdY, iNRecords);
+      }
+    } else {
+      rPlotFile.getColumn (0, pdX);
+      rPlotFile.getColumn (1, pdY);
+      m_pEZPlot->addCurve (pdX, pdY, iNRecords);
+    }
+    delete pdX;
     delete pdY;
   }