Skip to content

Commit

Permalink
re #10230 supports all axes types
Browse files Browse the repository at this point in the history
  • Loading branch information
NickDraper committed Sep 12, 2014
1 parent a5a0bfd commit c2e32e8
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 25 deletions.
25 changes: 20 additions & 5 deletions Code/Mantid/Framework/API/inc/MantidAPI/MatrixWorkspace.h
Expand Up @@ -167,7 +167,7 @@ namespace Mantid
const MantidVec& readDx(size_t const index) const { return getSpectrum(index)->dataDx(); }

/// Returns the x data
virtual MantidVec& dataX(const std::size_t index) { return getSpectrum(index)->dataX(); }
virtual MantidVec& dataX(const std::size_t index) { invalidateCommonBinsFlag(); return getSpectrum(index)->dataX(); }
/// Returns the y data
virtual MantidVec& dataY(const std::size_t index) { return getSpectrum(index)->dataY(); }
/// Returns the error data
Expand All @@ -192,13 +192,13 @@ namespace Mantid
virtual Kernel::cow_ptr<MantidVec> refX(const std::size_t index) const { return getSpectrum(index)->ptrX(); }

/// Set the specified X array to point to the given existing array
virtual void setX(const std::size_t index, const MantidVec& X) { getSpectrum(index)->setX(X); }
virtual void setX(const std::size_t index, const MantidVec& X) { getSpectrum(index)->setX(X); invalidateCommonBinsFlag(); }

/// Set the specified X array to point to the given existing array
virtual void setX(const std::size_t index, const MantidVecPtr& X) { getSpectrum(index)->setX(X); }
virtual void setX(const std::size_t index, const MantidVecPtr& X) { getSpectrum(index)->setX(X); invalidateCommonBinsFlag(); }

/// Set the specified X array to point to the given existing array
virtual void setX(const std::size_t index, const MantidVecPtr::ptr_type& X) { getSpectrum(index)->setX(X); }
virtual void setX(const std::size_t index, const MantidVecPtr::ptr_type& X) { getSpectrum(index)->setX(X); invalidateCommonBinsFlag(); }

/** Sets the data in the workspace
@param index :: the workspace index to set.
Expand Down Expand Up @@ -232,10 +232,13 @@ namespace Mantid
int axes() const;
Axis* getAxis(const std::size_t& axisIndex) const;
void replaceAxis(const std::size_t& axisIndex, Axis* const newAxis);

/// Returns true if the workspace contains data in histogram form (as opposed to point-like)
virtual bool isHistogramData() const;

/// Returns true if the workspace contains has common X bins
virtual bool isCommonBins() const;

std::string YUnit() const;
void setYUnit(const std::string& newUnit);
std::string YUnitLabel() const;
Expand Down Expand Up @@ -314,6 +317,9 @@ namespace Mantid
/// Initialises the workspace. Sets the size and lengths of the arrays. Must be overloaded.
virtual void init(const std::size_t &NVectors, const std::size_t &XLength, const std::size_t &YLength) = 0;

/// Invalidates the commons bins flag. This is generally called when a method could allow the X values to be changed.
void invalidateCommonBinsFlag() { m_isCommonBinsFlagSet = false; }

/// A vector of pointers to the axes for this workspace
std::vector<Axis*> m_axes;

Expand All @@ -332,6 +338,15 @@ namespace Mantid
std::string m_YUnitLabel;
/// Flag indicating whether the Y-values are dimensioned. False by default
bool m_isDistribution;

/// Flag indicating whether the data is histogram mode. Set in initialize
bool m_isHistogramFlag;

/// Flag indicating whether the m_isCommonBinsFlag has been set. False by default
mutable bool m_isCommonBinsFlagSet;
/// Flag indicating whether the data has common bins. False by default
mutable bool m_isCommonBinsFlag;

/// The set of masked bins in a map keyed on spectrum index
std::map< int64_t, MaskList > m_masks;

Expand Down
16 changes: 2 additions & 14 deletions Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceValidators.h
Expand Up @@ -222,20 +222,8 @@ class DLLExport CommonBinsValidator : public MatrixWorkspaceValidator
std::string checkValidity( const MatrixWorkspace_sptr& value ) const
{
if ( !value ) return "Enter an existing workspace";
//there being only one or zero histograms is accepted as not being an error
if ( !value->blocksize() || value->getNumberHistograms() < 2) return "";
//otherwise will compare some of the data, to save time just check two the first and the last
const size_t lastSpec = value->getNumberHistograms() - 1;
// Quickest check is to see if they are actually the same vector
if ( &(value->readX(0)[0]) == &(value->readX(lastSpec)[0]) ) return "";
// Now check numerically
const double first = std::accumulate(value->readX(0).begin(),value->readX(0).end(),0.);
const double last = std::accumulate(value->readX(lastSpec).begin(),value->readX(lastSpec).end(),0.);
if ( std::abs(first-last)/std::abs(first+last) > 1.0E-9 )
{
return "The workspace must have common bin boundaries for all histograms";
}
return "";
if ( !value->isCommonBins() ) return "";
else return "The workspace must have common bin boundaries for all histograms";
}

};
Expand Down
38 changes: 36 additions & 2 deletions Code/Mantid/Framework/API/src/MatrixWorkspace.cpp
Expand Up @@ -40,6 +40,8 @@ namespace Mantid
IMDWorkspace(), ExperimentInfo(),
m_axes(), m_isInitialized(false),
m_YUnit(), m_YUnitLabel(), m_isDistribution(false),
m_isHistogramFlag(false),
m_isCommonBinsFlagSet(false),m_isCommonBinsFlag(false),
m_masks(), m_indexCalculator(),
m_nearestNeighboursFactory((nnFactory == NULL) ? new NearestNeighboursFactory : nnFactory),
m_nearestNeighbours()
Expand Down Expand Up @@ -115,6 +117,7 @@ namespace Mantid
}

m_indexCalculator = MatrixWSIndexCalculator(this->blocksize());
m_isHistogramFlag = YLength==XLength ? false : true;
// Indicate that this workspace has been initialized to prevent duplicate attempts.
m_isInitialized = true;
}
Expand Down Expand Up @@ -937,14 +940,45 @@ namespace Mantid

/**
* Whether the workspace contains histogram data
* @return whether the worksapace contains histogram data
* @return whether the workspace contains histogram data
*/
bool MatrixWorkspace::isHistogramData() const
{
return ( readX(0).size()==blocksize() ? false : true );
return m_isHistogramFlag;
}

/**
* Whether the workspace contains common X bins
* @return whether the workspace contains common X bins
*/
bool MatrixWorkspace::isCommonBins() const
{
if (!m_isCommonBinsFlagSet)
{
m_isCommonBinsFlag = true;

//there being only one or zero histograms is accepted as not being an error
if ( blocksize() || getNumberHistograms() > 1)
{
//otherwise will compare some of the data, to save time just check two the first and the last
const size_t lastSpec = getNumberHistograms() - 1;
// Quickest check is to see if they are actually the same vector
if ( &(readX(0)[0]) != &(readX(lastSpec)[0]) )
{
// Now check numerically
const double first = std::accumulate(readX(0).begin(),readX(0).end(),0.);
const double last = std::accumulate(readX(lastSpec).begin(),readX(lastSpec).end(),0.);
if ( std::abs(first-last)/std::abs(first+last) > 1.0E-9 )
{
m_isCommonBinsFlag = false;
}
}
}
m_isCommonBinsFlagSet = true;
}

return m_isCommonBinsFlag;
}
//----------------------------------------------------------------------------------------------------
/**
* Mask a given workspace index, setting the data and error values to zero
Expand Down
1 change: 1 addition & 0 deletions Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp
Expand Up @@ -190,6 +190,7 @@ namespace Mantid
{
if (index >= m_noVectors)
throw std::range_error("EventWorkspace::getSpectrum, workspace index out of range");
invalidateCommonBinsFlag();
return data[index];
}

Expand Down
1 change: 1 addition & 0 deletions Code/Mantid/Framework/DataObjects/src/Workspace2D.cpp
Expand Up @@ -111,6 +111,7 @@ namespace Mantid
ss << "Workspace2D::getSpectrum, histogram number " << index << " out of range " << m_noVectors;
throw std::range_error(ss.str());
}
invalidateCommonBinsFlag();
return data[index];
}

Expand Down
126 changes: 122 additions & 4 deletions Code/Mantid/MantidPlot/src/Mantid/MantidMatrix.cpp
Expand Up @@ -10,6 +10,10 @@
#include "Preferences.h"
#include "../pixmaps.h"


#include "MantidAPI/NumericAxis.h"
#include "MantidAPI/RefAxis.h"
#include "MantidAPI/SpectraAxis.h"
#include "MantidAPI/TextAxis.h"
#include "MantidKernel/ReadLock.h"

Expand Down Expand Up @@ -1166,7 +1170,7 @@ double MantidMatrixModel::data(int row, int col) const

QVariant MantidMatrixModel::headerData(int section, Qt::Orientation orientation, int role ) const
{
if (role != Qt::DisplayRole) return QVariant();
if (!(role == Qt::DisplayRole || role == Qt::ToolTipRole)) return QVariant();
if (orientation == Qt::Vertical && m_workspace->axes() > 1)
{
Mantid::API::TextAxis* xAxis = dynamic_cast<Mantid::API::TextAxis*>(m_workspace->getAxis(1));
Expand All @@ -1175,7 +1179,121 @@ QVariant MantidMatrixModel::headerData(int section, Qt::Orientation orientation,
return QString::fromStdString(xAxis->label(section));
}
}

//initialise with horizontal values
int axisIndex = 0;
QString toolTipSeperator = "\n";
QString headerSeperator = "\n";
if (orientation == Qt::Vertical)
{
axisIndex = 1;
toolTipSeperator = "\n";
headerSeperator = " ";
}

if (m_workspace->axes() > axisIndex) //if the axis exists
{
Mantid::API::Axis* axis = m_workspace->getAxis(axisIndex);
Mantid::API::TextAxis* textAxis = dynamic_cast<Mantid::API::TextAxis*>(axis);
if (textAxis) //just return the text label
{
return QString::fromStdString(textAxis->label(section));
}

Mantid::API::SpectraAxis* spAxis = dynamic_cast<Mantid::API::SpectraAxis*>(axis);
if (spAxis)
{
if (role == Qt::ToolTipRole)
{
return QString("index %1%2spectra no %3").arg(QString::number(section), toolTipSeperator,
QString::number(m_workspace->getSpectrum(section)->getSpectrumNo()));
}
else
{
return QString("%1%2sp-%3").arg(QString::number(section), headerSeperator,
QString::number(m_workspace->getSpectrum(section)->getSpectrumNo()));
}
}


QString unit = QString::fromStdWString( axis->unit()->label().utf8());
Mantid::API::NumericAxis* numAxis = dynamic_cast<Mantid::API::NumericAxis*>(axis);
if (numAxis)
{
if (role == Qt::ToolTipRole)
{
return QString("index %1%2%3 %4%5").arg(QString::number(section), toolTipSeperator,
QString::fromStdString(axis->unit()->caption()),
QString::number(numAxis->getValue(section)),unit);
}
else
{
if (headerSeperator == " ") headerSeperator = " ";
return QString("%1%2%3%4").arg(QString::number(section), headerSeperator,
QString::number(numAxis->getValue(section)),unit);
}
}

Mantid::API::RefAxis* refAxis = dynamic_cast<Mantid::API::RefAxis*>(axis);
if (refAxis)
{
//still need to protect from ragged workspaces
if (m_type==X)
{
if (role == Qt::ToolTipRole)
{
return QString("index %1").arg(QString::number(section));
}
else
{
return section;
}
}

if (!m_workspace->isCommonBins())
{
if (role == Qt::ToolTipRole)
{
return QString("index %1%2bin centre value varies").arg(QString::number(section),toolTipSeperator);
}
else
{
return QString("%1%2varies").arg(QString::number(section),headerSeperator);
}
}

//get bin centre value
double binCentreValue;
const Mantid::MantidVec xVec = m_workspace->readX(0);
if (m_workspace->isHistogramData())
{
if ((section+1) >= xVec.size()) return section;
binCentreValue= (xVec[section] + xVec[section+1])/2.0;
}
else
{
if (section >= xVec.size()) return section;
binCentreValue = xVec[section];
}

if (role == Qt::ToolTipRole)
{
return QString("index %1%2%3 %4%5 (bin centre)").arg(QString::number(section), toolTipSeperator,
QString::fromStdString(axis->unit()->caption()),
QString::number(binCentreValue), unit);
}
else
{
return QString("%1%2%3%4").arg(QString::number(section), headerSeperator,
QString::number(binCentreValue), unit);
}
}

}
// fall through value, just return the section value
return section;


}

Qt::ItemFlags MantidMatrixModel::flags(const QModelIndex & index ) const
Expand Down Expand Up @@ -1326,8 +1444,8 @@ void findYRange(MatrixWorkspace_const_sptr ws, double &miny, double &maxy)

if (maxy == miny)
{
if ( maxy == 0.0 ) maxy += 1.0;
else
maxy += fabs(miny);
if ( maxy == 0.0 ) maxy += 1.0;
else
maxy += fabs(miny);
}
}

0 comments on commit c2e32e8

Please sign in to comment.