11#include <boost/python.hpp>
12#include <boost/python/class.hpp>
13#include <boost/python/list.hpp>
18using namespace
boost::python;
24void setupBasisAxes(
const PanelsSurfaceCalculator &self,
object &xAxis,
object &yAxis,
const object &zAxis) {
25 auto x = PyObjectToV3D(xAxis)();
26 auto y = PyObjectToV3D(yAxis)();
27 const auto z = PyObjectToV3D(zAxis)();
28 self.setupBasisAxes(z, x, y);
29 for (
size_t i = 0; i < 3; i++) {
35list retrievePanelCorners(
const PanelsSurfaceCalculator &self,
const object &componentInfo,
const size_t rootIndex) {
36 const std::shared_ptr<ComponentInfo> cInfoSharedPtr = extract<std::shared_ptr<ComponentInfo>>(componentInfo);
37 const auto panelCorners = self.retrievePanelCorners(*(cInfoSharedPtr.get()), rootIndex);
38 list panelCornersList;
39 for (
size_t i = 0; i < panelCorners.size(); i++) {
40 list corner(panelCorners[i]);
41 panelCornersList.append(corner);
43 return panelCornersList;
46list calculatePanelNormal(
const PanelsSurfaceCalculator &self,
const object &panelCorners) {
47 if (len(panelCorners) != 4) {
48 throw std::invalid_argument(
"Must be 4 panel corners");
50 std::vector<V3D> panelCornersVec{4};
51 for (
size_t i = 0; i < 4; i++) {
52 const object corner = panelCorners[i];
53 panelCornersVec[i] = PyObjectToV3D(panelCorners[i])();
55 const auto panelNormal = self.calculatePanelNormal(panelCornersVec);
56 list panelNormalList(panelNormal);
57 return panelNormalList;
60bool isBankFlat(PanelsSurfaceCalculator &self,
const object &componentInfo,
const size_t bankIndex,
const list &tubes,
61 const object &normal) {
62 const std::shared_ptr<ComponentInfo> cInfoSharedPtr = extract<std::shared_ptr<ComponentInfo>>(componentInfo);
63 std::vector<size_t> tubesVector;
64 const size_t lenTubes = len(tubes);
65 for (
size_t i = 0; i < lenTubes; i++) {
66 tubesVector.push_back(extract<size_t>(tubes[i]));
68 const auto normalV3D = PyObjectToV3D(normal)();
69 return self.isBankFlat(*(cInfoSharedPtr.get()), bankIndex, tubesVector, normalV3D);
72list calculateBankNormal(PanelsSurfaceCalculator &self,
const object &componentInfo,
const list &tubes) {
73 const std::shared_ptr<ComponentInfo> cInfoSharedPtr = extract<std::shared_ptr<ComponentInfo>>(componentInfo);
74 std::vector<size_t> tubesVector;
75 const size_t lenTubes = len(tubes);
76 for (
size_t i = 0; i < lenTubes; i++) {
77 tubesVector.push_back(extract<size_t>(tubes[i]));
79 const auto normal = self.calculateBankNormal(*(cInfoSharedPtr.get()), tubesVector);
80 list normalList{normal};
84void setBankVisited(
const PanelsSurfaceCalculator &self,
const object &componentInfo,
const size_t bankIndex,
85 list &visitedComponents) {
86 const std::shared_ptr<ComponentInfo> cInfoSharedPtr = extract<std::shared_ptr<ComponentInfo>>(componentInfo);
87 std::vector<bool> visitedComponentsVector;
88 const size_t lenVisitedComponents = len(visitedComponents);
89 for (
size_t i = 0; i < lenVisitedComponents; i++) {
90 visitedComponentsVector.push_back(extract<bool>(visitedComponents[i]));
92 self.setBankVisited(*(cInfoSharedPtr.get()), bankIndex, visitedComponentsVector);
93 for (
size_t i = 0; i < lenVisitedComponents; i++) {
98 visitedComponents[i] = visitedComponentsVector[i] ? true :
false;
102size_t findNumDetectors(
const PanelsSurfaceCalculator &self,
const object &componentInfo,
const list &components) {
103 const std::shared_ptr<ComponentInfo> cInfoSharedPtr = extract<std::shared_ptr<ComponentInfo>>(componentInfo);
104 std::vector<size_t> componentsVector;
105 const size_t lenComponents = len(components);
106 for (
size_t i = 0; i < lenComponents; i++) {
107 componentsVector.push_back(extract<size_t>(components[i]));
109 return self.findNumDetectors(*(cInfoSharedPtr.get()), componentsVector);
112list calcBankRotation(
const PanelsSurfaceCalculator &self,
const object &detPos,
object normal,
const object &zAxis,
113 const object &yAxis,
const object &samplePosition) {
114 const auto bankRotation =
115 self.calcBankRotation(PyObjectToV3D(detPos)(), PyObjectToV3D(normal)(), PyObjectToV3D(zAxis)(),
116 PyObjectToV3D(yAxis)(), PyObjectToV3D(samplePosition)());
119 quat.append(bankRotation.real());
120 quat.append(bankRotation.imagI());
121 quat.append(bankRotation.imagJ());
122 quat.append(bankRotation.imagK());
126list transformedBoundingBoxPoints(
const PanelsSurfaceCalculator &self,
const object &componentInfo,
128 const object &yaxis) {
129 const std::shared_ptr<ComponentInfo> cInfoSharedPtr = extract<std::shared_ptr<ComponentInfo>>(componentInfo);
132 const auto referencePosition = PyObjectToV3D(refPos)();
133 const auto xAxisVec = PyObjectToV3D(xaxis)();
134 const auto yAxisVec = PyObjectToV3D(yaxis)();
135 const auto boundingBoxPoints = self.transformedBoundingBoxPoints(*(cInfoSharedPtr.get()),
detectorIndex,
136 referencePosition, quatRotation, xAxisVec, yAxisVec);
138 pointA.append(boundingBoxPoints[0].
X());
139 pointA.append(boundingBoxPoints[0].
Y());
140 pointB.append(boundingBoxPoints[1].
X());
141 pointB.append(boundingBoxPoints[1].
Y());
143 result.append(pointA);
144 result.append(pointB);
148list getAllTubeDetectorFlatGroupParents(PanelsSurfaceCalculator &self,
const object &componentInfo) {
149 const std::shared_ptr<ComponentInfo> cInfoSharedPtr = extract<std::shared_ptr<ComponentInfo>>(componentInfo);
150 const auto allTubeGroupParents =
151 self.examineAllComponents(*(cInfoSharedPtr.get()), [&](
const auto &cinfo,
auto root,
auto &visited) {
152 return self.tubeDetectorParentIDs(cinfo, root, visited);
154 list pyAllTubeGroupParents;
155 for (
size_t groupIndex = 0; groupIndex < allTubeGroupParents.size(); groupIndex++) {
156 const auto tubeGroupParents = allTubeGroupParents[groupIndex];
157 list pyTubeGroupParents;
158 for (
size_t tubeParentIndex = 0; tubeParentIndex < tubeGroupParents.size(); tubeParentIndex++) {
159 pyTubeGroupParents.append(tubeGroupParents[tubeParentIndex]);
161 pyAllTubeGroupParents.append(pyTubeGroupParents);
163 return pyAllTubeGroupParents;
166tuple getSideBySideViewPos(
const PanelsSurfaceCalculator &self,
const object &componentInfo,
const object &instrument,
167 const size_t componentIndex) {
168 const std::shared_ptr<ComponentInfo> cInfoSharedPtr = extract<std::shared_ptr<ComponentInfo>>(componentInfo);
169 const std::shared_ptr<Instrument> instrumentSharedPtr = extract<std::shared_ptr<Instrument>>(instrument);
170 const auto sideBySidePos = self.getSideBySideViewPos(*(cInfoSharedPtr).get(), instrumentSharedPtr, componentIndex);
173 if (!sideBySidePos.has_value()) {
176 result.append(
false);
178 position.append(sideBySidePos->X());
179 position.append(sideBySidePos->Y());
183 return tuple(result);
192 class_<PanelsSurfaceCalculator, boost::noncopyable>(
"PanelsSurfaceCalculator",
193 init<>(
"Make a side by side projection calculator"))
194 .def(
"setupBasisAxes", &setupBasisAxes, (arg(
"self"), arg(
"xaxis"), arg(
"yaxis"), arg(
"zaxis")),
195 "Sets up the basis axes for the projection.")
196 .def(
"retrievePanelCorners", &retrievePanelCorners, (arg(
"self"), arg(
"componentInfo"), arg(
"rootIndex")),
197 "Retrieves the corners of the panel.")
198 .def(
"calculatePanelNormal", &calculatePanelNormal, (arg(
"self"), arg(
"panelCorners")),
199 "Calculates the normal vector of the panel.")
200 .def(
"isBankFlat", &isBankFlat,
201 (arg(
"self"), arg(
"componentInfo"), arg(
"bankIndex"), arg(
"tubes"), arg(
"normal")),
202 "Checks if a bank is flat based on its normal vector.")
203 .def(
"calculateBankNormal", &calculateBankNormal, (arg(
"self"), arg(
"componentInfo"), arg(
"tubes")),
204 "Calculates the normal vector of a bank.")
205 .def(
"setBankVisited", &setBankVisited,
206 (arg(
"self"), arg(
"componentInfo"), arg(
"bankIndex"), arg(
"visitedComponents")),
207 "Marks a bank as visited in the visitedComponents vector")
208 .def(
"findNumDetectors", &findNumDetectors, (arg(
"componentInfo"), arg(
"components")),
209 "Finds the number of detectors in a component.")
210 .def(
"calcBankRotation", &calcBankRotation,
211 (arg(
"self"), arg(
"detPos"), arg(
"normal"), arg(
"zAxis"), arg(
"yAxis"), arg(
"samplePosition")),
212 "Calculates the rotation quaternion for a bank based on its position and normal vector.")
213 .def(
"transformedBoundingBoxPoints", &transformedBoundingBoxPoints,
214 (arg(
"self"), arg(
"componentInfo"), arg(
"detectorIndex"), arg(
"refPos"), arg(
"rotation"), arg(
"xaxis"),
216 "Transforms a component's bounding box based on reference position and rotation. The rotation should be "
217 "provided as a list containing the real and imaginary parts of a quaternion (w, i, j, k).")
218 .def(
"getAllTubeDetectorFlatGroupParents", &getAllTubeDetectorFlatGroupParents,
219 (arg(
"self"), arg(
"componentInfo")),
220 "Returns the parent component indices of detectors of all groups of tubes arranged in flat banks")
221 .def(
"getSideBySideViewPos", &getSideBySideViewPos,
222 (arg(
"self"), arg(
"componentInfo"), arg(
"instrument"), arg(
"componentIndex")),
223 "Returns a tuple indicating whether the bank side-by-side projection position has been specified in the "
224 "IDF, and what it is.");
void export_PanelsSurfaceCalculator()
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
Takes a Python object and if it supports indexing and is of length 3 then it will attempt to convert ...