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

Re #2702. Added FunctionProperty.

parent 948341d7
......@@ -29,6 +29,7 @@ set ( SRC_FILES
src/FrameworkManager.cpp
src/FunctionDomain.cpp
src/FunctionFactory.cpp
src/FunctionProperty.cpp
src/IDataFileChecker.cpp
src/IEventList.cpp
src/IEventWorkspace.cpp
......@@ -127,6 +128,7 @@ set ( INC_FILES
inc/MantidAPI/FrameworkManager.h
inc/MantidAPI/FunctionDomain.h
inc/MantidAPI/FunctionFactory.h
inc/MantidAPI/FunctionProperty.h
inc/MantidAPI/IAlgorithm.h
inc/MantidAPI/IArchiveSearch.h
inc/MantidAPI/IBackgroundFunction.h
......@@ -223,6 +225,7 @@ set ( TEST_FILES
test/FilePropertyTest.h
test/FrameworkManagerTest.h
test/FunctionTest.h
test/FunctionPropertyTest.h
test/IEventListTest.h
test/IFunctionMDTest.h
test/IMDWorkspaceTest.h
......
#ifndef MANTID_API_FUNCTIONPROPERTY_H_
#define MANTID_API_FUNCTIONPROPERTY_H_
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/DllConfig.h"
#include "MantidAPI/IFitFunction.h"
#include "MantidKernel/PropertyWithValue.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/Exception.h"
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <string>
namespace Mantid
{
namespace API
{
/** A property class for functions. Holds a shared pointer to a function. The string representation
is the creation string accepted by the FunctionFactory.
@author Roman Tolchenov, Tessella plc
@date 08/02/2012
Copyright &copy; 2007-2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>.
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class MANTID_API_DLL FunctionProperty : public Kernel::PropertyWithValue< boost::shared_ptr<IFitFunction> >
{
public:
/// Constructor.
explicit FunctionProperty( const std::string &name );
/// Copy constructor
FunctionProperty( const FunctionProperty& right );
/// Copy assignment operator. Only copies the value (i.e. the pointer to the workspace)
FunctionProperty& operator=( const FunctionProperty& right );
/// Bring in the PropertyWithValue assignment operator explicitly (avoids VSC++ warning)
virtual boost::shared_ptr<IFitFunction>& operator=( const boost::shared_ptr<IFitFunction>& value );
///Add the value of another property
virtual FunctionProperty& operator+=( Kernel::Property const * );
/// 'Virtual copy constructor'
Kernel::Property* clone() { return new FunctionProperty(*this); }
/// Virtual destructor
virtual ~FunctionProperty();
/// Get the name of the workspace
virtual std::string value() const;
/// Get the value the property was initialised with -its default value
virtual std::string getDefault() const;
/// Set the value of the property
virtual std::string setValue( const std::string& value );
/// Checks whether the entered function is valid.
std::string isValid() const;
/// Is default
bool isDefault() const;
/// Create a history record
virtual const Kernel::PropertyHistory createHistory() const;
private:
/// The name of the workspace (as used by the AnalysisDataService)
std::string m_definition;
/// for access to logging streams
static Kernel::Logger& g_log;
};
} // namespace API
} // namespace Mantid
#endif /*MANTID_API_FUNCTIONPROPERTY_H_*/
......@@ -160,6 +160,8 @@ public:
/// Overload operator <<
MANTID_API_DLL std::ostream& operator<<(std::ostream& ostr,const IFitFunction& f);
typedef boost::shared_ptr<IFitFunction> IFitFunction_sptr;
/**
* Classes inherited from FunctionHandler will handle the function.
* The intended purpose is to help with displaying nested composite
......
#include "MantidAPI/FunctionProperty.h"
#include "MantidAPI/FunctionFactory.h"
namespace Mantid
{
namespace API
{
Kernel::Logger& FunctionProperty::g_log = Kernel::Logger::get("FunctionProperty");
/** Constructor.
* Sets the property names but initialises the function pointer to null.
* @param name :: The name to assign to the property
*/
FunctionProperty::FunctionProperty( const std::string &name ) :
Kernel::PropertyWithValue <boost::shared_ptr<IFitFunction> >(
name,
boost::shared_ptr<IFitFunction>( ),
new Kernel::NullValidator< boost::shared_ptr<IFitFunction> >,
Kernel::Direction::InOut
)
{
}
/// Copy constructor
FunctionProperty::FunctionProperty( const FunctionProperty& right ) :
Kernel::PropertyWithValue< boost::shared_ptr<IFitFunction> >( right )
{
}
/// Copy assignment operator. Copies the pointer to the function.
FunctionProperty& FunctionProperty::operator=( const FunctionProperty& right )
{
if ( &right == this ) return *this;
Kernel::PropertyWithValue< boost::shared_ptr<IFitFunction> >::operator=( right );
return *this;
}
/** Bring in the PropertyWithValue assignment operator explicitly (avoids VSC++ warning)
* @param value :: The value to set to
* @return assigned PropertyWithValue
*/
boost::shared_ptr<IFitFunction>& FunctionProperty::operator=( const boost::shared_ptr<IFitFunction>& value )
{
return Kernel::PropertyWithValue< boost::shared_ptr<IFitFunction> >::operator=( value );
}
//--------------------------------------------------------------------------------------
///Add the value of another property
FunctionProperty& FunctionProperty::operator+=( Kernel::Property const * )
{
throw Kernel::Exception::NotImplementedError("+= operator is not implemented for FunctionProperty.");
return *this;
}
/// Virtual destructor
FunctionProperty::~FunctionProperty()
{
}
/** Get the function definition
* @return The function definition
*/
std::string FunctionProperty::value() const
{
return m_value->asString();
}
/** Get the value the property was initialised with -its default value
* @return The default value
*/
std::string FunctionProperty::getDefault() const
{
return "";
}
/** Set the function definition.
* Also tries to create the function with FunctionFactory.
* @param value :: The function definition string.
* @return Error message from FunctionFactory or "" on success.
*/
std::string FunctionProperty::setValue( const std::string& value )
{
std::string error = "";
try
{
m_value = boost::shared_ptr<IFitFunction>(FunctionFactory::Instance().createInitialized(value));
m_definition = value;
}
catch(std::exception& e)
{
error = e.what();
}
return error;
}
/** Checks whether the entered function is valid.
* To be valid it has to be
* @returns A user level description of the problem or "" if it is valid.
*/
std::string FunctionProperty::isValid() const
{
return isDefault() ? "Funcion is empty." : "";
}
/** Indicates if the object is still pointing to the same workspace, using the workspace name
* @return true if the value is the same as the initial value or false otherwise
*/
bool FunctionProperty::isDefault() const
{
return m_value == boost::shared_ptr<IFitFunction>();
}
/// Create a history record
/// @return A populated PropertyHistory for this class
const Kernel::PropertyHistory FunctionProperty::createHistory() const
{
return Kernel::PropertyHistory(this->name(),this->value(),this->type(),this->isDefault(),Kernel::PropertyWithValue<boost::shared_ptr<IFitFunction> >::direction());
}
} // namespace API
} // namespace Mantid
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/Exception.h"
#include "MantidKernel/Logger.h"
#include "MantidAPI/IFitFunction.h"
#include "MantidAPI/Jacobian.h"
#include "MantidAPI/IConstraint.h"
#include "MantidAPI/ParameterTie.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/IPropertyManager.h"
#include <boost/lexical_cast.hpp>
#include <sstream>
......@@ -31,53 +33,6 @@ void IFitFunction::functionDeriv(Jacobian* out)
throw ("No derivative IFitFunction provided");
}
//void IFitFunction::updateActive(const double* in)
//{
// if (in)
// for(size_t i=0;i<nActive();i++)
// {
// setActiveParameter(i,in[i]);
// }
// applyTies();
//}
//
//void IFitFunction::setActiveParameter(size_t i,double value)
//{
// size_t j = indexOfActive(i);
// setParameter(j,value,false);
//}
//
//double IFitFunction::activeParameter(size_t i)const
//{
// size_t j = indexOfActive(i);
// return getParameter(j);
//}
//ParameterTie* IFitFunction::createTie(const std::string& parName)
//{
// return new ParameterTie(this,parName);
//}
//
//ParameterTie* IFitFunction::tie(const std::string& parName,const std::string& expr)
//{
// ParameterTie* tie = this->createTie(parName);
// size_t i = getParameterIndex(*tie);
// //if (i < 0)
// //{
// // delete tie;
// // throw std::logic_error("Parameter "+parName+" was not found.");
// //}
//
// tie->set(expr);
// addTie(tie);
// this->removeActive(i);
// return tie;
//}
//
//void IFitFunction::removeTie(const std::string& parName)
//{
// size_t i = parameterIndex(parName);
// this->removeTie(i);
//}
/**
* If any of the parameters do not satisfy a constraint penalty values will be added to the function output.
......@@ -154,234 +109,31 @@ std::ostream& operator<<(std::ostream& ostr,const IFitFunction& f)
return ostr;
}
///**
// * Const attribute visitor returning the type of the attribute
// */
//class AttType: public IFitFunction::ConstAttributeVisitor<std::string>
//{
//protected:
// /// Apply if string
// std::string apply(const std::string&)const{return "std::string";}
// /// Apply if int
// std::string apply(const int&)const{return "int";}
// /// Apply if double
// std::string apply(const double&)const{return "double";}
//};
//
//std::string IFitFunction::Attribute::type()const
//{
// AttType tmp;
// return apply(tmp);
//}
//
///**
// * Const attribute visitor returning the type of the attribute
// */
//class AttValue: public IFitFunction::ConstAttributeVisitor<std::string>
//{
//public:
// AttValue(bool quoteString=false) :
// IFitFunction::ConstAttributeVisitor<std::string>(),
// m_quoteString(quoteString)
// {
// }
//
//protected:
// /// Apply if string
// std::string apply(const std::string& str)const
// {
// return (m_quoteString) ? std::string("\"" + str + "\"") : str;
// }
// /// Apply if int
// std::string apply(const int& i)const{return boost::lexical_cast<std::string>(i);}
// /// Apply if double
// std::string apply(const double& d)const{return boost::lexical_cast<std::string>(d);}
//
//private:
// /// Flag to quote a string value returned
// bool m_quoteString;
//};
//
//std::string IFitFunction::Attribute::value()const
//{
// AttValue tmp(m_quoteValue);
// return apply(tmp);
//}
//
//std::string IFitFunction::Attribute::asString()const
//{
// if( m_quoteValue ) return asQuotedString();
//
// try
// {
// return boost::get<std::string>(m_data);
// }
// catch(...)
// {
// throw std::runtime_error("Trying to access a "+type()+" attribute "
// "as string");
// }
//}
//
//std::string IFitFunction::Attribute::asQuotedString()const
//{
// std::string attr;
//
// try
// {
// attr = boost::get<std::string>(m_data);
// }
// catch(...)
// {
// throw std::runtime_error("Trying to access a "+type()+" attribute "
// "as string");
// }
// std::string quoted(attr);
// if( *(attr.begin()) != '\"' ) quoted = "\"" + attr;
// if( *(quoted.end() - 1) != '\"' ) quoted += "\"";
//
// return quoted;
//}
//
//std::string IFitFunction::Attribute::asUnquotedString()const
//{
// std::string attr;
//
// try
// {
// attr = boost::get<std::string>(m_data);
// }
// catch(...)
// {
// throw std::runtime_error("Trying to access a "+type()+" attribute "
// "as string");
// }
// std::string unquoted(attr);
// if( *(attr.begin()) == '\"' ) unquoted = std::string(attr.begin() + 1, attr.end() - 1);
// if( *(unquoted.end() - 1) == '\"' ) unquoted = std::string(unquoted.begin(), unquoted.end() - 1);
//
// return unquoted;
//}
//
//int IFitFunction::Attribute::asInt()const
//{
// try
// {
// return boost::get<int>(m_data);
// }
// catch(...)
// {
// throw std::runtime_error("Trying to access a "+type()+" attribute "
// "as int");
// }
//}
//
//double IFitFunction::Attribute::asDouble()const
//{
// try
// {
// return boost::get<double>(m_data);
// }
// catch(...)
// {
// throw std::runtime_error("Trying to access a "+type()+" attribute "
// "as double");
// }
//}
//
///** Sets new value if attribute is a string. If the type is wrong
// * throws an exception
// * @param str :: The new value
// */
//void IFitFunction::Attribute::setString(const std::string& str)
//{
// try
// {
// boost::get<std::string>(m_data) = str;
// }
// catch(...)
// {
// throw std::runtime_error("Trying to access a "+type()+" attribute "
// "as string");
// }
//}
//
///** Sets new value if attribute is a double. If the type is wrong
// * throws an exception
// * @param d :: The new value
// */
//void IFitFunction::Attribute::setDouble(const double& d)
//{
// try
// {
// boost::get<double>(m_data) = d;
// }
// catch(...)
// {
// throw std::runtime_error("Trying to access a "+type()+" attribute "
// "as double");
// }
//}
//
///** Sets new value if attribute is an int. If the type is wrong
// * throws an exception
// * @param i :: The new value
// */
//void IFitFunction::Attribute::setInt(const int& i)
//{
// try
// {
// boost::get<int>(m_data) = i;
// }
// catch(...)
// {
// throw std::runtime_error("Trying to access a "+type()+" attribute "
// "as int");
// }
//}
//
///**
// * Attribute visitor setting new value to an attribute
// */
//class SetValue: public IFitFunction::AttributeVisitor<>
//{
//public:
// /**
// * Constructor
// * @param value :: The value to set
// */
// SetValue(const std::string& value):m_value(value){}
//protected:
// /// Apply if string
// void apply(std::string& str)const{str = m_value;}
// /// Apply if int
// void apply(int& i)const
// {
// std::istringstream istr(m_value+" ");
// istr >> i;
// if (!istr.good()) throw std::invalid_argument("Failed to set int attribute "
// "from string "+m_value);
// }
// /// Apply if double
// void apply(double& d)const
// {
// std::istringstream istr(m_value+" ");
// istr >> d;
// if (!istr.good()) throw std::invalid_argument("Failed to set double attribute "
// "from string "+m_value);
// }
//private:
// std::string m_value; ///<the value as a string
//};
//
///** Set value from a string. Throws exception if the string has wrong format
// * @param str :: String representation of the new value
// */
//void IFitFunction::Attribute::fromString(const std::string& str)
//{
// SetValue tmp(str);
// apply(tmp);
//}
} // namespace API
} // namespace Mantid
///\cond TEMPLATE
namespace Mantid
{
namespace Kernel
{
template<> MANTID_API_DLL
boost::shared_ptr<Mantid::API::IFitFunction> IPropertyManager::getValue<boost::shared_ptr<Mantid::API::IFitFunction> >(const std::string &name) const
{
PropertyWithValue<boost::shared_ptr<Mantid::API::IFitFunction> >* prop =
dynamic_cast<PropertyWithValue<boost::shared_ptr<Mantid::API::IFitFunction> >*>(getPointerToProperty(name));
if (prop)
{
return *prop;
}
else
{
std::string message = "Attempt to assign property "+ name +" to incorrect type. Expected IFitFunction.";
throw std::runtime_error(message);
}
}
} // namespace Kernel
} // namespace Mantid
///\endcond TEMPLATE
#ifndef FUNCTIONPROPERTYTEST_H_
#define FUNCTIONPROPERTYTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidAPI/FunctionProperty.h"
#include "MantidAPI/FunctionFactory.h"
#include "MantidAPI/ParamFunction.h"
#include <boost/shared_ptr.hpp>
using namespace Mantid::Kernel;
using namespace Mantid::API;
class FunctionPropertyTest_Function: public virtual ParamFunction, public virtual IFitFunction
{
public:
FunctionPropertyTest_Function()
{
this->declareParameter("A",1.0);
this->declareParameter("B",2.0);
}
virtual std::string name()const {return "FunctionPropertyTest_Function";}
virtual void setWorkspace(boost::shared_ptr<const Workspace>) {}
virtual void function(FunctionDomain&)const {}
virtual boost::shared_ptr<const Workspace> getWorkspace()const {return boost::shared_ptr<const Workspace>();}
virtual void setWorkspace(boost::shared_ptr<const Workspace>,bool) {}