Skip to content

Commit

Permalink
Refs #11887. Add option to tie parameters to PoldiFitPeaks2D
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Wedel committed Jun 3, 2015
1 parent 59a7491 commit 91c8ead
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h
Expand Up @@ -109,6 +109,8 @@ class MANTID_SINQ_DLL PoldiFitPeaks2D : public API::Algorithm {
const std::string &crystalSystem,
const PoldiPeakCollection_sptr &peakCollection);

std::string getUserSpecifiedTies(const API::IFunction_sptr &poldiFn);

PoldiPeakCollection_sptr
getPeakCollectionFromFunction(const API::IFunction_sptr &fitFunction);

Expand Down
70 changes: 68 additions & 2 deletions Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp
Expand Up @@ -616,6 +616,63 @@ std::string PoldiFitPeaks2D::getRefinedStartingCell(
return Geometry::unitCellToStr(refinedCell);
}

/**
* @brief Returns a string with ties that is passed to Fit
*
* This method uses the GlobalParameters property, which may contain a comma-
* separated list of parameter names that should be the same for all peaks.
*
* Parameters that do not exist are silently ignored, but a warning is written
* to the log so that users have a chance to find typos.
*
* @param poldiFn :: Function with some parameters.
* @return :: String to pass to the Ties-property of Fit.
*/
std::string
PoldiFitPeaks2D::getUserSpecifiedTies(const IFunction_sptr &poldiFn) {
std::string tieParameterList = getProperty("GlobalParameters");

if (!tieParameterList.empty()) {
std::vector<std::string> tieParameters;

boost::split(tieParameters, tieParameterList, boost::is_any_of(",;"));

std::vector<std::string> parameters = poldiFn->getParameterNames();

std::vector<std::string> tieComponents;
for (auto it = tieParameters.begin(); it != tieParameters.end(); ++it) {
if (!(*it).empty()) {
std::vector<std::string> matchedParameters;

for (auto parName = parameters.begin(); parName != parameters.end();
++parName) {
if (boost::algorithm::ends_with(*parName, *it)) {
matchedParameters.push_back(*parName);
}
}

if (matchedParameters.size() > 1) {
std::string reference = matchedParameters.front();

for (auto par = matchedParameters.begin() + 1;
par != matchedParameters.end(); ++par) {
tieComponents.push_back(*par + "=" + reference);
}
} else {
g_log.warning("Function does not have a parameter called '" + *it +
"', ignoring.");
}
}
}

if (tieComponents.size() > 0) {
return boost::algorithm::join(tieComponents, ",");
}
}

return "";
}

/**
* Construct a PoldiPeakCollection from a Poldi2DFunction
*
Expand Down Expand Up @@ -892,6 +949,10 @@ IAlgorithm_sptr PoldiFitPeaks2D::calculateSpectrum(
mdFunction->addFunction(getFunctionFromPeakCollection(*pc));
}

std::string ties = getUserSpecifiedTies(mdFunction);

std::cout << ties << std::endl;

// And finally background terms
addBackgroundTerms(mdFunction);

Expand All @@ -910,6 +971,7 @@ IAlgorithm_sptr PoldiFitPeaks2D::calculateSpectrum(
fit->setProperty("MaxIterations", maxIterations);

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

// Setting the level to Notice to avoid problems with Levenberg-MarquardtMD.
int oldLogLevel = g_log.getLevel();
Expand Down Expand Up @@ -1100,6 +1162,10 @@ void PoldiFitPeaks2D::init() {
"Profile function to use for integrating the peak profiles "
"before calculating the spectrum.");

declareProperty("GlobalParameters", "", "Comma-separated list of parameter "
"names that are identical for all "
"peaks.");

declareProperty("PawleyFit", false,
"Instead of refining individual peaks, "
"refine a unit cell. Peaks must be "
Expand Down Expand Up @@ -1173,8 +1239,8 @@ void PoldiFitPeaks2D::exec() {
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
43 changes: 43 additions & 0 deletions Code/Mantid/Framework/SINQ/test/PoldiFitPeaks2DTest.h
Expand Up @@ -225,6 +225,49 @@ class PoldiFitPeaks2DTest : public CxxTest::TestSuite
}
}

void testGetUserDefinedTies()
{
TestablePoldiFitPeaks2D spectrumCalculator;
spectrumCalculator.initialize();
spectrumCalculator.setProperty("PeakProfileFunction", "Gaussian");

// Create a function with some peaks
PoldiPeakCollection_sptr peaks = PoldiPeakCollectionHelpers::createPoldiPeakCollectionNormalized();
boost::shared_ptr<Poldi2DFunction> poldi2DFunction = spectrumCalculator.getFunctionFromPeakCollection(peaks);

// Make "Height" global, i.e. the same for all peaks
spectrumCalculator.setProperty("GlobalParameters", "Height");
std::string ties = spectrumCalculator.getUserSpecifiedTies(poldi2DFunction);
TS_ASSERT_EQUALS(ties, "f1.Height=f0.Height,f2.Height=f0.Height,f3.Height=f0.Height");

// Height and Sigma
spectrumCalculator.setProperty("GlobalParameters", "Height,Sigma");
ties = spectrumCalculator.getUserSpecifiedTies(poldi2DFunction);

TS_ASSERT_EQUALS(ties, "f1.Height=f0.Height,f2.Height=f0.Height,f3.Height=f0.Height,"
"f1.Sigma=f0.Sigma,f2.Sigma=f0.Sigma,f3.Sigma=f0.Sigma");

// Empty
spectrumCalculator.setProperty("GlobalParameters", "");
ties = spectrumCalculator.getUserSpecifiedTies(poldi2DFunction);
TS_ASSERT(ties.empty());

// Invalid name
spectrumCalculator.setProperty("GlobalParameters", "Invalid");
ties = spectrumCalculator.getUserSpecifiedTies(poldi2DFunction);
TS_ASSERT(ties.empty());

// Valid and invalid
spectrumCalculator.setProperty("GlobalParameters", "Height,Invalid");
ties = spectrumCalculator.getUserSpecifiedTies(poldi2DFunction);
TS_ASSERT_EQUALS(ties, "f1.Height=f0.Height,f2.Height=f0.Height,f3.Height=f0.Height");

// Several empty
spectrumCalculator.setProperty("GlobalParameters", ",,,,");
ties = spectrumCalculator.getUserSpecifiedTies(poldi2DFunction);
TS_ASSERT(ties.empty());
}

void testGetPeakCollectionFromFunction()
{
TestablePoldiFitPeaks2D spectrumCalculator;
Expand Down

0 comments on commit 91c8ead

Please sign in to comment.