8#include "MantidBeamline/ComponentInfo.h"
9#include "MantidBeamline/ComponentType.h"
16#include <Eigen/Geometry>
27const Eigen::Vector3d undoRotation(
const Eigen::Vector3d &point,
const Beamline::ComponentInfo &compInfo,
28 const size_t componentIndex) {
29 auto unRotateTransform = Eigen::Affine3d(compInfo.rotation(componentIndex).inverse());
30 return unRotateTransform * point;
39const Kernel::V3D toShapeFrame(
const Kernel::V3D &point,
const Beamline::ComponentInfo &compInfo,
40 const size_t componentIndex) {
42 undoRotation(
Kernel::toVector3d(point) - compInfo.position(componentIndex), compInfo, componentIndex));
55 std::unique_ptr<Beamline::ComponentInfo> componentInfo,
56 std::shared_ptr<
const std::vector<Mantid::Geometry::IComponent *>> componentIds,
57 std::shared_ptr<
const std::unordered_map<Geometry::IComponent const *, size_t>> componentIdToIndexMap,
58 std::shared_ptr<std::vector<std::shared_ptr<const Geometry::IObject>>> shapes)
59 : m_componentInfo(
std::move(componentInfo)), m_componentIds(
std::move(componentIds)),
60 m_compIDToIndex(
std::move(componentIdToIndexMap)), m_shapes(
std::move(shapes)) {
63 throw std::invalid_argument(
"Inconsistent ID and Mapping input containers "
64 "for Geometry::ComponentInfo");
67 throw std::invalid_argument(
"Inconsistent ID and base "
68 "Beamline::ComponentInfo sizes for "
69 "Geometry::ComponentInfo");
87 : m_componentInfo(other.m_componentInfo->cloneWithoutDetectorInfo()), m_componentIds(other.m_componentIds),
88 m_compIDToIndex(other.m_compIDToIndex), m_shapes(other.m_shapes) {}
110 if (!(type == Beamline::ComponentType::Structured || type == Beamline::ComponentType::Rectangular ||
111 parentType == Beamline::ComponentType::Grid))
112 throw std::runtime_error(
"ComponentType is not Structured or Rectangular "
113 "in ComponentInfo::quadrilateralComponent.");
116 const auto &innerRangeComp =
m_componentInfo->children(componentIndex);
117 corners.
nX = innerRangeComp.size();
120 corners.
nY = firstCol.size();
123 corners.
topLeft = firstCol.back();
140 const auto *shapeAtIndex = (*m_shapes)[componentIndex].get();
141 return shapeAtIndex !=
nullptr && shapeAtIndex->hasValidShape();
225 const auto range =
m_componentInfo->detectorRangeInSubtree(componentIndex);
226 return range.begin() < range.end();
254 std::unordered_map<std::shared_ptr<const IObject>, std::vector<size_t>> result;
256 for (
size_t i = 0; i < shapes.size(); ++i) {
257 const auto ¤tShape = shapes[i];
258 if (currentShape !=
nullptr && currentShape->hasValidShape())
259 result[currentShape].emplace_back(i);
286 throw std::runtime_error(
"ComponentType is not Rectangular or Grid in ComponentInfo::pixelGridComponent.");
296std::tuple<int, int, int> xyzFillFirstZ(
const Beamline::PixelGridComponent &grid,
int col,
int id) {
297 if (grid.idFillOrder[1] ==
'y') {
298 int row = (
id / grid.idStepByRow) % grid.nY;
299 int layer = (
id / grid.idStepByRow) / grid.nY;
300 return {layer, row, col};
302 int row = (
id / grid.idStepByRow) % grid.nX;
303 int layer = (
id / grid.idStepByRow) / grid.nX;
304 return {row, layer, col};
307std::tuple<int, int, int> xyzFillFirstY(
const Beamline::PixelGridComponent &grid,
int col,
int id) {
308 if (grid.idFillOrder[1] ==
'z') {
309 int row = (
id / grid.idStepByRow) % grid.nZ;
310 int layer = (
id / grid.idStepByRow) / grid.nZ;
311 return {layer, col, row};
313 int row = (
id / grid.idStepByRow) % grid.nX;
314 int layer = (
id / grid.idStepByRow) / grid.nX;
315 return {row, col, layer};
318std::tuple<int, int, int> xyzFillFirstX(
const Beamline::PixelGridComponent &grid,
int col,
int id) {
319 if (grid.idFillOrder[1] ==
'y') {
320 int row = (
id / grid.idStepByRow) % grid.nY;
321 int layer = (
id / grid.idStepByRow) / grid.nY;
322 return {col, row, layer};
324 int row = (
id / grid.idStepByRow) % grid.nZ;
325 int layer = (
id / grid.idStepByRow) / grid.nZ;
326 return {col, layer, row};
341 const int id = detectorID - grid.idStart;
342 if (grid.idStepByRow == 0 || grid.idStep == 0)
344 const int col = (
id % grid.idStepByRow) / grid.idStep;
346 if (grid.idFillOrder[0] ==
'z')
347 return xyzFillFirstZ(grid, col,
id);
348 if (grid.idFillOrder[0] ==
'y')
349 return xyzFillFirstY(grid, col,
id);
350 return xyzFillFirstX(grid, col,
id);
360 if ((scaleFactorAtIndex -
Kernel::V3D(1.0, 1.0, 1.0)).norm() < 1e-12)
365 return shape(componentIndex).
solidAngle(paramsWithRelativeObserver, scaleFactorAtIndex);
388 const bool excludeMonitors)
const {
408 const bool excludeMonitors)
const {
422 const bool excludeMonitors)
const {
427 if (excludeMonitors) {
441 const auto &s = this->
shape(index);
447 absoluteBB.
xMin() *= scaleFactorAtIndex[0];
448 absoluteBB.
xMax() *= scaleFactorAtIndex[0];
449 absoluteBB.
yMin() *= scaleFactorAtIndex[1];
450 absoluteBB.
yMax() *= scaleFactorAtIndex[1];
451 absoluteBB.
zMin() *= scaleFactorAtIndex[2];
452 absoluteBB.
zMax() *= scaleFactorAtIndex[2];
455 .rotateBB(absoluteBB.
xMin(), absoluteBB.
yMin(), absoluteBB.
zMin(), absoluteBB.
xMax(), absoluteBB.
yMax(),
460 absoluteBB.
xMin() += localPos[0];
461 absoluteBB.
xMax() += localPos[0];
462 absoluteBB.
yMin() += localPos[1];
463 absoluteBB.
yMax() += localPos[1];
464 absoluteBB.
zMin() += localPos[2];
465 absoluteBB.
zMax() += localPos[2];
469 std::vector<Kernel::V3D> coordSystem;
473 absoluteBB.
realign(&coordSystem);
491 const bool excludeMonitors)
const {
499 auto parentFlag = Beamline::ComponentType::Generic;
506 }
else if (compFlag == Beamline::ComponentType::Unstructured) {
507 for (
const auto &childIndex : this->
children(componentIndex)) {
510 }
else if (compFlag == Beamline::ComponentType::Grid) {
511 for (
const auto &childIndex : this->
children(componentIndex)) {
514 }
else if (compFlag == Beamline::ComponentType::Rectangular || compFlag == Beamline::ComponentType::Structured ||
515 parentFlag == Beamline::ComponentType::Grid) {
517 }
else if (compFlag == Beamline::ComponentType::OutlineComposite) {
531 m_componentInfo->setScanInterval({interval.first.totalNanoseconds(), interval.second.totalNanoseconds()});
547 constexpr size_t invalidIndex{0};
554 if (indexChildren.empty()) {
558 if (
name(indexChildren[0]).starts_with(bankPart)) {
562 for (
size_t const child : indexChildren) {
564 if (j != invalidIndex) {
575 const size_t n =
size();
579 const size_t componentIdsMem =
sizeof(std::vector<Geometry::IComponent *>) +
n *
sizeof(
Geometry::IComponent *);
582 const size_t compIDToIndexMem =
sizeof(std::unordered_map<Geometry::IComponent const *, size_t>) +
586 const size_t shapesMem =
587 m_shapes ?
sizeof(*m_shapes) +
m_shapes->capacity() *
sizeof(std::shared_ptr<const Geometry::IObject>) : 0;
588 return sizeof(*this) + beamlineMem + componentIdsMem + compIDToIndexMem + shapesMem;
std::map< DeltaEMode::Type, std::string > index
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
A simple structure that defines an axis-aligned cuboid shaped bounding box for a geometrical object.
double xMax() const
Return the maximum value of X.
double zMin() const
Return the minimum value of Z.
std::vector< Kernel::V3D > const & getCoordSystem() const
returns the coordinate system to which BB is alighned to;
double zMax() const
Return the maximum value of Z.
double yMax() const
Return the maximum value of Y.
bool isAxisAligned() const
Check if it is normal axis aligned bounding box or not.
double xMin() const
Return the minimum value of X.
double yMin() const
Return the minimum value of Y.
void grow(const BoundingBox &other)
Grow the bounding box so that it also encompasses the given box.
void realign(std::vector< Kernel::V3D > const *const pCS=nullptr)
reallign the BB according to new coordinate system, provided earlier or specified as parameter;
ComponentInfo : Provides a component centric view on to the instrument.
bool hasParent(const size_t componentIndex) const
const ComponentInfoIterator< const ComponentInfo > cend()
bool hasDetectorInfo() const
BoundingBox componentBoundingBox(const size_t index, const BoundingBox *reference, const bool excludeMonitors=false) const
Calculates the absolute bounding box for the leaf item at index.
size_t findBankParent(size_t index, const std::string &bankPart) const
std::unordered_map< std::shared_ptr< const Geometry::IObject >, std::vector< size_t > > shapeToComponentIndices() const
Build a map from each unique shape to the list of component indices that share it.
size_t indexOfAny(const std::string &name) const
void setRotation(size_t componentIndex, const Kernel::Quat &newRotation)
bool hasDetectors(const size_t componentIndex) const
bool hasEquivalentSource(const ComponentInfo &other) const
double solidAngle(const size_t componentIndex, const Geometry::SolidAngleParams ¶ms) const
size_t parent(const size_t componentIndex) const
Kernel::Quat rotation(const size_t componentIndex) const
bool isGridDetector(size_t const componentIndex) const
void growBoundingBoxAsOutline(size_t index, const Geometry::BoundingBox *reference, Geometry::BoundingBox &mutableBB, const bool excludeMonitors=false) const
Grow the bounding box on the basis that the component described by index has an outline,...
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...
std::shared_ptr< std::vector< std::shared_ptr< const Geometry::IObject > > > m_shapes
Shapes for each component.
void scaleComponent(const size_t componentIndex, const Kernel::V3D &newScaling)
std::shared_ptr< const std::unordered_map< Geometry::IComponent const *, size_t > > m_compIDToIndex
Map of component ids to indexes.
Kernel::V3D position(const size_t componentIndex) const
const std::vector< size_t > & children(size_t componentIndex) const
Kernel::V2D sideBySideViewPosition(const size_t componentIndex) const
std::vector< size_t > componentsInSubtree(size_t componentIndex) const
void merge(const ComponentInfo &other)
bool hasValidShape(const size_t componentIndex) const
Beamline::PixelGridComponent pixelGridComponent(const size_t componentIndex) const
Kernel::V3D sourcePosition() const
ComponentInfoIterator< ComponentInfo > begin()
bool hasEquivalentSample(const ComponentInfo &other) const
void setScaleFactor(const size_t componentIndex, const Kernel::V3D &scaleFactor)
ComponentInfoIterator< ComponentInfo > end()
std::unique_ptr< Beamline::ComponentInfo > m_componentInfo
Pointer to the actual ComponentInfo object (non-wrapping part).
std::vector< size_t > detectorsInSubtree(size_t componentIndex) const
bool isDetector(const size_t componentIndex) const
bool uniqueName(const std::string &name) const
void growBoundingBoxAsRectuangularBank(size_t index, const Geometry::BoundingBox *reference, Geometry::BoundingBox &mutableBB, const bool excludeMonitors=false) const
Grow the bounding box on the basis that the component described by index is a regular grid in a trape...
std::unique_ptr< ComponentInfo > cloneWithoutDetectorInfo() const
Clone current instance but not the DetectorInfo non-owned parts.
const ComponentInfoIterator< const ComponentInfo > cbegin()
std::shared_ptr< const std::vector< Geometry::IComponent * > > m_componentIds
Collection of component ids.
size_t detectorIndexAtXYZ(const size_t componentIndex, const int x, const int y, const int z) const
Kernel::V3D relativePosition(const size_t componentIndex) const
std::tuple< int, int, int > xyzForDetectorID(const size_t componentIndex, const detid_t detectorID) const
Given the component index of a Rectangular/Grid bank, and a detector ID within it,...
size_t indexOf(Geometry::IComponent const *id) const
const std::string & name(const size_t componentIndex) const
size_t getMemorySize() const
Return memory used by the component info, in bytes.
Kernel::Quat relativeRotation(const size_t componentIndex) const
void setPosition(size_t componentIndex, const Kernel::V3D &newPosition)
Kernel::V3D samplePosition() const
const Geometry::IObject & shape(const size_t componentIndex) const
void setScanInterval(const std::pair< Types::Core::DateAndTime, Types::Core::DateAndTime > &interval)
QuadrilateralComponent quadrilateralComponent(const size_t componentIndex) const
Beamline::ComponentType componentType(const size_t componentIndex) const
Kernel::V3D scaleFactor(const size_t componentIndex) const
ComponentInfo(const ComponentInfo &other)
Private copy constructor. Do not make public.
base class for Geometric IComponent
IObject : Interface for geometry objects.
virtual double solidAngle(const SolidAngleParams ¶ms) const =0
const SolidAngleParams copyWithNewObserver(Kernel::V3D newObserver) const
const Kernel::V3D & observer() const
Exception thrown when an attempt is made to dereference a null pointer.
Implements a 2-dimensional vector embedded in a 3D space, i.e.
ComponentInfoIterator< const ComponentInfo > ComponentInfoConstIt
ComponentInfoIterator< ComponentInfo > ComponentInfoIt
Kernel::Quat toQuat(const Eigen::Quaterniond &quat)
Converts Eigen::Quaterniond to Kernel::Quat.
Kernel::V2D toV2D(const Eigen::Vector2d &vec)
Converts Eigen::Vector2d to Kernel::V2D.
Eigen::Vector3d toVector3d(const Kernel::V3D &vec)
Converts Kernel::V3D to Eigen::Vector3d.
Kernel::V3D toV3D(const Eigen::Vector3d &vec)
This header provides conversion helpers between vector and rotation types in MantidKernel and equival...
Eigen::Quaterniond toQuaterniond(const Kernel::Quat &quat)
Converts Kernel::Quat to Eigen::Quaterniond.
int32_t detid_t
Typedef for a detector ID.