Commit 47f69465 authored by Roman Tolchenov's avatar Roman Tolchenov
Browse files

Re #19909. Pass 'local' attrs to child function's asString()

parent 9bd5abb9
......@@ -67,7 +67,7 @@ public:
/// Returns the function's name
std::string name() const override { return "CompositeFunction"; }
/// Writes itself into a string
std::string asString() const override;
std::string asString(const std::string &parentLocalAttributesStr = "") const override;
/// Sets the workspace for each member function
void setWorkspace(boost::shared_ptr<const Workspace> ws) override;
/// Set matrix workspace
......
......@@ -324,7 +324,7 @@ public:
/// Returns the function's name
virtual std::string name() const = 0;
/// Writes itself into a string
virtual std::string asString() const;
virtual std::string asString(const std::string &localAttributesStr = "") const;
/// Virtual copy constructor
virtual boost::shared_ptr<IFunction> clone() const;
/// Set the workspace.
......
......@@ -46,7 +46,7 @@ public:
/// Returns the function's name
std::string name() const override { return "ImmutableCompositeFunction"; }
/// Writes itself into a string
std::string asString() const override;
std::string asString(const std::string &parentLocalAttributesStr = "") const override;
/// Set i-th parameter
void setParameter(size_t i, const double &value,
bool explicitlySet = true) override {
......
......@@ -46,9 +46,11 @@ void CompositeFunction::init() {}
* // write NewFunction's own ties and constraints
* // ostr << ";constraints=(" << ... <<")";
* }
* @param parentLocalAttributesStr :: A preformatted string with parent's local attributes.
* Can be passed in by a CompositeFunction (eg MultiDomainFunction).
* @return the string representation of the composite function
*/
std::string CompositeFunction::asString() const {
std::string CompositeFunction::asString(const std::string &parentLocalAttributesStr) const {
std::ostringstream ostr;
// if empty just return function name
......@@ -57,7 +59,7 @@ std::string CompositeFunction::asString() const {
}
if (name() != "CompositeFunction" || nAttributes() > 1 ||
getAttribute("NumDeriv").asBool()) {
getAttribute("NumDeriv").asBool() || !parentLocalAttributesStr.empty()) {
ostr << "composite=" << name();
std::vector<std::string> attr = this->getAttributeNames();
for (const auto &attName : attr) {
......@@ -66,24 +68,25 @@ std::string CompositeFunction::asString() const {
ostr << ',' << attName << '=' << attValue;
}
}
ostr << ';';
ostr << parentLocalAttributesStr << ';';
}
const auto localAttr = this->getLocalAttributeNames();
for (size_t i = 0; i < nFunctions(); i++) {
const auto localAttr = this->getLocalAttributeNames();
IFunction_sptr fun = getFunction(i);
bool isComp =
boost::dynamic_pointer_cast<CompositeFunction>(fun) != nullptr;
if (isComp)
ostr << '(';
ostr << fun->asString();
std::ostringstream localAttributesStr;
for (const auto &localAttName : localAttr) {
const std::string localAttValue =
this->getLocalAttribute(i, localAttName).value();
if (!localAttValue.empty()) {
// local attribute names are prefixed by dollar sign
ostr << ',' << '$' << localAttName << '=' << localAttValue;
localAttributesStr << ',' << '$' << localAttName << '=' << localAttValue;
}
}
ostr << fun->asString(localAttributesStr.str());
if (isComp)
ostr << ')';
if (i < nFunctions() - 1) {
......
......@@ -397,9 +397,11 @@ std::string IFunction::writeConstraints() const {
/**
* Writes a string that can be used in Fit.IFunction to create a copy of this
* IFunction
* @param localAttributesStr :: A preformatted string with local attributes.
* Can be passed in by a CompositeFunction (eg MultiDomainFunction).
* @return string representation of the function
*/
std::string IFunction::asString() const {
std::string IFunction::asString(const std::string &localAttributesStr) const {
std::ostringstream ostr;
ostr << "name=" << this->name();
// print the attributes
......@@ -439,6 +441,8 @@ std::string IFunction::asString() const {
ostr << ",ties=(" << Kernel::Strings::join(ties.begin(), ties.end(), ",")
<< ")";
}
// "local" attributes of a parent composite function
ostr << localAttributesStr;
return ostr.str();
}
......
......@@ -16,8 +16,8 @@ using std::size_t;
* Overridden method creates an initialization string which makes it look like a
* siple function.
*/
std::string ImmutableCompositeFunction::asString() const {
return IFunction::asString();
std::string ImmutableCompositeFunction::asString(const std::string &parentLocalAttributesStr) const {
return IFunction::asString(parentLocalAttributesStr);
}
/**
......
......@@ -468,6 +468,30 @@ public:
"name=MultiDomainFunctionTest_Function,A=2,B=4");
}
void test_string_nested_composite() {
std::string ini = "composite=MultiDomainFunction;"
"(composite=CompositeFunction,$domains=i;"
"name=MultiDomainFunctionTest_Function; "
"(name=MultiDomainFunctionTest_Function;name="
"MultiDomainFunctionTest_Function));"
"(composite=CompositeFunction,$domains=i;"
"name=MultiDomainFunctionTest_Function; "
"(name=MultiDomainFunctionTest_Function;name="
"MultiDomainFunctionTest_Function))";
auto f = FunctionFactory::Instance().createInitialized(ini);
auto g = FunctionFactory::Instance().createInitialized(f->asString());
TS_ASSERT_EQUALS(g->asString(),
"composite=MultiDomainFunction,NumDeriv=false;(composite="
"CompositeFunction,NumDeriv=false,$domains=i;name="
"MultiDomainFunctionTest_Function,A=0,B=0;(name="
"MultiDomainFunctionTest_Function,A=0,B=0;name="
"MultiDomainFunctionTest_Function,A=0,B=0));(composite="
"CompositeFunction,NumDeriv=false,$domains=i;name="
"MultiDomainFunctionTest_Function,A=0,B=0;(name="
"MultiDomainFunctionTest_Function,A=0,B=0;name="
"MultiDomainFunctionTest_Function,A=0,B=0))");
}
private:
MultiDomainFunction multi;
JointDomain domain;
......
......@@ -36,7 +36,7 @@ public:
std::string name() const override { return "CrystalFieldSpectrum"; }
const std::string category() const override { return "General"; }
void buildTargetFunction() const override;
std::string asString() const override;
std::string asString(const std::string &parentLocalAttributesStr = "") const override;
protected:
void updateTargetFunction() const override;
......
......@@ -97,7 +97,7 @@ void CrystalFieldSpectrum::updateTargetFunction() const {
}
/// Custom string conversion method
std::string CrystalFieldSpectrum::asString() const {
std::string CrystalFieldSpectrum::asString(const std::string &parentLocalAttributesStr) const {
std::ostringstream ostr;
ostr << "name=" << this->name();
// Print the attributes
......@@ -108,6 +108,7 @@ std::string CrystalFieldSpectrum::asString() const {
ostr << ',' << attName << '=' << attValue;
}
}
ostr << parentLocalAttributesStr;
std::vector<std::string> ties;
// Print own parameters
for (size_t i = 0; i < m_nOwnParams; i++) {
......
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