Skip to content

Commit

Permalink
Start to integrate background. Refs #5306.
Browse files Browse the repository at this point in the history
  • Loading branch information
wdzhou committed Aug 10, 2012
1 parent 1afbbed commit 62f037a
Show file tree
Hide file tree
Showing 2 changed files with 241 additions and 14 deletions.
62 changes: 52 additions & 10 deletions Code/Mantid/Framework/CurveFitting/src/LeBailFit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1041,20 +1041,61 @@ void LeBailFit::generateBackgroundFunction(std::string backgroundtype, std::vect
*/
void LeBailFit::parseBackgroundTableWorkspace(DataObjects::TableWorkspace_sptr bkgdparamws, std::vector<double>& bkgdorderparams)
{
// 1. Clear
// 1. Clear (output) map
bkgdorderparams.clear();
std::map<std::string, double> parmap;

// 2. Read background
std::string a("A0");
std::string b("A1");
int smaller = a.compare(b);
int larger = b.compare(a);
std::cout << smaller << ", " << larger << std::endl;
// 2. Check
std::vector<std::string> colnames = bkgdparamws->getColumnNames();
if (colnames.size() < 2)
{
g_log.error() << "Input parameter table workspace must have more than 1 columns" << std::endl;
throw std::invalid_argument("Invalid input background table workspace. ");
}
else
{
if (!(boost::starts_with(colnames[0], "Name") && boost::starts_with(colnames[1], "Value")))
{
// Column 0 and 1 must be Name and Value (at least started with)
g_log.error() << "Input parameter table workspace have wrong column definition." << std::endl;
for (size_t i = 0; i < 2; ++i)
g_log.error() << "Column " << i << " Should Be Name. But Input is " << colnames[0] << std::endl;
throw std::invalid_argument("Invalid input background table workspace. ");
}
}

// 3. Input
for (size_t ir = 0; ir < bkgdparamws->rowCount(); ++ir)
{
API::TableRow row = bkgdparamws->getRow(ir);
std::string parname;
double parvalue;
row >> parname >> parvalue;

size_t order = bkgdparamws->rowCount();
bkgdorderparams.reserve(order);
if (parname.size() > 0 && parname[0] == 'A')
{
// Insert parameter name starting with A
parmap.insert(std::make_pair(parname, parvalue));
}
}

throw std::runtime_error("To be implemented ASAP!");
// 4. Sort: increasing order
bkgdorderparams.reserve(parmap.size());
for (size_t i = 0; i < parmap.size(); ++i)
{
bkgdorderparams.push_back(0.0);
}

std::map<std::string, double>::iterator mit;
for (mit = parmap.begin(); mit != parmap.end(); ++mit)
{
std::string parname = mit->first;
double parvalue = mit->second;
std::vector<std::string> terms;
boost::split(terms, parname, boost::is_any_of("A"));
int tmporder = atoi(terms[1].c_str());
bkgdorderparams[tmporder] = parvalue;
}

return;
}
Expand All @@ -1072,6 +1113,7 @@ void LeBailFit::importParametersTable()
<< " Number of columns = " << colnames.size() << " < 3 as required. " << std::endl;
throw std::runtime_error("Input parameter workspace is wrong. ");
}

if (colnames[0].compare("Name") != 0 ||
colnames[1].compare("Value") != 0 ||
colnames[2].compare("FitOrTie") != 0)
Expand Down
193 changes: 189 additions & 4 deletions Code/Mantid/Framework/CurveFitting/test/LeBailFitTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

#include "MantidCurveFitting/LeBailFit.h"

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>

using namespace Mantid;
using namespace Mantid::CurveFitting;
using namespace Mantid::API;
Expand All @@ -33,7 +36,7 @@ class LeBailFitTest : public CxxTest::TestSuite
* Fundamental test to calcualte 2 peak w/o background.
* It is migrated from LeBailFunctionTest.test_CalculatePeakParameters
*/
void Ptest_cal2Peaks()
void test_cal2Peaks()
{
// 1. Create input workspace
API::MatrixWorkspace_sptr dataws;
Expand Down Expand Up @@ -112,7 +115,7 @@ class LeBailFitTest : public CxxTest::TestSuite
/*
* Test on peak calcualtion with non-trivial background
*/
void test_cal2PeaksWithBackground()
void Ptest_cal2PeaksWithBackground()
{
// 1. Create input workspace
API::MatrixWorkspace_sptr dataws;
Expand Down Expand Up @@ -393,6 +396,118 @@ class LeBailFitTest : public CxxTest::TestSuite
}


/*
* Test a complete LeBail Fit process with background
* Using Run 4862 Bank 7 as the testing data
*/
void Diabletest_CompleteLeBailFit_PG3Bank7()
{
// 1. Create input workspace
API::MatrixWorkspace_sptr dataws;
DataObjects::TableWorkspace_sptr parameterws;
DataObjects::TableWorkspace_sptr hklws;
DataObjects::TableWorkspace_sptr bkgdws;

// a) Reflections
std::vector<std::vector<int> > hkls;
importReflectionTxtFile("/home/wzz/Mantid/Code/debug/MyTestData/pg3_4862bank7_reflection.txt", hkls);
size_t numpeaks = hkls.size();
std::cout << "TestXXX Number of peaks = " << hkls.size() << std::endl;

// b) data
dataws = createInputDataWorkspace(4);
std::cout << "Data Workspace Range: " << dataws->readX(0)[0] << ", " << dataws->readX(0).back() << std::endl;

// c) Workspaces
std::vector<double> pkheights(numpeaks, 1.0);
parameterws = createPeakParameterWorkspace();
hklws = createReflectionWorkspace(hkls, pkheights);
std::cout << "ReflectionWorkspace is created. " << std::endl;

bkgdws = createBackgroundParameterWorksapce("/home/wzz/Mantid/Code/debug/MyTestData/pg3_4862bank7_background.dat");
std::cout << "Background Parameters TableWorkspace is created. " << std::endl;

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

std::vector<double> fitregion;
fitregion.push_back(56198.0);
fitregion.push_back(151239.0);

// 3. Genearte LeBailFit algorithm and set it up
LeBailFit lbfit;
lbfit.initialize();

lbfit.setPropertyValue("InputWorkspace", "Data");
lbfit.setPropertyValue("ParametersWorkspace", "PeakParameters");
lbfit.setPropertyValue("ReflectionsWorkspace", "Reflections");
lbfit.setProperty("WorkspaceIndex", 0);
lbfit.setProperty("FitRegion", fitregion);
lbfit.setProperty("Function", "LeBailFit");
lbfit.setProperty("BackgroundType", "Polynomial");
lbfit.setPropertyValue("BackgroundParametersWorkspace", "BackgroundParameters");
lbfit.setProperty("OutputWorkspace", "FittedData");
lbfit.setProperty("PeaksWorkspace", "FittedPeaks");
lbfit.setProperty("PeakRadius", 8);

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

// a) Internal method test
// i) Read Background Parameter TableWorkspace
// ii) Proposed Peaks' Heights
// iii) Compare the cal

// Take output peak parameters
throw std::runtime_error("Do know how to implement");

// Take the output data
DataObjects::Workspace2D_sptr outws =
boost::dynamic_pointer_cast<DataObjects::Workspace2D>
(AnalysisDataService::Instance().retrieve("FittedData"));
TS_ASSERT(outws);

DataObjects::TableWorkspace_sptr paramws =
boost::dynamic_pointer_cast<DataObjects::TableWorkspace>
(AnalysisDataService::Instance().retrieve("PeakParameters"));
TS_ASSERT(paramws);
if (!paramws)
{
return;
}

TS_ASSERT_EQUALS(paramws->columnCount(), 3);
std::map<std::string, double> paramvalues;
std::map<std::string, char> paramfitstatus;
parseParameterTableWorkspace(paramws, paramvalues, paramfitstatus);

std::string testplan("zero");
if (testplan.compare("zero") == 0)
{
double zero = paramvalues["Zero"];
TS_ASSERT_DELTA(zero, 0.0, 0.5);
}
else if (testplan.compare("alpha") == 0)
{
double alph0 = paramvalues["Alph0"];
TS_ASSERT_DELTA(alph0, 4.026, 1.00);
}
else if (testplan.compare("sigma") == 0)
{
double sig0 = paramvalues["Sig0"];
TS_ASSERT_DELTA(sig0, 17.37, 0.01);
double sig1 = paramvalues["Sig1"];
TS_ASSERT_DELTA(sig1, 9.901, 0.01);
}



}


/*
* Fit 2 (separate) peaks
*/
Expand Down Expand Up @@ -922,9 +1037,14 @@ class LeBailFitTest : public CxxTest::TestSuite
importDataFromColumnFile("/home/wzz/Mantid/Code/debug/unittest_multigroups.dat", vecX, vecY, vecE);
break;

case 4:
importDataFromColumnFile("/home/wzz/Mantid/Code/debug/MyTestData/4862b7.inp", vecX, vecY, vecE);
std::cout << "Option 4: Vector Size = " << vecX.size() << std::endl;
break;

default:
// not supported
std::cout << "LeBailFitTest.createInputDataWorkspace() Option " << option << "is not supported. " << std::endl;
std::cout << "LeBailFitTest.createInputDataWorkspace() Option " << option << " is not supported. " << std::endl;
throw std::invalid_argument("Unsupported option. ");
}

Expand Down Expand Up @@ -1144,7 +1264,7 @@ class LeBailFitTest : public CxxTest::TestSuite
}
else
{
std::cout << "File " << filename << " is opened." << std::endl;
std::cout << "File " << filename << " is opened for parsing." << std::endl;
}
char line[256];
while(ins.getline(line, 256))
Expand All @@ -1163,6 +1283,8 @@ class LeBailFitTest : public CxxTest::TestSuite
}
}

ins.close();

return;
}

Expand All @@ -1173,6 +1295,17 @@ class LeBailFitTest : public CxxTest::TestSuite
{
std::ifstream ins;
ins.open(filename.c_str());

if (!ins.is_open())
{
std::cout << "Data file " << filename << " cannot be opened. " << std::endl;
throw std::invalid_argument("Unable to open data fiile. ");
}
else
{
std::cout << "Data file " << filename << " is opened for parsing. " << std::endl;
}

char line[256];
// std::cout << "File " << filename << " isOpen = " << ins.is_open() << std::endl;
while(ins.getline(line, 256))
Expand Down Expand Up @@ -1229,6 +1362,58 @@ class LeBailFitTest : public CxxTest::TestSuite
return;
}

/*
* Create a table worskpace for background parameters
* Format:
* parameter name1, parameter Value1
* parameter name2, parameter value2
*/
DataObjects::TableWorkspace_sptr createBackgroundParameterWorksapce(std::string filename)
{
// 1. Open file
std::ifstream ins;
ins.open(filename.c_str());
if (!ins.is_open())
{
std::cout << "File " << filename << " cannot be opened. " << std::endl;
throw std::invalid_argument("Unable to open input background parameter file. ");
}

// 2. Parse
DataObjects::TableWorkspace* tablewsptr = new DataObjects::TableWorkspace();
DataObjects::TableWorkspace_sptr tablews(tablewsptr);

tablews->addColumn("str", "Name");
tablews->addColumn("double", "Value");

char line[256];
while(ins.getline(line, 256))
{
std::string theline(line);
std::vector<std::string> terms;
boost::split(terms, theline, boost::is_any_of(","));

if (terms.size() < 2)
{
std::cout << theline << " --- Not a good line" << std::endl;
continue;
}

std::string parname = terms[0];
boost::algorithm::trim(parname);
std::string parvaluestr = terms[1];
boost::algorithm::trim(parvaluestr);
double parvalue = atof( parvaluestr.c_str() );
API::TableRow newrow = tablews->appendRow();
newrow << parname << parvalue;
std::cout << parname << " : " << parvalue << std::endl;
}

ins.close();

return tablews;
}

};


Expand Down

0 comments on commit 62f037a

Please sign in to comment.