Commit 21e3534b authored by Stephen's avatar Stephen
Browse files

Fix CrystalFieldFunction(s) issues due to to Attribute API change

This commit also makes a small change to composite function, so the behaviour of ConvolutionFunctionModel is similar as before.
parent 9a2593b7
......@@ -103,6 +103,9 @@ public:
void setAttribute(const std::string &name, const Attribute &) override;
/// Check if attribute attName exists
bool hasAttribute(const std::string &name) const override;
// Get ith attribute name
std::string attributeName(size_t i) const override;
//@}
/// Evaluate the function
......
......@@ -28,6 +28,7 @@ namespace {
/// static logger
Kernel::Logger g_log("CompositeFunction");
constexpr char *ATTNUMDERIV = "NumDeriv";
constexpr int NUMDEFAULTATTRIBUTES = 1;
template <typename T>
void replaceVariableIndexRange(std::vector<T> &variableFunctionIndexList,
size_t oldSize, size_t newSize,
......@@ -65,7 +66,7 @@ CompositeFunction::CompositeFunction()
void CompositeFunction::createDefaultGlobalAttributes() {
m_globalAttributeNames.clear();
declareAttribute(ATTNUMDERIV, Attribute(false));
m_nAttributes = 1;
m_nAttributes = NUMDEFAULTATTRIBUTES;
}
/// Function initialization. Declare function parameters in this method.
......@@ -96,7 +97,8 @@ std::string CompositeFunction::writeToString(
return "name=" + name();
}
if (name() != "CompositeFunction" || nAttributes() > nGlobalAttributes() ||
if (name() != "CompositeFunction" ||
nGlobalAttributes() > NUMDEFAULTATTRIBUTES ||
getAttribute(ATTNUMDERIV).asBool() || !parentLocalAttributesStr.empty()) {
ostr << "composite=" << name();
std::vector<std::string> attr = m_globalAttributeNames;
......
......@@ -223,10 +223,6 @@ size_t FunctionGenerator::nAttributes() const {
std::vector<std::string> FunctionGenerator::getAttributeNames() const {
checkTargetFunction();
std::vector<std::string> attNames = IFunction::getAttributeNames();
auto cfNames = m_source->getAttributeNames();
auto spNames = m_target->getAttributeNames();
attNames.insert(attNames.end(), cfNames.begin(), cfNames.end());
attNames.insert(attNames.end(), spNames.begin(), spNames.end());
return attNames;
}
......@@ -272,6 +268,19 @@ bool FunctionGenerator::hasAttribute(const std::string &attName) const {
}
}
std::string FunctionGenerator::attributeName(size_t i) const {
if (i < IFunction::nAttributes()) {
return IFunction::attributeName(i);
} else if (i < IFunction::nAttributes() + m_source->nAttributes()) {
return m_source->attributeName(i - IFunction::nAttributes());
} else if (i < nAttributes()) {
return m_target->attributeName(
i - (IFunction::nAttributes() + m_source->nAttributes()));
} else {
throw(std::runtime_error("Attribute index out of range"));
}
}
// Evaluates the function
void FunctionGenerator::function(const FunctionDomain &domain,
FunctionValues &values) const {
......
......@@ -201,7 +201,6 @@ private:
size_t makeMapsForFunction(const IFunction &fun, size_t iFirst,
const std::string &prefix) const;
void cacheSourceParameters() const;
/// Function that creates the source function.
mutable CrystalFieldControl m_control;
/// Function that calculates parameters of the target function.
......
......@@ -63,8 +63,9 @@ void CrystalFieldControl::setAttribute(const std::string &name,
} else if (name == "FWHMs") {
const size_t nSpec = m_temperatures.size();
m_FWHMs = attr.asVector();
auto frontValue = m_FWHMs.front();
if (m_FWHMs.size() == 1 && m_FWHMs.size() != nSpec) {
m_FWHMs.assign(nSpec, m_FWHMs.front());
m_FWHMs.assign(nSpec, frontValue);
}
if (!m_FWHMs.empty()) {
m_fwhmX.resize(nSpec);
......
......@@ -401,8 +401,12 @@ void CrystalFieldFunction::buildAttributeNames() const {
if (!m_attributeNames.empty()) {
return;
}
m_attributeNames = IFunction::getAttributeNames();
auto numAttributes = IFunction::nAttributes();
for (int i = 0; i < numAttributes; ++i) {
m_attributeNames.emplace_back(IFunction::attributeName(i));
}
auto controlAttributeNames = m_control.getAttributeNames();
// Lambda function that moves a attribute name from controlAttributeNames
// to attNames.
auto moveAttributeName = [&](const std::string &name) {
......@@ -417,7 +421,7 @@ void CrystalFieldFunction::buildAttributeNames() const {
auto prependPrefix = [&](const std::string &prefix,
const std::vector<std::string> &names) {
for (auto name : names) {
if (name == "NumDeriv")
if (name.find("NumDeriv") != std::string::npos)
continue;
name.insert(name.begin(), prefix.begin(), prefix.end());
m_attributeNames.emplace_back(name);
......@@ -428,9 +432,13 @@ void CrystalFieldFunction::buildAttributeNames() const {
moveAttributeName("Symmetries");
moveAttributeName("Temperatures");
moveAttributeName("Background");
// Copy the rest of the names
m_attributeNames.insert(m_attributeNames.end(), controlAttributeNames.begin(),
controlAttributeNames.end());
// Only copy the unprefixed attributes - as the loop below will include
// And modify the prefixed attributes accordingly
std::copy_if(controlAttributeNames.begin(), controlAttributeNames.end(),
std::back_inserter(m_attributeNames), [](const auto &name) {
return name.find(".") == std::string::npos;
});
// Get
for (size_t iSpec = 0; iSpec < m_control.nFunctions(); ++iSpec) {
std::string prefix(SPECTRUM_PREFIX);
......
......@@ -333,9 +333,9 @@ public:
TS_ASSERT_EQUALS(
fitFunctionAsString,
"composite=MultiDomainFunction,NumDeriv=true;(composite=Convolution,"
"FixResolution=true,NumDeriv=true,$domains=i;name=Resolution,Workspace="
"abc,WorkspaceIndex=1,X=(),Y=());(composite=Convolution,FixResolution="
"true,NumDeriv=true,$domains=i;name=Resolution,Workspace=abc,"
"NumDeriv=true,FixResolution=true,$domains=i;name=Resolution,Workspace="
"abc,WorkspaceIndex=1,X=(),Y=());(composite=Convolution,NumDeriv="
"true,FixResolution=true,$domains=i;name=Resolution,Workspace=abc,"
"WorkspaceIndex=2,X=(),Y=())");
}
......@@ -361,11 +361,11 @@ public:
TS_ASSERT_EQUALS(
fitFunctionAsString,
"composite=MultiDomainFunction,NumDeriv=true;(composite=Convolution,"
"FixResolution=true,NumDeriv=true,$domains=i;name=Resolution,Workspace="
"NumDeriv=true,FixResolution=true,$domains=i;name=Resolution,Workspace="
"abc,WorkspaceIndex=1,X=(),Y=();name=DeltaFunction,Height=1,Centre=0,"
"constraints=(0<Height));("
"composite=Convolution,FixResolution="
"true,NumDeriv=true,$domains=i;name=Resolution,Workspace=abc,"
"composite=Convolution,NumDeriv="
"true,FixResolution=true,$domains=i;name=Resolution,Workspace=abc,"
"WorkspaceIndex=2,X=(),Y=();name=DeltaFunction,Height=1,Centre=0,"
"constraints=(0<Height))");
}
......@@ -393,14 +393,15 @@ public:
fitFunctionAsString,
"composite=MultiDomainFunction,NumDeriv=true;(composite="
"CompositeFunction,NumDeriv=false,$domains=i;name=FlatBackground,A0=0;("
"composite=Convolution,FixResolution=true,NumDeriv=true;name="
"composite=Convolution,NumDeriv=true,FixResolution=true;name="
"Resolution,Workspace=abc,WorkspaceIndex=1,X=(),Y=();(name="
"TeixeiraWaterSQE,Q=8.9884656743115785e+307,WorkspaceIndex=2147483647,"
"Height=1,DiffCoeff=2.3,Tau=1.25,Centre=0;name=DeltaFunction,Height=1,"
"Centre=0,constraints=(0<Height))));(composite=CompositeFunction,"
"NumDeriv=false,$domains=i;"
"name=FlatBackground,A0=0;(composite=Convolution,FixResolution=true,"
"NumDeriv=true;name=Resolution,Workspace=abc,WorkspaceIndex=2,X=(),Y=()"
"name=FlatBackground,A0=0;(composite=Convolution,NumDeriv=true,"
"FixResolution=true;name=Resolution,Workspace=abc,WorkspaceIndex=2,X=()"
",Y=()"
";(name=TeixeiraWaterSQE,Q=8.9884656743115785e+307,WorkspaceIndex="
"2147483647,Height=1,DiffCoeff=2.3,Tau=1.25,Centre=0;name="
"DeltaFunction,Height=1,Centre=0,constraints=(0<Height))))");
......@@ -430,14 +431,15 @@ public:
fitFunctionAsString,
"composite=MultiDomainFunction,NumDeriv=true;(composite="
"CompositeFunction,NumDeriv=false,$domains=i;name=FlatBackground,A0=0;("
"composite=Convolution,FixResolution=true,NumDeriv=true;name="
"composite=Convolution,NumDeriv=true,FixResolution=true;name="
"Resolution,Workspace=abc,WorkspaceIndex=1,X=(),Y=();(name=Lorentzian,"
"Amplitude=1,PeakCentre=0,FWHM=0;name=Lorentzian,Amplitude=1,"
"PeakCentre=0,FWHM=0;name=DeltaFunction,Height=1,Centre=0,constraints=("
"0<Height))));("
"composite=CompositeFunction,NumDeriv=false,$domains=i;name="
"FlatBackground,A0=0;(composite=Convolution,FixResolution=true,"
"NumDeriv=true;name=Resolution,Workspace=abc,WorkspaceIndex=2,X=(),Y=()"
"FlatBackground,A0=0;(composite=Convolution,NumDeriv=true,"
"FixResolution=true;name=Resolution,Workspace=abc,WorkspaceIndex=2,X=()"
",Y=()"
";(name=Lorentzian,Amplitude=1,PeakCentre=0,FWHM=0;name=Lorentzian,"
"Amplitude=1,PeakCentre=0,FWHM=0;name=DeltaFunction,Height=1,Centre=0,"
"constraints=(0<Height)))"
......@@ -468,7 +470,7 @@ public:
fitFunctionAsString,
"composite=MultiDomainFunction,NumDeriv=true;(composite="
"CompositeFunction,NumDeriv=false,$domains=i;name=FlatBackground,A0=0;("
"composite=Convolution,FixResolution=true,NumDeriv=true;name="
"composite=Convolution,NumDeriv=true,FixResolution=true;name="
"Resolution,Workspace=abc,WorkspaceIndex=1,X=(),Y=();(name="
"DeltaFunction,Height=1,Centre=0,constraints=(0<Height);(composite="
"ProductFunction,NumDeriv="
......@@ -476,8 +478,9 @@ public:
"name=Lorentzian,Amplitude=1,"
"PeakCentre=0,FWHM=0;name=Lorentzian,Amplitude=1,PeakCentre=0,FWHM=0)))"
"));(composite=CompositeFunction,NumDeriv=false,$domains=i;name="
"FlatBackground,A0=0;(composite=Convolution,FixResolution=true,"
"NumDeriv=true;name=Resolution,Workspace=abc,WorkspaceIndex=2,X=(),Y=()"
"FlatBackground,A0=0;(composite=Convolution,NumDeriv=true,"
"FixResolution=true;name=Resolution,Workspace=abc,WorkspaceIndex=2,X=()"
",Y=()"
";(name=DeltaFunction,Height=1,Centre=0,constraints=(0<Height);("
"composite=ProductFunction,"
"NumDeriv=false;name=ConvTempCorrection,Temperature=100,ties=("
......@@ -618,4 +621,4 @@ public:
TS_ASSERT_EQUALS(model.deltaFunctionPrefix().value().toStdString(),
"f1.f1.f0.");
}
};
};
\ No newline at end of file
......@@ -614,3 +614,7 @@ class CrystalFieldMultiSiteTests(unittest.TestCase):
self.assertTrue('ion0.IntensityScaling=0.2*ion2.IntensityScaling' in ties)
self.assertTrue('ion1.IntensityScaling=0.8*ion2.IntensityScaling' in ties)
self.assertTrue('ion3.IntensityScaling=0.1*ion2.IntensityScaling' in ties)
if __name__ == '__main__':
unittest.main()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment