Skip to content

Commit

Permalink
Re #10390. Added image get functions and unit tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
mantid-roman committed Oct 21, 2014
1 parent d865271 commit 3a94199
Show file tree
Hide file tree
Showing 3 changed files with 390 additions and 0 deletions.
20 changes: 20 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/MatrixWorkspace.h
Expand Up @@ -33,6 +33,11 @@ namespace Mantid
{
class SpectrumDetectorMapping;

/// typedef for the image type
typedef std::vector<std::vector<double>> MantidImage;
/// shared pointer to MantidImage
typedef boost::shared_ptr<MantidImage> MantidImage_sptr;

//----------------------------------------------------------------------
/** Base MatrixWorkspace Abstract Class.
Expand Down Expand Up @@ -311,6 +316,19 @@ namespace Mantid
// End IMDWorkspace methods
//=====================================================================================

//=====================================================================================
// Image methods
//=====================================================================================

/// Create an image of Ys.
MantidImage_sptr getImageY (size_t start = 0, size_t stop = 0, size_t width = 0, size_t indexStart = 0, size_t indexEnd = 0) const;
/// Create an image of Es.
MantidImage_sptr getImageE (size_t start = 0, size_t stop = 0, size_t width = 0, size_t indexStart = 0, size_t indexEnd = 0) const;

//=====================================================================================
// End image methods
//=====================================================================================

protected:
MatrixWorkspace(Mantid::Geometry::INearestNeighboursFactory* factory = NULL);

Expand All @@ -328,6 +346,8 @@ namespace Mantid
MatrixWorkspace(const MatrixWorkspace&);
/// Private copy assignment operator. NO ASSIGNMENT ALLOWED
MatrixWorkspace& operator=(const MatrixWorkspace&);
/// Create an MantidImage instance.
MantidImage_sptr getImage(const MantidVec& (MatrixWorkspace::*read)(std::size_t const) const, size_t start, size_t stop, size_t width, size_t indexStart, size_t indexEnd) const;

/// Has this workspace been initialised?
bool m_isInitialized;
Expand Down
132 changes: 132 additions & 0 deletions Code/Mantid/Framework/API/src/MatrixWorkspace.cpp
Expand Up @@ -1713,6 +1713,138 @@ namespace Mantid
return Mantid::API::None;
}

/**
* Creates a 2D image.
* @param read :: Pointer to a method returning a MantidVec to provide data for the image.
* @param start :: First workspace index for the image.
* @param stop :: Last workspace index for the image.
* @param width :: Image width. Must divide (stop - start + 1) exactly.
* @param indexStart :: First index of the x integration range.
* @param indexEnd :: Last index of the x integration range.
*/
MantidImage_sptr MatrixWorkspace::getImage(const MantidVec& (MatrixWorkspace::*read)(std::size_t const) const, size_t start, size_t stop, size_t width, size_t indexStart, size_t indexEnd) const
{
// width must be provided (for now)
if ( width == 0 )
{
throw std::runtime_error("Cannot create image with width 0");
}

size_t nHist = getNumberHistograms();
// use all spectra by default
if ( stop == 0 )
{
stop = nHist;
}

// check start and stop
if ( stop < start )
{
throw std::runtime_error("Cannot create image for an empty data set.");
}

if ( start >= nHist )
{
throw std::runtime_error("Cannot create image: start index is out of range");
}

if ( stop >= nHist )
{
throw std::runtime_error("Cannot create image: stop index is out of range");
}

// calculate image geometry
size_t dataSize = stop - start + 1;
size_t height = dataSize / width;

// and check that the data fits exactly into this geometry
if ( height * width != dataSize )
{
throw std::runtime_error("Cannot create image: the data set cannot form a rectangle.");
}

size_t nBins = blocksize();
bool isHisto = isHistogramData();

// default indexEnd is the last index of the X vector
if ( indexEnd == 0 )
{
indexEnd = nBins;
if ( !isHisto && indexEnd > 0 ) --indexEnd;
}

// check the x-range indices
if ( indexEnd < indexStart )
{
throw std::runtime_error("Cannot create image for an empty data set.");
}

if ( indexStart >= nBins || indexEnd > nBins || (!isHisto && indexEnd == nBins) )
{
throw std::runtime_error("Cannot create image: integration interval is out of range.");
}

// initialize the image
auto image = boost::make_shared<MantidImage>( height );
if ( !isHisto ) ++indexEnd;

// deal separately with single-binned workspaces: no integration is required
if ( isHisto && indexEnd == indexStart + 1 )
{
size_t spec = start;
for(auto row = image->begin(); row != image->end(); ++row)
{
row->resize( width );
for(size_t i = 0; i < width; ++i, ++spec)
{
(*row)[i] = (this->*read)(spec)[indexStart];
}
}
}
else
{
// each image pixel is integrated over the x-range [indexStart,indexEnd)
size_t spec = start;
for(auto row = image->begin(); row != image->end(); ++row)
{
row->resize( width );
for(size_t i = 0; i < width; ++i, ++spec)
{
auto &V = (this->*read)(spec);
(*row)[i] = std::accumulate( V.begin() + indexStart, V.begin() + indexEnd, 0.0 );
}
}
}

return image;
}

/**
* Creates a 2D image of the y values in this workspace.
* @param start :: First workspace index for the image.
* @param stop :: Last workspace index for the image.
* @param width :: Image width. Must divide (stop - start + 1) exactly.
* @param indexStart :: First index of the x integration range.
* @param indexEnd :: Last index of the x integration range.
*/
MantidImage_sptr MatrixWorkspace::getImageY(size_t start, size_t stop, size_t width, size_t indexStart, size_t indexEnd) const
{
return getImage(&MatrixWorkspace::readY,start,stop,width,indexStart,indexEnd);
}

/**
* Creates a 2D image of the error values in this workspace.
* @param start :: First workspace index for the image.
* @param stop :: Last workspace index for the image.
* @param width :: Image width. Must divide (stop - start + 1) exactly.
* @param indexStart :: First index of the x integration range.
* @param indexEnd :: Last index of the x integration range.
*/
MantidImage_sptr MatrixWorkspace::getImageE(size_t start, size_t stop, size_t width, size_t indexStart, size_t indexEnd) const
{
return getImage(&MatrixWorkspace::readE,start,stop,width,indexStart,indexEnd);
}

} // namespace API
} // Namespace Mantid

Expand Down

0 comments on commit 3a94199

Please sign in to comment.