Mantid
Loading...
Searching...
No Matches
Projection.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 +
12#include <boost/python/class.hpp>
13#include <boost/python/copy_non_const_reference.hpp>
14#include <boost/python/exec.hpp>
15#include <boost/python/import.hpp>
16#include <boost/python/make_constructor.hpp>
17
18using namespace Mantid::API;
19using namespace Mantid::PythonInterface;
20using namespace boost::python;
21
22GNU_DIAG_OFF("strict-aliasing")
23
24namespace {
25std::string getUnit(Projection &p, size_t nd) { return (p.getUnit(nd) == RLU ? "r" : "a"); }
26
27void setUnit(Projection &p, size_t nd, const std::string &unit) {
28 if (unit == "r")
29 p.setUnit(nd, RLU);
30 else if (unit == "a")
31 p.setUnit(nd, INV_ANG);
32 else
33 throw std::runtime_error("Invalid unit");
34}
35
36// This is a bit strange, but it works. The users want x =
37// proj.createWorkspace()
38// to behave like the simpleapi, i.e. put a workspace named 'x' into the ADS for
39// them. To do that kind of black magic we have to introspect from the Python
40// side, so that's what we do.
41object createWorkspace() {
42 // Create a namespace for us to add a function to
43 object main = import("__main__");
44 object global(main.attr("__dict__"));
45 // Add a function to the namespace
46 exec("def createWorkspace(proj, OutputWorkspace=None):\n"
47 " '''Create a TableWorkspace using this projection'''\n"
48 " import inspect\n"
49 " from mantid import api, kernel, AnalysisDataService\n"
50 " ws = api.WorkspaceFactory.createTable('TableWorkspace')\n"
51 " ws.addColumn('str', 'name')\n"
52 " ws.addColumn('V3D', 'value')\n"
53 " ws.addColumn('str', 'type')\n"
54 " ws.addColumn('double', 'offset')\n"
55 " for (name, i) in zip('uvw', range(3)):\n"
56 " ws.addRow({\n"
57 " 'name': name,\n"
58 " 'value': proj.getAxis(i),\n"
59 " 'type': proj.getType(i),\n"
60 " 'offset': proj.getOffset(i)\n"
61 " })\n"
62
63 " if OutputWorkspace is None:\n"
64 " lhs = "
65 "kernel.funcinspect.process_frame(inspect.currentframe().f_back)\n"
66 " if lhs[0] > 0:\n"
67 " OutputWorkspace = lhs[1][0]\n"
68 " else:\n"
69 " raise RuntimeError('createWorkspace failed to infer a name for its"
70 " output projection workspace. Please pass an"
71 " OutputWorkspace parameter to it.')\n"
72 " if OutputWorkspace:\n"
73 " AnalysisDataService[OutputWorkspace] = ws\n"
74
75 " return ws\n"
76 "\n",
77 global, global);
78 // extract the function object from the namespace and return it so it can be
79 // bound by Boost::Python.
80 return global["createWorkspace"];
81}
82
83void projSetAxis(Projection &self, size_t nd, const object &data) {
84 self.setAxis(nd, Converters::PyObjectToV3D(data)());
85}
86
87Projection_sptr projCtor2(const object &d1, const object &d2) {
89}
90
91Projection_sptr projCtor3(const object &d1, const object &d2, const object &d3) {
94}
95
96} // anonymous namespace
97
99 using namespace std::placeholders;
100 class_<Projection>("Projection", init<>("Default constructor creates a two dimensional projection"))
101 .def(init<const Mantid::Kernel::V3D &, const Mantid::Kernel::V3D &>(
102 "Constructs a 3 dimensional projection, with w as the cross product "
103 "of u and v.",
104 args("u", "v")))
105 .def(init<const Mantid::Kernel::V3D &, const Mantid::Kernel::V3D &, const Mantid::Kernel::V3D &>(
106 "Constructs a 3 dimensional projection", args("u", "v", "w")))
107 .def("__init__", make_constructor(&projCtor2, default_call_policies(), (arg("u"), arg("v"))),
108 "Constructs a 3 dimensional projection, with w as the cross product "
109 "of u and v.")
110 .def("__init__", make_constructor(&projCtor3, default_call_policies(), (arg("u"), arg("v"), arg("w"))),
111 "Constructs a 3 dimensional projection")
112 .def("getOffset", &Projection::getOffset, (arg("self"), arg("nd")), "Returns the offset for the given dimension",
113 args("dimension"))
114 .def("getAxis", &Projection::getAxis, (arg("self"), arg("nd")), "Returns the axis for the given dimension",
115 args("dimension"))
116 .def("getType", &getUnit, (arg("self"), arg("dimension")), "Returns the unit for the given dimension")
117 .def("setOffset", &Projection::setOffset, (arg("self"), arg("nd"), arg("offset")),
118 "Sets the offset for the given dimension", args("dimension", "offset"))
119 .def("setAxis", &Projection::setAxis, (arg("self"), arg("dimension"), arg("axis")),
120 "Sets the axis for the given dimension")
121 .def("setAxis", &projSetAxis, (arg("self"), arg("nd"), arg("data")), "Sets the axis for the given dimension")
122 .def("setType", &setUnit, (arg("self"), arg("dimension"), arg("unit")), "Sets the unit for the given dimension")
123 .add_property("u",
124 make_function(&Projection::U, return_internal_reference<>(),
125 boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
126 make_function(std::bind(&Projection::setAxis, _1, 0, _2), default_call_policies(),
127 boost::mpl::vector3<void, Projection &, Mantid::Kernel::V3D>()))
128 .add_property("v",
129 make_function(&Projection::V, return_internal_reference<>(),
130 boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
131 make_function(std::bind(&Projection::setAxis, _1, 1, _2), default_call_policies(),
132 boost::mpl::vector3<void, Projection &, Mantid::Kernel::V3D>()))
133 .add_property("w",
134 make_function(&Projection::W, return_internal_reference<>(),
135 boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
136 make_function(std::bind(&Projection::setAxis, _1, 2, _2), default_call_policies(),
137 boost::mpl::vector3<void, Projection &, Mantid::Kernel::V3D>()))
138 .add_property("u",
139 make_function(&Projection::U, return_internal_reference<>(),
140 boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
141 make_function(std::bind(&projSetAxis, _1, 0, _2), default_call_policies(),
142 boost::mpl::vector3<void, Projection &, const object &>()))
143 .add_property("v",
144 make_function(&Projection::V, return_internal_reference<>(),
145 boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
146 make_function(std::bind(&projSetAxis, _1, 1, _2), default_call_policies(),
147 boost::mpl::vector3<void, Projection &, const object &>()))
148 .add_property("w",
149 make_function(&Projection::W, return_internal_reference<>(),
150 boost::mpl::vector2<Mantid::Kernel::V3D &, Projection &>()),
151 make_function(std::bind(&projSetAxis, _1, 2, _2), default_call_policies(),
152 boost::mpl::vector3<void, Projection &, const object &>()))
153 .def("createWorkspace", createWorkspace(), "Create a TableWorkspace representing the projection");
154}
PeakIndexingStats main
Definition: IndexPeaks.cpp:164
void export_Projection()
Definition: Projection.cpp:98
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
Kernel::V3D getAxis(size_t nd)
Retrieves the axis vector for the given dimension.
Definition: Projection.cpp:104
void setOffset(size_t nd, double offset)
Set the offset for a given dimension.
Definition: Projection.cpp:118
ProjectionUnit getUnit(size_t nd)
Retrives the unit of the given dimension.
Definition: Projection.cpp:111
Kernel::V3D & W()
Definition: Projection.h:59
void setUnit(size_t nd, ProjectionUnit unit)
Set the unit for a given dimension.
Definition: Projection.cpp:132
void setAxis(size_t nd, const Kernel::V3D &axis)
Set the axis vector for a given dimension.
Definition: Projection.cpp:125
Kernel::V3D & U()
Definition: Projection.h:57
Kernel::V3D & V()
Definition: Projection.h:58
double getOffset(size_t nd)
Retrieves the offset for the given dimension.
Definition: Projection.cpp:97
std::shared_ptr< T > createWorkspace(InitArgs... args)
std::shared_ptr< Projection > Projection_sptr
Definition: Projection.h:70
Takes a Python object and if it supports indexing and is of length 3 then it will attempt to convert ...
Definition: PyObjectToV3D.h:22