/** * Create a function from an expression. * @param expr :: The input expression * @param parentAttributes :: An output map filled with the attribute name & values of the parent function * @return A pointer to the created function */ IFunction_sptr FunctionFactoryImpl::createSimple(const Expression& expr, std::map<std::string,std::string>& parentAttributes)const { if (expr.name() == "=" && expr.size() > 1) { return createFunction(expr.terms()[1].name()); } if (expr.name() != "," || expr.size() == 0) { inputError(expr.str()); } const std::vector<Expression>& terms = expr.terms(); std::vector<Expression>::const_iterator term = terms.begin(); if (term->name() != "=") inputError(expr.str()); if (term->terms()[0].name() != "name" && term->terms()[0].name() != "composite") { throw std::invalid_argument("Function name must be defined before its parameters"); } std::string fnName = term->terms()[1].name(); IFunction_sptr fun = createFunction(fnName); for(++term;term!=terms.end();++term) {// loop over function's parameters/attributes if (term->name() != "=") inputError(expr.str()); std::string parName = term->terms()[0].name(); std::string parValue = term->terms()[1].str(); if (fun->hasAttribute(parName)) {// set attribute if (parValue.size() > 1 && parValue[0] == '"') {// remove the double quotes parValue = parValue.substr(1,parValue.size()-2); } IFunction::Attribute att = fun->getAttribute(parName); att.fromString(parValue); fun->setAttribute(parName,att); } else if (parName.size() >= 10 && parName.substr(0,10) == "constraint") {// or it can be a list of constraints addConstraints(fun,(*term)[1]); } else if (parName == "ties") { addTies(fun,(*term)[1]); } else if (!parName.empty() && parName[0] == '$') { parName.erase(0,1); parentAttributes[parName] = parValue; } else {// set initial parameter value fun->setParameter(parName,atof(parValue.c_str())); } }// for term fun->applyTies(); return fun; }
/* Propagate the attribute to its member functions. * NOTE: we pass this->getAttribute(name) by reference, thus the same * object is shared by the composite function and its members. */ void DiffSphere::trickleDownAttribute(const std::string &name) { for (size_t iFun = 0; iFun < nFunctions(); iFun++) { IFunction_sptr fun = getFunction(iFun); if (fun->hasAttribute(name)) { fun->setAttribute(name, this->getAttribute(name)); } } }
/** * Gets the new attribute values to be updated in the function and in the fit * property browser. * @param function The function containing the attributes * @param attributeNames The names of the attributes to update */ std::unordered_map<std::string, IFunction::Attribute> IndirectFitAnalysisTab::getAttributes( IFunction_sptr const &function, std::vector<std::string> const &attributeNames) { std::unordered_map<std::string, IFunction::Attribute> attributes; for (auto const &name : attributeNames) if (function->hasAttribute(name)) attributes[name] = name == "WorkspaceIndex" ? IFunction::Attribute(m_fitPropertyBrowser->workspaceIndex()) : function->getAttribute(name); return attributes; }
/** * Set any WorkspaceIndex attributes in the fitting function. If the function is composite * try all its members. * @param fun :: The fitting function * @param wsIndex :: Value for WorkspaceIndex attributes to set. */ void PlotPeakByLogValue::setWorkspaceIndexAttribute(IFunction_sptr fun, int wsIndex) const { const std::string attName = "WorkspaceIndex"; if ( fun->hasAttribute(attName) ) { fun->setAttributeValue(attName,wsIndex); } API::CompositeFunction_sptr cf = boost::dynamic_pointer_cast<API::CompositeFunction>( fun ); if ( cf ) { for(size_t i = 0; i < cf->nFunctions(); ++i) { setWorkspaceIndexAttribute( cf->getFunction(i), wsIndex ); } } }