Newer
Older
Russell Taylor
committed
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
Peterson, Peter
committed
#include "MantidAlgorithms/ConvertSpectrumAxis.h"
#include "MantidAPI/NumericAxis.h"
Peterson, Peter
committed
/// @cond
// Don't document this very long winded way of getting "radians" to print on the axis.
namespace
{
class Degrees : public Mantid::Kernel::Unit
{
const std::string unitID() const { return ""; }
const std::string caption() const { return "Scattering angle"; }
const std::string label() const { return "degrees"; }
Russell Taylor
committed
void toTOF(std::vector<double>& xdata, std::vector<double>& ydata, const double& l1, const double& l2,
const double& twoTheta, const int& emode, const double& efixed, const double& delta) const {}
void fromTOF(std::vector<double>& xdata, std::vector<double>& ydata, const double& l1, const double& l2,
const double& twoTheta, const int& emode, const double& efixed, const double& delta) const {}
Peterson, Peter
committed
};
Peterson, Peter
committed
/// @endcond
Russell Taylor
committed
namespace Mantid
{
namespace Algorithms
{
Peterson, Peter
committed
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(ConvertSpectrumAxis)
using namespace Kernel;
using namespace API;
using namespace Geometry;
void ConvertSpectrumAxis::init()
{
Russell Taylor
committed
declareProperty(new WorkspaceProperty<>("InputWorkspace","",Direction::Input));
Peterson, Peter
committed
declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output));
declareProperty("Target","",new ListValidator(std::vector<std::string>(1,"theta")),
"The detector attribute to convert the spectrum axis to");
}
void ConvertSpectrumAxis::exec()
{
// Get the input workspace
Russell Taylor
committed
MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace");
Peterson, Peter
committed
// Check that the input workspace has a spectrum axis for axis 1
// Could put this in a validator later
const Axis* const specAxis = inputWS->getAxis(1);
if ( ! specAxis->isSpectra() )
{
g_log.error("The input workspace must have spectrum numbers along one axis");
throw std::runtime_error("The input workspace must have spectrum numbers along one axis");
}
// Loop over the original spectrum axis, finding the theta (n.b. not 2theta!) for each spectrum
// and storing it's corresponding workspace index
// Map will be sorted on theta, so resulting axis will be ordered as well
std::multimap<double,int> theta2indexMap;
const int axisLength = inputWS->getNumberHistograms();
bool warningGiven = false;
for (int i = 0; i < axisLength; ++i)
{
try {
IDetector_const_sptr det = inputWS->getDetector(i);
theta2indexMap.insert( std::make_pair( inputWS->detectorTwoTheta(det)*180.0/M_PI , i ) );
} catch(Exception::NotFoundError) {
if (!warningGiven) g_log.warning("The instrument definition is incomplete - spectra dropped from output");
warningGiven = true;
}
}
// Create the output workspace. Can't re-use the input one because we'll be re-ordering the spectra.
Russell Taylor
committed
MatrixWorkspace_sptr outputWS = WorkspaceFactory::Instance().create(inputWS,
theta2indexMap.size(),inputWS->readX(0).size(),inputWS->blocksize());
Peterson, Peter
committed
setProperty("OutputWorkspace",outputWS);
// Now set up a new, numeric axis holding the theta values corresponding to each spectrum
NumericAxis* const newAxis = new NumericAxis(theta2indexMap.size());
Peterson, Peter
committed
outputWS->replaceAxis(1,newAxis);
// The unit of this axis is radians. Use the 'radians' unit defined above.
newAxis->unit() = boost::shared_ptr<Unit>(new Degrees);
std::multimap<double,int>::const_iterator it;
int currentIndex = 0;
for (it = theta2indexMap.begin(); it != theta2indexMap.end(); ++it)
{
// Set the axis value
newAxis->setValue(currentIndex,it->first);
// Now copy over the data
outputWS->dataX(currentIndex) = inputWS->dataX(it->second);
outputWS->dataY(currentIndex) = inputWS->dataY(it->second);
outputWS->dataE(currentIndex) = inputWS->dataE(it->second);
++currentIndex;
}
}
Russell Taylor
committed
} // namespace Algorithms
Peterson, Peter
committed
} // namespace Mantid