Skip to content

Commit

Permalink
Refs #11674. Checkpointing work
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Wedel committed May 5, 2015
1 parent 6331195 commit f49bebf
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 23 deletions.
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/CurveFitting/CMakeLists.txt
Expand Up @@ -75,6 +75,7 @@ set ( SRC_FILES
src/PawleyFunction.cpp
src/PeakParameterFunction.cpp
src/PlotPeakByLogValue.cpp
src/PoldiCalibrationProfile.cpp
src/Polynomial.cpp
src/ProcessBackground.cpp
src/ProductFunction.cpp
Expand Down Expand Up @@ -193,6 +194,7 @@ set ( INC_FILES
inc/MantidCurveFitting/PawleyFunction.h
inc/MantidCurveFitting/PeakParameterFunction.h
inc/MantidCurveFitting/PlotPeakByLogValue.h
inc/MantidCurveFitting/PoldiCalibrationProfile.h
inc/MantidCurveFitting/Polynomial.h
inc/MantidCurveFitting/ProcessBackground.h
inc/MantidCurveFitting/ProductFunction.h
Expand Down Expand Up @@ -302,6 +304,7 @@ set ( TEST_FILES
PawleyFunctionTest.h
PeakParameterFunctionTest.h
PlotPeakByLogValueTest.h
PoldiCalibrationProfileTest.h
PolynomialTest.h
ProcessBackgroundTest.h
ProductFunctionTest.h
Expand Down
@@ -0,0 +1,69 @@
#ifndef MANTID_CURVEFITTING_POLDICALIBRATIONFUNCTION_H_
#define MANTID_CURVEFITTING_POLDICALIBRATIONFUNCTION_H_

#include "MantidCurveFitting/Gaussian.h"

namespace Mantid {
namespace CurveFitting {

/** PoldiCalibrationProfile
Instrument parameters at POLDI are calibrated using an additional parameter
that changes the slope of Bragg lines in the POLDI 2D data. If the
instrument is calibrated properly, the parameter is 0.
Since silicon powder is used as standard, peak profiles are always Gaussian,
so the Gaussian function from this module is re-used. The additional
parameter depends on 2theta, so it can only be used in conjunction with the
PoldiSpectrumCalibrationFunction in the SINQ module. If used otherwise
it will behave like Gaussian with an additional parameter that does nothing.
@author Michael Wedel, Paul Scherrer Institut - SINQ
@date 04/05/2015
Copyright © 2015 PSI-NXMM
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport PoldiCalibrationProfile : public Gaussian {
public:
~PoldiCalibrationProfile() {}

std::string name() const { return "PoldiCalibrationProfile"; }

double centre() const;

void functionLocal(double *out, const double *xValues,
const size_t nData) const;
void functionDerivLocal(API::Jacobian *out, const double *xValues,
const size_t nData);

// void functionDerivLocal(API::Jacobian *out, const double *xValues, const
// size_t nData);

protected:
double getAbsoluteShift() const;

void init();
};

} // namespace CurveFitting
} // namespace Mantid

#endif /* MANTID_CURVEFITTING_POLDICALIBRATIONFUNCTION_H_ */
68 changes: 68 additions & 0 deletions Code/Mantid/Framework/CurveFitting/src/PoldiCalibrationProfile.cpp
@@ -0,0 +1,68 @@
#include "MantidCurveFitting/PoldiCalibrationProfile.h"
#include "MantidAPI/FunctionFactory.h"

namespace Mantid {
namespace CurveFitting {

using namespace API;

DECLARE_FUNCTION(PoldiCalibrationProfile)

void PoldiCalibrationProfile::functionLocal(double *out, const double *xValues,
const size_t nData) const {

const double height = getParameter("Height");
const double peakCentre = getParameter("PeakCentre");
const double shift = getAbsoluteShift();
const double realCentre = peakCentre + peakCentre * shift;

const double weight = pow(1 / getParameter("Sigma"), 2);

for (size_t i = 0; i < nData; i++) {
double diff = xValues[i] - realCentre;
out[i] = height * exp(-0.5 * diff * diff * weight);
}
}

void PoldiCalibrationProfile::functionDerivLocal(Jacobian *out,
const double *xValues,
const size_t nData) {
const double height = getParameter("Height");
const double peakCentre = getParameter("PeakCentre");
const double shift = getAbsoluteShift();
const double realCentre = peakCentre + peakCentre * shift;

const double weight = pow(1 / getParameter("Sigma"), 2);
const double factor = getAttribute("DeltaTheta").asDouble() / 1000.0;

for (size_t i = 0; i < nData; i++) {
double diff = xValues[i] - realCentre;
double e = exp(-0.5 * diff * diff * weight);
double b = e * height * diff * weight;
out->set(i, 0, e);
out->set(i, 1, b * (1.0 + shift));
out->set(i, 2, -0.5 * diff * diff * height *
e); // derivative with respect to weight not sigma
out->set(i, 3, b * factor * peakCentre);
}
}

double PoldiCalibrationProfile::centre() const {
return getParameter("PeakCentre") +
getParameter("PeakCentre") * getAbsoluteShift();
}

double PoldiCalibrationProfile::getAbsoluteShift() const {
return getParameter("Slope") * 1.e-3 * getAttribute("DeltaTheta").asDouble();
}

/// Initialize Gaussian parameters and declare additional parameter.
void PoldiCalibrationProfile::init() {
Gaussian::init();

declareParameter("Slope");
declareAttribute("DeltaTheta", IFunction::Attribute(0.0));
}

} // namespace CurveFitting
} // namespace Mantid
@@ -0,0 +1,44 @@
#ifndef MANTID_CURVEFITTING_POLDICALIBRATIONFUNCTIONTEST_H_
#define MANTID_CURVEFITTING_POLDICALIBRATIONFUNCTIONTEST_H_

#include <cxxtest/TestSuite.h>

#include "MantidCurveFitting/PoldiCalibrationProfile.h"

using namespace Mantid::CurveFitting;
using namespace Mantid::API;

class PoldiCalibrationProfileTest : public CxxTest::TestSuite {
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static PoldiCalibrationProfileTest *createSuite() {
return new PoldiCalibrationProfileTest();
}
static void destroySuite(PoldiCalibrationProfileTest *suite) { delete suite; }

void testParameters() {
PoldiCalibrationProfile fn;
fn.initialize();

Gaussian gaussian;
gaussian.initialize();

TS_ASSERT_EQUALS(fn.nParams(), gaussian.nParams() + 1);
}

void testDerivatives() {
PoldiCalibrationProfile fn;
fn.initialize();

fn.setParameter("Height", 2.0);
fn.setParameter("PeakCentre", 1.1);
fn.setParameter("Sigma", 0.01);
fn.setParameter("Slope", 0.001);
fn.setAttribute("DeltaTheta", IFunction::Attribute(0.01));


}
};

#endif /* MANTID_CURVEFITTING_POLDICALIBRATIONFUNCTIONTEST_H_ */
Expand Up @@ -43,7 +43,9 @@ class MANTID_SINQ_DLL PoldiSpectrumCalibrationFunction
}

protected:
virtual getPeakCenter(const Poldi2DHelper_sptr &poldi2DHelper) const;
void init();

void functionModificationHook(const Poldi2DHelper_sptr &poldi2DHelper) const;
};

} // namespace Poldi
Expand Down
Expand Up @@ -42,7 +42,7 @@ struct MANTID_SINQ_DLL Poldi2DHelper {
/// Default constructor
Poldi2DHelper()
: dFractionalOffsets(), dOffsets(), domain(), values(), factors(),
deltaD(), deltaTwoTheta(), minTOFN() {}
deltaD(), deltaTwoTheta(), tofFactor(), minTOFN() {}

/// Transforms the chopper slit offsets for a given 2theta/distance pair.
void setChopperSlitOffsets(double distance, double sinTheta, double deltaD,
Expand Down Expand Up @@ -96,6 +96,7 @@ struct MANTID_SINQ_DLL Poldi2DHelper {

double deltaD;
double deltaTwoTheta;
double tofFactor;
int minTOFN;
};

Expand Down Expand Up @@ -260,7 +261,8 @@ class MANTID_SINQ_DLL PoldiSpectrumDomainFunction
protected:
virtual void init();

virtual double getPeakCenter(const Poldi2DHelper_sptr &poldi2DHelper) const;
virtual void
functionModificationHook(const Poldi2DHelper_sptr &poldi2DHelper) const;

void initializeParametersFromWorkspace(
const DataObjects::Workspace2D_const_sptr &workspace2D);
Expand Down
20 changes: 16 additions & 4 deletions Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp
Expand Up @@ -463,14 +463,14 @@ Poldi2DFunction_sptr PoldiFitPeaks2D::getFunctionIndividualPeaks(
boost::shared_ptr<PoldiSpectrumDomainFunction> peakFunction =
boost::dynamic_pointer_cast<PoldiSpectrumDomainFunction>(
FunctionFactory::Instance().createFunction(
"PoldiSpectrumDomainFunction"));
"PoldiSpectrumCalibrationFunction"));

if (!peakFunction) {
throw std::invalid_argument(
"Cannot process null pointer poldi function.");
}

peakFunction->setDecoratedFunction(profileFunctionName);
//peakFunction->setDecoratedFunction(profileFunctionName);

IPeakFunction_sptr wrappedProfile =
boost::dynamic_pointer_cast<IPeakFunction>(
Expand All @@ -483,6 +483,12 @@ Poldi2DFunction_sptr PoldiFitPeaks2D::getFunctionIndividualPeaks(
}

mdFunction->addFunction(peakFunction);

if (i > 0) {
std::string paramName =
"f" + boost::lexical_cast<std::string>(i) + ".Slope";
mdFunction->tie(paramName, paramName + "=f0.Slope");
}
}

return mdFunction;
Expand Down Expand Up @@ -1166,15 +1172,21 @@ void PoldiFitPeaks2D::exec() {
// The FitFunction is used to generate...
IFunction_sptr fitFunction = getFunction(fitAlgorithm);

for (size_t i = 0; i < fitFunction->nParams(); ++i) {
std::cout << i << " " << fitFunction->parameterName(i) << " "
<< fitFunction->getParameter(i) << " " << fitFunction->getError(i)
<< std::endl;
}

// ...a calculated 1D-spectrum...
MatrixWorkspace_sptr outWs1D = get1DSpectrum(fitFunction, ws);

// ...a vector of peak collections.
std::vector<PoldiPeakCollection_sptr> integralPeaks =
getCountPeakCollections(fitFunction);

for(size_t i = 0; i < peakCollections.size(); ++i) {
assignMillerIndices(peakCollections[i], integralPeaks[i]);
for (size_t i = 0; i < peakCollections.size(); ++i) {
assignMillerIndices(peakCollections[i], integralPeaks[i]);
}

// Get the calculated 2D workspace
Expand Down
@@ -1,21 +1,25 @@
#include "MantidSINQ/PoldiUtilities/PoldiSpectrumCalibrationFunction.h"
#include "MantidAPI/FunctionFactory.h"

namespace Mantid
{
namespace Poldi
{
namespace Mantid {
namespace Poldi {

PoldiSpectrumCalibrationFunction::PoldiSpectrumCalibrationFunction() :
PoldiSpectrumDomainFunction()
{
using namespace API;

}
DECLARE_FUNCTION(PoldiSpectrumCalibrationFunction)

PoldiSpectrumCalibrationFunction::getPeakCenter(const Poldi2DHelper_sptr &poldi2DHelper) const
{
PoldiSpectrumCalibrationFunction::PoldiSpectrumCalibrationFunction()
: PoldiSpectrumDomainFunction() {}

void PoldiSpectrumCalibrationFunction::init() {
setDecoratedFunction("PoldiCalibrationProfile");
}

void PoldiSpectrumCalibrationFunction::functionModificationHook(
const Poldi2DHelper_sptr &poldi2DHelper) const {
m_profileFunction->setAttribute(
"DeltaTheta", IFunction::Attribute(poldi2DHelper->deltaTwoTheta / 2.0));
}

} // namespace Poldi
} // namespace Mantid
Expand Up @@ -60,10 +60,12 @@ void PoldiSpectrumDomainFunction::function1DSpectrum(
Poldi2DHelper_sptr helper = m_2dHelpers[index];

if (helper) {
functionModificationHook(helper);

int domainSize = static_cast<int>(domain.size());

double fwhm = m_profileFunction->fwhm();
double centre = getPeakCenter(helper);
double centre = m_profileFunction->centre();

double dWidth = 2.0 * fwhm;
double dCalcMin = centre - dWidth;
Expand Down Expand Up @@ -116,10 +118,12 @@ void PoldiSpectrumDomainFunction::functionDeriv1DSpectrum(
Poldi2DHelper_sptr helper = m_2dHelpers[index];

if (helper) {
functionModificationHook(helper);

size_t domainSize = domain.size();

double fwhm = m_profileFunction->fwhm();
double centre = getPeakCenter(helper);
double centre = m_profileFunction->centre();

double dWidth = 2.0 * fwhm;
double dCalcMin = centre - dWidth;
Expand Down Expand Up @@ -185,11 +189,9 @@ IPeakFunction_sptr PoldiSpectrumDomainFunction::getProfileFunction() const {
/// Does nothing.
void PoldiSpectrumDomainFunction::init() {}

/// Returns the centre parameter of the decorated profile function.
double PoldiSpectrumDomainFunction::getPeakCenter(
void PoldiSpectrumDomainFunction::functionModificationHook(
const Poldi2DHelper_sptr &poldi2DHelper) const {
UNUSED_ARG(poldi2DHelper)
return m_profileFunction->centre();
UNUSED_ARG(poldi2DHelper)
}

/**
Expand Down

0 comments on commit f49bebf

Please sign in to comment.