Skip to content

Commit

Permalink
Add background option to LeBailFit. Refs #5306.
Browse files Browse the repository at this point in the history
  • Loading branch information
wdzhou committed Aug 10, 2012
1 parent b62568c commit 0d95e87
Show file tree
Hide file tree
Showing 7 changed files with 240 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidCurveFitting/ThermalNeutronBk2BkExpConvPV.h"
#include "MantidAPI/CompositeFunction.h"
#include "MantidCurveFitting/BackgroundFunction.h"


using namespace Mantid;
Expand Down Expand Up @@ -138,6 +139,8 @@ namespace CurveFitting
std::map<int, double> mPeakHeights;
std::map<int, CurveFitting::ThermalNeutronBk2BkExpConvPV_sptr> mPeaks;

CurveFitting::BackgroundFunction_sptr mBackgroundFunction;

API::CompositeFunction_sptr mLeBailFunction;
std::map<std::string, std::pair<double, char> > mFuncParameters; // char = f: fit... = t: tie to value

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ class DLLExport ThermalNeutronBk2BkExpConvPV : virtual public API::IPeakFunction
/// Get Miller Index from this peak
void getMillerIndex(int& h, int &k, int &l);

/// Get peak parameters
double getPeakParameters(std::string);

protected:

virtual void functionLocal(double* out, const double* xValues, const size_t nData)const;
Expand Down Expand Up @@ -104,6 +107,8 @@ class DLLExport ThermalNeutronBk2BkExpConvPV : virtual public API::IPeakFunction
int mL;

bool mHKLSet;

mutable std::map<std::string, double> mParameters;

};

Expand Down
40 changes: 17 additions & 23 deletions Code/Mantid/Framework/CurveFitting/src/LeBailFit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ void LeBailFit::exec()
g_log.debug() << "DB1113: Input Data(Workspace) Range: " << dataWS->dataX(workspaceindex)[0] << ", "
<< dataWS->dataX(workspaceindex).back() << std::endl;

// 2. Determine Function
// 2. Determine Functionality
std::string function = this->getProperty("Function");
int functionmode = 0; // calculation
if (function.compare("Calculation") == 0)
Expand Down Expand Up @@ -187,7 +187,9 @@ void LeBailFit::exec()
{
mLeBailFunction->addFunction(mit->second);
}
std::cout << "LeBail Composite Function: " << mLeBailFunction->asString() << std::endl;
mLeBailFunction->addFunction(mBackgroundFunction);

g_log.information() << "LeBail Composite Function: " << mLeBailFunction->asString() << std::endl;

// 5. Create output workspace
size_t nspec = 1;
Expand Down Expand Up @@ -428,6 +430,13 @@ bool LeBailFit::unitLeBailFit(size_t workspaceindex, std::map<std::string, std::
// 4. Construct the Fit
double tof_min = dataWS->dataX(workspaceindex)[0];
double tof_max = dataWS->dataX(workspaceindex).back();
std::vector<double> fitrange = this->getProperty("FitRegion");
if (fitrange.size() == 2 && fitrange[0] < fitrange[1])
{
// Properly defined
tof_min = fitrange[0];
tof_max = fitrange[1];
}

// a) Initialize
API::IAlgorithm_sptr fitalg = this->createSubAlgorithm("Fit", 0.0, 0.2, true);
Expand Down Expand Up @@ -963,25 +972,6 @@ void LeBailFit::setPeakParameters(

peak->setParameter(parname, value);

/* Tie will be handled at in unitLeBailFit()
if (fitortie == 'f')
{
// Case of "Fit": do nothing
;
}
else if (fitortie == 't')
{
// Case of "Tie": say tie to the value
std::stringstream ss;
ss << value;
peak->tie(parname, ss.str());
}
else
{
g_log.error() << "Peak parameter " << parname << ": fit/tie bit = " << fitortie << " is not allowed. " << std::endl;
throw std::invalid_argument("Only f and t are supported as for fit or tie.");
}
*/
} // ENDFOR: parameter iterator

// 3. Peak height
Expand Down Expand Up @@ -1021,13 +1011,17 @@ void LeBailFit::generatePeaksFromInput()
void LeBailFit::generateBackgroundFunction(std::string backgroundtype, std::vector<double> bkgdparamws)
{
auto background = API::FunctionFactory::Instance().createFunction(backgroundtype);
CurveFitting::BackgroundFunction_sptr mBackgroundFunction = boost::dynamic_pointer_cast<CurveFitting::BackgroundFunction>(background);
mBackgroundFunction = boost::dynamic_pointer_cast<CurveFitting::BackgroundFunction>(background);

// CurveFitting::BackgroundFunction_sptr mBackgroundFunction = boost::make_shared<CurveFitting::BackgroundFunction>(background);
// boost::dynamic_pointer_cast<CurveFitting::BackgroundFunction>(
// boost::make_shared<(background));
size_t order = bkgdparamws.size();
mBackgroundFunction->setAttributeValue("order", int(order));
std::cout << "----------- polynomial order = " << order << std::endl;

mBackgroundFunction->setAttributeValue("n", int(order));
mBackgroundFunction->initialize();

for (size_t i = 0; i < order; ++i)
{
std::stringstream ss;
Expand Down
2 changes: 1 addition & 1 deletion Code/Mantid/Framework/CurveFitting/src/Polynomial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ void Polynomial::setAttribute(const std::string& attName,const API::IFunction::A
{
throw std::invalid_argument("Polynomial: polynomial order cannot be negative.");
}
for(int i=0;i<=m_n;++i)
for(int i=0; i<=m_n; ++i)
{
std::string parName = "A" + boost::lexical_cast<std::string>(i);
declareParameter(parName);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "MantidCurveFitting/ThermalNeutronBk2BkExpConvPV.h"
#include "MantidAPI/FunctionFactory.h"
#include "MantidKernel/EmptyValues.h"
#include <gsl/gsl_sf_erf.h>

#define PI 3.14159265358979323846264338327950288419716939937510582
Expand Down Expand Up @@ -69,6 +70,13 @@ void ThermalNeutronBk2BkExpConvPV::init()
/// Lattice parameter
declareParameter("LatticeConstant", 10.0);

/// Initialize parameters
mParameters.insert(std::make_pair("Alpha", 1.0));
mParameters.insert(std::make_pair("Beta", 1.0));
mParameters.insert(std::make_pair("Gamma", 1.0));
mParameters.insert(std::make_pair("Sigma2", 1.0));
mParameters.insert(std::make_pair("FWHM", 1.0));

return;
}

Expand Down Expand Up @@ -181,6 +189,13 @@ void ThermalNeutronBk2BkExpConvPV::functionLocal(double* out, const double* xVal
out[id] = height*omega;
}

// 5. Record recent value
mParameters["Alpha"] = alpha;
mParameters["Beta"] = beta;
mParameters["Sigma2"] = sigma2;
mParameters["Gamma"] = gamma;
mParameters["FWHM"] = H;

return;
}

Expand Down Expand Up @@ -384,5 +399,26 @@ std::complex<double> ThermalNeutronBk2BkExpConvPV::E1(std::complex<double> z) co
return z;
}

/*
* Get peak parameters stored locally
*/
double ThermalNeutronBk2BkExpConvPV::getPeakParameters(std::string paramname)
{
std::map<std::string, double>::iterator mit;
mit = mParameters.find(paramname);
double paramvalue;
if (mit == mParameters.end())
{
g_log.error() << "Parameter " << paramname << " does not exist in peak profile. " << std::endl;
paramvalue = Mantid::EMPTY_DBL();
}
else
{
paramvalue = mit->second;
}

return paramvalue;
}

} // namespace CurveFitting
} // namespace Mantid
79 changes: 78 additions & 1 deletion Code/Mantid/Framework/CurveFitting/test/LeBailFitTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,83 @@ class LeBailFitTest : public CxxTest::TestSuite
return;
}


/*
* Test on peak calcualtion with non-trivial background
*/
void test_cal2PeaksWithBackground()
{
// 1. Create input workspace
API::MatrixWorkspace_sptr dataws;
DataObjects::TableWorkspace_sptr parameterws;
DataObjects::TableWorkspace_sptr hklws;

dataws = createInputDataWorkspace(1);
parameterws = createPeakParameterWorkspace();
// a) Add reflection (111) and (110)
double h110 = 660.0/0.0064;
double h111 = 1370.0/0.008;
std::vector<double> peakheights;
peakheights.push_back(h111); peakheights.push_back(h110);
std::vector<std::vector<int> > hkls;
std::vector<int> p111;
p111.push_back(1); p111.push_back(1); p111.push_back(1);
hkls.push_back(p111);
std::vector<int> p110;
p110.push_back(1); p110.push_back(1); p110.push_back(0);
hkls.push_back(p110);
hklws = createReflectionWorkspace(hkls, peakheights);

AnalysisDataService::Instance().addOrReplace("Data", dataws);
AnalysisDataService::Instance().addOrReplace("PeakParameters", parameterws);
AnalysisDataService::Instance().addOrReplace("Reflections", hklws);

// 2. Initialize the algorithm
LeBailFit lbfit;

TS_ASSERT_THROWS_NOTHING(lbfit.initialize());
TS_ASSERT(lbfit.isInitialized());

// 3. Set properties
lbfit.setPropertyValue("InputWorkspace", "Data");
lbfit.setPropertyValue("ParametersWorkspace", "PeakParameters");
lbfit.setPropertyValue("ReflectionsWorkspace", "Reflections");
lbfit.setProperty("WorkspaceIndex", 0);
lbfit.setProperty("BackgroundType", "Polynomial");
/// a second order polynomial background
lbfit.setPropertyValue("BackgroundParameters", "101.0, 0.001");
lbfit.setProperty("Function", "Calculation");
lbfit.setProperty("OutputWorkspace", "CalculatedPeaks");
lbfit.setProperty("PeaksWorkspace", "PeakParameterWS");
lbfit.setProperty("UseInputPeakHeights", true);
lbfit.setProperty("PeakRadius", 8);

// 4. Run
TS_ASSERT_THROWS_NOTHING(lbfit.execute());
TS_ASSERT(lbfit.isExecuted());

// 5. Get output & Test
DataObjects::Workspace2D_sptr outws = boost::dynamic_pointer_cast<DataObjects::Workspace2D>(
AnalysisDataService::Instance().retrieve("CalculatedPeaks"));
TS_ASSERT(outws);

for (size_t i = 0; i < outws->dataY(0).size(); ++i)
std::cout << outws->dataX(0)[i] << "\t\t" << outws->dataY(0)[i] << std::endl;


double bkgdx = outws->readX(0).back()*0.001 + 101.0;
TS_ASSERT_DELTA(outws->readY(0).back(), bkgdx, 1.0);

// 5. Clean
AnalysisDataService::Instance().remove("Data");
AnalysisDataService::Instance().remove("PeakParameters");
AnalysisDataService::Instance().remove("Reflections");
AnalysisDataService::Instance().remove("CalculatedPeaks");

return;
}


/*
* Unit test on figure out peak height
* The test data are of reflection (932) and (852) @ TOF = 12721.91 and 12790.13
Expand Down Expand Up @@ -462,7 +539,7 @@ class LeBailFitTest : public CxxTest::TestSuite
/*
* Fit 2 (overlapped) peaks
*/
void test_fitTwiPeaks()
void Ptest_fitTwiPeaks()
{
// 0. Test Plan
// std::string testplan("zero");
Expand Down

0 comments on commit 0d95e87

Please sign in to comment.