Newer
Older
Russell Taylor
committed
#ifndef MANTID_KERNEL_WORKSPACEPROPERTY_H_
#define MANTID_KERNEL_WORKSPACEPROPERTY_H_
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/PropertyWithValue.h"
Russell Taylor
committed
#include "MantidAPI/AnalysisDataService.h"
#include <boost/shared_ptr.hpp>
Russell Taylor
committed
Russell Taylor
committed
namespace Mantid
{
Russell Taylor
committed
{
/** @class WorkspaceProperty WorkspaceProperty.h Kernel/WorkspaceProperty.h
A property class for workspaces. Inherits from PropertyWithValue, with the value being
a pointer to the workspace type given to the WorkspaceProperty constructor. This kind
of property also holds the name of the workspace (as used by the AnalysisDataService)
and an indication of whether it is an input or output to an algorithm (or both).
Russell Taylor
committed
The pointers to the workspaces are fetched from the ADS when the properties are validated
(i.e. when the PropertyManager::validateProperties() method calls isValid() ).
Pointers to output workspaces are also fetched, if they exist, and can then be used within
an algorithm. (An example of when this might be useful is if the user wants to write the
output into the same workspace as is used for input - this avoids creating a new workspace
and the overwriting the old one at the end.)
Russell Taylor
committed
@author Russell Taylor, Tessella Support Services plc
@date 10/12/2007
Russell Taylor
committed
Copyright © 2007-8 STFC Rutherford Appleton Laboratory
Russell Taylor
committed
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/>.
Russell Taylor
committed
Russell Taylor
committed
File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>.
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
template <typename TYPE>
class WorkspaceProperty : public Kernel::PropertyWithValue< boost::shared_ptr<TYPE> >, public IWorkspaceProperty
Russell Taylor
committed
{
Russell Taylor
committed
public:
Russell Taylor
committed
/** Constructor.
* Sets the property and workspace names but initialises the workspace pointer to null.
* @param name The name to assign to the property
* @param wsName The name of the workspace
* @param direction Whether this is a Direction::Input, Direction::Output or Direction::InOut (Input & Output) workspace
* @throw std::out_of_range if the direction argument is not a member of the Direction enum (i.e. 0-2)
*/
WorkspaceProperty( const std::string &name, const std::string &wsName, const unsigned int direction ) :
Roman Tolchenov
committed
Kernel::PropertyWithValue <boost::shared_ptr<TYPE> >( name, boost::shared_ptr<TYPE>( ), direction ),
m_workspaceName( wsName )
Russell Taylor
committed
{
}
/// Copy constructor
WorkspaceProperty( const WorkspaceProperty& right ) :
Roman Tolchenov
committed
m_workspaceName( right.m_workspaceName )
Russell Taylor
committed
{
}
Russell Taylor
committed
Russell Taylor
committed
/// Copy assignment operator. Only copies the value (i.e. the pointer to the workspace)
WorkspaceProperty& operator=( const WorkspaceProperty& right )
{
if ( &right == this ) return *this;
Kernel::PropertyWithValue< boost::shared_ptr<TYPE> >::operator=( right );
Russell Taylor
committed
return *this;
}
Russell Taylor
committed
// Unhide the base class assignment operator
using Kernel::PropertyWithValue< boost::shared_ptr<TYPE> >::operator=;
Russell Taylor
committed
Russell Taylor
committed
/// Virtual destructor
virtual ~WorkspaceProperty()
{
}
/** Get the name of the workspace
* @return The workspace's name
*/
virtual std::string value() const
{
return m_workspaceName;
}
/** Set the name of the workspace
* @param value The new name for the workspace
*/
Russell Taylor
committed
virtual bool setValue( const std::string& value )
{
if ( ! value.empty() )
{
m_workspaceName = value;
Russell Taylor
committed
Kernel::PropertyWithValue<boost::shared_ptr<TYPE> >::m_isDefault = false;
return true;
}
// Setting an empty workspace name is not allowed
Russell Taylor
committed
return false;
}
Russell Taylor
committed
/** Checks whether the property is valid.
* To be valid, a property must not have an empty name and must exist in the AnalysisDataService
* if it is an input workspace (Direction::Input or Direction::InOut).
* This method also fetches the pointer to an output workspace, if it exists in the ADS.
Russell Taylor
committed
* @returns True if the property is valid, otherwise false.
*/
virtual const bool isValid() const
Russell Taylor
committed
{
// Assume that any declared WorkspaceProperty must have a name set (i.e. is not an optional property)
if ( m_workspaceName.empty() ) return false;
Russell Taylor
committed
Workspace_sptr ws = AnalysisDataService::Instance().retrieve(m_workspaceName);
// Check retrieved workspace is the type that it should be
Kernel::PropertyWithValue< boost::shared_ptr<TYPE> >::m_value = boost::dynamic_pointer_cast<TYPE>(ws);
if ( ! Kernel::PropertyWithValue< boost::shared_ptr<TYPE> >::m_value ) return false;
// Only concerned with failing to find workspace in ADS if it's an input type
if ( !this->operator()() &&
(( Kernel::PropertyWithValue<boost::shared_ptr<TYPE> >::direction() == 0 ) ||
( Kernel::PropertyWithValue<boost::shared_ptr<TYPE> >::direction() == 2 )) )
{
Russell Taylor
committed
return false;
}
else
{
return true;
}
Russell Taylor
committed
}
Russell Taylor
committed
Russell Taylor
committed
return true;
}
/** Returns the current contents of the AnalysisDataService for input workspaces.
* For output workspaces, an empty vector is returned
*/
virtual const std::vector<std::string> allowedValues() const
{
if ( ( Kernel::PropertyWithValue<boost::shared_ptr<TYPE> >::direction() == 0 ) ||
( Kernel::PropertyWithValue<boost::shared_ptr<TYPE> >::direction() == 2 ) )
{
// If an input workspace, get the list of workspaces currently in the ADS
return AnalysisDataService::Instance().getObjectNames();
}
else
{
// For output workspaces, just return an empty vector
return std::vector<std::string>();
}
}
Russell Taylor
committed
Russell Taylor
committed
virtual const Kernel::PropertyHistory createHistory() const
{
return Kernel::PropertyHistory(this->name(),this->value(),this->type(),this->isDefault(),Kernel::PropertyWithValue<boost::shared_ptr<TYPE> >::direction());
Russell Taylor
committed
}
/** If this is an output workspace, store it into the AnalysisDataService
* @return True if the workspace is an output workspace and has been stored
* @throw std::runtime_error if unable to store the workspace successfully
*/
virtual bool store()
Russell Taylor
committed
{
Matt Clarke
committed
bool result = false;
Russell Taylor
committed
if ( Kernel::PropertyWithValue<boost::shared_ptr<TYPE> >::direction() )
Russell Taylor
committed
{
// Check that workspace exists
if ( ! this->operator()() ) throw std::runtime_error("WorkspaceProperty doesn't point to a workspace");
// Note use of addOrReplace rather than add
API::AnalysisDataService::Instance().addOrReplace(m_workspaceName, this->operator()() );
Matt Clarke
committed
result = true;
Russell Taylor
committed
}
Russell Taylor
committed
Matt Clarke
committed
return result;
Russell Taylor
committed
}
Russell Taylor
committed
Workspace_sptr getWorkspace() const
Russell Taylor
committed
Russell Taylor
committed
private:
Russell Taylor
committed
/// Reset the pointer to the workspace
void clear()
{
Kernel::PropertyWithValue< boost::shared_ptr<TYPE> >::m_value = boost::shared_ptr<TYPE>();
}
Russell Taylor
committed
/// The name of the workspace (as used by the AnalysisDataService)
std::string m_workspaceName;
Russell Taylor
committed
};
} // namespace API
} // namespace Mantid
Russell Taylor
committed
#endif /*MANTID_KERNEL_WORKSPACEPROPERTY_H_*/