Skip to content

Commit

Permalink
Miniplot shows sum of counts in detectors covered by shapes.
Browse files Browse the repository at this point in the history
Refactored 2d shape classes to work with multiple selections. Re #7222
  • Loading branch information
mantid-roman committed Jul 2, 2013
1 parent d5bafca commit 116f83c
Show file tree
Hide file tree
Showing 12 changed files with 306 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,7 @@ void InputControllerDrawShape::mouseMoveEvent(QMouseEvent *event)
m_rect.setBottomRight(QPoint( event->x(), event->y() ));
m_x = event->x();
m_y = event->y();
if ( m_rect.width() > 1 || m_rect.height() > 1 )
{
emit setSelection( m_rect );
}
emit setSelection( m_rect );
}
}
else
Expand All @@ -213,10 +210,7 @@ void InputControllerDrawShape::mouseReleaseEvent(QMouseEvent *)
m_isButtonPressed = false;
m_creating = false;
m_shapeType = "";
if ( m_rect.width() > 1 || m_rect.height() > 1 )
{
emit finishSelection( m_rect );
}
emit finishSelection( m_rect );
}

/**
Expand Down Expand Up @@ -250,6 +244,14 @@ void InputControllerDrawShape::startCreatingShape2D(const QString& type,const QC
m_fillColor = fillColor;
}

/**
* Action on disabling.
*/
void InputControllerDrawShape::onDisabled()
{
m_creating = false;
emit disabled();
}
//--------------------------------------------------------------------------------

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class InputControllerDrawShape: public InputController

public slots:
void startCreatingShape2D(const QString& type,const QColor& borderColor,const QColor& fillColor);
void onDisabled();

private:
bool m_creating; ///< a shape is being created with a mouse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ using namespace Mantid::Geometry;
using namespace Mantid::API;
using namespace Mantid;

/// to be used in std::transform
struct Sqrt
{
double operator()(double x)
{
return sqrt(x);
}
};

double InstrumentActor::m_tolerance = 0.00001;

/**
Expand Down Expand Up @@ -380,7 +389,87 @@ double InstrumentActor::getIntegratedCounts(Mantid::detid_t id)const
} catch (NotFoundError &) {
// If the detector is not represented in the workspace
return -1.0;
}
}
}

/**
* Sum counts in detectors for purposes of rough plotting against time of flight.
* Silently assumes that all spectra share the x vector.
*
* @param dets :: A list of detector IDs to sum.
* @param x :: (output) Time of flight values (or whatever values the x axis has) to plot against.
* @param y :: (output) The sums of the counts for each bin.
* @param err :: (optional output) Pointer to a buffer to receive the errors of the summed spectra.
* If NULL the errors are not returned.
*/
void InstrumentActor::sumDetectors(QList<int> &dets, std::vector<double> &x, std::vector<double> &y, std::vector<double> *err) const
{

size_t wi;
bool isDataEmpty = dets.isEmpty();

if ( !isDataEmpty )
{
try {
wi = getWorkspaceIndex( dets[0] );
} catch (Mantid::Kernel::Exception::NotFoundError &) {
isDataEmpty = true; // Detector doesn't have a workspace index relating to it
}
}

if ( isDataEmpty )
{
x.clear();
y.clear();
if ( err )
{
err->clear();
}
return;
}

// find the bins inside the integration range
size_t imin,imax;
getBinMinMaxIndex(wi,imin,imax);

Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace();
const Mantid::MantidVec& X = ws->readX(wi);
x.assign(X.begin() + imin, X.begin() + imax);
if ( ws->isHistogramData() )
{
// calculate the bin centres
std::transform(x.begin(),x.end(),X.begin() + imin + 1,x.begin(),std::plus<double>());
std::transform(x.begin(),x.end(),x.begin(),std::bind2nd(std::divides<double>(),2.0));
}
y.resize(x.size(),0);
if (err)
{
err->resize(x.size(),0);
}

foreach(int id, dets)
{
try {
size_t index = getWorkspaceIndex( id );
const Mantid::MantidVec& Y = ws->readY(index);
std::transform(y.begin(),y.end(),Y.begin() + imin,y.begin(),std::plus<double>());
if (err)
{
const Mantid::MantidVec& E = ws->readE(index);
std::vector<double> tmp;
tmp.assign(E.begin() + imin,E.begin() + imax);
std::transform(tmp.begin(),tmp.end(),tmp.begin(),tmp.begin(),std::multiplies<double>());
std::transform(err->begin(),err->end(),tmp.begin(),err->begin(),std::plus<double>());
}
} catch (Mantid::Kernel::Exception::NotFoundError &) {
continue; // Detector doesn't have a workspace index relating to it
}
}

if (err)
{
std::transform(err->begin(),err->end(),err->begin(),Sqrt());
}
}

/**
Expand Down Expand Up @@ -782,6 +871,54 @@ void InstrumentActor::BasisRotation(const Mantid::Kernel::V3D& Xfrom,
}
}

/**
* Find the offsets in the spectrum's x vector of the bounds of integration.
* @param wi :: The works[ace index of the spectrum.
* @param imin :: Index of the lower bound: x_min == readX(wi)[imin]
* @param imax :: Index of the upper bound: x_max == readX(wi)[imax]
*/
void InstrumentActor::getBinMinMaxIndex( size_t wi, size_t& imin, size_t& imax ) const
{
Mantid::API::MatrixWorkspace_const_sptr ws = getWorkspace();
const Mantid::MantidVec& x = ws->readX(wi);
Mantid::MantidVec::const_iterator x_begin = x.begin();
Mantid::MantidVec::const_iterator x_end = x.end();
if (x_begin == x_end)
{
throw std::runtime_error("No bins found to plot");
}
if (ws->isHistogramData())
{
--x_end;
}
if ( wholeRange() )
{
imin = 0;
imax = static_cast<size_t>(x_end - x_begin);
}
else
{
Mantid::MantidVec::const_iterator x_from = std::lower_bound( x_begin, x_end, minBinValue() );
Mantid::MantidVec::const_iterator x_to = std::upper_bound( x_begin, x_end, maxBinValue() );
imin = static_cast<size_t>(x_from - x_begin);
imax = static_cast<size_t>(x_to - x_begin);
if (imax <= imin)
{
if (x_from == x_end)
{
--x_from;
x_to = x_end;
}
else
{
x_to = x_from + 1;
}
imin = static_cast<size_t>(x_from - x_begin);
imax = static_cast<size_t>(x_to - x_begin);
}
}
}

bool SetVisibleComponentVisitor::visit(GLActor* actor)
{
ComponentActor* comp = dynamic_cast<ComponentActor*>(actor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class InstrumentActor: public QObject, public GLActor
void applyMaskWorkspace();
/// Remove the attached mask workspace without applying the mask.
void clearMaskWorkspace();

/// Get the color map.
const MantidColorMap & getColorMap() const;
/// Load a new color map from a file
Expand All @@ -83,6 +84,7 @@ class InstrumentActor: public QObject, public GLActor
void setAutoscaling(bool);
/// Get colormap scale autoscaling status.
bool autoscaling()const{return m_autoscaling;}

/// Set the integration range.
void setIntegrationRange(const double& xmin,const double& xmax);
/// Get the minimum data value on the color map scale.
Expand All @@ -103,6 +105,7 @@ class InstrumentActor: public QObject, public GLActor
double maxBinValue()const{return m_BinMaxValue;}
/// Return true if the integration range covers the whole of the x-axis in the data workspace.
bool wholeRange()const;

/// Get the number of detectors in the instrument.
size_t ndetectors()const{return m_detIDs.size();}
/// Get shared pointer to a detector by a pick ID converted form a color in the pick image.
Expand All @@ -121,6 +124,11 @@ class InstrumentActor: public QObject, public GLActor
size_t getWorkspaceIndex(Mantid::detid_t id) const;
/// Get the integrated counts of a detector by its detector ID.
double getIntegratedCounts(Mantid::detid_t id)const;
/// Sum the counts in detectors
void sumDetectors(QList<int>& dets, std::vector<double>&x, std::vector<double>&y, std::vector<double>* err = NULL) const;
/// Calc indexes for min and max bin values
void getBinMinMaxIndex(size_t wi,size_t& imin, size_t& imax) const;

/// Update the detector colors to match the integrated counts within the current integration range.
void update();
/// Invalidate the OpenGL display lists to force full re-drawing of the instrument and creation of new lists.
Expand All @@ -140,6 +148,7 @@ class InstrumentActor: public QObject, public GLActor
bool out = false
);


/* Masking */

void initMaskHelper() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,55 +486,6 @@ void InstrumentWindowPickTab::updatePick(int detid)
m_currentDetID = detid;
}

/**
* Find the offsets in the spectrum's x vector of the bounds of integration.
* @param wi :: The works[ace index of the spectrum.
* @param imin :: Index of the lower bound: x_min == readX(wi)[imin]
* @param imax :: Index of the upper bound: x_max == readX(wi)[imax]
*/
void InstrumentWindowPickTab::getBinMinMaxIndex(size_t wi,size_t& imin, size_t& imax)
{
InstrumentActor* instrActor = m_instrWindow->getInstrumentActor();
Mantid::API::MatrixWorkspace_const_sptr ws = instrActor->getWorkspace();
const Mantid::MantidVec& x = ws->readX(wi);
Mantid::MantidVec::const_iterator x_begin = x.begin();
Mantid::MantidVec::const_iterator x_end = x.end();
if (x_begin == x_end)
{
throw std::runtime_error("No bins found to plot");
}
if (ws->isHistogramData())
{
--x_end;
}
if (instrActor->wholeRange())
{
imin = 0;
imax = static_cast<size_t>(x_end - x_begin);
}
else
{
Mantid::MantidVec::const_iterator x_from = std::lower_bound(x_begin,x_end,instrActor->minBinValue());
Mantid::MantidVec::const_iterator x_to = std::upper_bound(x_begin,x_end,instrActor->maxBinValue());
imin = static_cast<size_t>(x_from - x_begin);
imax = static_cast<size_t>(x_to - x_begin);
if (imax <= imin)
{
if (x_from == x_end)
{
--x_from;
x_to = x_end;
}
else
{
x_to = x_from + 1;
}
imin = static_cast<size_t>(x_from - x_begin);
imax = static_cast<size_t>(x_to - x_begin);
}
}
}

/**
* Plot data for a detector.
* @param detid :: ID of the detector to be plotted.
Expand Down Expand Up @@ -862,7 +813,7 @@ void InstrumentWindowPickTab::prepareDataForSinglePlot(

// find min and max for x
size_t imin,imax;
getBinMinMaxIndex(wi,imin,imax);
instrActor->getBinMinMaxIndex(wi,imin,imax);

x.assign(X.begin() + imin,X.begin() + imax);
y.assign(Y.begin() + imin,Y.begin() + imax);
Expand Down Expand Up @@ -905,7 +856,7 @@ void InstrumentWindowPickTab::prepareDataForSumsPlot(
return; // Detector doesn't have a workspace index relating to it
}
size_t imin,imax;
getBinMinMaxIndex(wi,imin,imax);
instrActor->getBinMinMaxIndex(wi,imin,imax);

const Mantid::MantidVec& X = ws->readX(wi);
x.assign(X.begin() + imin, X.begin() + imax);
Expand Down Expand Up @@ -988,7 +939,7 @@ void InstrumentWindowPickTab::prepareDataForIntegralsPlot(
}
// imin and imax give the bin integration range
size_t imin,imax;
getBinMinMaxIndex(wi,imin,imax);
instrActor->getBinMinMaxIndex(wi,imin,imax);

const int n = ass->nelements();
if (n == 0)
Expand Down Expand Up @@ -1268,6 +1219,9 @@ void InstrumentWindowPickTab::initSurface()
connect(surface,SIGNAL(peaksWorkspaceAdded()),this,SLOT(updateSelectionInfoDisplay()));
connect(surface,SIGNAL(peaksWorkspaceDeleted()),this,SLOT(updateSelectionInfoDisplay()));
connect(surface,SIGNAL(shapeCreated()),this,SLOT(shapeCreated()));
connect(surface,SIGNAL(shapeChangeFinished()),this,SLOT(updatePlotMultipleDetectors()));
connect(surface,SIGNAL(shapesCleared()),this,SLOT(updatePlotMultipleDetectors()));
connect(surface,SIGNAL(shapesDeselected()),this,SLOT(updatePlotMultipleDetectors()));
}

/**
Expand Down Expand Up @@ -1331,6 +1285,7 @@ void InstrumentWindowPickTab::selectTool(const ToolType tool)
case DrawEllipse: m_ellipse->setChecked(true);
break;
case EditShape: m_edit->setChecked(true);
updatePlotMultipleDetectors();
break;
default: throw std::invalid_argument("Invalid tool type.");
}
Expand All @@ -1342,7 +1297,6 @@ void InstrumentWindowPickTab::singleDetectorTouched(int detid)
{
if (canUpdateTouchedDetector())
{
//mInteractionInfo->setText(cursorPos.display());
updatePick(detid);
}
}
Expand All @@ -1369,3 +1323,21 @@ void InstrumentWindowPickTab::shapeCreated()
selectTool( EditShape );
}

/**
* Update the mini-plot with information from multiple detector
* selected with drawn shapes.
*/
void InstrumentWindowPickTab::updatePlotMultipleDetectors()
{
QList<int> dets;
getSurface()->getMaskedDetectors( dets );
std::vector<double> x,y;
m_instrWindow->getInstrumentActor()->sumDetectors( dets, x, y );
m_plot->clearAll();
if ( !x.empty() )
{
m_plot->setData(&x[0],&y[0],static_cast<int>(y.size()), m_instrWindow->getInstrumentActor()->getWorkspace()->getAxis(0)->unit()->unitID());
}
m_plot->replot();
}

Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,13 @@ private slots:
void singleDetectorPicked(int detid);
void updateSelectionInfoDisplay();
void shapeCreated();
void updatePlotMultipleDetectors();
private:
void showEvent (QShowEvent *);
void updatePlot(int detid);
void updateSelectionInfo(int detid);
void plotSingle(int detid);
void plotTube(int detid);
/// Calc indexes for min and max bin values defined in the instrument Actor
void getBinMinMaxIndex(size_t wi,size_t& imin, size_t& imax);
void plotTubeSums(int detid);
void plotTubeIntegrals(int detid);
void prepareDataForSinglePlot(
Expand Down

0 comments on commit 116f83c

Please sign in to comment.