18using Mantid::Beamline::ComponentType;
37 }
else if (phi <= 45.0) {
54std::vector<Mantid::Kernel::V3D>
56 const size_t rootIndex)
const {
58 auto child = rootIndex;
62 const auto &children = componentInfo.
children(child);
66 const auto &shape = componentInfo.
shape(child);
68 const auto &points = shapeInfo.points();
73 for (
size_t i = 0; i < points.size() - 1; ++i) {
74 double xdiff = std::abs(points[i + 1].
X() - points[i].
X());
75 double ydiff = std::abs(points[i + 1].
Y() - points[i].
Y());
82 std::vector<Mantid::Kernel::V3D> corners{
83 componentInfo.
position(panel.bottomLeft), componentInfo.
position(panel.bottomRight),
84 componentInfo.
position(panel.topRight), componentInfo.
position(panel.topLeft)};
87 double xmin = corners[0].
X();
88 double xmax = corners[0].X();
89 double ymin = corners[0].Y();
90 double ymax = corners[0].Y();
92 for (
const auto &corner : corners) {
93 xmin = corner.X() < xmin ? corner.X() : xmin;
94 xmax = corner.X() > xmax ? corner.X() : xmax;
95 ymin = corner.Y() < ymin ? corner.Y() : ymin;
96 ymax = corner.Y() > ymax ? corner.Y() : ymax;
100 for (
auto &corner : corners) {
103 corner.setX(
x == xmin ?
x - xoff :
x + xoff);
104 corner.setY(
y == ymin ?
y - yoff :
y + yoff);
119 auto xaxis = panelCorners[1] - panelCorners[0];
120 auto yaxis = panelCorners[3] - panelCorners[0];
121 const auto normal =
normalize(xaxis.cross_prod(yaxis));
136 for (
auto tube : tubes) {
137 const auto &children = componentInfo.
children(tube);
140 this->
g_log.
warning() <<
"Assembly " << componentInfo.
name(bankIndex) <<
" isn't flat.\n";
155 const std::vector<size_t> &tubes) {
157 const auto &tube0 = componentInfo.
children(tubes[0]);
158 const auto &tube1 = componentInfo.
children(tubes[1]);
159 auto pos = componentInfo.
position(tube0[0]);
160 auto x = componentInfo.
position(tube0[1]) - pos;
163 auto y = componentInfo.
position(tube1[0]) - pos;
165 auto normal =
x.cross_prod(
y);
167 if (normal.nullVector()) {
170 normal =
x.cross_prod(
y);
175 if (normal.nullVector())
189 std::vector<bool> &visitedComponents)
const {
190 const auto &children = componentInfo.
children(bankIndex);
191 visitedComponents[bankIndex] =
true;
192 for (
auto child : children) {
193 const auto &subChildren = componentInfo.
children(child);
194 if (subChildren.size() > 0)
197 visitedComponents[child] =
true;
209 const std::vector<size_t> &components)
const {
210 return std::accumulate(
211 components.cbegin(), components.cend(), std::size_t{0u},
212 [&componentInfo](
size_t lhs,
const auto &comp) { return componentInfo.isDetector(comp) ? lhs + 1u : lhs; });
227 const V3D &yAxis,
const V3D &samplePosition)
const {
228 V3D directionToViewer = zAxis;
229 V3D bankToOrigin = samplePosition - detPos;
242 directionToViewer *= -1;
244 if (directionToViewer == -normal) {
254 V3D normalInXZPlane = {normal.
X(), 0., normal.
Z()};
258 auto rotationLocalY =
259 normalInXZPlane == -directionToViewer ? rotAboutY180 :
Mantid::Kernel::Quat(normalInXZPlane, directionToViewer);
260 requiredRotation = rotationLocalY * rotationLocalX;
262 return requiredRotation;
276std::vector<Mantid::Kernel::V2D>
279 const V3D &xaxis,
const V3D &yaxis)
const {
281 auto bbMinPoint = bb.
minPoint() - refPos;
282 auto bbMaxPoint = bb.maxPoint() - refPos;
285 bbMinPoint += refPos;
286 bbMaxPoint += refPos;
301 std::function<std::vector<size_t>(
const ComponentInfo &,
size_t, std::vector<bool> &)> operation) {
302 std::vector<bool> visited(componentInfo.
size(),
false);
303 std::vector<std::vector<size_t>> detectorIDs;
305 for (int64_t i =
static_cast<int64_t
>(componentInfo.
root() - 1); i > 0; --i) {
306 auto children = componentInfo.
children(i);
308 if (children.size() > 0 && !visited[i]) {
310 detectorIDs.push_back(operation(componentInfo, i, visited));
311 }
else if (children.size() == 0 && componentInfo.
parent(i) == componentInfo.
root()) {
327 std::vector<bool> &visited) {
328 const auto componentType = componentInfo.
componentType(rootIndex);
329 if (componentType != ComponentType::OutlineComposite)
332 const auto bankIndex0 = componentInfo.
parent(rootIndex);
333 auto tubes = std::vector<size_t>();
334 bool foundFlatBank =
false;
337 auto addTubes = [&componentInfo](
size_t parentIndex, std::vector<size_t> &tubes) {
338 const auto &children = componentInfo.
children(parentIndex);
339 for (
auto child : children) {
340 if (componentInfo.
componentType(child) == ComponentType::OutlineComposite)
342 if (componentInfo.
children(child).size() > 1)
343 tubes.emplace_back(child);
351 if (componentInfo.
hasParent(bankIndex0)) {
352 bankIndex = componentInfo.
parent(bankIndex0);
353 const auto &bankChildren = componentInfo.
children(bankIndex);
356 for (
const auto index : bankChildren)
357 addTubes(
index, tubes);
367 if (!normal.
nullVector() && this->isBankFlat(componentInfo, bankIndex, tubes, normal))
368 foundFlatBank =
true;
371 if (!foundFlatBank) {
374 bankIndex = bankIndex0;
375 addTubes(bankIndex, tubes);
377 if (normal.
nullVector() || !this->isBankFlat(componentInfo, bankIndex, tubes, normal))
395 const size_t componentIndex)
const {
396 const auto *componentID = componentInfo.
componentID(componentIndex);
397 const auto component = instrument->getComponentByID(componentID);
399 return std::optional<Kernel::V2D>();
402 return component->getSideBySideViewPos();
std::map< DeltaEMode::Type, std::string > index
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
bool isBankFlat(const ComponentInfo &componentInfo, size_t bankIndex, const std::vector< size_t > &tubes, const V3D &normal)
Do all the detectors lie in a plane?
std::vector< V3D > retrievePanelCorners(const ComponentInfo &componentInfo, const size_t rootIndex) const
Returns the four corners of the specified panel.
V3D calculateBankNormal(const ComponentInfo &componentInfo, const std::vector< size_t > &tubes)
Calculate the normal vector of a bank of detectors.
void setupBasisAxes(const V3D &zaxis, V3D &xaxis, V3D &yaxis) const
Given the z axis, define the x and y ones.
std::vector< std::vector< size_t > > examineAllComponents(const ComponentInfo &componentInfo, std::function< std::vector< size_t >(const ComponentInfo &, size_t, std::vector< bool > &)> operation)
Perform a specified operation on all the components.
size_t findNumDetectors(const ComponentInfo &componentInfo, const std::vector< size_t > &components) const
How many detectors are there in the given list of component indices?
Mantid::Kernel::Quat calcBankRotation(const V3D &detPos, V3D normal, const V3D &zAxis, const V3D &yAxis, const V3D &samplePosition) const
Calculate the rotation needed around the bank's local x and y axes to place a bank on the projection ...
V3D calculatePanelNormal(const std::vector< V3D > &panelCorners) const
Calculate the normal vector to a panel.
void setBankVisited(const ComponentInfo &componentInfo, size_t bankIndex, std::vector< bool > &visitedComponents) const
Recursively set all detectors and subcomponents of a bank as visited.
std::vector< size_t > tubeDetectorParentIDs(const ComponentInfo &componentInfo, size_t rootIndex, std::vector< bool > &visited)
Parent indices of tubes.
Mantid::Kernel::Logger g_log
std::optional< Kernel::V2D > getSideBySideViewPos(const ComponentInfo &componentInfo, const Instrument_const_sptr &instrument, const size_t componentIndex) const
Gives the specified side-by-side view position from the IDF.
std::vector< Mantid::Kernel::V2D > transformedBoundingBoxPoints(const ComponentInfo &componentInfo, size_t detectorIndex, const V3D &refPos, const Mantid::Kernel::Quat &rotation, const V3D &xaxis, const V3D &yaxis) const
Transforms bounding box of a detector.
const Kernel::V3D & minPoint() const
Returns the min point of the box.
ComponentInfo : Provides a component centric view on to the instrument.
bool hasParent(const size_t componentIndex) const
size_t parent(const size_t componentIndex) const
BoundingBox boundingBox(const size_t componentIndex, const BoundingBox *reference=nullptr, const bool excludeMonitors=false) const
Compute the bounding box for the component with componentIndex taking into account all sub components...
Kernel::V3D position(const size_t componentIndex) const
const std::vector< size_t > & children(size_t componentIndex) const
const IComponent * componentID(const size_t componentIndex) const
bool isDetector(const size_t componentIndex) const
const std::string & name(const size_t componentIndex) const
const Geometry::IObject & shape(const size_t componentIndex) const
QuadrilateralComponent quadrilateralComponent(const size_t componentIndex) const
Beamline::ComponentType componentType(const size_t componentIndex) const
virtual std::shared_ptr< GeometryHandler > getGeometryHandler() const =0
void warning(const std::string &msg)
Logs at warning level.
void rotate(V3D &) const
Rotate a vector.
Implements a 2-dimensional vector embedded in a 3D space, i.e.
std::size_t size() const noexcept
Number of components in V3D.
constexpr double scalar_prod(const V3D &v) const noexcept
Calculates the cross product.
constexpr double X() const noexcept
Get x.
double normalize()
Make a normalized vector (return norm value)
constexpr V3D cross_prod(const V3D &v) const noexcept
Cross product (this * argument)
constexpr double Y() const noexcept
Get y.
void getSpherical(double &R, double &theta, double &phi) const noexcept
Return the vector's position in spherical coordinates.
constexpr double Z() const noexcept
Get z.
bool nullVector(const double tolerance=1e-3) const noexcept
Determine if the point is null.
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
constexpr double Tolerance
Standard tolerance value.
MANTID_KERNEL_DLL V3D normalize(V3D v)
Normalizes a V3D.