Commit 64cf1e3e authored by Russell Taylor's avatar Russell Taylor
Browse files

Modified CropWorkspace to allow a ragged workspace when only cutting out...

Modified CropWorkspace to allow a ragged workspace when only cutting out spectra (not cropping on X). Re #717.
parent 6225006a
......@@ -17,7 +17,7 @@ namespace Algorithms
Required Properties:
<UL>
<LI> InputWorkspace - The name of the Workspace2D to take as input. Must have common bins. </LI>
<LI> InputWorkspace - The name of the Workspace2D to take as input. </LI>
<LI> OutputWorkspace - The name under which to store the output workspace. </LI>
</UL>
......@@ -29,6 +29,7 @@ namespace Algorithms
<LI> EndSpectrum - The workspace index number to end the cropped workspace at (default max)</LI>
</UL>
If cropping in X, then the input workspace must have common bin boundaries/X values.
If an X value given does not exactly match a bin boundary, then the closest bin boundary
within the range will be used.
Note that if none of the optional properties are given, then the output workspace will be
......@@ -37,7 +38,7 @@ namespace Algorithms
@author Russell Taylor, Tessella Support Services plc
@date 15/10/2008
Copyright &copy; 2008 STFC Rutherford Appleton Laboratory
Copyright &copy; 2008-9 STFC Rutherford Appleton Laboratory
This file is part of Mantid.
......@@ -76,8 +77,8 @@ private:
void exec();
void checkProperties();
void getXMin();
void getXMax();
bool getXMin();
bool getXMax();
/// The input workspace
DataObjects::Workspace2D_const_sptr m_inputWorkspace;
......@@ -89,6 +90,8 @@ private:
int m_minSpec;
/// The spectrum index to end the cropped workspace at
int m_maxSpec;
/// Flag indicating whether the input workspace has common boundaries
bool m_commonBoundaries;
///a flag int value to indicate that the value wasn't set by users
static const int unSetInt = INT_MAX-15;
......
......@@ -18,8 +18,7 @@ using DataObjects::Workspace2D;
/// Default constructor
CropWorkspace::CropWorkspace() :
Algorithm(), //call the parent constructor
m_minX(0), m_maxX(0), m_minSpec(0), m_maxSpec(unSetInt)
Algorithm(), m_minX(0), m_maxX(0), m_minSpec(0), m_maxSpec(0), m_commonBoundaries(false)
{}
/// Destructor
......@@ -27,27 +26,26 @@ CropWorkspace::~CropWorkspace() {}
void CropWorkspace::init()
{
declareProperty(new WorkspaceProperty<Workspace2D>("InputWorkspace","",Direction::Input,new CommonBinsValidator<Workspace2D>),
"The input workspace2D must have common bins" );
declareProperty(new WorkspaceProperty<Workspace2D>("InputWorkspace","",Direction::Input),
"The input Workspace2D" );
declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output),
"Name of the output workspace2D" );
declareProperty("XMin",0.0,
"An X value that is within the first (lowest X value) bin that will be retained\n"
"(default 0)");
"(default: workspace min)");
declareProperty("XMax", EMPTY_DBL(),
"An X value that is in the highest X value bin to be retained (default highest X\n"
"in the workspace)");
"An X value that is in the highest X value bin to be retained (default: max X)");
BoundedValidator<int> *mustBePositive = new BoundedValidator<int>();
mustBePositive->setLower(0);
declareProperty("StartSpectrum",0, mustBePositive,
"The index number of the first spectrum in the series that will be retained\n"
"(default 0)");
"(default: last spectrum)");
// As the property takes ownership of the validator pointer, have to take care to pass in a unique
// pointer to each property.
declareProperty("EndSpectrum", unSetInt, mustBePositive->clone(),
declareProperty("EndSpectrum", EMPTY_INT(), mustBePositive->clone(),
"The index number of the last spectrum in the series to be retained\n"
"default (the last spectrum)");
"(default: first spectrum)");
}
/** Executes the algorithm
......@@ -58,6 +56,8 @@ void CropWorkspace::exec()
// Get the input workspace
m_inputWorkspace = getProperty("InputWorkspace");
const bool histogram = m_inputWorkspace->isHistogramData();
// Check for common boundaries in input workspace
m_commonBoundaries = WorkspaceHelpers::commonBoundaries(m_inputWorkspace);
// Retrieve and validate the input properties
this->checkProperties();
......@@ -76,13 +76,22 @@ void CropWorkspace::exec()
}
DataObjects::Histogram1D::RCtype newX;
const MantidVec& oldX = m_inputWorkspace->readX(m_minSpec);
newX.access().assign(oldX.begin()+m_minX,oldX.begin()+m_maxX);
if ( m_commonBoundaries )
{
const MantidVec& oldX = m_inputWorkspace->readX(m_minSpec);
newX.access().assign(oldX.begin()+m_minX,oldX.begin()+m_maxX);
}
// Loop over the required spectra, copying in the desired bins
for (int i = m_minSpec, j = 0; i <= m_maxSpec; ++i,++j)
{
output2D->setX(j,newX);
// Preserve/restore sharing if X vectors are the same
if ( m_commonBoundaries )
output2D->setX(j,newX);
else
// Safe to just copy whole vector 'cos can't be cropping in X if not common
outputWorkspace->dataX(j) = m_inputWorkspace->readX(i);
const MantidVec& oldY = m_inputWorkspace->readY(i);
outputWorkspace->dataY(j).assign(oldY.begin()+m_minX,oldY.begin()+(m_maxX-histogram));
const MantidVec& oldE = m_inputWorkspace->readE(i);
......@@ -104,8 +113,6 @@ void CropWorkspace::exec()
}
setProperty("OutputWorkspace", outputWorkspace);
// Reset the input workspace member variable
m_inputWorkspace = DataObjects::Workspace2D_const_sptr();
}
/** Retrieves the optional input properties and checks that they have valid values.
......@@ -115,31 +122,32 @@ void CropWorkspace::exec()
*/
void CropWorkspace::checkProperties()
{
// Do the full check on common workspace binning
if ( ! WorkspaceHelpers::commonBoundaries(m_inputWorkspace) )
{
g_log.error("The input workspace must have common X values across all spectra");
throw std::invalid_argument("The input workspace must have common X values across all spectra");
}
this->getXMin();
this->getXMax();
if ( m_minX > m_maxX )
{
g_log.error("XMin must be less than XMax");
throw std::out_of_range("XMin must be less than XMax");
}
if ( m_minX == m_maxX )
const bool xmaxSet = this->getXMax();
if ( ! this->getXMin() || ! xmaxSet )
{
g_log.error("The X range given lies entirely within a single bin");
throw std::out_of_range("The X range given lies entirely within a single bin");
// If not using full X range, do a check on common workspace binning
if ( ! m_commonBoundaries )
{
const std::string mess("If cropping in X, the input workspace must have common X values across all spectra");
g_log.error(mess);
throw std::invalid_argument(mess);
}
if ( m_minX > m_maxX )
{
g_log.error("XMin must be less than XMax");
throw std::out_of_range("XMin must be less than XMax");
}
if ( m_minX == m_maxX )
{
g_log.error("The X range given lies entirely within a single bin");
throw std::out_of_range("The X range given lies entirely within a single bin");
}
}
m_minSpec = getProperty("StartSpectrum");
const int numberOfSpectra = m_inputWorkspace->getNumberHistograms();
m_maxSpec = getProperty("EndSpectrum");
if ( m_maxSpec == unSetInt ) m_maxSpec = numberOfSpectra-1;
if ( isEmpty(m_maxSpec) ) m_maxSpec = numberOfSpectra-1;
// Check 'StartSpectrum' is in range 0-numberOfSpectra
if ( m_minSpec > numberOfSpectra-1 )
......@@ -161,28 +169,33 @@ void CropWorkspace::checkProperties()
/** Find the X index corresponding to (or just within) the value given in the XMin property.
* Sets the default if the property has not been set.
* @return True if the XMin property has been set.
*/
void CropWorkspace::getXMin()
bool CropWorkspace::getXMin()
{
Property *minX = getProperty("XMin");
if ( !minX->isDefault() )
const bool def = minX->isDefault();
if ( !def )
{//A value has been passed to the algorithm, check it and maybe store it
const double minX_val = getProperty("XMin");
const MantidVec& X = m_inputWorkspace->readX(0);
if ( minX_val > X.back() )
if ( m_commonBoundaries && minX_val > X.back() )
{
g_log.error("XMin is greater than the largest X value");
throw std::out_of_range("XMin is greater than the largest X value");
}
m_minX = std::lower_bound(X.begin(),X.end(),minX_val) - X.begin();
}
return def;
}
/** Find the X index corresponding to (or just within) the value given in the XMax property.
* Sets the default if the property has not been set.
* @return True if the Xmin property has been set.
*/
void CropWorkspace::getXMax()
bool CropWorkspace::getXMax()
{
bool def = true;
const MantidVec& X = m_inputWorkspace->readX(0);
//get the value that the user entered if they entered one at all
const double maxX_val = getProperty("XMax");
......@@ -192,13 +205,15 @@ void CropWorkspace::getXMax()
}
else
{//we have a user value, check it and maybe store it
if ( maxX_val < X.front() )
if ( m_commonBoundaries && maxX_val < X.front() )
{
g_log.error("XMax is less than the smallest X value");
throw std::out_of_range("XMax is less than the smallest X value");
}
m_maxX = std::upper_bound(X.begin(),X.end(),maxX_val) - X.begin();
def = false;
}
return def;
}
} // namespace Algorithms
......
......@@ -450,14 +450,6 @@
RelativePath=".\test\ManagedRawFileWorkspace2DTest.h"
>
</File>
<File
RelativePath=".\test\MarkDeadDetectorsInShapeTest.h"
>
</File>
<File
RelativePath=".\test\MarkDeadDetectorsTest.h"
>
</File>
<File
RelativePath=".\inc\MantidDataHandling\MaskDetectors.h"
>
......@@ -494,10 +486,6 @@
RelativePath=".\inc\MantidDataHandling\SaveGSS.h"
>
</File>
<File
RelativePath=".\test\SaveNeXusTest.h"
>
</File>
<File
RelativePath=".\inc\MantidDataHandling\SaveRKH.h"
>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment