X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;f=src%2Fviews.cpp;h=c9689bfab866a05e6b81b901f2d697b0198d2a07;hb=de411914da8b157958e9caae917bf1edeafbb713;hp=13774796c6d2206876a141250ae99c566dbb8ac6;hpb=cd93aebb4dec4e0ae88d53f131c2320ae92d0cab;p=ctsim.git diff --git a/src/views.cpp b/src/views.cpp index 1377479..c9689bf 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.126 2001/03/04 22:30:20 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 @@ -1095,6 +1095,12 @@ ImageFileView::OnExport (wxCommandEvent& event) strExt = ".png"; strWildcard = "PNG Files (*.png)|*.png"; } +#endif +#ifdef HAVE_CTN_DICOM + else if (m_iDefaultExportFormatID == ImageFile::EXPORT_FORMAT_DICOM) { + strExt = ""; + strWildcard = "DICOM Files (*.*)|*.*"; + } #endif else { strExt = ""; @@ -1408,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"; @@ -1508,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"; @@ -1949,7 +1955,7 @@ PhantomFileView::OnProjections (wxCommandEvent& event) } } else { #if HAVE_WXTHREADS - if (theApp->getUseBackgroundTasks() || theApp->getNumberCPU() > 1) { + if (theApp->getUseBackgroundTasks()) { ProjectorSupervisorThread* pProjector = new ProjectorSupervisorThread (this, m_iDefaultNDet, m_iDefaultNView, sGeometry.c_str(), m_iDefaultNSample, dRotationRadians, m_dDefaultFocalLength, m_dDefaultCenterDetectorLength, m_dDefaultViewRatio, m_dDefaultScanRatio, os.str().c_str()); @@ -2032,7 +2038,7 @@ PhantomFileView::OnRasterize (wxCommandEvent& event) << m_iDefaultRasterNSamples;; #if HAVE_WXTHREADS - if (theApp->getUseBackgroundTasks() || theApp->getNumberCPU() > 1) { + if (theApp->getUseBackgroundTasks()) { RasterizerSupervisorThread* pThread = new RasterizerSupervisorThread (this, m_iDefaultRasterNX, m_iDefaultRasterNY, m_iDefaultRasterNSamples, m_dDefaultRasterViewRatio, os.str().c_str()); if (pThread->Create() != wxTHREAD_NO_ERROR) { @@ -2271,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) { @@ -2336,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"); @@ -2402,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) { @@ -2411,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) @@ -2436,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(); @@ -2450,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++) { @@ -2472,11 +2557,11 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event) delete pReconstructor; } else { #if HAVE_WXTHREADS - if (theApp->getUseBackgroundTasks() || theApp->getNumberCPU() > 1) { + if (theApp->getUseBackgroundTasks()) { 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; @@ -2491,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++) { @@ -2525,6 +2610,12 @@ ProjectionFileView::OnReconstructFBP (wxCommandEvent& event) } +void +ProjectionFileView::OnArtifactReduction (wxCommandEvent& event) +{ +} + + ProjectionFileCanvas* ProjectionFileView::CreateCanvas (wxFrame *parent) { @@ -2584,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"); @@ -2600,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<er"); + 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('L'), PJMENU_CONVERT_POLAR); accelEntries[1].Set (wxACCEL_CTRL, static_cast('M'), PJMENU_CONVERT_FFT_POLAR); accelEntries[2].Set (wxACCEL_CTRL, static_cast('R'), PJMENU_RECONSTRUCT_FBP); accelEntries[3].Set (wxACCEL_CTRL, static_cast('E'), PJMENU_RECONSTRUCT_FOURIER); accelEntries[4].Set (wxACCEL_CTRL, static_cast('I'), PJMENU_FILE_PROPERTIES); - wxAcceleratorTable accelTable (5, accelEntries); + accelEntries[5].Set (wxACCEL_CTRL, static_cast('T'), PJMENU_PLOT_TTHETA_SAMPLING); + wxAcceleratorTable accelTable (6, accelEntries); subframe->SetAcceleratorTable (accelTable); return subframe; @@ -2996,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; @@ -3019,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; }