Commit a47a2d2f authored by Roman Tolchenov's avatar Roman Tolchenov
Browse files

Re #18312. Fix bugs and tests.

parent dd78d0ee
......@@ -564,10 +564,10 @@ protected:
void storeReadOnlyAttribute(const std::string &name,
const API::IFunction::Attribute &value) const;
/// Write the list of ties to a stream
void writeTies(std::ostringstream &ostr) const;
/// Write the list of constraints to a stream
void writeConstraints(std::ostringstream &ostr) const;
/// Write a parameter tie to a string
virtual std::string writeTie(size_t iParam) const;
/// Write a parameter constraint to a string
virtual std::string writeConstraint(size_t iParam) const;
friend class ParameterTie;
friend class CompositeFunction;
......
#include "MantidAPI/Axis.h"
#include "MantidAPI/IFunction.h"
#include "MantidAPI/Jacobian.h"
#include "MantidAPI/IConstraint.h"
#include "MantidAPI/ParameterTie.h"
#include "MantidAPI/Expression.h"
#include "MantidAPI/Axis.h"
#include "MantidAPI/ConstraintFactory.h"
#include "MantidAPI/Expression.h"
#include "MantidAPI/FunctionFactory.h"
#include "MantidAPI/IConstraint.h"
#include "MantidAPI/IFunctionWithLocation.h"
#include "MantidAPI/Jacobian.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/MultiDomainFunction.h"
#include "MantidAPI/IFunctionWithLocation.h"
#include "MantidAPI/ParameterTie.h"
#include "MantidGeometry/Instrument.h"
#include "MantidGeometry/Instrument/ParameterMap.h"
#include "MantidGeometry/Instrument/Component.h"
#include "MantidGeometry/Instrument/DetectorGroup.h"
#include "MantidGeometry/Instrument/FitParameter.h"
#include "MantidGeometry/Instrument/ParameterMap.h"
#include "MantidGeometry/muParser_Silent.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/IPropertyManager.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/UnitFactory.h"
#include "MantidKernel/MultiThreaded.h"
#include "MantidKernel/ProgressBase.h"
#include "MantidKernel/IPropertyManager.h"
#include "MantidKernel/Strings.h"
#include "MantidKernel/UnitFactory.h"
#include <boost/lexical_cast.hpp>
......@@ -111,7 +112,7 @@ ParameterTie *IFunction::tie(const std::string &parName,
const std::string &expr, bool isDefault) {
auto ti = new ParameterTie(this, parName, expr, isDefault);
this->fix(getParameterIndex(*ti));
if (ti->isConstant()) {
if (!isDefault && ti->isConstant()) {
setParameter(parName, ti->eval());
delete ti;
ti = nullptr;
......@@ -156,52 +157,34 @@ void IFunction::removeTie(const std::string &parName) {
this->removeTie(i);
}
/// Write the list of ties to a stream
void IFunction::writeTies(std::ostringstream &ostr) const {
// collect the non-default ties
std::string ties;
bool hasTies = false;
for (size_t i = 0; i < nParams(); i++) {
std::ostringstream tieStream;
const ParameterTie *tie = getTie(i);
if (tie && !tie->isDefault()) {
/// Write a parameter tie to a string
/// @param iParam :: An index of a parameter.
/// @return A tie string for the parameter.
std::string IFunction::writeTie(size_t iParam) const {
std::ostringstream tieStream;
const ParameterTie *tie = getTie(iParam);
if (tie) {
if (!tie->isDefault()) {
tieStream << tie->asString(this);
} else if (isFixed(i)) {
tieStream << parameterName(i) << "=" << getParameter(i);
}
if (!tieStream.str().empty()) {
if (!ties.empty()) {
ties += ",";
}
ties += tieStream.str();
}
} else if (isFixed(iParam)) {
tieStream << parameterName(iParam) << "=" << getParameter(iParam);
}
// print the ties
if (!ties.empty()) {
ostr << ",ties=(" << ties << ")";
}
return tieStream.str();
}
/// Write the list of constraints to a stream
void IFunction::writeConstraints(std::ostringstream &ostr) const {
// collect non-default constraints
std::string constraints;
for (size_t i = 0; i < nParams(); i++) {
const IConstraint *c = getConstraint(i);
if (c && !c->isDefault()) {
std::string tmp = c->asString();
if (!tmp.empty()) {
if (!constraints.empty()) {
constraints += ",";
}
constraints += tmp;
}
/// Write a parameter constraint to a string
/// @param iParam :: An index of a parameter.
/// @return A constraint string for the parameter.
std::string IFunction::writeConstraint(size_t iParam) const {
const IConstraint *c = getConstraint(iParam);
if (c && !c->isDefault()) {
std::string constraint = c->asString();
if (!constraint.empty()) {
return constraint;
}
}
// print constraints
if (!constraints.empty()) {
ostr << ",constraints=(" << constraints << ")";
}
return "";
}
/**
......@@ -223,12 +206,39 @@ std::string IFunction::asString() const {
// print the parameters
for (size_t i = 0; i < nParams(); i++) {
const ParameterTie *tie = getTie(i);
if (!isFixed(i) || (tie && tie->isDefault())) {
if (!isFixed(i)) {
ostr << ',' << parameterName(i) << '=' << getParameter(i);
}
}
writeConstraints(ostr);
writeTies(ostr);
// collect non-default constraints
std::vector<std::string> constraints;
for (size_t i = 0; i < nParams(); i++) {
auto constraint = writeConstraint(i);
if (!constraint.empty()) {
constraints.push_back(constraint);
}
}
// print constraints
if (!constraints.empty()) {
ostr << ",constraints=("
<< Kernel::Strings::join(constraints.begin(), constraints.end(), ",")
<< ")";
}
// collect the non-default ties
std::vector<std::string> ties;
for (size_t i = 0; i < nParams(); i++) {
auto tie = writeTie(i);
if (!tie.empty()) {
ties.push_back(tie);
}
}
// print the ties
if (!ties.empty()) {
ostr << ",ties=(" << Kernel::Strings::join(ties.begin(), ties.end(), ",")
<< ")";
}
return ostr.str();
}
......
......@@ -356,17 +356,17 @@ public:
TS_ASSERT_EQUALS(mfun->nParams(), 12);
TS_ASSERT_EQUALS(mfun->getParameter(0), 0.8);
TS_ASSERT_EQUALS(mfun->getParameter(0), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter(1), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter(2), 1.1);
TS_ASSERT_EQUALS(mfun->getParameter(3), 1.2);
TS_ASSERT_EQUALS(mfun->getParameter(4), 1.3);
TS_ASSERT_EQUALS(mfun->getParameter(4), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter(5), 2.1);
TS_ASSERT_EQUALS(mfun->getParameter(6), 2.2);
TS_ASSERT_EQUALS(mfun->getParameter(7), 2.3);
TS_ASSERT_EQUALS(mfun->getParameter(6), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter(7), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter(8), 2.4);
TS_ASSERT_EQUALS(mfun->getParameter(9), 3.1);
TS_ASSERT_EQUALS(mfun->getParameter(10), 3.2);
TS_ASSERT_EQUALS(mfun->getParameter(10), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter(11), 3.3);
TS_ASSERT_EQUALS(mfun->parameterName(0), "f0.a");
......@@ -382,17 +382,17 @@ public:
TS_ASSERT_EQUALS(mfun->parameterName(10), "f3.h");
TS_ASSERT_EQUALS(mfun->parameterName(11), "f3.s");
TS_ASSERT_EQUALS(mfun->getParameter("f0.a"), 0.8);
TS_ASSERT_EQUALS(mfun->getParameter("f0.a"), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter("f0.b"), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter("f1.c"), 1.1);
TS_ASSERT_EQUALS(mfun->getParameter("f1.h"), 1.2);
TS_ASSERT_EQUALS(mfun->getParameter("f1.s"), 1.3);
TS_ASSERT_EQUALS(mfun->getParameter("f1.s"), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter("f2.c0"), 2.1);
TS_ASSERT_EQUALS(mfun->getParameter("f2.c1"), 2.2);
TS_ASSERT_EQUALS(mfun->getParameter("f2.c2"), 2.3);
TS_ASSERT_EQUALS(mfun->getParameter("f2.c1"), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter("f2.c2"), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter("f2.c3"), 2.4);
TS_ASSERT_EQUALS(mfun->getParameter("f3.c"), 3.1);
TS_ASSERT_EQUALS(mfun->getParameter("f3.h"), 3.2);
TS_ASSERT_EQUALS(mfun->getParameter("f3.h"), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter("f3.s"), 3.3);
TS_ASSERT_EQUALS(mfun->parameterIndex("f0.a"), 0);
......@@ -461,17 +461,17 @@ public:
TS_ASSERT_EQUALS(mfun->nParams(), 12);
TS_ASSERT_EQUALS(mfun->getParameter(0), 0.8);
TS_ASSERT_EQUALS(mfun->getParameter(1), 0.0);
TS_ASSERT_EQUALS(mfun->getParameter(0), -1);
TS_ASSERT_EQUALS(mfun->getParameter(1), -2);
TS_ASSERT_EQUALS(mfun->getParameter(2), 100);
TS_ASSERT_EQUALS(mfun->getParameter(3), 101);
TS_ASSERT_EQUALS(mfun->getParameter(4), 1.3);
TS_ASSERT_EQUALS(mfun->getParameter(4), -3);
TS_ASSERT_EQUALS(mfun->getParameter(5), 102);
TS_ASSERT_EQUALS(mfun->getParameter(6), 2.2);
TS_ASSERT_EQUALS(mfun->getParameter(7), 2.3);
TS_ASSERT_EQUALS(mfun->getParameter(6), -4);
TS_ASSERT_EQUALS(mfun->getParameter(7), -5);
TS_ASSERT_EQUALS(mfun->getParameter(8), 103);
TS_ASSERT_EQUALS(mfun->getParameter(9), 104);
TS_ASSERT_EQUALS(mfun->getParameter(10), 3.2);
TS_ASSERT_EQUALS(mfun->getParameter(10), -6);
TS_ASSERT_EQUALS(mfun->getParameter(11), 105);
delete mfun;
......@@ -658,7 +658,7 @@ public:
TS_ASSERT_EQUALS(mfun->nParams(), 12);
TS_ASSERT_DIFFERS(mfun->getParameter(0), 154);
TS_ASSERT_EQUALS(mfun->getParameter(0), 154);
TS_ASSERT_EQUALS(mfun->getParameter(1), 77);
TS_ASSERT_EQUALS(mfun->getParameter(2), 1.1);
TS_ASSERT_EQUALS(mfun->getParameter(3), 1.2);
......
......@@ -255,7 +255,7 @@ public:
f.setParameter("c3", 1.3);
f.tie("c1", "0");
f.tie("c3", "0");
f.tie("c3", "c2");
TS_ASSERT_EQUALS(f.nParams(), 4);
......@@ -276,7 +276,7 @@ public:
TS_ASSERT(!f.isActive(3));
TS_ASSERT(!f.getTie(0));
TS_ASSERT(f.getTie(1) && !f.getTie(1)->isDefault());
TS_ASSERT(!f.getTie(1));
TS_ASSERT(!f.getTie(2));
TS_ASSERT(f.getTie(3) && !f.getTie(3)->isDefault());
}
......
......@@ -268,18 +268,6 @@ public:
TS_ASSERT_EQUALS(icf.getParameter(3), 2.0);
}
// BoundaryConstraint isn't defined (it's in CurveFitting) so this test
// doesn't work
void xtestConstraints() {
ImmutableCompositeFunctionTest_Function icf;
icf.addConstraints("0 < b1 < 5");
TS_ASSERT(!icf.getConstraint(0));
TS_ASSERT(!icf.getConstraint(1));
TS_ASSERT(icf.getConstraint(2));
TS_ASSERT(!icf.getConstraint(3));
}
void testAsString() {
ImmutableCompositeFunctionTest_Function icf;
......@@ -292,8 +280,7 @@ public:
icf.applyTies();
TS_ASSERT_EQUALS(icf.asString(), "name=ImmutableCompositeFunctionTest_"
"Function,NumDeriv=false,a1=11,b1=12,a2=2."
"2,b2=12,ties=(a2=a1/5,b2=b1)");
"Function,NumDeriv=false,a1=11,b1=12,ties=(a2=a1/5,b2=b1)");
auto fun = FunctionFactory::Instance().createInitialized(icf.asString());
TS_ASSERT(fun);
......
......@@ -444,8 +444,8 @@ public:
const std::string expected =
"composite=MultiDomainFunction,NumDeriv=true;"
"name=MultiDomainFunctionTest_Function,A=0,B=1,$domains=i;"
"name=MultiDomainFunctionTest_Function,A=0,B=2,$domains=i;"
"name=MultiDomainFunctionTest_Function,A=0,B=3,$domains=i;ties=(f1.A="
"name=MultiDomainFunctionTest_Function,B=2,$domains=i;"
"name=MultiDomainFunctionTest_Function,B=3,$domains=i;ties=(f1.A="
"f0.A,f2.A=f0.A)";
TS_ASSERT_EQUALS(multi.asString(), expected);
TS_ASSERT_EQUALS(multi.asString(), multi.clone()->asString());
......
......@@ -207,6 +207,9 @@ API::IFunction_sptr CrystalFieldMultiSpectrum::buildSpectrum(
auto background =
API::FunctionFactory::Instance().createInitialized(bkgdShape);
spectrum->addFunction(background);
if (fixAllPeaks) {
background->fixAll();
}
m_nPeaks[iSpec] = CrystalFieldUtils::buildSpectrumFunction(
*spectrum, peakShape, values, m_fwhmX[iSpec], m_fwhmY[iSpec],
......@@ -228,10 +231,15 @@ void CrystalFieldMultiSpectrum::updateTargetFunction() const {
auto &peakCalculator = dynamic_cast<Peaks &>(*m_source);
peakCalculator.calculateEigenSystem(en, wf, nre);
auto &fun = dynamic_cast<MultiDomainFunction &>(*m_target);
auto temperatures = getAttribute("Temperatures").asVector();
for (size_t i = 0; i < temperatures.size(); ++i) {
updateSpectrum(*fun.getFunction(i), nre, en, wf, temperatures[i], i);
auto &fun = dynamic_cast<MultiDomainFunction &>(*m_target);
try {
for (size_t i = 0; i < temperatures.size(); ++i) {
updateSpectrum(*fun.getFunction(i), nre, en, wf, temperatures[i], i);
}
} catch (std::out_of_range &) {
buildTargetFunction();
return;
}
}
......
......@@ -186,7 +186,7 @@ size_t updateSpectrumFunction(API::CompositeFunction &spectrum,
const std::vector<double> &yVec,
double fwhmVariation) {
size_t nGoodPeaks = calculateNPeaks(centresAndIntensities);
size_t maxNPeaks = spectrum.nFunctions() - iFirst;
size_t maxNPeaks = calculateMaxNPeaks(nGoodPeaks);
bool mustUpdateWidth = !xVec.empty();
for (size_t i = 0; i < maxNPeaks; ++i) {
......
......@@ -8,6 +8,7 @@
#include "MantidAPI/FunctionFactory.h"
#include "MantidAPI/ParameterTie.h"
#include "MantidCurveFitting/Constraints/BoundaryConstraint.h"
#include "MantidKernel/Strings.h"
#include <algorithm>
#include <iostream>
......@@ -116,11 +117,29 @@ std::string CrystalFieldSpectrum::asString() const {
}
}
// collect non-default constraints
std::vector<std::string> constraints;
for (size_t i = 0; i < m_nOwnParams; i++) {
auto constraint = writeConstraint(i);
if (!constraint.empty()) {
constraints.push_back(constraint);
}
}
// collect the non-default ties
std::vector<std::string> ties;
for (size_t i = 0; i < m_nOwnParams; i++) {
auto tie = writeTie(i);
if (!tie.empty()) {
ties.push_back(tie);
}
}
// Print parameters of the important peaks only
const CompositeFunction &spectrum =
dynamic_cast<const CompositeFunction &>(*m_target);
for (size_t ip = 0; ip < m_nPeaks; ++ip) {
const auto &peak = *spectrum.getFunction(ip);
const auto &peak = dynamic_cast<IPeakFunction &>(*spectrum.getFunction(ip));
// Print peak's atributes
auto attr = peak.getAttributeNames();
for (const auto &attName : attr) {
......@@ -136,11 +155,30 @@ std::string CrystalFieldSpectrum::asString() const {
ostr << ",f" << ip << "." << peak.parameterName(i) << '='
<< peak.getParameter(i);
}
auto constraint = writeConstraint(i);
if (!constraint.empty()) {
constraints.push_back(constraint);
}
auto tieStr = writeTie(i);
if (!tieStr.empty()) {
ties.push_back(tieStr);
}
}
} // for peaks
// print constraints
if (!constraints.empty()) {
ostr << ",constraints=("
<< Kernel::Strings::join(constraints.begin(), constraints.end(), ",")
<< ")";
}
// print the ties
if (!ties.empty()) {
ostr << ",ties=(" << Kernel::Strings::join(ties.begin(), ties.end(), ",")
<< ")";
}
writeConstraints(ostr);
writeTies(ostr);
return ostr.str();
}
......
......@@ -346,9 +346,9 @@ public:
mc->setRethrows(true);
mc->setPropertyValue(
"Function",
"name=CrystalFieldMultiSpectrum,Ion=Ce,"
"name=CrystalFieldMultiSpectrum,Ion=Ce,FixAllPeaks=1,"
"Symmetry=C2v,Temperatures=(44.0, 50.0),FWHMs=(1.0, 1.0),NPeaks=3,"
"constraints=(0<B20<2,1<B22<4,-0.1<B40<0.1,-0.1<B42<0.1,-0.1<B44<0.1)");
"constraints=(0<B20<0.5,3<B22<4,-0.1<B40<0.0,-0.1<B42<0.0,-0.1<B44<0.0)");
mc->setProperty("InputWorkspace", ws);
mc->setProperty("WorkspaceIndex", 0);
mc->setProperty("InputWorkspace_1", ws);
......
......@@ -180,22 +180,19 @@ public:
auto i = fun->parameterIndex("f2.FWHM");
auto tie = fun->getTie(i);
TS_ASSERT(tie);
if (tie) {
TS_ASSERT_EQUALS(tie->asString(), "f2.FWHM=2.1")
}
TS_ASSERT(!tie);
TS_ASSERT(fun->isFixed(i));
TS_ASSERT_EQUALS(fun->getParameter(i), 2.1);
i = fun->parameterIndex("B60");
tie = fun->getTie(i);
TS_ASSERT(tie);
if (tie) {
TS_ASSERT_EQUALS(tie->asString(), "B60=0")
}
TS_ASSERT(!tie);
TS_ASSERT(fun->isFixed(i));
TS_ASSERT_EQUALS(fun->getParameter(i), 0);
i = fun->parameterIndex("BmolY");
tie = fun->getTie(i);
TS_ASSERT(tie);
if (tie) {
TS_ASSERT_EQUALS(tie->asString(), "BmolY=0")
}
TS_ASSERT(!tie);
TS_ASSERT(fun->isFixed(i));
TS_ASSERT_EQUALS(fun->getParameter(i), 0);
size_t nTies = 0;
for (size_t i = 0; i < fun->nParams(); ++i) {
......@@ -204,7 +201,7 @@ public:
++nTies;
}
}
TS_ASSERT_EQUALS(nTies, 11);
TS_ASSERT_EQUALS(nTies, 0);
}
void test_constraints() {
......
......@@ -229,7 +229,7 @@ class CrystalField(object):
"""
out = ',ToleranceEnergy=%s,ToleranceIntensity=%s' % (self._toleranceEnergy, self._toleranceIntensity)
out += ',PeakShape=%s' % self.getPeak().name
out += ',FixAllPeaks=%s' % self._fixAllPeaks
out += ',FixAllPeaks=%s' % (1 if self._fixAllPeaks else 0)
if self.background is not None:
out += ',Background=%s' % self.background[0].nameString()
out += ',Temperatures=(%s)' % ','.join(map(str, self._temperature))
......@@ -849,7 +849,7 @@ class CrystalFieldMulti(object):
ties = self.getTies()
if len(ties) > 0:
fun += ';ties=(%s)' % ties
return fun
return 'composite=CompositeFunction,NumDeriv=1;' + fun
def makeMultiSpectrumFunction(self):
fun = ';'.join([a.makeMultiSpectrumFunction() for a in self.sites])
......@@ -857,7 +857,7 @@ class CrystalFieldMulti(object):
ties = self.getTies()
if len(ties) > 0:
fun += ';ties=(%s)' % ties
return fun
return 'composite=CompositeFunction,NumDeriv=1;' + fun
def ties(self, **kwargs):
"""Set ties on the parameters."""
......
......@@ -12,6 +12,7 @@ from mantid.kernel import ConfigService
c_mbsr = 79.5774715459 # Conversion from barn to mb/sr
class BackgroundTest(unittest.TestCase):
def setUp(self):
......@@ -342,7 +343,7 @@ class CrystalFieldTests(unittest.TestCase):
x0, y0 = cf.getSpectrum()
x1, y1 = cf.getSpectrum(1)
# Original test was for FOCUS convention - intensity in barn.
# Original test was for FOCUS convention - intensity in barn.
# Now use ISIS convention with intensity in milibarn/steradian
y0 = y0 / c_mbsr
y1 = y1 / c_mbsr
......@@ -442,7 +443,6 @@ class CrystalFieldFitTest(unittest.TestCase):
self.assertAlmostEqual(cf.peaks.param[2]['FWHM'], 1.10000812804, 4)
self.assertAlmostEqual(cf.peaks.param[2]['Amplitude'], 0.429808829601*c_mbsr, 2)
def test_CrystalFieldFit_multi_spectrum(self):
from CrystalField.fitting import makeWorkspace
from CrystalField import CrystalField, CrystalFieldFit, Background, Function
......@@ -529,7 +529,6 @@ class CrystalFieldFitTest(unittest.TestCase):
self.assertNotEqual(cf.peaks[1].param[3]['FWHM'], 0.0)
self.assertNotEqual(cf.peaks[1].param[3]['Amplitude'], 0.0)
def test_CrystalFieldFit_multi_spectrum_simple_background(self):
from CrystalField.fitting import makeWorkspace
from CrystalField import CrystalField, CrystalFieldFit, Background, Function
......@@ -649,6 +648,7 @@ class CrystalFieldFitTest(unittest.TestCase):
fit = CrystalFieldFit(Model=cf, InputWorkspace=ws, MaxIterations=10)
fit.fit()
self.assertTrue(cf.chi2 > 0.0)
self.assertTrue(cf.chi2 < chi2)
# Fit outputs are different on different platforms.
......@@ -680,9 +680,11 @@ class CrystalFieldFitTest(unittest.TestCase):
cf1 = CrystalField('Ce', 'C2v', B40=-0.02, B42=-0.11, B44=-0.12, Temperature=[44.0, 50.0], FWHM=[1.0, 1.0])
cf1.ties(B20=0.37737, B22=3.977, IntensityScaling0=1.0, IntensityScaling1=1.0)
cf1.FixAllPeaks = True
cf2 = CrystalField('Pr', 'C2v', B40=-0.03, B42=-0.116, B44=-0.125, Temperature=[44.0, 50.0], FWHM=[1.0, 1.0],
ToleranceIntensity=6.0, ToleranceEnergy=1.0)
cf2.ties(B20=0.37737, B22=3.977, IntensityScaling0=1.0, IntensityScaling1=1.0)
cf2.FixAllPeaks = True
cf = cf1 + cf2
chi2 = CalculateChiSquared(cf.makeMultiSpectrumFunction(), InputWorkspace=ws1, InputWorkspace_1=ws2)[1]
......@@ -690,6 +692,7 @@ class CrystalFieldFitTest(unittest.TestCase):
fit = CrystalFieldFit(Model=cf, InputWorkspace=[ws1, ws2])
fit.fit()
self.assertTrue(cf.chi2 > 0.0)
self.assertTrue(cf.chi2 < chi2)
# Fit outputs are different on different platforms.
......@@ -1249,7 +1252,7 @@ class CrystalFieldFitTest(unittest.TestCase):
ws2 = makeWorkspace(*origin.getSpectrum(1))
# Define a CrystalField object with parameters slightly shifted.
cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=0, B42=0, B44=0, NPeaks=9,
cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=0, B42=0, B44=0, NPeaks=11,
Temperature=[44.0, 50.0], FWHM=[1.0, 1.0])
# Set the ties
......@@ -1257,9 +1260,10 @@ class CrystalFieldFitTest(unittest.TestCase):
cf.constraints('2<B22<6', '-0.2<B40<0.2', '-0.2<B42<0.2', '-0.2<B44<0.2')
# Create a fit object
fit = CrystalFieldFit(cf, InputWorkspace=[ws1, ws2])
fit.monte_carlo(NSamples=1000, Constraints='20<f1.PeakCentre<45,20<f2.PeakCentre<45')
fit.monte_carlo(NSamples=1000, Constraints='20<f0.f1.PeakCentre<45,20<f0.f2.PeakCentre<45')
# Run fit
fit.fit()
self.assertTrue(cf.chi2 > 0.0)
self.assertTrue(cf.chi2 < 100.0)
def test_multi_ion_intensity_scaling(self):
......