Skip to content

Commit

Permalink
refs #5167. MVP method controlling peaks
Browse files Browse the repository at this point in the history
  • Loading branch information
OwenArnold committed Aug 28, 2012
1 parent 59f9df4 commit c3395de
Show file tree
Hide file tree
Showing 11 changed files with 192 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ namespace SliceViewer

public:
/// Constructor
PeakOverlay(QwtPlot * plot, QWidget * parent, const QPointF& origin, const QPointF& radius);
PeakOverlay(QwtPlot * plot, QWidget * parent, const QPointF& origin, const double& radius);
/// Destructor
virtual ~PeakOverlay();
/// Set the distance between the origin and the plane in the z-md-coordinate system.
void setPlaneDistance(const double& dz);
virtual void setPlaneDistance(const double& dz);
/// Update the view.
virtual void updateView();
/// Get the origin. md x, md y
const QPointF & getOrigin() const;
double getRadius() const;
Expand All @@ -70,18 +72,16 @@ namespace SliceViewer
/// Origin md-x, md-y
QPointF m_origin;
/// Radius md-x, md-y
QPointF m_radius;
double m_radius;
/// Max opacity
const double m_opacityMax;
/// Min opacity
const double m_opacityMin;
/// Cached opacity at the distance z from origin
double m_opacityAtDistance;
/// Cached radius at the distance z from origin
double m_radiusXAtDistance;
/// Cached radius x at the distance x from origin, in md-x coordinates
double m_radiusYAtDistance;
/// Cached radius y at the distance y from origin, in md-y coordinates
double m_radiusAtDistance;
/// Cached radius at distance
};


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ namespace MantidQt
private:
QwtPlot * m_plot;
QWidget * m_parent;
PeakDimensions m_peakDims;
public:
PeakOverlayFactory(QwtPlot * plot, QWidget * parent);
PeakOverlayFactory(QwtPlot * plot, QWidget * parent, const PeakDimensions peakDims);
virtual ~PeakOverlayFactory();
virtual PeakOverlayView* createView(const QPointF& origin, const QPointF& radius) const;
virtual boost::shared_ptr<PeakOverlayView> createView(const Mantid::API::IPeak&) const;
};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ namespace MantidQt
{
namespace SliceViewer
{
/// Enum describing types of peak dimensions.
enum PeakDimensions{LabView, SampleView, HKLView};

/** Abstract view in MVP model representing a PeakOverlay.
@date 2012-08-24
Expand Down Expand Up @@ -40,7 +43,9 @@ namespace MantidQt
/// Get the origin. md x, md y
virtual const QPointF & getOrigin() const = 0;
/// Get the radius. md x, md y
virtual const QPointF & getRadius() const = 0;
virtual const double & getRadius() const = 0;
/// Update the view.
virtual void updateView() = 0;
/// Destructor
virtual ~PeakOverlayView()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@

#include "MantidKernel/System.h"
#include "MantidQtSliceViewer/PeakOverlayView.h"
#include <boost/shared_ptr.hpp>

namespace Mantid
{
namespace API
{
// Forward dec.
class IPeak;
}
}

namespace MantidQt
{
Expand Down Expand Up @@ -35,8 +45,8 @@ namespace MantidQt
class DLLExport PeakOverlayViewFactory
{
public:
/// Set the distance between the plane and the origin in md-z coordinates.
virtual PeakOverlayView* createView(const QPointF& origin, const QPointF& radius) const = 0;
/// Create a peak view from the peak object.
virtual boost::shared_ptr<PeakOverlayView> createView(const Mantid::API::IPeak&) const = 0;
/// Destructor
virtual ~PeakOverlayViewFactory()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define MANTID_SLICEVIEWER_PEAKSPRESENTER_H_

#include "MantidKernel/System.h"
#include <vector>
#include <boost/shared_ptr.hpp>

namespace Mantid
Expand All @@ -19,11 +20,33 @@ namespace SliceViewer
{
// Forward dec.
class PeakOverlayViewFactory;
class PeakOverlayView;

class DLLExport PeaksPresenter
{
public:
PeaksPresenter(PeakOverlayViewFactory* factory, boost::shared_ptr<Mantid::API::IPeaksWorkspace> peaksWS);
virtual void update() = 0;
};

class DLLExport NullPeaksPresenter : public PeaksPresenter
{
public:
virtual void update(){};
};

class DLLExport ConcretePeaksPresenter : public PeaksPresenter
{
public:
ConcretePeaksPresenter(PeakOverlayViewFactory* factory, boost::shared_ptr<Mantid::API::IPeaksWorkspace> peaksWS);
virtual void update();
private:
typedef std::vector< boost::shared_ptr<PeakOverlayView> > VecPeakOverlayView;
/// Peak overlay views.
VecPeakOverlayView m_viewPeaks;
};

typedef boost::shared_ptr<PeaksPresenter> PeaksPresenter_sptr;
typedef boost::shared_ptr<const PeaksPresenter> PeaksPresenter_const_sptr;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ namespace MantidQt
namespace SliceViewer
{

// Forward dec
class PeaksPresenter;

/** GUI for viewing a 2D slice out of a multi-dimensional workspace.
* You can select which dimension to plot as X,Y, and the cut point
* along the other dimension(s).
Expand Down Expand Up @@ -162,6 +165,10 @@ public slots:


private:
// -------------------------- Controllers ------------------------

boost::shared_ptr<PeaksPresenter> m_peaksPresenter;

// -------------------------- Widgets ----------------------------

/// Auto-generated UI controls.
Expand Down
35 changes: 16 additions & 19 deletions Code/Mantid/MantidQt/SliceViewer/src/PeakOverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace SliceViewer
//----------------------------------------------------------------------------------------------
/** Constructor
*/
PeakOverlay::PeakOverlay(QwtPlot * plot, QWidget * parent, const QPointF& origin, const QPointF& radius)
PeakOverlay::PeakOverlay(QwtPlot * plot, QWidget * parent, const QPointF& origin, const double& radius)
: QWidget( parent ),
m_plot(plot),
m_origin(origin),
Expand All @@ -31,6 +31,7 @@ namespace SliceViewer
m_opacityMin(0.1)
{
setAttribute(Qt::WA_NoMousePropagation, false);
this->setVisible(true);
}

//----------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -61,16 +62,11 @@ namespace SliceViewer
*/
void PeakOverlay::setPlaneDistance(const double& dz)
{
/*
Note that this is actually slightly wrong since the distance is in the z-axis, we must scale the distance to the x-axis and
y-axis first. However, since the same feature will be applied to each peak radius and each peak opacity, I'm leaving it for the time-being.
*/
const double distanceSQ = dz * dz;
m_radiusXAtDistance = std::sqrt( (m_radius.x() * m_radius.x()) - distanceSQ );
m_radiusYAtDistance = std::sqrt( (m_radius.y() * m_radius.y()) - distanceSQ );
m_radiusAtDistance = std::sqrt( (m_radius * m_radius) - distanceSQ );

// Apply a linear transform to convert from a distance to an opacity between opacityMin and opacityMax.
m_opacityAtDistance = ((m_opacityMin - m_opacityMax)/m_radius.x()) * dz + m_opacityMax;
m_opacityAtDistance = ((m_opacityMin - m_opacityMax)/m_radius) * dz + m_opacityMax;
m_opacityAtDistance = m_opacityAtDistance >= m_opacityMin ? m_opacityAtDistance : m_opacityMin;

this->update(); //repaint
Expand Down Expand Up @@ -109,31 +105,32 @@ namespace SliceViewer
const int xOrigin = m_plot->transform( QwtPlot::xBottom, m_origin.x() );
const int yOrigin = m_plot->transform( QwtPlot::yLeft, m_origin.y() );
const QPointF originWindows(xOrigin, yOrigin);

const double xMin = m_plot->axisScaleDiv(QwtPlot::xBottom)->lowerBound();
const double xMax = m_plot->axisScaleDiv(QwtPlot::xBottom)->upperBound();
const double scaleX = width()/(xMax - xMin);

const double yMin = m_plot->axisScaleDiv(QwtPlot::yLeft)->lowerBound();
const double yMax = m_plot->axisScaleDiv(QwtPlot::yLeft)->upperBound();
const double scaleY = height()/(yMax - yMin);
const double yMin = m_plot->axisScaleDiv(QwtPlot::yLeft)->lowerBound();
const double yMax = m_plot->axisScaleDiv(QwtPlot::yLeft)->upperBound();
const double scale = height()/(yMax - yMin);

int rx = scaleX * m_radiusXAtDistance;
int ry = scaleY * m_radiusYAtDistance;
const double radius = scale * m_radiusAtDistance;

// Draw circle and inner circle.
QPainter painter(this);
painter.setRenderHint( QPainter::Antialiasing );

painter.setOpacity(m_opacityAtDistance); //Set the pre-calculated opacity
painter.setBrush(Qt::cyan);
painter.drawEllipse( originWindows, rx, ry );
painter.drawEllipse( originWindows, radius, radius );

QPen pen( Qt::green );
pen.setWidth(2);
painter.setPen( pen );
painter.drawEllipse( originWindows, rx, ry );
painter.drawEllipse( originWindows, radius, radius );

}

void PeakOverlay::updateView()
{
this->update();
this->repaint();
}


Expand Down
38 changes: 35 additions & 3 deletions Code/Mantid/MantidQt/SliceViewer/src/PeakOverlayFactory.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,54 @@
#include "MantidQtSliceViewer/PeakOverlayFactory.h"
#include "MantidQtSliceViewer/PeakOverlay.h"
#include "MantidAPI/IPeak.h"
#include <boost/make_shared.hpp>

using namespace Mantid::API;

namespace MantidQt
{
namespace SliceViewer
{

PeakOverlayFactory::PeakOverlayFactory(QwtPlot * plot, QWidget * parent) : m_plot(plot), m_parent(parent)
PeakOverlayFactory::PeakOverlayFactory(QwtPlot * plot, QWidget * parent, const PeakDimensions peakDims) : m_plot(plot), m_parent(parent), m_peakDims(peakDims)
{
if(!plot)
throw std::invalid_argument("PeakOverlayFactory plot is null");
if(!parent)
throw std::invalid_argument("PeakOverlayFactory parent widget is null");
}

PeakOverlayView* PeakOverlayFactory::createView(const QPointF& origin, const QPointF& radius) const
boost::shared_ptr<PeakOverlayView> PeakOverlayFactory::createView(const Mantid::API::IPeak& peak) const
{
return new PeakOverlay(m_plot, m_parent, origin, radius);
Mantid::Kernel::V3D position;
switch(m_peakDims)
{
case PeakDimensions::LabView:
position = peak.getQLabFrame();
break;
case PeakDimensions::SampleView:
position = peak.getQSampleFrame();
break;
case PeakDimensions::HKLView:
position = peak.getHKL();
break;
default:
throw std::runtime_error("Unknown PeakDimension type");
}

double radius = peak.getIntensity(); //TODO: we should normalise this!
radius = 1; //HACK
//QwtText xDim = m_plot->axisTitle(QwtPlot::xBottom);
//QwtText yDim = m_plot->axisTitle(QwtPlot::yLeft);

/* 1) Find out which dimensions are being plotted on x and y
2) Find out what h, k, l each of these dimensions correspond to.
3) Create the origin x, y based on these hkl values.
*/

QPointF origin(position.X(), position.Y()); // This needs to be calculated properly! See above.

return boost::make_shared<PeakOverlay>(m_plot, m_parent, origin, radius);
}

PeakOverlayFactory::~PeakOverlayFactory()
Expand Down
19 changes: 15 additions & 4 deletions Code/Mantid/MantidQt/SliceViewer/src/PeaksPresenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,31 @@ namespace MantidQt
{
namespace SliceViewer
{
PeaksPresenter::PeaksPresenter(PeakOverlayViewFactory* factory, Mantid::API::IPeaksWorkspace_sptr peaksWS)
ConcretePeaksPresenter::ConcretePeaksPresenter(PeakOverlayViewFactory* factory, Mantid::API::IPeaksWorkspace_sptr peaksWS)
{
if(factory == NULL)
{
throw std::invalid_argument("PeakOverlayViewFactory is null");
}

// Create views for every peak in the workspace.
boost::scoped_ptr<PeakOverlayViewFactory> factory_scptr(factory);
for(int i = 0; i < peaksWS->getNumberPeaks(); ++i)
{
const Mantid::API::IPeak& peak = peaksWS->getPeak(i);
//peak.getHKL();
//TODO: translate the peak into an origin & radius.
auto view = boost::shared_ptr<PeakOverlayView>( factory_scptr->createView(peak) );
m_viewPeaks.push_back( view );
view->setPlaneDistance(0); // HACK
}
}

factory_scptr->createView(QPointF(0,0), QPointF(1,1));
void ConcretePeaksPresenter::update()
{
VecPeakOverlayView::iterator it = m_viewPeaks.begin();
while(it != m_viewPeaks.end())
{
(*it)->updateView();
++it;
}
}
}
Expand Down

0 comments on commit c3395de

Please sign in to comment.