diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/ExtractWorkspace.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/ExtractWorkspace.h
new file mode 100644
index 000000000000..aea2f398e4e7
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/api/ExtractWorkspace.h
@@ -0,0 +1,43 @@
+#ifndef MANTID_PYTHONINTERFACE_EXTRACTWORKSPACE_H_
+#define MANTID_PYTHONINTERFACE_EXTRACTWORKSPACE_H_
+/**
+ Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+ National Laboratory & European Spallation Source
+
+ 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 .
+
+ File change history is stored at:
+ Code Documentation is available at:
+*/
+#include
+
+#include
+
+namespace Mantid {
+namespace PythonInterface {
+
+struct ExtractWorkspace {
+ ExtractWorkspace(const boost::python::object &pyvalue);
+ bool check() const;
+ const API::Workspace_sptr operator()() const;
+
+private:
+ API::Workspace_sptr m_value;
+};
+}
+}
+
+#endif // MANTID_PYTHONINTERFACE_EXTRACTWORKSPACE_H_
diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/DowncastingPolicies.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/DowncastingPolicies.h
deleted file mode 100644
index d13f07a7e0ab..000000000000
--- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Policies/DowncastingPolicies.h
+++ /dev/null
@@ -1,130 +0,0 @@
-#ifndef MANITD_PYTHONINTERFACE_TOWEAKPTRWITHDOWNCASTIMPL_H_
-#define MANITD_PYTHONINTERFACE_TOWEAKPTRWITHDOWNCASTIMPL_H_
-/**
- Copyright © 2012 ISIS Rutherford Appleton Laboratory, NScD Oak Ridg
- National Laboratory & European Spallation Source
-
- 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 .
-
- File change history is stored at:
- Code Documentation is available at:
- */
-#include "MantidPythonInterface/kernel/Registry/DowncastRegistry.h"
-#include
-
-#include // for PyObject
-
-#include
-#include
-
-namespace Mantid {
-
-namespace PythonInterface {
-
-//--------------------------------------------------------------------------------
-// Implementations
-//--------------------------------------------------------------------------------
-///@cond
-namespace // anonymous namespace with the implementation
- {
-template struct AsWeakPtr {
- static PyObject *apply(const Registry::DowncastDataItem &caster,
- const ArgType &p) {
- return caster.toPythonAsWeakPtr(p);
- }
-};
-template struct AsSharedPtr {
- static PyObject *apply(const Registry::DowncastDataItem &caster,
- const ArgType &p) {
- return caster.toPythonAsSharedPtr(p);
- }
-};
-
-/**
- * Converts a ArgType object to a Python object and performs an downcast if it
- * can.
- * Only used for DataItem's at the moment so ArgType will always equal
- * DataItem_sptr
- * but the template is kept for possible extension in the future
- */
-template struct DowncastImpl {
- inline PyObject *operator()(const ArgType &p) const {
- if (!p)
- Py_RETURN_NONE;
- return CasterType::apply(Registry::DowncastRegistry::retrieve(p->id()), p);
- }
-
- inline PyTypeObject const *get_pytype() const {
- return boost::python::converter::registered::converters
- .to_python_target_type();
- }
-};
-
-} // end
-///@endcond
-
-namespace Policies {
-/**
- * NOTE: These only workspace for functions/methods returning a shared_ptr
- * where T is convertible to a Kernel::DataItem as it requires
- * the presence of an id() method
- */
-
-//--------------------------------------------------------------------------------
-// ToWeakPtrWithDowncast
-//--------------------------------------------------------------------------------
-/**
- * This defines the structure as required by boost::python.
- * If T is convertible to a shared_ptr then it calls
- * ToWeakPtrWithDownastImpl or else just return the value as is
- */
-struct ToWeakPtrWithDowncast {
- template struct apply {
- // if convertible to shared_ptr then call
- // ToWeakPtrWithDownCastImpl or else
- // just return the value as is
- typedef typename boost::mpl::if_c<
- boost::is_convertible>::value,
- DowncastImpl>,
- boost::python::to_python_value>::type type;
- };
-};
-
-//--------------------------------------------------------------------------------
-// ToSharedPtrWithDowncast
-//--------------------------------------------------------------------------------
-/**
- * This defines the structure as required by boost::python.
- * If T is convertible to a shared_ptr then it calls
- * ToSharedPtrWithDowncastImpl or else just return the value as is
- */
-struct ToSharedPtrWithDowncast {
- template struct apply {
- // if convertible to shared_ptr then call
- // ToWeakPtrWithDownCastImpl or else
- // just return the value as is
- typedef typename boost::mpl::if_c<
- boost::is_convertible>::value,
- DowncastImpl>,
- boost::python::to_python_value>::type type;
- };
-};
-
-} // Policies
-}
-} // namespace Mantid::PythonInterface
-
-#endif /* MANITD_PYTHONINTERFACE_TOWEAKPTRWITHDOWNCASTIMPL_H_ */
diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValueExporter.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValueExporter.h
index 558c583ee3ce..168d4d80df41 100644
--- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValueExporter.h
+++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/PropertyWithValueExporter.h
@@ -25,12 +25,12 @@
*/
#include "MantidKernel/PropertyWithValue.h"
-#include "MantidPythonInterface/kernel/Policies/DowncastingPolicies.h"
#ifndef Q_MOC_RUN
#include
#include
#include
+#include
#endif
namespace Mantid {
@@ -38,18 +38,17 @@ namespace PythonInterface {
/**
* A helper struct to export PropertyWithValue<> types to Python.
*/
-template struct PropertyWithValueExporter {
+template
+struct PropertyWithValueExporter {
static void define(const char *pythonClassName) {
using namespace boost::python;
using namespace Mantid::Kernel;
class_, bases, boost::noncopyable>(
pythonClassName, no_init)
- .add_property(
- "value",
- make_function(
- &PropertyWithValue::operator(),
- return_value_policy()));
+ .add_property("value",
+ make_function(&PropertyWithValue::operator(),
+ return_value_policy()));
}
};
}
diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/DowncastDataItem.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/DowncastDataItem.h
deleted file mode 100644
index 455c759ecbda..000000000000
--- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/DowncastDataItem.h
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifndef MANTID_PYTHONINTERFACE_DOWNCASTDATAITEM_H_
-#define MANTID_PYTHONINTERFACE_DOWNCASTDATAITEM_H_
-/**
- Copyright © 2014 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
- National Laboratory & European Spallation Source
-
- 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 .
-
- File change history is stored at:
- Code Documentation is available at:
-*/
-#include "MantidKernel/DataItem.h"
-#include "MantidPythonInterface/kernel/WeakPtr.h"
-
-#include
-#include // for PyObject
-#include
-
-namespace Mantid {
-namespace PythonInterface {
-namespace Registry {
-/**
- * Interface class so that we can store derived objects in a map
- * It defines functions for converting shared_ptr into
- * Python objects of the required type
- */
-struct DLLExport DowncastDataItem {
- virtual ~DowncastDataItem() {}
- /// Convert a shared_ptr to a python object that holds a shared_ptr
- virtual PyObject *
- toPythonAsSharedPtr(const Kernel::DataItem_sptr &data) const = 0;
- /// Convert a shared_ptr to a python object that holds a weak_ptr
- virtual PyObject *
- toPythonAsWeakPtr(const Kernel::DataItem_sptr &data) const = 0;
- /// Convert a Python object to a DataItem_sptr
- virtual Kernel::DataItem_sptr
- fromPythonAsSharedPtr(const boost::python::object &data) const = 0;
-};
-
-/**
- * Implementation of DowncastDataItem interface
- * @tparam CastedType The final type that the input item should be cast to when
- * going to Python
- */
-template
-struct DLLExport DowncastToType : public DowncastDataItem {
- typedef boost::shared_ptr PythonType_sptr;
- typedef boost::weak_ptr PythonType_wptr;
-
- /**
- * Convert a shared_ptr to a python object that holds a
- * shared_ptr
- * @param data The original C++ DataItem pointer
- * @returns A new PyObject holding the requested data
- */
- PyObject *toPythonAsSharedPtr(const Kernel::DataItem_sptr &data) const {
- using namespace boost::python;
- typedef to_python_value ToSharedValue;
- // boost python handles NULL pointers by converting them to None objects
- return ToSharedValue()(boost::dynamic_pointer_cast(data));
- }
- /**
- * Convert a shared_ptr to a python object that holds a
- * weak_ptr
- * @param data The original C++ DataItem pointer
- * @returns A new PyObject holding the requested data
- */
- PyObject *toPythonAsWeakPtr(const Kernel::DataItem_sptr &data) const {
- using namespace boost::python;
- typedef to_python_value ToWeakValue;
- return ToWeakValue()(
- PythonType_wptr(boost::dynamic_pointer_cast(data)));
- }
- /**
- * Convert a Python object to a boost::shared_ptr
- * @param data A Python object that should be holding either a
- * boost::shared_ptr
- * or a boost::weak_ptr
- */
- Kernel::DataItem_sptr
- fromPythonAsSharedPtr(const boost::python::object &data) const {
- using namespace boost::python;
- // If we can extract a weak pointer then we must construct the shared
- // pointer
- // from the weak pointer itself to ensure the new shared_ptr has the correct
- // use count.
- // The order is important as if we try the shared_ptr first then
- // boost::python will
- // just construct a brand new shared pointer for the object rather than
- // converting from the
- // stored weak one.
- extract weakPtr(data);
- if (weakPtr.check()) {
- return boost::dynamic_pointer_cast(weakPtr().lock());
- } else {
- return boost::dynamic_pointer_cast(
- extract(data)());
- }
- }
-};
-
-} // namespace Registry
-} // namespace PythonInterface
-} // namespace Mantid
-
-#endif /* MANTID_PYTHONINTERFACE_DOWNCASTDATAITEM_H_ */
diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/DowncastRegistry.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/DowncastRegistry.h
deleted file mode 100644
index c3c0befd01d0..000000000000
--- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/DowncastRegistry.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef MANTID_PYTHONINTERFACE_DOWNCASTREGISTRY_H_
-#define MANTID_PYTHONINTERFACE_DOWNCASTREGISTRY_H_
-/**
- Copyright © 2012 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
- National Laboratory & European Spallation Source
-
- 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 .
-
- File change history is stored at:
- Code Documentation is available at:
-*/
-#include "MantidPythonInterface/kernel/Registry/DowncastDataItem.h"
-#include
-
-namespace Mantid {
-namespace PythonInterface {
-namespace Registry {
-// We currently only expose up to the API level in Python. Due to the
-// inner workings of boost::python this means that if a DataItem_sptr or
-// Workspace_sptr is returned from a particular method then it is not
-// automatically converted to the most derived pointer that boost::python
-// knows about.
-//
-// In order for returned objects to be of any use in Python then they must be
-// cast to the highest-type that has been exposed, i.e a Workspace2D should be
-// return as a MatrixWorkspace or a MaskWorkspace should be returned as an
-// IMaskWorkspace. Here we define a registry that allows the required mappings
-// to be defined and used.
-//
-// The mappings are between the string returned by the id() method and a simple
-// templated DowncastDataItem converter class.
-
-/**
- * A simple static class with methods to subscribe and retrieve the relevant
- * DowncastDataItem object
- */
-class DLLExport DowncastRegistry {
-public:
- /**
- * Create an entry in the registry for a type given by the template type
- * that will be identified by the id string given
- * @param id string that will be returned by the concrete types id() method
- */
- template static void subscribe(const std::string &id) {
- subscribe(id, new DowncastToType());
- }
- /// Retrieve a registered casting object
- static const DowncastDataItem &retrieve(const std::string &id);
-
-private:
- /// Implementation for the templated subscribe for a given id. Keeps impl out
- /// of header
- static void subscribe(const std::string &id, const DowncastDataItem *caster);
-};
-}
-}
-}
-
-#endif /* MANTID_PYTHONINTERFACE_DOWNCASTREGISTRY_H_ */
diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/DataItemInterface.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h
similarity index 90%
rename from Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/DataItemInterface.h
rename to Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h
index 8250d812b784..3c69a5b0a711 100644
--- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/DataItemInterface.h
+++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h
@@ -24,6 +24,8 @@
*/
#include "MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h"
#include "MantidPythonInterface/kernel/Registry/TypeRegistry.h"
+#include "MantidPythonInterface/kernel/WeakPtr.h"
+
#include
namespace Mantid {
@@ -37,11 +39,11 @@ namespace Registry {
* - Calls register_ptr_to_python>
* - Registers a new PropertyValueHandler for a boost::shared_ptr
*/
-template struct DLLExport DataItemInterface {
+template struct DLLExport RegisterWorkspacePtrToPython {
typedef boost::shared_ptr IType_sptr;
typedef boost::weak_ptr IType_wptr;
/// Constructor
- DataItemInterface() {
+ RegisterWorkspacePtrToPython() {
using namespace boost::python;
using namespace Registry;
@@ -50,11 +52,6 @@ template struct DLLExport DataItemInterface {
// properties can only ever store pointers to these
TypeRegistry::subscribe>();
}
- /// Register a downcast for this ID
- DataItemInterface &castFromID(const std::string &id) {
- using namespace Registry;
- return *this;
- }
};
}
}
diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h
index fbb6a7bfbb5f..b784421835f7 100644
--- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h
+++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/Registry/TypedPropertyValueHandler.h
@@ -22,16 +22,19 @@
File change history is stored at:
Code Documentation is available at:
*/
+#include "MantidPythonInterface/api/ExtractWorkspace.h"
#include "MantidPythonInterface/kernel/Registry/PropertyValueHandler.h"
-#include "MantidPythonInterface/kernel/Registry/DowncastRegistry.h"
-
#include "MantidPythonInterface/kernel/IsNone.h" // includes object.hpp
+
#include "MantidAPI/Workspace.h"
#include "MantidKernel/PropertyWithValue.h"
#include "MantidKernel/IPropertyManager.h"
#include
#include
+#include
+#include
+
#include
namespace Mantid {
@@ -88,7 +91,7 @@ struct DLLExport TypedPropertyValueHandler : public PropertyValueHandler {
};
//
-// Specialization for shared_ptr types that can be set via weak pointers
+// Specialization for shared_ptr types. They need special handling for workspaces
//
template
struct DLLExport TypedPropertyValueHandler>
@@ -109,21 +112,7 @@ struct DLLExport TypedPropertyValueHandler>
*/
void set(Kernel::IPropertyManager *alg, const std::string &name,
const boost::python::object &value) const {
- using namespace boost::python;
- using Mantid::API::Workspace_sptr;
- typedef boost::weak_ptr Workspace_wptr;
-
- Workspace_sptr p;
- extract weakExtract(value);
- extract sharedExtract(value);
- if(weakExtract.check()) {
- p = weakExtract().lock();
- } else if(sharedExtract.check()) {
- p = sharedExtract();
- } else {
- throw std::runtime_error("Unable to add unknown object type to ADS");
- }
- alg->setProperty(name, boost::dynamic_pointer_cast(p));
+ alg->setProperty(name, boost::dynamic_pointer_cast(ExtractWorkspace(value)()));
}
/**
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/api/CMakeLists.txt
index cc3435e40577..5627f30ebfdb 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/CMakeLists.txt
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/CMakeLists.txt
@@ -80,6 +80,7 @@ set ( SRC_FILES
src/PythonAlgorithm/AlgorithmAdapter.cpp
src/PythonAlgorithm/DataProcessorAdapter.cpp
src/CloneMatrixWorkspace.cpp
+ src/ExtractWorkspace.cpp
)
set ( INC_FILES
@@ -91,6 +92,7 @@ set ( INC_FILES
${HEADER_DIR}/api/PythonAlgorithm/DataProcessorAdapter.h
${HEADER_DIR}/api/BinaryOperations.h
${HEADER_DIR}/api/CloneMatrixWorkspace.h
+ ${HEADER_DIR}/api/ExtractWorkspace.h
${HEADER_DIR}/api/WorkspacePropertyExporter.h
)
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp
index c15bd4e9b70e..773955d9bd63 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp
@@ -1,223 +1,220 @@
#include "MantidPythonInterface/api/Algorithms/RunPythonScript.h"
+#include "MantidPythonInterface/api/ExtractWorkspace.h"
#include "MantidPythonInterface/kernel/Environment/ErrorHandling.h"
#include "MantidPythonInterface/kernel/Environment/Threading.h"
-#include "MantidPythonInterface/kernel/Policies/DowncastingPolicies.h"
-#include "MantidPythonInterface/kernel/Registry/DowncastDataItem.h"
+#include "MantidPythonInterface/kernel/IsNone.h"
#include "MantidKernel/MandatoryValidator.h"
#include
#include
#include
#include
+#include
#include
-namespace Mantid
-{
- namespace PythonInterface
- {
-
- /// Algorithm's name for identification. @see Algorithm::name
- const std::string RunPythonScript::name() const { return "RunPythonScript";}
-
- /// Algorithm's version for identification. @see Algorithm::version
- int RunPythonScript::version() const { return 1;}
-
- /// Algorithm's category for identification. @see Algorithm::category
- const std::string RunPythonScript::category() const { return "DataHandling\\LiveData\\Support"; }
-
- /// @copydoc Algorithm::summary
- const std::string RunPythonScript::summary() const { return "Executes a snippet of Python code"; }
-
- /**
- * Override standard group behaviour so that the algorithm is only
- * called once for the whole group
- */
- bool RunPythonScript::checkGroups()
- {
- return false;
- }
-
- /**
- * Initialize the algorithm's properties.
- */
- void RunPythonScript::init()
- {
- using namespace API;
- using namespace Kernel;
-
- declareProperty(new WorkspaceProperty("InputWorkspace","",Direction::Input, PropertyMode::Optional),
- "An input workspace that the python code will modify."
- "The workspace will be in the python variable named 'input'.");
- declareProperty("Code", "", "Python code (can be on multiple lines).",
- boost::make_shared >());
- declareProperty(new WorkspaceProperty("OutputWorkspace","",Direction::Output, PropertyMode::Optional),
- "An output workspace to be produced by the python code."
- "The workspace will be in the python variable named 'output'.");
- }
-
- //----------------------------------------------------------------------------------------------
- /** Execute the algorithm.
- */
- void RunPythonScript::exec()
- {
- using namespace API;
-
- Workspace_sptr outputWS = executeScript(scriptCode());
- setProperty("OutputWorkspace", outputWS);
- }
-
- /**
- * Builds the code string from the user input. The user script is wrapped
- * in a tiny PythonAlgorithm to 'fool' the Python framework into
- * creating a child algorithm for each algorithm that is run. See
- * PythonInterface/mantid/simpleapi.py:_create_algorithm_object
- * This has to be the case to get the workspace locking correct.
- *
- * The code assumes that the scope in which it is executed has defined
- * the variables input & output.
- *
- * @return A string containing the code ready to execute
- */
- std::string RunPythonScript::scriptCode() const
- {
- std::string userCode = getPropertyValue("Code");
- // Unify line endings
- boost::regex eol("\\R"); // \R is Perl syntax for matching any EOL sequence
- userCode = boost::regex_replace(userCode, eol, "\n"); // converts all to LF
-
- // Wrap and indent the user code (see method documentation)
- std::istringstream is(userCode);
- std::ostringstream os;
- const char * indent = " ";
- os << "import mantid\n"
- << "from mantid.simpleapi import *\n"
- << "class _DUMMY_ALG(mantid.api.PythonAlgorithm):\n"
- << indent << "def PyExec(self, input=None,output=None):\n";
- std::string line;
- while(getline(is, line))
- {
- os << indent << indent << line << "\n";
- }
- os << indent << indent << "return input,output\n"; // When executed the global scope needs to know about input,output so we return them
- os << "input,output = _DUMMY_ALG().PyExec(input,output)";
-
- if(g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) g_log.debug() << "Full code to be executed:\n" << os.str() << "\n";
- return os.str();
- }
-
- /**
- * Sets up the code context & executes it.
- * A python dictionary of local attributes is setup to contain a reference to the input workspace
- * & the output workspace. This together with the __main__ global dictionary defines the execution
- * context
- * @param script A string containing a read-to-execute script
- * @return A pointer to the output workspace if one was generated. If one was not then this is an empty pointer
- */
- boost::shared_ptr RunPythonScript::executeScript(const std::string & script) const
- {
- using namespace API;
- using namespace boost::python;
-
- // Execution
- Environment::GlobalInterpreterLock gil;
- auto locals = doExecuteScript(script);
- return extractOutputWorkspace(locals);
- }
-
- /**
- * Uses the __main__ object to define the globals context and together with the given locals
- * dictionary executes the script. The GIL is acquired and released during this call
- * @param script The script code
- * @returns A dictionary defining the input & output variables
- */
- boost::python::dict RunPythonScript::doExecuteScript(const std::string & script) const
- {
- // Retrieve the main module.
- auto main = boost::python::import("__main__");
- // Retrieve the main module's namespace
- boost::python::object globals(main.attr("__dict__"));
- boost::python::dict locals = buildLocals();
- try
- {
- boost::python::exec(script.c_str(), globals, locals);
- }
- catch(boost::python::error_already_set &)
- {
- Environment::throwRuntimeError();
- }
- return locals;
- }
-
- /**
- * Creates a Python dictionary containing definitions of the 'input' & 'output' variable
- * references that the script may use
- * @return A Python dictionary that can be used as the locals argument for the script execution
- */
- boost::python::dict RunPythonScript::buildLocals() const
- {
- // Define the local variable names required by the script, in this case
- // - input: Points to input workspace if one has been given
- // - output: Will point to the output workspace if one has been given
- using namespace boost::python;
-
- dict locals;
- locals["input"] = object(); // default to None
- locals["output"] = object();
-
- API::Workspace_sptr inputWS = getProperty("InputWorkspace");
- if(inputWS)
- {
- // We have a generic workspace ptr but the Python needs to see the derived type so
- // that it can access the appropriate methods for that instance
- // The ToSharedPtrWithDowncast policy is already in place for this and is used in many
- // method exports as part of a return_value_policy struct.
- // It is called manually here.
- typedef Policies::ToSharedPtrWithDowncast::apply::type WorkspaceDowncaster;
- locals["input"] = object(handle<>(WorkspaceDowncaster()(inputWS)));
- }
- std::string outputWSName = getPropertyValue("OutputWorkspace");
- if(!outputWSName.empty())
- {
- locals["output"] = object(handle<>(to_python_value()(outputWSName)));
- }
- return locals;
- }
-
-
- /**
- * If an output workspace was created then extract it from the given dictionary
- * @param locals A dictionary possibly containing an 'output' reference
- * @return A pointer to the output workspace if created, otherwise an empty pointer
- */
- boost::shared_ptr RunPythonScript::extractOutputWorkspace(const boost::python::dict & locals) const
- {
- using namespace API;
- using namespace boost::python;
-
- // Might be None, string or a workspace object
- object pyoutput = locals["output"];
- if(pyoutput.ptr() == Py_None) return Workspace_sptr();
-
- if(PyObject_HasAttrString(pyoutput.ptr(), "id"))
- {
- const auto & entry = Registry::DowncastRegistry::retrieve(call_method(pyoutput.ptr(), "id"));
- return boost::dynamic_pointer_cast(entry.fromPythonAsSharedPtr(pyoutput));
- }
- else
- {
- extract stringExtractor(pyoutput);
- if(stringExtractor.check())
- {
- // Will raise an error if the workspace does not exist as the user requested an output workspace
- // but didn't create one.
- return AnalysisDataService::Instance().retrieve(stringExtractor());
- }
- else
- {
- throw std::runtime_error("Invalid type assigned to 'output' variable. Must be a string or a Workspace object");
- }
- }
+namespace Mantid {
+namespace PythonInterface {
+
+using namespace API;
+using namespace Kernel;
+
+/// Algorithm's name for identification. @see Algorithm::name
+const std::string RunPythonScript::name() const { return "RunPythonScript"; }
+
+/// Algorithm's version for identification. @see Algorithm::version
+int RunPythonScript::version() const { return 1; }
+
+/// Algorithm's category for identification. @see Algorithm::category
+const std::string RunPythonScript::category() const {
+ return "DataHandling\\LiveData\\Support";
+}
+
+/// @copydoc Algorithm::summary
+const std::string RunPythonScript::summary() const {
+ return "Executes a snippet of Python code";
+}
+
+/**
+ * Override standard group behaviour so that the algorithm is only
+ * called once for the whole group
+ */
+bool RunPythonScript::checkGroups() { return false; }
+
+/**
+ * Initialize the algorithm's properties.
+ */
+void RunPythonScript::init() {
+ declareProperty(
+ new WorkspaceProperty("InputWorkspace", "", Direction::Input,
+ PropertyMode::Optional),
+ "An input workspace that the python code will modify."
+ "The workspace will be in the python variable named 'input'.");
+ declareProperty("Code", "", "Python code (can be on multiple lines).",
+ boost::make_shared>());
+ declareProperty(
+ new WorkspaceProperty("OutputWorkspace", "", Direction::Output,
+ PropertyMode::Optional),
+ "An output workspace to be produced by the python code."
+ "The workspace will be in the python variable named 'output'.");
+}
+
+//----------------------------------------------------------------------------------------------
+/** Execute the algorithm.
+ */
+void RunPythonScript::exec() {
+ Workspace_sptr outputWS = executeScript(scriptCode());
+ setProperty("OutputWorkspace", outputWS);
+}
+
+/**
+ * Builds the code string from the user input. The user script is wrapped
+ * in a tiny PythonAlgorithm to 'fool' the Python framework into
+ * creating a child algorithm for each algorithm that is run. See
+ * PythonInterface/mantid/simpleapi.py:_create_algorithm_object
+ * This has to be the case to get the workspace locking correct.
+ *
+ * The code assumes that the scope in which it is executed has defined
+ * the variables input & output.
+ *
+ * @return A string containing the code ready to execute
+ */
+std::string RunPythonScript::scriptCode() const {
+ std::string userCode = getPropertyValue("Code");
+ // Unify line endings
+ boost::regex eol("\\R"); // \R is Perl syntax for matching any EOL sequence
+ userCode = boost::regex_replace(userCode, eol, "\n"); // converts all to LF
+
+ // Wrap and indent the user code (see method documentation)
+ std::istringstream is(userCode);
+ std::ostringstream os;
+ const char *indent = " ";
+ os << "import mantid\n"
+ << "from mantid.simpleapi import *\n"
+ << "class _DUMMY_ALG(mantid.api.PythonAlgorithm):\n" << indent
+ << "def PyExec(self, input=None,output=None):\n";
+ std::string line;
+ while (getline(is, line)) {
+ os << indent << indent << line << "\n";
+ }
+ os << indent << indent
+ << "return input,output\n"; // When executed the global scope needs to know
+ // about input,output so we return them
+ os << "input,output = _DUMMY_ALG().PyExec(input,output)";
+
+ if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG))
+ g_log.debug() << "Full code to be executed:\n" << os.str() << "\n";
+ return os.str();
+}
+
+/**
+ * Sets up the code context & executes it.
+ * A python dictionary of local attributes is setup to contain a reference to
+ * the input workspace
+ * & the output workspace. This together with the __main__ global dictionary
+ * defines the execution
+ * context
+ * @param script A string containing a read-to-execute script
+ * @return A pointer to the output workspace if one was generated. If one was
+ * not then this is an empty pointer
+ */
+boost::shared_ptr
+RunPythonScript::executeScript(const std::string &script) const {
+ using namespace API;
+ using namespace boost::python;
+
+ // Execution
+ Environment::GlobalInterpreterLock gil;
+ auto locals = doExecuteScript(script);
+ return extractOutputWorkspace(locals);
+}
+
+/**
+ * Uses the __main__ object to define the globals context and together with the
+ * given locals
+ * dictionary executes the script. The GIL is acquired and released during this
+ * call
+ * @param script The script code
+ * @returns A dictionary defining the input & output variables
+ */
+boost::python::dict
+RunPythonScript::doExecuteScript(const std::string &script) const {
+ // Retrieve the main module.
+ auto main = boost::python::import("__main__");
+ // Retrieve the main module's namespace
+ boost::python::object globals(main.attr("__dict__"));
+ boost::python::dict locals = buildLocals();
+ try {
+ boost::python::exec(script.c_str(), globals, locals);
+ } catch (boost::python::error_already_set &) {
+ Environment::throwRuntimeError();
+ }
+ return locals;
+}
+
+/**
+ * Creates a Python dictionary containing definitions of the 'input' & 'output'
+ * variable
+ * references that the script may use
+ * @return A Python dictionary that can be used as the locals argument for the
+ * script execution
+ */
+boost::python::dict RunPythonScript::buildLocals() const {
+ // Define the local variable names required by the script, in this case
+ // - input: Points to input workspace if one has been given
+ // - output: Will point to the output workspace if one has been given
+ using namespace boost::python;
+
+ dict locals;
+ locals["input"] = object(); // default to None
+ locals["output"] = object();
+
+ API::Workspace_sptr inputWS = getProperty("InputWorkspace");
+ if (inputWS) {
+ locals["input"] =
+ object(handle<>(to_python_value()(inputWS)));
+ }
+ std::string outputWSName = getPropertyValue("OutputWorkspace");
+ if (!outputWSName.empty()) {
+ locals["output"] =
+ object(handle<>(to_python_value()(outputWSName)));
+ }
+ return locals;
+}
+
+/**
+ * If an output workspace was created then extract it from the given dictionary
+ * @param locals A dictionary possibly containing an 'output' reference
+ * @return A pointer to the output workspace if created, otherwise an empty
+ * pointer
+ */
+boost::shared_ptr RunPythonScript::extractOutputWorkspace(
+ const boost::python::dict &locals) const {
+ using namespace API;
+ using namespace boost::python;
+
+ // Might be None, string or a workspace object
+ auto pyoutput = locals.get("output");
+ if (isNone(pyoutput))
+ return Workspace_sptr();
+
+ auto ptrExtract = ExtractWorkspace(pyoutput);
+ if (ptrExtract.check()) {
+ return ptrExtract();
+ } else {
+ extract extractString(pyoutput);
+ if (extractString.check()) {
+ // Will raise an error if the workspace does not exist as the user
+ // requested
+ // an output workspace
+ // but didn't create one.
+ return AnalysisDataService::Instance().retrieve(extractString());
+ } else {
+ throw std::runtime_error(
+ "Invalid type assigned to 'output' variable. Must "
+ "be a string or a Workspace object");
}
+ }
+}
- } // namespace PythonInterface
+} // namespace PythonInterface
} // namespace Mantid
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp
index 90af321c1614..4a3773de97c0 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp
@@ -1,21 +1,17 @@
+#include "MantidPythonInterface/api/ExtractWorkspace.h"
#include "MantidPythonInterface/kernel/DataServiceExporter.h"
#include "MantidPythonInterface/kernel/TrackingInstanceMethod.h"
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/Workspace.h"
-#include
-#include
-
using namespace Mantid::API;
using namespace Mantid::Kernel;
-using Mantid::PythonInterface::DataServiceExporter;
-using Mantid::PythonInterface::TrackingInstanceMethod;
+using namespace Mantid::PythonInterface;
using namespace boost::python;
namespace {
-typedef boost::weak_ptr Workspace_wptr;
/**
* Add an item into the ADS, if it exists then an error is raised
@@ -25,19 +21,12 @@ typedef boost::weak_ptr Workspace_wptr;
*/
void addItem(AnalysisDataServiceImpl &self, const std::string &name,
const boost::python::object &item) {
- extract weakExtract(item);
- if(weakExtract.check()) {
- self.add(name, weakExtract().lock());
- return;
- }
-
- extract sharedExtract(item);
- if(sharedExtract.check()) {
- self.add(name, sharedExtract());
+ ExtractWorkspace extractWS(item);
+ if(extractWS.check()) {
+ self.add(name, extractWS());
} else {
throw std::runtime_error("Unable to add unknown object type to ADS");
}
-
}
/**
@@ -48,17 +37,11 @@ void addItem(AnalysisDataServiceImpl &self, const std::string &name,
*/
void addOrReplaceItem(AnalysisDataServiceImpl &self, const std::string &name,
const boost::python::object &item) {
- extract weakExtract(item);
- if(weakExtract.check()) {
- self.add(name, weakExtract().lock());
- return;
- }
-
- extract sharedExtract(item);
- if(sharedExtract.check()) {
- self.add(name, sharedExtract());
+ ExtractWorkspace extractWS(item);
+ if(extractWS.check()) {
+ self.addOrReplace(name, extractWS());
} else {
- throw std::runtime_error("Unable to add unknown object type to ADS");
+ throw std::runtime_error("Unable to add/replace unknown object type to ADS");
}
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp
index ca1f13e79308..d804b454a980 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp
@@ -1,25 +1,20 @@
#include "MantidPythonInterface/api/BinaryOperations.h"
-#include "MantidPythonInterface/kernel/Policies/DowncastingPolicies.h"
-#include "MantidAPI/WorkspaceOpOverloads.h"
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/AnalysisDataService.h"
-#include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/IMDHistoWorkspace.h"
#include "MantidAPI/IMDWorkspace.h"
#include "MantidAPI/MatrixWorkspace.h"
-#include "MantidAPI/IMDHistoWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/WorkspaceOpOverloads.h"
#include
-#include
-
-namespace Policies = Mantid::PythonInterface::Policies;
// clang-format off
void export_BinaryOperations()
// clang-format on
{
using namespace Mantid::API;
- using boost::python::return_value_policy;
//Operator overloads dispatch through the above structure. The typedefs save some typing
typedef IMDWorkspace_sptr(*binary_fn_md_md)(const IMDWorkspace_sptr, const IMDWorkspace_sptr, const std::string &,const std::string &,bool, bool);
@@ -38,16 +33,15 @@ void export_BinaryOperations()
using Mantid::PythonInterface::performBinaryOp;
using Mantid::PythonInterface::performBinaryOpWithDouble;
- def("performBinaryOp", (binary_fn_md_md)&performBinaryOp, return_value_policy());
- def("performBinaryOp", (binary_fn_md_gp)&performBinaryOp, return_value_policy());
- def("performBinaryOp", (binary_fn_gp_md)&performBinaryOp, return_value_policy());
- def("performBinaryOp", (binary_fn_gp_gp)&performBinaryOp, return_value_policy());
- def("performBinaryOp", (binary_fn_mh_mh)&performBinaryOp, return_value_policy());
-
- def("performBinaryOp", (binary_fn_md_db)&performBinaryOpWithDouble, return_value_policy());
- def("performBinaryOp", (binary_fn_mh_db)&performBinaryOpWithDouble, return_value_policy());
- def("performBinaryOp", (binary_fn_gp_db)&performBinaryOpWithDouble, return_value_policy());
+ def("performBinaryOp", (binary_fn_md_md)&performBinaryOp);
+ def("performBinaryOp", (binary_fn_md_gp)&performBinaryOp);
+ def("performBinaryOp", (binary_fn_gp_md)&performBinaryOp);
+ def("performBinaryOp", (binary_fn_gp_gp)&performBinaryOp);
+ def("performBinaryOp", (binary_fn_mh_mh)&performBinaryOp);
+ def("performBinaryOp", (binary_fn_md_db)&performBinaryOpWithDouble);
+ def("performBinaryOp", (binary_fn_mh_db)&performBinaryOpWithDouble);
+ def("performBinaryOp", (binary_fn_gp_db)&performBinaryOpWithDouble);
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IEventWorkspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IEventWorkspace.cpp
index af2bfc0bea8f..1eafc7d43408 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IEventWorkspace.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IEventWorkspace.cpp
@@ -1,12 +1,12 @@
#include "MantidAPI/IEventWorkspace.h"
#include "MantidAPI/IEventList.h"
-#include "MantidPythonInterface/kernel/Registry/DataItemInterface.h"
+#include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
#include
#include
using namespace Mantid::API;
-using Mantid::PythonInterface::Registry::DataItemInterface;
+using Mantid::PythonInterface::Registry::RegisterWorkspacePtrToPython;
using namespace boost::python;
/**
@@ -28,9 +28,6 @@ void export_IEventWorkspace()
.def("clearMRU", &IEventWorkspace::clearMRU, args("self"), "Clear the most-recently-used lists")
;
- DataItemInterface()
- // map IDs to this interface
- .castFromID("EventWorkspace")
- ;
+ RegisterWorkspacePtrToPython();
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDEventWorkspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDEventWorkspace.cpp
index 8bc619371670..e960e1110e11 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDEventWorkspace.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDEventWorkspace.cpp
@@ -1,20 +1,13 @@
#include "MantidAPI/IMDEventWorkspace.h"
-#include "MantidPythonInterface/kernel/Registry/DataItemInterface.h"
+#include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
#include
#include
using namespace Mantid::API;
-using Mantid::PythonInterface::Registry::DataItemInterface;
+using Mantid::PythonInterface::Registry::RegisterWorkspacePtrToPython;
using namespace boost::python;
-namespace
-{
- // THIS NUMBER SHOULD MATCH MAX_MD_DIMENSIONS_NUM IN MDEvents/inc/MantidMDEvents/MDEventFactory
- static const unsigned int MAX_MD_DIMS = 9;
- static const unsigned int NUM_EVENT_TYPES = 2;
-}
-
// clang-format off
void export_IMDEventWorkspace()
// clang-format on
@@ -33,20 +26,6 @@ void export_IMDEventWorkspace()
;
//-----------------------------------------------------------------------------------------------
- DataItemInterface entry;
- // The IDs for the MDEventWorkpaces are constructed from the event types and number of dimensions
- const char *eventTypes[NUM_EVENT_TYPES]= { "MDEvent", "MDLeanEvent" };
-
- std::ostringstream out;
- for(unsigned int i = 1; i <= MAX_MD_DIMS; ++i)
- {
- for(unsigned int j = 0; j < NUM_EVENT_TYPES; ++j)
- {
- out.str("");
- out << "MDEventWorkspace<" << eventTypes[j] << "," << i << ">";
- entry.castFromID(out.str());
- }
- }
-
+ RegisterWorkspacePtrToPython();
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp
index 24ab708188fe..0c9595268fd2 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp
@@ -1,6 +1,6 @@
#include "MantidAPI/IMDHistoWorkspace.h"
#include "MantidPythonInterface/kernel/Converters/CArrayToNDArray.h"
-#include "MantidPythonInterface/kernel/Registry/DataItemInterface.h"
+#include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
#include
#include
@@ -8,7 +8,7 @@
using namespace Mantid::API;
-using Mantid::PythonInterface::Registry::DataItemInterface;
+using Mantid::PythonInterface::Registry::RegisterWorkspacePtrToPython;
namespace Converters = Mantid::PythonInterface::Converters;
using namespace boost::python;
@@ -191,8 +191,6 @@ void export_IMDHistoWorkspace()
//-------------------------------------------------------------------------------------------------
- DataItemInterface()
- .castFromID("MDHistoWorkspace")
- ;
+ RegisterWorkspacePtrToPython();
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDWorkspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDWorkspace.cpp
index 8b0931b83894..884e5cda994c 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDWorkspace.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IMDWorkspace.cpp
@@ -1,12 +1,12 @@
#include "MantidAPI/IMDWorkspace.h"
-#include "MantidPythonInterface/kernel/Registry/DataItemInterface.h"
+#include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
#include
#include
#include
using namespace Mantid::API;
-using Mantid::PythonInterface::Registry::DataItemInterface;
+using Mantid::PythonInterface::Registry::RegisterWorkspacePtrToPython;
using namespace boost::python;
// clang-format off
@@ -30,6 +30,6 @@ void export_IMDWorkspace()
.def("getNEvents", &IMDWorkspace::getNEvents, args("self"), "Returns the total number of events, contributed to the workspace")
.def("getSpecialCoordinateSystem", &IMDWorkspace::getSpecialCoordinateSystem, args("self"), "Returns the special coordinate system of the workspace");
- DataItemInterface();
+ RegisterWorkspacePtrToPython();
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IPeaksWorkspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IPeaksWorkspace.cpp
index 9ea3e721fbc8..51c434c57511 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IPeaksWorkspace.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IPeaksWorkspace.cpp
@@ -1,6 +1,6 @@
#include "MantidAPI/IPeaksWorkspace.h"
#include "MantidAPI/IPeak.h"
-#include "MantidPythonInterface/kernel/Registry/DataItemInterface.h"
+#include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
#include "MantidPythonInterface/kernel/Converters/PyObjectToV3D.h"
#include
#include
@@ -8,7 +8,7 @@
#include
using namespace Mantid::API;
-using Mantid::PythonInterface::Registry::DataItemInterface;
+using Mantid::PythonInterface::Registry::RegisterWorkspacePtrToPython;
using namespace boost::python;
namespace {
@@ -54,8 +54,6 @@ void export_IPeaksWorkspace()
//-------------------------------------------------------------------------------------------------
- DataItemInterface()
- .castFromID("PeaksWorkspace")
- ;
+ RegisterWorkspacePtrToPython();
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp
index a614c7c8ae00..fe5b68600ee4 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/ITableWorkspace.cpp
@@ -5,7 +5,7 @@
#include "MantidPythonInterface/kernel/Converters/NDArrayToVector.h"
#include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h"
#include "MantidPythonInterface/kernel/Converters/CloneToNumpy.h"
-#include "MantidPythonInterface/kernel/Registry/DataItemInterface.h"
+#include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
#include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h"
#include
@@ -23,7 +23,7 @@
#include
using namespace Mantid::API;
-using Mantid::PythonInterface::Registry::DataItemInterface;
+using Mantid::PythonInterface::Registry::RegisterWorkspacePtrToPython;
using namespace boost::python;
namespace
@@ -393,8 +393,6 @@ void export_ITableWorkspace()
//-------------------------------------------------------------------------------------------------
- DataItemInterface()
- .castFromID("TableWorkspace")
- ;
+ RegisterWorkspacePtrToPython();
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp
index 815cf0cb2392..e27352ecbba7 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp
@@ -1,5 +1,4 @@
#include "MantidAPI/MDGeometry.h"
-#include "MantidPythonInterface/kernel/Policies/DowncastingPolicies.h"
#include "MantidPythonInterface/kernel/Policies/RemoveConst.h"
#include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h"
#include
@@ -9,7 +8,6 @@
using Mantid::API::MDGeometry;
using Mantid::Geometry::IMDDimension_const_sptr;
-using Mantid::PythonInterface::Policies::ToSharedPtrWithDowncast;
using Mantid::PythonInterface::Policies::RemoveConstSharedPtr;
using Mantid::PythonInterface::Policies::VectorToNumpy;
using namespace boost::python;
@@ -86,8 +84,7 @@ void export_MDGeometry()
.def("numOriginalWorkspaces", &MDGeometry::numOriginalWorkspaces,
"Returns the number of source workspaces attached" )
- .def("getOriginalWorkspace", &MDGeometry::getOriginalWorkspace, (args("index")),
- return_value_policy(),
+ .def("getOriginalWorkspace", &MDGeometry::getOriginalWorkspace, (args("index")),
"Returns the source workspace attached at the given index")
.def("getOrigin", (const Mantid::Kernel::VMD & (MDGeometry::*)() const)&MDGeometry::getOrigin,
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp
index 726a9e7db745..460e2424b947 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp
@@ -5,13 +5,13 @@
#include "MantidPythonInterface/kernel/Converters/WrapWithNumpy.h"
#include "MantidPythonInterface/kernel/Policies/RemoveConst.h"
#include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h"
-#include "MantidPythonInterface/kernel/Registry/DataItemInterface.h"
+#include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
#include
-#include
#include
#include
#include
+#include
#include
using namespace Mantid::API;
@@ -241,5 +241,5 @@ void export_MatrixWorkspace()
"CheckWorkspacesMatch algorithm")
;
- DataItemInterface();
+ RegisterWorkspacePtrToPython();
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp
index 83a024efd0a9..7050d9b0c187 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp
@@ -1,6 +1,6 @@
#include "MantidAPI/Workspace.h"
-#include "MantidPythonInterface/kernel/Registry/DataItemInterface.h"
+#include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
#include
#include
@@ -46,5 +46,5 @@ void export_Workspace()
"Return read-only access to the workspace history");
// register pointers
- DataItemInterface();
+ RegisterWorkspacePtrToPython();
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroup.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroup.cpp
index 67de0e52e7fc..e3931e62e87d 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroup.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroup.cpp
@@ -1,14 +1,12 @@
#include "MantidAPI/WorkspaceGroup.h"
-#include "MantidPythonInterface/kernel/Policies/DowncastingPolicies.h"
-#include "MantidPythonInterface/kernel/Registry/DataItemInterface.h"
+#include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
#include
#include
using namespace Mantid::API;
-using Mantid::PythonInterface::Registry::DataItemInterface;
+using Mantid::PythonInterface::Registry::RegisterWorkspacePtrToPython;
using namespace boost::python;
-namespace Policies = Mantid::PythonInterface::Policies;
// clang-format off
void export_WorkspaceGroup()
@@ -21,20 +19,17 @@ void export_WorkspaceGroup()
.def("add", &WorkspaceGroup::add, "Add a name to the group")
.def("size", &WorkspaceGroup::size, "Returns the number of workspaces contained in the group")
.def("remove", &WorkspaceGroup::remove, "Remove a name from the group")
- .def("getItem", (Workspace_sptr (WorkspaceGroup::*)(const size_t) const)&WorkspaceGroup::getItem,
- return_value_policy(), "Returns the item at the given index")
+ .def("getItem", (Workspace_sptr (WorkspaceGroup::*)(const size_t) const)&WorkspaceGroup::getItem,
+ "Returns the item at the given index")
.def("isMultiPeriod", &WorkspaceGroup::isMultiperiod, "Retuns true if the workspace group is multi-period")
// ------------ Operators --------------------------------
.def("__len__", &WorkspaceGroup::getNumberOfEntries)
.def("__contains__", (bool (WorkspaceGroup::*)(const std::string & wsName) const)&WorkspaceGroup::contains)
- .def("__getitem__", (Workspace_sptr (WorkspaceGroup::*)(const size_t) const)&WorkspaceGroup::getItem,
- return_value_policy())
+ .def("__getitem__", (Workspace_sptr (WorkspaceGroup::*)(const size_t) const)&WorkspaceGroup::getItem)
;
//-----------------------------------------------------------------------------------------------
- DataItemInterface()
- .castFromID("WorkspaceGroup")
- ;
+ RegisterWorkspacePtrToPython();
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/ExtractWorkspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/ExtractWorkspace.cpp
new file mode 100644
index 000000000000..f43c2c825ed5
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/ExtractWorkspace.cpp
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------
+#include "MantidPythonInterface/api/ExtractWorkspace.h"
+
+#include
+#include
+
+namespace Mantid {
+namespace PythonInterface {
+
+using namespace API;
+
+using boost::python::extract;
+
+//-----------------------------------------------------------------------------
+// Public methods
+//-----------------------------------------------------------------------------
+/**
+ * @param pyvalue Python object from which to extract
+ */
+ExtractWorkspace::ExtractWorkspace(const boost::python::api::object &pyvalue)
+ : m_value() {
+ // Test for a weak pointer first
+ typedef boost::weak_ptr Workspace_wptr;
+ extract extractWeak(pyvalue);
+ if (extractWeak.check()) {
+ m_value = extractWeak().lock();
+ }
+ extract extractShared(pyvalue);
+ if (extractShared.check()) {
+ m_value = extractShared();
+ }
+}
+
+/**
+ * Check whether the extract can pull out the workspace type
+ * @return True if it can be converted, false otherwise
+ */
+bool ExtractWorkspace::check() const { return !m_value; }
+
+/**
+ * @return The extracted shared_ptr or throws std::invalid_argument
+ */
+const API::Workspace_sptr ExtractWorkspace::operator()() const {
+ if (check()) {
+ return m_value;
+ } else {
+ throw std::invalid_argument(
+ "Unable to extract boost::shared_ptr from Python object");
+ }
+}
+}
+}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/dataobjects/src/Exports/TableWorkspace.cpp b/Code/Mantid/Framework/PythonInterface/mantid/dataobjects/src/Exports/TableWorkspace.cpp
index bfda43f40655..a113a7cefcec 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/dataobjects/src/Exports/TableWorkspace.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/dataobjects/src/Exports/TableWorkspace.cpp
@@ -15,5 +15,5 @@ class_,
;
// register pointers
- DataItemInterface();
+ RegisterWorkspacePtrToPython();
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp b/Code/Mantid/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp
index ad2410f06c87..1172626af320 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/dataobjects/src/Exports/Workspace2D.cpp
@@ -1,5 +1,5 @@
#include "MantidDataObjects/Workspace2D.h"
-#include "MantidPythonInterface/kernel/Registry/DataItemInterface.h"
+#include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
#include
#include
@@ -16,5 +16,5 @@ void export_Workspace2D()
;
// register pointers
- DataItemInterface();
+ RegisterWorkspacePtrToPython();
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
index 853745062795..6a19edb68323 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
+++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
@@ -63,7 +63,6 @@ set ( SRC_FILES
src/Registry/PropertyWithValueFactory.cpp
src/Registry/SequenceTypeHandler.cpp
src/Registry/TypeRegistry.cpp
- src/Registry/DowncastRegistry.cpp
src/Environment/ErrorHandling.cpp
src/Environment/Threading.cpp
src/Environment/WrapperHelpers.cpp
@@ -93,7 +92,7 @@ set ( INC_FILES
${HEADER_DIR}/kernel/Registry/SequenceTypeHandler.h
${HEADER_DIR}/kernel/Registry/TypedPropertyValueHandler.h
${HEADER_DIR}/kernel/Registry/TypeRegistry.h
- ${HEADER_DIR}/kernel/Registry/DowncastRegistry.h
+ ${HEADER_DIR}/kernel/Registry/RegisterWorkspacePtrToPython.h
${HEADER_DIR}/kernel/DataServiceExporter.h
${HEADER_DIR}/kernel/IsNone.h
${HEADER_DIR}/kernel/PropertyWithValueExporter.h
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyWithValue.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyWithValue.cpp
index a7eb9bd5f20f..2bb53ccf8a15 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyWithValue.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/PropertyWithValue.cpp
@@ -1,40 +1,50 @@
#include "MantidPythonInterface/kernel/PropertyWithValueExporter.h"
+#include
+
using Mantid::PythonInterface::PropertyWithValueExporter;
// clang-format off
void export_BasicPropertyWithValueTypes()
// clang-format on
{
- // cut down copy-and-paste code
-#define EXPORT_PROP(CType, ExportName) \
- PropertyWithValueExporter::define(ExportName);
-
- //ints & vectors
- EXPORT_PROP(int, "IntPropertyWithValue");
- EXPORT_PROP(std::vector, "VectorIntPropertyWithValue");
- EXPORT_PROP(unsigned int, "UIntPropertyWithValue");
- EXPORT_PROP(std::vector, "VectorUIntPropertyWithValue");
+ // ints & vectors
+ PropertyWithValueExporter::define("IntPropertyWithValue");
+ PropertyWithValueExporter>::define(
+ "VectorIntPropertyWithValue");
+ PropertyWithValueExporter::define("UIntPropertyWithValue");
+ PropertyWithValueExporter>::define(
+ "VectorUIntPropertyWithValue");
+
// longs & vectors
- EXPORT_PROP(long, "LongPropertyWithValue");
- EXPORT_PROP(std::vector, "VectorLongPropertyWithValue");
- EXPORT_PROP(unsigned long, "ULongPropertyWithValue");
- EXPORT_PROP(std::vector, "VectorULongPropertyWithValue");
+ PropertyWithValueExporter::define("LongPropertyWithValue");
+ PropertyWithValueExporter>::define(
+ "VectorLongPropertyWithValue");
+ PropertyWithValueExporter::define("ULongPropertyWithValue");
+ PropertyWithValueExporter>::define(
+ "VectorULongPropertyWithValue");
+
// long long long longs & vectors
- EXPORT_PROP(long long, "LongLongPropertyWithValue");
- EXPORT_PROP(std::vector, "VectorLongLongPropertyWithValue");
- EXPORT_PROP(unsigned long long, "ULongLongPropertyWithValue");
- EXPORT_PROP(std::vector, "VectorULongLongPropertyWithValue");
+ PropertyWithValueExporter::define("LongLongPropertyWithValue");
+ PropertyWithValueExporter>::define(
+ "VectorLongLongPropertyWithValue");
+ PropertyWithValueExporter::define(
+ "ULongLongPropertyWithValue");
+ PropertyWithValueExporter>::define(
+ "VectorULongLongPropertyWithValue");
+
// double
- EXPORT_PROP(double, "FloatPropertyWithValue");
- EXPORT_PROP(std::vector, "VectorFloatPropertyWithValue");
+ PropertyWithValueExporter::define("FloatPropertyWithValue");
+ PropertyWithValueExporter>::define(
+ "VectorFloatPropertyWithValue");
+
// boolean
- EXPORT_PROP(bool, "BoolPropertyWithValue");
- EXPORT_PROP(std::vector, "VectorBoolPropertyWithValue");
+ PropertyWithValueExporter::define("BoolPropertyWithValue");
+ PropertyWithValueExporter>::define(
+ "VectorBoolPropertyWithValue");
+
// std::string
- EXPORT_PROP(std::string, "StringPropertyWithValue");
- EXPORT_PROP(std::vector, "VectorStringPropertyWithValue");
-
-
-#undef EXPORT_PROP
+ PropertyWithValueExporter::define("StringPropertyWithValue");
+ PropertyWithValueExporter>::define(
+ "VectorStringPropertyWithValue");
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Registry/DowncastRegistry.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Registry/DowncastRegistry.cpp
deleted file mode 100644
index 07b01ebe6a00..000000000000
--- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Registry/DowncastRegistry.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-//-----------------------------------------------------------------------------
-// Includes
-//-----------------------------------------------------------------------------
-#include "MantidPythonInterface/kernel/Registry/DowncastRegistry.h"
-
-#include
-#include
-#include
-#include
-
-namespace Mantid
-{
- namespace PythonInterface
- {
- namespace Registry
- {
- namespace //
- {
- /// Typedef the map of type_info -> Downcaster objects
- typedef boost::unordered_map> RegistryType;
- //typedef std::map> RegistryType;
-
- /**
- * Returns a reference to the static type map. Creates on first call to the function
- * @return A reference to the type map
- */
- RegistryType & downcastRegistry()
- {
- static RegistryType registry;
- return registry;
- }
- } // end
-
- //-----------------------------------------------------------------------
- // Public methods
- //-----------------------------------------------------------------------
- /**
- * Throws std::invalid_argument if the item does not exist
- * @param id A string ID from a concrete DataItem type
- * @return The object responsible for casting and creating a Python object
- * from it
- */
- const DowncastDataItem & DowncastRegistry::retrieve(const std::string & id)
- {
- auto & registry = downcastRegistry();
- auto entry = registry.find(id);
- if(entry != registry.cend())
- {
- return *(entry->second);
- }
- else
- {
- throw std::invalid_argument("DowncastRegistry::retrieve - Unable to find registered "
- "object with id=" + id);
- }
- }
-
-
- //-----------------------------------------------------------------------
- // Private methods
- //-----------------------------------------------------------------------
- /**
- * Subscribe a caster object with a given ID
- * @param id A string ID that will map to the object
- * @param caster A pointer to a DowncastDataItem object. Ownership of the
- * object is transferred here
- */
- void DowncastRegistry::subscribe(const std::string & id, const DowncastDataItem * caster)
- {
- auto & registry = downcastRegistry();
- if(registry.find(id) == registry.cend())
- {
- typedef boost::shared_ptr DowncastDataItemPtr;
- registry.insert(std::make_pair(id, DowncastDataItemPtr(caster)));
- }
- else
- {
- throw std::invalid_argument("DowncastRegistry::subscribe - object with ID=" + id + \
- " has already been registered");
- }
- }
-
- }
- }
-}