+// ProjectionCanvas
+
+ProjectionFileCanvas::ProjectionFileCanvas (ProjectionFileView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style)
+: wxScrolledWindow(frame, -1, pos, size, style)
+{
+ m_pView = v;
+}
+
+ProjectionFileCanvas::~ProjectionFileCanvas ()
+{
+ m_pView = NULL;
+}
+
+void
+ProjectionFileCanvas::OnDraw(wxDC& dc)
+{
+ if (m_pView)
+ m_pView->OnDraw(& dc);
+}
+
+wxSize
+ProjectionFileCanvas::GetBestSize () const
+{
+ wxSize best (0, 0);
+ if (m_pView) {
+ Projections& rProj = m_pView->GetDocument()->getProjections();
+ best.Set (rProj.nDet(), rProj.nView());
+ }
+
+ return best;
+}
+
+
+// ProjectionFileView
+
+IMPLEMENT_DYNAMIC_CLASS(ProjectionFileView, wxView)
+
+BEGIN_EVENT_TABLE(ProjectionFileView, wxView)
+EVT_MENU(PJMENU_FILE_PROPERTIES, ProjectionFileView::OnProperties)
+EVT_MENU(PJMENU_RECONSTRUCT_FBP, ProjectionFileView::OnReconstructFBP)
+EVT_MENU(PJMENU_RECONSTRUCT_FBP_REBIN, ProjectionFileView::OnReconstructFBPRebin)
+EVT_MENU(PJMENU_RECONSTRUCT_FOURIER, ProjectionFileView::OnReconstructFourier)
+EVT_MENU(PJMENU_CONVERT_RECTANGULAR, ProjectionFileView::OnConvertRectangular)
+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_PLOT_HISTOGRAM, ProjectionFileView::OnPlotHistogram)
+EVT_MENU(PJMENU_ARTIFACT_REDUCTION, ProjectionFileView::OnArtifactReduction)
+END_EVENT_TABLE()
+
+
+ProjectionFileView::ProjectionFileView()
+: wxView(), m_pFrame(0), m_pCanvas(0), m_pFileMenu(0)
+{
+#ifdef DEBUG
+ m_iDefaultNX = 115;
+ m_iDefaultNY = 115;
+#else
+ m_iDefaultNX = 256;
+ m_iDefaultNY = 256;
+#endif
+
+ m_iDefaultFilter = SignalFilter::FILTER_ABS_BANDLIMIT;
+ m_dDefaultFilterParam = 1.;
+#if HAVE_FFTW
+ m_iDefaultFilterMethod = ProcessSignal::FILTER_METHOD_RFFTW;
+ m_iDefaultFilterGeneration = ProcessSignal::FILTER_GENERATION_INVERSE_FOURIER;
+#else
+ m_iDefaultFilterMethod = ProcessSignal::FILTER_METHOD_CONVOLUTION;
+ m_iDefaultFilterGeneration = ProcessSignal::FILTER_GENERATION_DIRECT;
+#endif
+ m_iDefaultZeropad = 1;
+ m_iDefaultBackprojector = Backprojector::BPROJ_IDIFF;
+ m_iDefaultInterpolation = Backprojector::INTERP_LINEAR;
+ m_iDefaultInterpParam = 1;
+ m_iDefaultTrace = Trace::TRACE_NONE;
+
+ m_iDefaultPolarNX = 256;
+ m_iDefaultPolarNY = 256;
+ m_iDefaultPolarInterpolation = Projections::POLAR_INTERP_BILINEAR;
+ m_iDefaultPolarZeropad = 1;
+}
+
+ProjectionFileView::~ProjectionFileView()
+{
+ GetDocumentManager()->FileHistoryRemoveMenu (m_pFileMenu);
+ GetDocumentManager()->ActivateView(this, FALSE, TRUE);;
+}
+
+void
+ProjectionFileView::OnProperties (wxCommandEvent& event)
+{
+ const Projections& rProj = GetDocument()->getProjections();
+ std::ostringstream os;
+ rProj.printScanInfo(os);
+ *theApp->getLog() << ">>>>\n" << os.str().c_str() << "<<<<\n";
+ wxMessageDialog dialogMsg (getFrameForChild(), os.str().c_str(), "Projection File Properties", wxOK | wxICON_INFORMATION);
+ dialogMsg.ShowModal();
+ GetDocument()->Activate();
+}
+
+
+void
+ProjectionFileView::OnConvertRectangular (wxCommandEvent& event)
+{
+ Projections& rProj = GetDocument()->getProjections();
+
+ int nDet = rProj.nDet();
+ int nView = rProj.nView();
+ ImageFile* pIF = new ImageFile (nDet, nView);
+ ImageFileArray v = pIF->getArray();
+ for (int iv = 0; iv < nView; iv++) {
+ DetectorValue* detval = rProj.getDetectorArray(iv).detValues();
+
+ for (int id = 0; id < nDet; id++)
+ v[id][iv] = detval[id];
+ }
+
+ ImageFileDocument* pRectDoc = theApp->newImageDoc ();
+ if (! pRectDoc) {
+ sys_error (ERR_SEVERE, "Unable to create image file");
+ return;
+ }
+ pRectDoc->setImageFile (pIF);
+ pIF->labelAdd (rProj.getLabel().getLabelString().c_str(), rProj.calcTime());
+ std::ostringstream os;
+ os << "Convert projection file " << GetFrame()->GetTitle().c_str() << " to rectangular image";
+ *theApp->getLog() << os.str().c_str() << "\n";
+ pIF->labelAdd (os.str().c_str());
+ if (theApp->getAskDeleteNewDocs())
+ pRectDoc->Modify (true);
+ pRectDoc->getView()->getFrame()->Show(true);
+ pRectDoc->UpdateAllViews ();
+ pRectDoc->Activate();
+}
+
+void
+ProjectionFileView::OnConvertPolar (wxCommandEvent& event)
+{
+ Projections& rProj = GetDocument()->getProjections();
+ DialogGetConvertPolarParameters dialogPolar (getFrameForChild(), "Convert Polar", m_iDefaultPolarNX, m_iDefaultPolarNY,
+ m_iDefaultPolarInterpolation, -1);
+ if (dialogPolar.ShowModal() == wxID_OK) {
+ wxProgressDialog dlgProgress (wxString("Convert Polar"), wxString("Conversion Progress"), 1, getFrameForChild(), wxPD_APP_MODAL);
+ wxString strInterpolation (dialogPolar.getInterpolationName());
+ m_iDefaultPolarNX = dialogPolar.getXSize();
+ m_iDefaultPolarNY = dialogPolar.getYSize();
+ 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");
+ return;
+ }
+ pPolarDoc->setImageFile (pIF);
+ pIF->labelAdd (rProj.getLabel().getLabelString().c_str(), rProj.calcTime());
+ std::ostringstream os;
+ os << "Convert projection file " << GetFrame()->GetTitle().c_str() << " to polar image: xSize="
+ << m_iDefaultPolarNX << ", ySize=" << m_iDefaultPolarNY << ", interpolation="
+ << strInterpolation.c_str();
+ *theApp->getLog() << os.str().c_str() << "\n";
+ pIF->labelAdd (os.str().c_str());
+ if (theApp->getAskDeleteNewDocs())
+ pPolarDoc->Modify (true);
+ pPolarDoc->getView()->getFrame()->Show(true);
+ pPolarDoc->UpdateAllViews ();
+ pPolarDoc->Activate();
+ }
+}
+
+void
+ProjectionFileView::OnConvertFFTPolar (wxCommandEvent& event)
+{
+ Projections& rProj = GetDocument()->getProjections();
+ DialogGetConvertPolarParameters dialogPolar (getFrameForChild(), "Convert to FFT Polar", m_iDefaultPolarNX, m_iDefaultPolarNY,
+ m_iDefaultPolarInterpolation, m_iDefaultPolarZeropad);
+ if (dialogPolar.ShowModal() == wxID_OK) {
+ wxProgressDialog dlgProgress (wxString("Convert FFT Polar"), wxString("Conversion Progress"), 1, getFrameForChild(), wxPD_APP_MODAL);
+ wxString strInterpolation (dialogPolar.getInterpolationName());
+ m_iDefaultPolarNX = dialogPolar.getXSize();
+ m_iDefaultPolarNY = dialogPolar.getYSize();
+ m_iDefaultPolarZeropad = dialogPolar.getZeropad();
+ ImageFile* pIF = new ImageFile (m_iDefaultPolarNX, m_iDefaultPolarNY);
+
+ m_iDefaultPolarInterpolation = Projections::convertInterpNameToID (strInterpolation.c_str());
+ if (! rProj.convertFFTPolar (*pIF, m_iDefaultPolarInterpolation, m_iDefaultPolarZeropad)) {
+ delete pIF;
+ *theApp->getLog() << "Error converting to polar\n";
+ return;
+ }
+ ImageFileDocument* pPolarDoc = theApp->newImageDoc();
+ if (! pPolarDoc) {
+ sys_error (ERR_SEVERE, "Unable to create image file");
+ return;
+ }
+ pPolarDoc->setImageFile (pIF);
+ pIF->labelAdd (rProj.getLabel().getLabelString().c_str(), rProj.calcTime());
+ std::ostringstream os;
+ os << "Convert projection file " << GetFrame()->GetTitle().c_str() << " to FFT polar image: xSize="
+ << m_iDefaultPolarNX << ", ySize=" << m_iDefaultPolarNY << ", interpolation="
+ << strInterpolation.c_str() << ", zeropad=" << m_iDefaultPolarZeropad;
+ *theApp->getLog() << os.str().c_str() << "\n";
+ pIF->labelAdd (os.str().c_str());
+ if (theApp->getAskDeleteNewDocs())
+ pPolarDoc->Modify (true);
+ pPolarDoc->getView()->getFrame()->Show(true);
+ pPolarDoc->UpdateAllViews ();
+ pPolarDoc->Activate();
+ }
+}
+
+void
+ProjectionFileView::OnPlotTThetaSampling (wxCommandEvent& event)
+{
+ DialogGetThetaRange dlgTheta (this->getFrame(), ParallelRaysums::THETA_RANGE_UNCONSTRAINED);
+ if (dlgTheta.ShowModal() != wxID_OK)
+ return;
+
+ int iThetaRange = dlgTheta.getThetaRange();
+
+ Projections& rProj = GetDocument()->getProjections();
+ ParallelRaysums parallel (&rProj, iThetaRange);
+ 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->getView()->getFrame()->Show(true);
+ pPlotDoc->UpdateAllViews ();
+ pPlotDoc->Activate();
+}
+
+
+void
+ProjectionFileView::OnPlotHistogram (wxCommandEvent& event)
+{
+ Projections& rProj = GetDocument()->getProjections();
+ int nDet = rProj.nDet();
+ int nView = rProj.nView();
+
+ if (nDet < 1 || nView < 1)
+ return;