/** * Create a fitting function from an expression. * @param expr :: The input expression made by parsing the input string to createFitFunction(const std::string& input) */ IFitFunction* FunctionFactoryImpl::createFitFunction(const Expression& expr) const { const Expression& e = expr.bracketsRemoved(); std::string fnName = e.name(); IFitFunction* fun = createUnwrapped(fnName); if (!fun) { throw std::runtime_error("Cannot create function "+fnName); } fun->initialize(); const std::vector<Expression>& terms = e.terms(); std::vector<Expression>::const_iterator term = terms.begin(); for(;term!=terms.end();++term) {// loop over function's parameters/attributes if (term->name() == "=") { 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); } IFitFunction::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 {// set initial parameter value fun->setParameter(parName,atof(parValue.c_str())); } } else // if the term isn't a name=value pair it could be a member function of a composite function { throw Kernel::Exception::NotImplementedError("Composite functions are not implemented yet for IFitFunction"); //CompositeFunction* cfun = dynamic_cast<CompositeFunction*>(fun); //if (!cfun) //{ // throw std::runtime_error("Cannot add a function to a non-composite function "+fnName); //} //IFitFunction* mem = createFitFunction(*term); //cfun->addFunction(mem); } }// for term return fun; }
/** * 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; }
IFunction_sptr PoldiFitPeaks1D::getPeakProfile(const PoldiPeak_sptr &poldiPeak) const { IPeakFunction_sptr clonedProfile = boost::dynamic_pointer_cast<IPeakFunction>( FunctionFactory::Instance().createFunction(m_profileTemplate)); clonedProfile->setCentre(poldiPeak->q()); clonedProfile->setFwhm(poldiPeak->fwhm(PoldiPeak::AbsoluteQ)); clonedProfile->setHeight(poldiPeak->intensity()); IFunction_sptr clonedBackground = m_backgroundTemplate->clone(); auto totalProfile = boost::make_shared<CompositeFunction>(); totalProfile->initialize(); totalProfile->addFunction(clonedProfile); totalProfile->addFunction(clonedBackground); if (!m_profileTies.empty()) { totalProfile->addTies(m_profileTies); } return totalProfile; }
/** * Create a function from an expression. * @param expr :: The input expression * @return A pointer to the created function */ IFitFunction* FunctionFactoryImpl::createSimple(const Expression& expr)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(); IFitFunction* fun = createFunction(fnName); std::string wsName,wsParam; 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); } IFitFunction::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 == "Workspace") { wsName = parValue; } else if (parName == "WSParam") { wsParam = parValue; } else {// set initial parameter value fun->setParameter(parName,atof(parValue.c_str())); } }// for term if (!wsName.empty()) { Workspace_sptr ws = AnalysisDataService::Instance().retrieve(wsName); fun->setWorkspace(ws,wsParam); } return fun; }
/** * Create a composite function from an expression. * @param expr :: The input expression * @return A pointer to the created function */ CompositeFunction* FunctionFactoryImpl::createComposite(const Expression& expr)const { if (expr.name() != ";") inputError(expr.str()); if (expr.size() == 0) { return 0; } const std::vector<Expression>& terms = expr.terms(); std::vector<Expression>::const_iterator it = terms.begin(); const Expression& term = it->bracketsRemoved(); CompositeFunction* cfun = 0; std::string wsName,wsParam; if (term.name() == "=") { if (term.terms()[0].name() == "composite") { cfun = dynamic_cast<CompositeFunction*>(createFunction(term.terms()[1].name())); if (!cfun) inputError(expr.str()); ++it; } else if (term.terms()[0].name() == "name") { cfun = dynamic_cast<CompositeFunction*>(createFunction("CompositeFunctionMW")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } else if (term.name() == ",") { std::vector<Expression>::const_iterator firstTerm = term.terms().begin(); if (firstTerm->name() == "=") { if (firstTerm->terms()[0].name() == "composite") { cfun = dynamic_cast<CompositeFunction*>(createSimple(term)); if (!cfun) inputError(expr.str()); ++it; } else if (firstTerm->terms()[0].name() == "name") { cfun = dynamic_cast<CompositeFunction*>(createFunction("CompositeFunctionMW")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } } else if (term.name() == ";") { cfun = dynamic_cast<CompositeFunction*>(createFunction("CompositeFunctionMW")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } for(;it!=terms.end();++it) { const Expression& term = it->bracketsRemoved(); IFitFunction* fun = NULL; if (term.name() == ";") { fun = createComposite(term); if (!fun) continue; } else { std::string parName = term[0].name(); std::string parValue = term[1].str(); if (term[0].name().size() >= 10 && term[0].name().substr(0,10) == "constraint") { addConstraints(cfun,term[1]); continue; } else if (term[0].name() == "ties") { addTies(cfun,term[1]); continue; } else if (parName == "Workspace") { wsName = parValue; } else if (parName == "WSParam") { wsParam = parValue; } else { fun = createSimple(term); } } cfun->addFunction(fun); } if (!wsName.empty()) { Workspace_sptr ws = AnalysisDataService::Instance().retrieve(wsName); cfun->setWorkspace(ws,wsParam); } return cfun; }
/** * Create a composite 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 */ CompositeFunction_sptr FunctionFactoryImpl::createComposite( const Expression &expr, std::map<std::string, std::string> &parentAttributes) const { if (expr.name() != ";") inputError(expr.str()); if (expr.size() == 0) { return CompositeFunction_sptr(); } const std::vector<Expression> &terms = expr.terms(); auto it = terms.cbegin(); const Expression &term = it->bracketsRemoved(); CompositeFunction_sptr cfun; if (term.name() == "=") { if (term.terms()[0].name() == "composite") { cfun = boost::dynamic_pointer_cast<CompositeFunction>( createFunction(term.terms()[1].name())); if (!cfun) inputError(expr.str()); ++it; } else if (term.terms()[0].name() == "name") { cfun = boost::dynamic_pointer_cast<CompositeFunction>( createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } else if (term.name() == ",") { auto firstTerm = term.terms().cbegin(); if (firstTerm->name() == "=") { if (firstTerm->terms()[0].name() == "composite") { cfun = boost::dynamic_pointer_cast<CompositeFunction>( createSimple(term, parentAttributes)); if (!cfun) inputError(expr.str()); ++it; } else if (firstTerm->terms()[0].name() == "name") { cfun = boost::dynamic_pointer_cast<CompositeFunction>( createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } } else if (term.name() == ";") { cfun = boost::dynamic_pointer_cast<CompositeFunction>( createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } if (!cfun) inputError(expr.str()); for (; it != terms.end(); ++it) { const Expression &term = it->bracketsRemoved(); IFunction_sptr fun; std::map<std::string, std::string> pAttributes; if (term.name() == ";") { fun = createComposite(term, pAttributes); if (!fun) continue; } else { std::string parName = term[0].name(); if (parName.size() >= 10 && parName.substr(0, 10) == "constraint") { addConstraints(cfun, term[1]); continue; } else if (parName == "ties") { addTies(cfun, term[1]); continue; } else { fun = createSimple(term, pAttributes); } } cfun->addFunction(fun); size_t i = cfun->nFunctions() - 1; for (auto &pAttribute : pAttributes) { // Apply parent attributes of the child function to this function. If this // function doesn't have those attributes, they get passed up the chain to // this function's parent. if (cfun->hasLocalAttribute(pAttribute.first)) { cfun->setLocalAttributeValue(i, pAttribute.first, pAttribute.second); } else { parentAttributes[pAttribute.first] = pAttribute.second; } } } if (cfun) { cfun->applyTies(); } return cfun; }
/** * Create a composite 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 */ CompositeFunction_sptr FunctionFactoryImpl::createComposite(const Expression& expr, std::map<std::string,std::string>& parentAttributes)const { if (expr.name() != ";") inputError(expr.str()); if (expr.size() == 0) { return CompositeFunction_sptr(); } const std::vector<Expression>& terms = expr.terms(); std::vector<Expression>::const_iterator it = terms.begin(); const Expression& term = it->bracketsRemoved(); CompositeFunction_sptr cfun; if (term.name() == "=") { if (term.terms()[0].name() == "composite") { cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction(term.terms()[1].name())); if (!cfun) inputError(expr.str()); ++it; } else if (term.terms()[0].name() == "name") { cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } else if (term.name() == ",") { std::vector<Expression>::const_iterator firstTerm = term.terms().begin(); if (firstTerm->name() == "=") { if (firstTerm->terms()[0].name() == "composite") { cfun = boost::dynamic_pointer_cast<CompositeFunction>(createSimple(term,parentAttributes)); if (!cfun) inputError(expr.str()); ++it; } else if (firstTerm->terms()[0].name() == "name") { cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } } else if (term.name() == ";") { cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } for(;it!=terms.end();++it) { const Expression& term = it->bracketsRemoved(); IFunction_sptr fun; std::map<std::string,std::string> pAttributes; if (term.name() == ";") { fun = createComposite(term,pAttributes); if (!fun) continue; } else { std::string parName = term[0].name(); if (parName.size() >= 10 && parName.substr(0,10) == "constraint") { addConstraints(cfun,term[1]); continue; } else if (parName == "ties") { addTies(cfun,term[1]); continue; } else { fun = createSimple(term,pAttributes); } } cfun->addFunction(fun); size_t i = cfun->nFunctions() - 1; for(auto att = pAttributes.begin(); att != pAttributes.end(); ++att) { cfun->setLocalAttributeValue(i,att->first,att->second); } } cfun->applyTies(); return cfun; }