Skip to content

Commit

Permalink
Refs #10623. Added properties to algorithm.
Browse files Browse the repository at this point in the history
The algorithm now also produces a PoldiPeakCollection with the fitted peaks.
  • Loading branch information
Michael Wedel committed Dec 4, 2014
1 parent 9f64ec8 commit 0d23d95
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 11 deletions.
Expand Up @@ -4,13 +4,12 @@
#include "MantidKernel/System.h"
#include "MantidSINQ/DllConfig.h"
#include "MantidAPI/Algorithm.h"
#include "MantidAPI/MultiDomainFunction.h"
#include "MantidAPI/IFunction.h"
#include "MantidDataObjects/TableWorkspace.h"
#include "MantidSINQ/PoldiUtilities/PoldiPeakCollection.h"
#include "MantidSINQ/PoldiUtilities/PoldiTimeTransformer.h"
#include "MantidSINQ/PoldiUtilities/Poldi2DFunction.h"


namespace Mantid
{
namespace Poldi
Expand Down Expand Up @@ -64,10 +63,13 @@ class MANTID_SINQ_DLL PoldiCalculateSpectrum2D : public API::Algorithm
PoldiPeakCollection_sptr getNormalizedPeakCollection(const PoldiPeakCollection_sptr &peakCollection) const;
PoldiPeakCollection_sptr getCountPeakCollection(const PoldiPeakCollection_sptr &peakCollection) const;

PoldiPeakCollection_sptr getPeakCollectionFromFunction(const API::IFunction_sptr &fitFunction) const;
boost::shared_ptr<Poldi2DFunction> getFunctionFromPeakCollection(const PoldiPeakCollection_sptr &peakCollection) const;
void addBackgroundTerms(boost::shared_ptr<Poldi2DFunction> poldi2DFunction) const;

API::MatrixWorkspace_sptr calculateSpectrum(const PoldiPeakCollection_sptr &peakCollection, const API::MatrixWorkspace_sptr &matrixWorkspace);
API::IAlgorithm_sptr calculateSpectrum(const PoldiPeakCollection_sptr &peakCollection, const API::MatrixWorkspace_sptr &matrixWorkspace);
API::MatrixWorkspace_sptr getWorkspace(const API::IAlgorithm_sptr &fitAlgorithm) const;
API::IFunction_sptr getFunction(const API::IAlgorithm_sptr &fitAlgorithm) const;

void setTimeTransformerFromInstrument(const PoldiInstrumentAdapter_sptr &poldiInstrument);
void setTimeTransformer(const PoldiTimeTransformer_sptr &poldiTimeTransformer);
Expand Down
93 changes: 85 additions & 8 deletions Code/Mantid/Framework/SINQ/src/PoldiCalculateSpectrum2D.cpp
Expand Up @@ -74,7 +74,53 @@ namespace Poldi
declareProperty("FitLinearBackground", true, "Add a background term linear in 2theta to the fit.");
declareProperty("LinearBackgroundParameter", 0.0, "Initial value of linear background.");

declareProperty("MaximumIterations", 0, "Maximum number of iterations for the fit. Use 0 to calculate 2D-spectrum without fitting.");

declareProperty(new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace","",Direction::Output), "Calculated POLDI 2D-spectrum");
declareProperty(new WorkspaceProperty<TableWorkspace>("RefinedPoldiPeakWorkspace", "", Direction::Output), "Table workspace with fitted peaks.");
}

/**
* Construct a PoldiPeakCollection from a Poldi2DFunction
*
* This method performs the opposite operation of getFunctionFromPeakCollection.
* It takes a function, checks if it's of the proper type and turns the information
* into a PoldiPeakCollection.
*
* @param Poldi2DFunction with one PoldiSpectrumDomainFunction per peak
* @return PoldiPeakCollection containing peaks with normalized intensities
*/
PoldiPeakCollection_sptr PoldiCalculateSpectrum2D::getPeakCollectionFromFunction(const IFunction_sptr &fitFunction) const
{
boost::shared_ptr<Poldi2DFunction> poldi2DFunction = boost::dynamic_pointer_cast<Poldi2DFunction>(fitFunction);

if(!poldi2DFunction) {
throw std::invalid_argument("Cannot process function that is not a Poldi2DFunction.");
}

PoldiPeakCollection_sptr normalizedPeaks = boost::make_shared<PoldiPeakCollection>(PoldiPeakCollection::Integral);

for(size_t i = 0; i < poldi2DFunction->nFunctions(); ++i) {
boost::shared_ptr<PoldiSpectrumDomainFunction> peakFunction = boost::dynamic_pointer_cast<PoldiSpectrumDomainFunction>(poldi2DFunction->getFunction(i));

if(peakFunction) {
size_t dIndex = peakFunction->parameterIndex("Centre");
UncertainValue d(peakFunction->getParameter(dIndex), peakFunction->getError(dIndex));

size_t iIndex = peakFunction->parameterIndex("Area");
UncertainValue intensity(peakFunction->getParameter(iIndex), peakFunction->getError(iIndex));

size_t fIndex = peakFunction->parameterIndex("Fwhm");
UncertainValue fwhm(peakFunction->getParameter(fIndex), peakFunction->getError(fIndex));

PoldiPeak_sptr peak = PoldiPeak::create(MillerIndices(), d, intensity, UncertainValue(1.0));
peak->setFwhm(fwhm, PoldiPeak::FwhmRelation::AbsoluteD);

normalizedPeaks->addPeak(peak);
}
}

return normalizedPeaks;
}

/**
Expand Down Expand Up @@ -124,7 +170,14 @@ namespace Poldi
peakCollection->setProfileFunctionName(profileFunctionProperty->value());
}

setProperty("OutputWorkspace", calculateSpectrum(peakCollection, ws));
IAlgorithm_sptr fitAlgorithm = calculateSpectrum(peakCollection, ws);

IFunction_sptr fitFunction = getFunction(fitAlgorithm);
PoldiPeakCollection_sptr normalizedPeaks = getPeakCollectionFromFunction(fitFunction);
PoldiPeakCollection_sptr integralPeaks = getCountPeakCollection(normalizedPeaks);

setProperty("OutputWorkspace", getWorkspace(fitAlgorithm));
setProperty("RefinedPoldiPeakWorkspace", integralPeaks->asTableWorkspace());
}

/**
Expand Down Expand Up @@ -154,15 +207,17 @@ namespace Poldi
}

/**
* Calculates the 2D spectrum in a MatrixWorkspace
* Performs the fit and returns the fit algorithm
*
* In this method the actual function calculation is performed using Fit.
* In this method the actual function fit/calculation is performed
* using the Fit algorithm. After execution the algorithm is returned for
* further processing.
*
* @param peakCollection :: PoldiPeakCollection
* @param matrixWorkspace :: MatrixWorkspace with POLDI instrument and correct dimensions
* @return MatrixWorkspace with the calculated data
* @return Instance of Fit-algorithm, after execution
*/
MatrixWorkspace_sptr PoldiCalculateSpectrum2D::calculateSpectrum(const PoldiPeakCollection_sptr &peakCollection, const MatrixWorkspace_sptr &matrixWorkspace)
IAlgorithm_sptr PoldiCalculateSpectrum2D::calculateSpectrum(const PoldiPeakCollection_sptr &peakCollection, const MatrixWorkspace_sptr &matrixWorkspace)
{
PoldiPeakCollection_sptr integratedPeaks = getIntegratedPeakCollection(peakCollection);
PoldiPeakCollection_sptr normalizedPeakCollection = getNormalizedPeakCollection(integratedPeaks);
Expand All @@ -180,14 +235,36 @@ namespace Poldi
fit->setProperty("Function", boost::dynamic_pointer_cast<IFunction>(mdFunction));
fit->setProperty("InputWorkspace", matrixWorkspace);
fit->setProperty("CreateOutput", true);
fit->setProperty("MaxIterations", 0);

int maxIterations = getProperty("MaximumIterations");
fit->setProperty("MaxIterations", maxIterations);

fit->setProperty("Minimizer", "Levenberg-MarquardtMD");

fit->execute();

MatrixWorkspace_sptr outputWs = fit->getProperty("OutputWorkspace");
return fit;
}

/// Returns the output workspace stored in the Fit algorithm.
MatrixWorkspace_sptr PoldiCalculateSpectrum2D::getWorkspace(const IAlgorithm_sptr &fitAlgorithm) const
{
if(!fitAlgorithm) {
throw std::invalid_argument("Cannot extract workspace from null-algorithm.");
}

MatrixWorkspace_sptr outputWorkspace = fitAlgorithm->getProperty("OutputWorkspace");
return outputWorkspace;
}

IFunction_sptr PoldiCalculateSpectrum2D::getFunction(const IAlgorithm_sptr &fitAlgorithm) const
{
if(!fitAlgorithm) {
throw std::invalid_argument("Cannot extract function from null-algorithm.");
}

return outputWs;
IFunction_sptr fitFunction = fitAlgorithm->getProperty("Function");
return fitFunction;
}

/**
Expand Down
20 changes: 20 additions & 0 deletions Code/Mantid/Framework/SINQ/test/PoldiCalculateSpectrum2DTest.h
Expand Up @@ -202,6 +202,26 @@ class PoldiCalculateSpectrum2DTest : public CxxTest::TestSuite
}
}

void testGetPeakCollectionFromFunction()
{
TestablePoldiCalculateSpectrum2D spectrumCalculator;
PoldiPeakCollection_sptr peaks = PoldiPeakCollectionHelpers::createPoldiPeakCollectionNormalized();

IFunction_sptr poldi2DFunction = spectrumCalculator.getFunctionFromPeakCollection(peaks);

PoldiPeakCollection_sptr peaksFromFunction = spectrumCalculator.getPeakCollectionFromFunction(poldi2DFunction);

TS_ASSERT_EQUALS(peaksFromFunction->peakCount(), peaks->peakCount());
for(size_t i = 0; i < peaksFromFunction->peakCount(); ++i) {
PoldiPeak_sptr functionPeak = peaksFromFunction->peak(i);
PoldiPeak_sptr referencePeak = peaks->peak(i);

TS_ASSERT_EQUALS(functionPeak->d(), referencePeak->d());
TS_ASSERT_EQUALS(functionPeak->fwhm(), referencePeak->fwhm());
TS_ASSERT_EQUALS(functionPeak->intensity(), referencePeak->intensity());
}
}

void testAddBackgroundFunctions()
{
TestablePoldiCalculateSpectrum2D spectrumCalculator;
Expand Down

0 comments on commit 0d23d95

Please sign in to comment.