Mantid
Loading...
Searching...
No Matches
BinaryOperations.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8
19
20#include <boost/python/def.hpp>
21#include <boost/python/return_value_policy.hpp>
22
24 using namespace Mantid::API;
26 using namespace boost::python;
27
28 // Typedefs the various function types
29 using binary_fn_md_md = IMDWorkspace_sptr (*)(const IMDWorkspace_sptr, const IMDWorkspace_sptr, const std::string &,
30 const std::string &, bool, bool);
31 using binary_fn_md_gp = WorkspaceGroup_sptr (*)(const IMDWorkspace_sptr, const WorkspaceGroup_sptr,
32 const std::string &, const std::string &, bool, bool);
33 using binary_fn_gp_md = WorkspaceGroup_sptr (*)(const WorkspaceGroup_sptr, const IMDWorkspace_sptr,
34 const std::string &, const std::string &, bool, bool);
35 using binary_fn_gp_gp = WorkspaceGroup_sptr (*)(const WorkspaceGroup_sptr, const WorkspaceGroup_sptr,
36 const std::string &, const std::string &, bool, bool);
37
38 using binary_fn_mh_mh = IMDHistoWorkspace_sptr (*)(const IMDHistoWorkspace_sptr, const IMDHistoWorkspace_sptr,
39 const std::string &, const std::string &, bool, bool);
40
41 using binary_fn_md_db =
42 IMDWorkspace_sptr (*)(const IMDWorkspace_sptr, double, const std::string &, const std::string &, bool, bool);
43 using binary_fn_mh_db = IMDHistoWorkspace_sptr (*)(const IMDHistoWorkspace_sptr, double, const std::string &,
44 const std::string &, bool, bool);
45 using binary_fn_gp_db =
46 WorkspaceGroup_sptr (*)(const WorkspaceGroup_sptr, double, const std::string &, const std::string &, bool, bool);
47
48 // Always a return a Workspace_sptr
49 using ReturnWorkspaceSptr = return_value_policy<AsType<Workspace_sptr>>;
50
51 // Binary operations that return a workspace
52 using boost::python::def;
55
56 def("performBinaryOp", (binary_fn_md_md)&performBinaryOp, ReturnWorkspaceSptr());
57 def("performBinaryOp", (binary_fn_md_gp)&performBinaryOp, ReturnWorkspaceSptr());
58 def("performBinaryOp", (binary_fn_gp_md)&performBinaryOp, ReturnWorkspaceSptr());
59 def("performBinaryOp", (binary_fn_gp_gp)&performBinaryOp, ReturnWorkspaceSptr());
60 def("performBinaryOp", (binary_fn_mh_mh)&performBinaryOp, ReturnWorkspaceSptr());
61
62 def("performBinaryOp", (binary_fn_md_db)&performBinaryOpWithDouble, ReturnWorkspaceSptr());
63 def("performBinaryOp", (binary_fn_mh_db)&performBinaryOpWithDouble, ReturnWorkspaceSptr());
64 def("performBinaryOp", (binary_fn_gp_db)&performBinaryOpWithDouble, ReturnWorkspaceSptr());
65}
66
68using namespace Mantid::API;
69
83template <typename LHSType, typename RHSType, typename ResultType>
84ResultType performBinaryOp(const LHSType lhs, const RHSType rhs, const std::string &op, const std::string &name,
85 bool inplace, bool reverse) {
86 // ----- Determine which version of the algo should be called -----
87 MatrixWorkspace_const_sptr lhs_mat = std::dynamic_pointer_cast<const MatrixWorkspace>(lhs);
88 MatrixWorkspace_const_sptr rhs_mat = std::dynamic_pointer_cast<const MatrixWorkspace>(rhs);
89 WorkspaceGroup_const_sptr lhs_grp = std::dynamic_pointer_cast<const WorkspaceGroup>(lhs);
90 WorkspaceGroup_const_sptr rhs_grp = std::dynamic_pointer_cast<const WorkspaceGroup>(rhs);
91
92 const auto algoName = (lhs_mat || lhs_grp) && (rhs_mat || rhs_grp) ? op : op + "MD";
93
94 ResultType result;
95 try {
97 if (reverse) {
98 result = API::OperatorOverloads::executeBinaryOperation<RHSType, LHSType, ResultType>(algoName, rhs, lhs, inplace,
99 false, name, true);
100 } else {
101 result = API::OperatorOverloads::executeBinaryOperation<LHSType, RHSType, ResultType>(algoName, lhs, rhs, inplace,
102 false, name, true);
103 }
104 } catch (std::runtime_error &exc) {
105 std::string error = exc.what();
106 if (error == "algorithm") {
107 error = "Unknown binary operation requested: " + op;
108 throw std::runtime_error(error);
109 } else {
110 throw;
111 }
112 }
113 return result;
114}
115
130template <typename LHSType, typename ResultType>
131ResultType performBinaryOpWithDouble(const LHSType inputWS, const double value, const std::string &op,
132 const std::string &name, bool inplace, bool reverse) {
133
134 auto alg = API::AlgorithmManager::Instance().createUnmanaged("CreateSingleValuedWorkspace");
135 alg->setChild(false);
136 alg->setAlwaysStoreInADS(false);
137 alg->initialize();
138 alg->setProperty<double>("DataValue", value);
139 alg->setPropertyValue("OutputWorkspace", "python_binary_op_single_value");
140 { // instantiate releaseGIL in limited scope to allow for repeat in 'performBinaryOp'
142 alg->execute();
143 }
144
145 MatrixWorkspace_sptr singleValue;
146 if (alg->isExecuted()) {
147 singleValue = alg->getProperty("OutputWorkspace");
148 } else {
149 throw std::runtime_error("performBinaryOp: Error in execution of "
150 "CreateSingleValuedWorkspace");
151 }
152 ResultType result =
153 performBinaryOp<LHSType, MatrixWorkspace_sptr, ResultType>(inputWS, singleValue, op, name, inplace, reverse);
154 return result;
155}
156
157// Concrete instantations
158template IMDWorkspace_sptr performBinaryOp(const IMDWorkspace_sptr, const IMDWorkspace_sptr, const std::string &,
159 const std::string &name, bool, bool);
161 const std::string &name, bool, bool);
163 const std::string &name, bool, bool);
165 const std::string &name, bool, bool);
166
168 const std::string &, const std::string &name, bool, bool);
170 const std::string &, const std::string &name, bool, bool);
171
172// Double variants
173template IMDWorkspace_sptr performBinaryOpWithDouble(const IMDWorkspace_sptr, const double, const std::string &op,
174 const std::string &, bool, bool);
176 const std::string &op, const std::string &, bool, bool);
177template WorkspaceGroup_sptr performBinaryOpWithDouble(const WorkspaceGroup_sptr, const double, const std::string &op,
178 const std::string &, bool, bool);
179} // namespace Mantid::PythonInterface
std::string name
Definition Run.cpp:60
void export_BinaryOperations()
const std::vector< double > & rhs
double value
The value of the point.
Definition FitMW.cpp:51
double error
Defines a structure for releasing the Python GIL using the RAII pattern.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< IMDHistoWorkspace > IMDHistoWorkspace_sptr
shared pointer to Mantid::API::IMDHistoWorkspace
std::shared_ptr< IMDWorkspace > IMDWorkspace_sptr
Shared pointer to the IMDWorkspace base class.
std::shared_ptr< const WorkspaceGroup > WorkspaceGroup_const_sptr
shared pointer to Mantid::API::WorkspaceGroup, pointer to const version
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
ResultType performBinaryOpWithDouble(const LHSType inputWS, const double value, const std::string &op, const std::string &name, bool inplace, bool reverse)
Binary op for a workspace and a double.
ResultType performBinaryOp(const LHSType lhs, const RHSType rhs, const std::string &op, const std::string &name, bool inplace, bool reverse)
Binary op for two workspaces.