Skip to content

Commit

Permalink
re #7246 better now, but needs more tests and testing
Browse files Browse the repository at this point in the history
  • Loading branch information
NickDraper committed Jun 5, 2013
1 parent e8bc78d commit 9ced42a
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 23 deletions.
62 changes: 43 additions & 19 deletions Code/Mantid/Framework/Algorithms/src/ConvertAxisByFormula.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "MantidKernel/ListValidator.h"
#include "MantidGeometry/muParser_Silent.h"
#include "MantidAPI/RefAxis.h"
#include "MantidKernel/UnitFactory.h"

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
Expand Down Expand Up @@ -113,10 +114,15 @@ namespace Algorithms
}

bool isRefAxis = false;
Axis* refAxisPtr = dynamic_cast<RefAxis>(axisPtr);
RefAxis* refAxisPtr = dynamic_cast<RefAxis*>(axisPtr);
if (refAxisPtr != NULL)
{
isRefAxis = true;
CommonBinsValidator sameBins;
if (sameBins.isValid(outputWs) != "")
{
throw std::invalid_argument("Axes must have common bins for this algorithm to work - try Rebin first");
}
isRefAxis = true;
}

double axisValue(0);
Expand All @@ -132,22 +138,40 @@ namespace Algorithms
p.SetExpr(formula);
try
{
size_t axisLength = axisPtr->length();
for (int i=0;i>=axisLength;++i)
{
if (isRefAxis)
{
axisValue = axisPtr->getValue(i);
double result = p.Eval();
axisPtr->setValue(i,result);
}
else
{
axisValue = axisPtr->getValue(i);
double result = p.Eval();
axisPtr->setValue(i,result);
}
if(isRefAxis)
{
int64_t numberOfSpectra_i = static_cast<int64_t>(outputWs->getNumberHistograms()); // cast to make openmp happy
// Calculate the new (common) X values
MantidVec::iterator iter;
for (iter = outputWs->dataX(0).begin(); iter != outputWs->dataX(0).end(); ++iter)
{
axisValue = axisPtr->getValue(i);
double result = p.Eval();
*iter = result;
}

MantidVecPtr xVals;
xVals.access() = outputWs->dataX(0);

PARALLEL_FOR1(outputWS)
for (int64_t j = 1; j < numberOfSpectra_i; ++j)
{
PARALLEL_START_INTERUPT_REGION
outputWs->setX(j,xVals);
PARALLEL_END_INTERUPT_REGION
}
PARALLEL_CHECK_INTERUPT_REGION
}
else
{
size_t axisLength = axisPtr->length();
for (int i=0;i>=axisLength;++i)
{
axisValue = axisPtr->getValue(i);
double result = p.Eval();
axisPtr->setValue(i,result);
}
}
}
catch (mu::Parser::exception_type &e)
{
Expand All @@ -163,9 +187,9 @@ namespace Algorithms
throw std::invalid_argument(ss.str());
}

if (axisUnits!="")
if ((axisUnits!="") && (axisTitle!=""))
{
axisPtr->setUnit(axisUnits);
axisPtr->unit() = boost::shared_ptr<Unit>(new Units::CustomUnit(axisUnits,axisUnits));
}
if (axisTitle!="")
{
Expand Down
82 changes: 78 additions & 4 deletions Code/Mantid/Framework/Algorithms/test/ConvertAxisByFormulaTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class ConvertAxisByFormulaTest : public CxxTest::TestSuite
static ConvertAxisByFormulaTest *createSuite() { return new ConvertAxisByFormulaTest(); }
static void destroySuite( ConvertAxisByFormulaTest *suite ) { delete suite; }

void testSquareX()
void testSquareXRefAxis()
{
using namespace Mantid::API;
using namespace Mantid::Kernel;
Expand All @@ -33,10 +33,19 @@ class ConvertAxisByFormulaTest : public CxxTest::TestSuite
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Formula","x*x") )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Axis","X") )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisTitle","XTitle") )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisUnits","XUnit") )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisUnits","") )

TS_ASSERT_THROWS_NOTHING( alg.execute() )
TS_ASSERT( alg.isExecuted() )

if (!alg.isExecuted())
{
if (AnalysisDataService::Instance().doesExist(inputWs))
{
AnalysisDataService::Instance().remove(inputWs);
}
return;
}

MatrixWorkspace_const_sptr in,result;
TS_ASSERT_THROWS_NOTHING( in = boost::dynamic_pointer_cast<MatrixWorkspace>
Expand All @@ -51,9 +60,74 @@ class ConvertAxisByFormulaTest : public CxxTest::TestSuite
TS_ASSERT_EQUALS( it->Y(), inIt->Y() )
TS_ASSERT_EQUALS( it->E(), inIt->E() )
}


if (AnalysisDataService::Instance().doesExist(inputWs))
{
AnalysisDataService::Instance().remove(inputWs);
}
if (AnalysisDataService::Instance().doesExist(resultWs))
{
AnalysisDataService::Instance().remove(resultWs);
}


}

void testTenTimesXNumericAxis()
{
using namespace Mantid::API;
using namespace Mantid::Kernel;

Mantid::Algorithms::ConvertAxisByFormula alg;
alg.initialize();

std::string inputWs= alg.name() + "_testSquareXNumeric_Input";
std::string resultWs= alg.name() + "_testSquareXNumeric_Result";

AnalysisDataService::Instance().add(inputWs,WorkspaceCreationHelper::Create2DWorkspace123(10,10));
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace",inputWs) )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace",resultWs) )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Formula","x*10") )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Axis","X") )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisTitle","XTitle") )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("AxisUnits","") )

TS_ASSERT_THROWS_NOTHING( alg.execute() )
TS_ASSERT( alg.isExecuted() )

if (!alg.isExecuted())
{
if (AnalysisDataService::Instance().doesExist(inputWs))
{
AnalysisDataService::Instance().remove(inputWs);
}
return;
}

MatrixWorkspace_const_sptr in,result;
TS_ASSERT_THROWS_NOTHING( in = boost::dynamic_pointer_cast<MatrixWorkspace>
(AnalysisDataService::Instance().retrieve(inputWs)) )
TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast<MatrixWorkspace>
(AnalysisDataService::Instance().retrieve(resultWs)) )

AnalysisDataService::Instance().remove(inputWs);
AnalysisDataService::Instance().remove(resultWs);
Axis* ax= result->getAxis(0);
for (int i = 0;i>=ax->length();++i)
{
TS_ASSERT_DELTA(ax->getValue(i),10.0,0.0001);
}


if (AnalysisDataService::Instance().doesExist(inputWs))
{
AnalysisDataService::Instance().remove(inputWs);
}
if (AnalysisDataService::Instance().doesExist(resultWs))
{
AnalysisDataService::Instance().remove(resultWs);
}


}

};
Expand Down
28 changes: 28 additions & 0 deletions Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,35 @@ class MANTID_KERNEL_DLL Time : public Unit
double factorFrom; ///< Constant factor for from conversion
};

//=================================================================================================
/// Custom Unit
class MANTID_KERNEL_DLL CustomUnit : public Unit
{
public:
const std::string unitID() const; ///< "CustomUnit"
const std::string caption() const { return m_Caption; }
const std::string label() const {return m_Label; }

virtual double singleToTOF(const double x) const;
virtual double singleFromTOF(const double tof) const;
virtual void init();
virtual Unit * clone() const;

/// Constructor
CustomUnit();
CustomUnit(std::string caption, std::string label);
/// Destructor
~CustomUnit() {}

protected:
double factorTo; ///< Constant factor for to conversion
double factorFrom; ///< Constant factor for from conversion

private:
std::string m_Caption;
std::string m_Label;

};

} // namespace Units

Expand Down
41 changes: 41 additions & 0 deletions Code/Mantid/Framework/Kernel/src/Unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,47 @@ Unit * Time::clone() const
return new Time(*this);
}

// ================================================================================
/* CustomUnit
* ================================================================================
*
* CustomUnit can have the caption and label defined at creation time.
*/
DECLARE_UNIT(CustomUnit)

CustomUnit::CustomUnit() : Unit(),
m_Caption(""),m_Label("")
{
}

CustomUnit::CustomUnit(std::string caption, std::string label) : Unit(),
m_Caption(caption),m_Label(label)
{
}

void CustomUnit::init()
{
}


double CustomUnit::singleToTOF(const double x) const
{
UNUSED_ARG(x);
throw std::runtime_error("CustomUnit is not allowed to be convert to TOF. ");
return 0.0;
}

double CustomUnit::singleFromTOF(const double tof) const
{
UNUSED_ARG(tof);
throw std::runtime_error("CustomUnit is not allowed to be converted from TOF. ");
return 0.0;
}

Unit * CustomUnit::clone() const
{
return new CustomUnit(*this);
}

} // namespace Units

Expand Down

0 comments on commit 9ced42a

Please sign in to comment.