** This is part of the CTSim program
** Copyright (c) 1983-2001 Kevin Rosenberg
**
-** $Id: views.cpp,v 1.138 2001/03/13 10:35:06 kevin Exp $
+** $Id: views.cpp,v 1.139 2001/03/18 18:08:26 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
view_menu->Append(IFMENU_VIEW_SCALE_FULL, "Display F&ull Scale\tCtrl-U");
wxMenu* filter_menu = new wxMenu;
- filter_menu->Append (IFMENU_FILTER_INVERTVALUES, "&Invert Values");
+ filter_menu->Append (IFMENU_FILTER_INVERTVALUES, "In&vert Values");
filter_menu->Append (IFMENU_FILTER_SQUARE, "&Square");
filter_menu->Append (IFMENU_FILTER_SQRT, "Square &Root");
filter_menu->Append (IFMENU_FILTER_LOG, "&Log");
accelEntries[4].Set (wxACCEL_CTRL, static_cast<int>('C'), IFMENU_EDIT_COPY);
accelEntries[5].Set (wxACCEL_CTRL, static_cast<int>('X'), IFMENU_EDIT_CUT);
accelEntries[6].Set (wxACCEL_CTRL, static_cast<int>('V'), IFMENU_EDIT_PASTE);
-#if wxUSE_GLCANVAS
+#ifdef wxUSE_GLCANVAS
accelEntries[7].Set (wxACCEL_CTRL, static_cast<int>('3'), IFMENU_IMAGE_CONVERT3D);
wxAcceleratorTable accelTable (8, accelEntries);
#else
strWildcard = "DICOM Files (*.*)|*.*";
}
#endif
+ else if (m_iDefaultExportFormatID == ImageFile::EXPORT_FORMAT_TEXT) {
+ strExt = ".txt";
+ strWildcard = "Text (*.txt)|*.txt";
+ }
else {
strExt = "";
strWildcard = "Miscellaneous (*.*)|*.*";
s += rIF.labelGet(iL).getLabelString();
rPlotFile.addDescription (s.c_str());
}
- os << " Plot of " << GetDocument()->GetFirstView()->GetFrame()->GetTitle().c_str();
+ os << " plot of " << GetDocument()->GetFirstView()->GetFrame()->GetTitle().c_str();
*theApp->getLog() << os.str().c_str() << "\n";
rPlotFile.addDescription (os.str().c_str());
delete pX;
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()
}
+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)
{
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;
+
+ PlotFileDocument* pPlotDoc = theApp->newPlotDoc();
+ if (! pPlotDoc) {
+ sys_error (ERR_SEVERE, "Internal error: unable to create Plot file");
+ return;
+ }
+
+ DetectorValue* pdDetval = rProj.getDetectorArray(0).detValues();
+ double dMin = pdDetval[0], dMax = pdDetval[0];
+
+ for (int iv = 0; iv < nView; iv++) {
+ pdDetval = rProj.getDetectorArray(iv).detValues();
+ for (int id = 0; id < nDet; id++) {
+ double dV = pdDetval[id];
+ if (dV < dMin)
+ dMin = dV;
+ else if (dV > dMax)
+ dMax = dV;
+ }
+ }
+
+ double* pX = new double [NUMBER_HISTOGRAM_BINS];
+ double* pY = new double [NUMBER_HISTOGRAM_BINS];
+ double dBinWidth = (dMax - dMin) / NUMBER_HISTOGRAM_BINS;
+
+ for (int i = 0; i < NUMBER_HISTOGRAM_BINS; i++) {
+ pX[i] = dMin + (i + 0.5) * dBinWidth;
+ pY[i] = 0;
+ }
+ for (int j = 0; j < nView; j++) {
+ pdDetval = rProj.getDetectorArray(j).detValues();
+ for (int id = 0; id < nDet; id++) {
+ int iBin = nearest<int> ((pdDetval[id] - dMin) / dBinWidth);
+ if (iBin >= 0 && iBin < NUMBER_HISTOGRAM_BINS)
+ pY[iBin] += 1;
+ }
+ }
+ PlotFile& rPlotFile = pPlotDoc->getPlotFile();
+ std::ostringstream os;
+ os << "Histogram";
+ std::string title("title ");
+ title += os.str();
+ rPlotFile.addEzsetCommand (title.c_str());
+ rPlotFile.addEzsetCommand ("xlabel Detector Value");
+ rPlotFile.addEzsetCommand ("ylabel Count");
+ rPlotFile.addEzsetCommand ("box");
+ rPlotFile.addEzsetCommand ("grid");
+ rPlotFile.setCurveSize (2, NUMBER_HISTOGRAM_BINS);
+ rPlotFile.addColumn (0, pX);
+ rPlotFile.addColumn (1, pY);
+ rPlotFile.addDescription (rProj.remark());
+ os << " plot of " << GetDocument()->GetFirstView()->GetFrame()->GetTitle().c_str();
+ *theApp->getLog() << os.str().c_str() << "\n";
+ rPlotFile.addDescription (os.str().c_str());
+ delete pX;
+ delete pY;
+ if (theApp->getAskDeleteNewDocs())
+ pPlotDoc->Modify (true);
+ pPlotDoc->getView()->getFrame()->Show(true);
+ pPlotDoc->UpdateAllViews ();
+ pPlotDoc->Activate();
+}
+
+
void
ProjectionFileView::OnConvertParallel (wxCommandEvent& event)
{
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();
if (bRebinToParallel)
os << "; Interpolate to Parallel";
-
+
Timer timerRecon;
ImageFile* pImageFile = NULL;
if (m_iDefaultTrace > Trace::TRACE_CONSOLE) {
GetDocumentManager()->FileHistoryUseMenu(m_pFileMenu);
wxMenu *convert_menu = new wxMenu;
+ convert_menu->Append (PJMENU_CONVERT_RECTANGULAR, "&Rectangular Image");
convert_menu->Append (PJMENU_CONVERT_POLAR, "&Polar Image...\tCtrl-L");
- convert_menu->Append (PJMENU_CONVERT_FFT_POLAR, "&FFT->Polar Image...\tCtrl-M");
+ convert_menu->Append (PJMENU_CONVERT_FFT_POLAR, "FF&T->Polar Image...\tCtrl-T");
convert_menu->AppendSeparator();
convert_menu->Append (PJMENU_CONVERT_PARALLEL, "&Interpolate to Parallel");
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");
-
+ analyze_menu->Append (PJMENU_PLOT_HISTOGRAM, "&Plot Histogram");
+ analyze_menu->Append (PJMENU_PLOT_TTHETA_SAMPLING, "Plot T-T&heta Sampling...\tCtrl-H");
+
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_FBP_REBIN, "Filtered &Backprojection (Rebin to Parallel)...\tCtrl-B", "Reconstruct image using filtered backprojection");
wxAcceleratorEntry accelEntries[7];
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[1].Set (wxACCEL_CTRL, static_cast<int>('T'), PJMENU_CONVERT_FFT_POLAR);
accelEntries[2].Set (wxACCEL_CTRL, static_cast<int>('R'), PJMENU_RECONSTRUCT_FBP);
accelEntries[3].Set (wxACCEL_CTRL, static_cast<int>('B'), PJMENU_RECONSTRUCT_FBP_REBIN);
accelEntries[4].Set (wxACCEL_CTRL, static_cast<int>('E'), PJMENU_RECONSTRUCT_FOURIER);
accelEntries[5].Set (wxACCEL_CTRL, static_cast<int>('I'), PJMENU_FILE_PROPERTIES);
- accelEntries[6].Set (wxACCEL_CTRL, static_cast<int>('T'), PJMENU_PLOT_TTHETA_SAMPLING);
+ accelEntries[6].Set (wxACCEL_CTRL, static_cast<int>('H'), PJMENU_PLOT_TTHETA_SAMPLING);
wxAcceleratorTable accelTable (7, accelEntries);
subframe->SetAcceleratorTable (accelTable);