+void
+ImageFileView::OnCompareRow (wxCommandEvent& event)
+{
+ int xCursor, yCursor;
+ if (! m_canvas->GetCurrentCursor (xCursor, yCursor)) {
+ wxMessageBox ("No column selected. Please use left mouse button on image to select column","Error");
+ return;
+ }
+
+ std::vector<ImageFileDocument*> vecIFDoc;
+ theApp->getCompatibleImages (GetDocument(), vecIFDoc);
+
+ if (vecIFDoc.size() == 0) {
+ wxMessageBox ("No compatible images for Row Comparison", "Error");
+ return;
+ }
+
+ DialogGetComparisonImage dialogGetCompare (m_frame, "Get Comparison Image", vecIFDoc, false);
+
+ if (dialogGetCompare.ShowModal() == wxID_OK) {
+ ImageFileDocument* pCompareDoc = dialogGetCompare.getImageFileDocument();
+ const ImageFile& rIF = GetDocument()->getImageFile();
+ const ImageFile& rCompareIF = pCompareDoc->getImageFile();
+
+ ImageFileArrayConst v1 = rIF.getArray();
+ ImageFileArrayConst v2 = rCompareIF.getArray();
+ int nx = rIF.nx();
+ int ny = rIF.ny();
+
+ if (v1 != NULL && yCursor < ny) {
+ double* pX = new double [nx];
+ double* pY1 = new double [nx];
+ double* pY2 = new double [nx];
+ for (int i = 0; i < nx; i++) {
+ pX[i] = i;
+ pY1[i] = v1[i][yCursor];
+ pY2[i] = v2[i][yCursor];
+ }
+ PlotFileDocument* pPlotDoc = dynamic_cast<PlotFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.plt", wxDOC_SILENT));
+ if (! pPlotDoc) {
+ sys_error (ERR_SEVERE, "Internal error: unable to create Plot file");
+ } else {
+ PlotFile& rPlotFile = pPlotDoc->getPlotFile();
+ std::ostringstream os;
+ os << "Row " << yCursor << " Comparison";
+ std::string title("title ");
+ title += os.str();
+ rPlotFile.addEzsetCommand (title.c_str());
+ rPlotFile.addEzsetCommand ("xlabel Column");
+ rPlotFile.addEzsetCommand ("ylabel Pixel Value");
+ rPlotFile.addEzsetCommand ("lxfrac 0");
+ rPlotFile.addEzsetCommand ("curve 1");
+ rPlotFile.addEzsetCommand ("color 2");
+ rPlotFile.addEzsetCommand ("curve 2");
+ rPlotFile.addEzsetCommand ("color 4");
+ rPlotFile.addEzsetCommand ("dash 5");
+ rPlotFile.addEzsetCommand ("box");
+ rPlotFile.addEzsetCommand ("grid");
+ rPlotFile.setCurveSize (3, ny);
+ rPlotFile.addColumn (0, pX);
+ rPlotFile.addColumn (1, pY1);
+ rPlotFile.addColumn (2, pY2);
+ }
+ delete pX;
+ delete pY1;
+ delete pY2;
+ if (theApp->getSetModifyNewDocs())
+ pPlotDoc->Modify(true);
+ pPlotDoc->UpdateAllViews();
+ }
+ }
+}
+
+static int NUMBER_HISTOGRAM_BINS = 256;
+
+void
+ImageFileView::OnPlotHistogram (wxCommandEvent& event)
+{
+ const ImageFile& rIF = dynamic_cast<ImageFileDocument*>(GetDocument())->getImageFile();
+ ImageFileArrayConst v = rIF.getArray();
+ int nx = rIF.nx();
+ int ny = rIF.ny();
+
+ if (v != NULL && nx > 0 && ny > 0) {
+ PlotFileDocument* pPlotDoc = dynamic_cast<PlotFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.plt", wxDOC_SILENT));
+ if (! pPlotDoc) {
+ sys_error (ERR_SEVERE, "Internal error: unable to create Plot file");
+ return;
+ }
+
+ double* pX = new double [NUMBER_HISTOGRAM_BINS];
+ double* pY = new double [NUMBER_HISTOGRAM_BINS];
+ double dMin, dMax;
+ rIF.getMinMax (dMin, dMax);
+ 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 ix = 0; ix < nx; ix++)
+ for (int iy = 0; iy < ny; iy++) {
+ int iBin = nearest<int> ((v[ix][iy] - 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 Pixel Value");
+ rPlotFile.addEzsetCommand ("ylabel Count");
+ rPlotFile.addEzsetCommand ("box");
+ rPlotFile.addEzsetCommand ("grid");
+ rPlotFile.setCurveSize (2, nx);
+ rPlotFile.addColumn (0, pX);
+ rPlotFile.addColumn (1, pY);
+ delete pX;
+ delete pY;
+ if (theApp->getSetModifyNewDocs())
+ pPlotDoc->Modify(true);
+ pPlotDoc->UpdateAllViews();
+ }
+}
+
+
+// PhantomCanvas
+
+PhantomCanvas::PhantomCanvas (PhantomView* v, wxFrame *frame, const wxPoint& pos, const wxSize& size, const long style)
+: wxScrolledWindow(frame, -1, pos, size, style)
+{
+ m_pView = v;
+}
+
+void
+PhantomCanvas::OnDraw (wxDC& dc)
+{
+ if (m_pView)
+ m_pView->OnDraw(& dc);
+}
+
+
+// PhantomView
+
+IMPLEMENT_DYNAMIC_CLASS(PhantomView, wxView)
+
+BEGIN_EVENT_TABLE(PhantomView, wxView)
+EVT_MENU(PHMMENU_FILE_PROPERTIES, PhantomView::OnProperties)
+EVT_MENU(PHMMENU_PROCESS_RASTERIZE, PhantomView::OnRasterize)
+EVT_MENU(PHMMENU_PROCESS_PROJECTIONS, PhantomView::OnProjections)
+END_EVENT_TABLE()
+
+PhantomView::PhantomView(void)
+: wxView(), m_canvas(NULL), m_frame(NULL)
+{
+ m_iDefaultNDet = 367;
+ m_iDefaultNView = 320;
+ m_iDefaultNSample = 2;
+ m_dDefaultRotation = 1;
+ m_dDefaultFocalLength = 2;
+ m_dDefaultFieldOfView = 1;
+ m_iDefaultGeometry = Scanner::GEOMETRY_PARALLEL;
+ m_iDefaultTrace = Trace::TRACE_NONE;
+}
+
+PhantomView::~PhantomView(void)
+{
+}
+
+void
+PhantomView::OnProperties (wxCommandEvent& event)
+{
+ const int idPhantom = GetDocument()->getPhantomID();
+ const wxString& namePhantom = GetDocument()->getPhantomName();
+ std::ostringstream os;
+ os << "Phantom " << namePhantom.c_str() << " (" << idPhantom << ")" << "\n";
+ const Phantom& rPhantom = GetDocument()->getPhantom();
+ rPhantom.printDefinitions (os);
+#if DEBUG
+ rPhantom.print (os);
+#endif
+ *theApp->getLog() << os.str().c_str() << "\n";
+ wxMessageBox (os.str().c_str(), "Phantom Properties");
+}
+
+
+void
+PhantomView::OnProjections (wxCommandEvent& event)
+{
+ DialogGetProjectionParameters dialogProjection (m_frame, m_iDefaultNDet, m_iDefaultNView, m_iDefaultNSample, m_dDefaultRotation, m_dDefaultFocalLength, m_dDefaultFieldOfView, 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_dDefaultFieldOfView = dialogProjection.getFieldOfViewRatio();
+ wxString sGeometry = dialogProjection.getGeometry();
+ m_iDefaultGeometry = Scanner::convertGeometryNameToID (sGeometry.c_str());
+
+ if (m_iDefaultNDet > 0 && m_iDefaultNView > 0 && sGeometry != "") {
+ const Phantom& rPhantom = GetDocument()->getPhantom();
+ ProjectionFileDocument* pProjectionDoc = dynamic_cast<ProjectionFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.pj", wxDOC_SILENT));
+ if (! pProjectionDoc) {
+ sys_error (ERR_SEVERE, "Unable to create projection document");
+ return;
+ }
+ Projections& rProj = pProjectionDoc->getProjections();
+ Scanner theScanner (rPhantom, sGeometry.c_str(), m_iDefaultNDet, m_iDefaultNView, m_iDefaultNSample, m_dDefaultRotation, m_dDefaultFocalLength, m_dDefaultFieldOfView);
+ if (theScanner.fail()) {
+ *theApp->getLog() << "Failed making scanner: " << theScanner.failMessage().c_str() << "\n";
+ return;
+ }
+ rProj.initFromScanner (theScanner);
+ m_dDefaultRotation /= PI; // convert back to PI units
+
+ Timer timer;
+ if (m_iDefaultTrace > Trace::TRACE_CONSOLE) {
+ ProjectionsDialog dialogProjections (theScanner, rProj, rPhantom, m_iDefaultTrace, dynamic_cast<wxWindow*>(m_frame));
+ for (int iView = 0; iView < rProj.nView(); iView++) {
+ ::wxYield();
+ ::wxYield();
+ if (dialogProjections.isCancelled() || ! dialogProjections.projectView (iView)) {
+ pProjectionDoc->DeleteAllViews();
+ return;
+ }
+ ::wxYield();
+ ::wxYield();
+ while (dialogProjections.isPaused()) {
+ ::wxYield();
+ ::wxUsleep(50);
+ }
+ }
+ } else {
+ wxProgressDialog dlgProgress (wxString("Projection"), wxString("Projection Progress"), rProj.nView() + 1, m_frame, wxPD_CAN_ABORT);
+ for (int i = 0; i < rProj.nView(); i++) {
+ theScanner.collectProjections (rProj, rPhantom, i, 1, true, m_iDefaultTrace);
+ if (! dlgProgress.Update (i+1)) {
+ pProjectionDoc->DeleteAllViews();
+ return;
+ }
+ }
+ }
+
+ std::ostringstream os;
+ os << "Projections for " << rPhantom.name() << ": nDet=" << m_iDefaultNDet << ", nView=" << m_iDefaultNView << ", nSamples=" << m_iDefaultNSample << ", RotAngle=" << m_dDefaultRotation << ", FocalLengthRatio=" << m_dDefaultFocalLength << ", FieldOfViewRatio=" << m_dDefaultFieldOfView << ", Geometry=" << sGeometry.c_str();
+ rProj.setCalcTime (timer.timerEnd());
+ rProj.setRemark (os.str());
+ *theApp->getLog() << os.str().c_str() << "\n";
+
+ m_frame->Lower();
+ ::wxYield();
+ ProjectionFileView* projView = dynamic_cast<ProjectionFileView*>(pProjectionDoc->GetFirstView());
+ if (projView) {
+ projView->getFrame()->SetFocus();
+ projView->OnUpdate (projView, NULL);
+ }
+ if (wxView* pView = pProjectionDoc->GetFirstView()) {
+ if (wxFrame* pFrame = pView->GetFrame()) {
+ pFrame->SetFocus();
+ pFrame->Raise();
+ }
+ theApp->getDocManager()->ActivateView (pView, true, false);
+ }
+ ::wxYield();
+ if (theApp->getSetModifyNewDocs())
+ pProjectionDoc->Modify(true);
+ pProjectionDoc->UpdateAllViews(this);
+ }
+ }
+}
+
+
+void
+PhantomView::OnRasterize (wxCommandEvent& event)
+{
+ DialogGetRasterParameters dialogRaster (m_frame, 256, 256, 1);
+ int retVal = dialogRaster.ShowModal();
+ if (retVal == wxID_OK) {
+ int xSize = dialogRaster.getXSize();
+ int ySize = dialogRaster.getYSize();
+ int nSamples = dialogRaster.getNSamples();
+ if (nSamples < 1)
+ nSamples = 1;
+ if (xSize > 0 && ySize > 0) {
+ const Phantom& rPhantom = GetDocument()->getPhantom();
+ ImageFileDocument* pRasterDoc = dynamic_cast<ImageFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.if", wxDOC_SILENT));
+ if (! pRasterDoc) {
+ sys_error (ERR_SEVERE, "Unable to create image file");
+ return;
+ }
+ ImageFile& imageFile = pRasterDoc->getImageFile();
+
+ imageFile.setArraySize (xSize, ySize);
+ wxProgressDialog dlgProgress (wxString("Rasterize"), wxString("Rasterization Progress"), imageFile.nx() + 1, m_frame, wxPD_CAN_ABORT);
+ Timer timer;
+ for (unsigned int i = 0; i < imageFile.nx(); i++) {
+ rPhantom.convertToImagefile (imageFile, nSamples, Trace::TRACE_NONE, i, 1, true);
+ if (! dlgProgress.Update(i+1)) {
+ pRasterDoc->DeleteAllViews();
+ return;
+ }
+ }
+ if (theApp->getSetModifyNewDocs())
+ pRasterDoc->Modify(true);
+ pRasterDoc->UpdateAllViews(this);
+ std::ostringstream os;
+ os << "Rasterize Phantom " << rPhantom.name() << ": XSize=" << xSize << ", YSize=" << ySize << ", nSamples=" << nSamples;
+ *theApp->getLog() << os.str().c_str() << "\n";
+ imageFile.labelAdd (os.str().c_str(), timer.timerEnd());
+ ImageFileView* rasterView = dynamic_cast<ImageFileView*>(pRasterDoc->GetFirstView());
+ if (rasterView) {
+ rasterView->getFrame()->SetFocus();
+ rasterView->OnUpdate (rasterView, NULL);
+ }
+
+ }
+ }
+}