Mantid
Loading...
Searching...
No Matches
ComponentInfo.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#include "MantidBeamline/ComponentInfo.h"
9#include "MantidBeamline/ComponentType.h"
20
21#include <Eigen/Geometry>
22#include <algorithm>
23#include <exception>
24#include <iterator>
25#include <string>
26
27namespace Mantid::Geometry {
28
29namespace {
33const Eigen::Vector3d undoRotation(const Eigen::Vector3d &point, const Beamline::ComponentInfo &compInfo,
34 const size_t componentIndex) {
35 auto unRotateTransform = Eigen::Affine3d(compInfo.rotation(componentIndex).inverse());
36 return unRotateTransform * point;
37}
45const Kernel::V3D toShapeFrame(const Kernel::V3D &point, const Beamline::ComponentInfo &compInfo,
46 const size_t componentIndex) {
47 return Kernel::toV3D(
48 undoRotation(Kernel::toVector3d(point) - compInfo.position(componentIndex), compInfo, componentIndex));
49}
50
51} // namespace
52
62 std::unique_ptr<Beamline::ComponentInfo> componentInfo,
63 std::shared_ptr<const std::vector<Mantid::Geometry::IComponent *>> componentIds,
64 std::shared_ptr<const std::unordered_map<Geometry::IComponent const *, size_t>> componentIdToIndexMap,
65 std::shared_ptr<std::vector<std::shared_ptr<const Geometry::IObject>>> shapes,
66 std::shared_ptr<ParameterInfo> parameterInfo)
67 : m_componentInfo(std::move(componentInfo)), m_componentIds(std::move(componentIds)),
68 m_compIDToIndex(std::move(componentIdToIndexMap)), m_shapes(std::move(shapes)),
69 m_parameterInfo(std::move(parameterInfo)) {
70
71 if (m_componentIds->size() != m_compIDToIndex->size()) {
72 throw std::invalid_argument("Inconsistent ID and Mapping input containers "
73 "for Geometry::ComponentInfo");
74 }
75 if (m_componentIds->size() != m_componentInfo->size()) {
76 throw std::invalid_argument("Inconsistent ID and base "
77 "Beamline::ComponentInfo sizes for "
78 "Geometry::ComponentInfo");
79 }
80}
81
86std::unique_ptr<Geometry::ComponentInfo> ComponentInfo::cloneWithoutDetectorInfo() const {
87
88 return std::unique_ptr<Geometry::ComponentInfo>(new Geometry::ComponentInfo(*this));
89}
90
96 : m_componentInfo(other.m_componentInfo->cloneWithoutDetectorInfo()), m_componentIds(other.m_componentIds),
97 m_compIDToIndex(other.m_compIDToIndex), m_shapes(other.m_shapes), m_parameterInfo(other.m_parameterInfo) {}
98
99// Defined as default in source for forward declaration with std::unique_ptr.
101
102std::vector<size_t> ComponentInfo::detectorsInSubtree(size_t componentIndex) const {
103 return m_componentInfo->detectorsInSubtree(componentIndex);
104}
105
106std::vector<size_t> ComponentInfo::componentsInSubtree(size_t componentIndex) const {
107 return m_componentInfo->componentsInSubtree(componentIndex);
108}
109
110const std::vector<size_t> &ComponentInfo::children(size_t componentIndex) const {
111 return m_componentInfo->children(componentIndex);
112}
113
114size_t ComponentInfo::size() const { return m_componentInfo->size(); }
115
117 auto type = componentType(componentIndex);
118 auto parentType = componentType(parent(componentIndex));
119 if (!(type == Beamline::ComponentType::Structured || type == Beamline::ComponentType::Rectangular ||
120 parentType == Beamline::ComponentType::Grid))
121 throw std::runtime_error("ComponentType is not Structured or Rectangular "
122 "in ComponentInfo::quadrilateralComponent.");
123
125 const auto &innerRangeComp = m_componentInfo->children(componentIndex);
126 corners.nX = innerRangeComp.size();
127 const auto &firstCol = m_componentInfo->children(innerRangeComp[0]);
128 const auto &lastCol = m_componentInfo->children(innerRangeComp[corners.nX - 1]);
129 corners.nY = firstCol.size();
130 corners.bottomLeft = firstCol.front();
131 corners.topRight = lastCol.back();
132 corners.topLeft = firstCol.back();
133 corners.bottomRight = lastCol.front();
134
135 return corners;
136}
137
138size_t ComponentInfo::indexOf(Geometry::IComponent const *id) const { return m_compIDToIndex->at(id); }
139
141 auto const found = m_compIDToIndex->find(id);
142 return found == m_compIDToIndex->end() ? invalidIndex : found->second;
143}
144
145size_t ComponentInfo::indexOfAny(const std::string &name) const { return m_componentInfo->indexOfAny(name); }
146
147bool ComponentInfo::uniqueName(const std::string &name) const { return m_componentInfo->uniqueName(name); }
148
149bool ComponentInfo::isDetector(const size_t componentIndex) const {
150 return m_componentInfo->isDetector(componentIndex);
151}
152
153bool ComponentInfo::hasValidShape(const size_t componentIndex) const {
154 const auto *shapeAtIndex = (*m_shapes)[componentIndex].get();
155 return shapeAtIndex != nullptr && shapeAtIndex->hasValidShape();
156}
157
158Kernel::V3D ComponentInfo::position(const size_t componentIndex) const {
159 return Kernel::toV3D(m_componentInfo->position(componentIndex));
160}
161
162Kernel::V3D ComponentInfo::position(const std::pair<size_t, size_t> &index) const {
163 return Kernel::toV3D(m_componentInfo->position(index));
164}
165
166Kernel::Quat ComponentInfo::rotation(const size_t componentIndex) const {
167 return Kernel::toQuat(m_componentInfo->rotation(componentIndex));
168}
169
170Kernel::Quat ComponentInfo::rotation(const std::pair<size_t, size_t> &index) const {
171 return Kernel::toQuat(m_componentInfo->rotation(index));
172}
173
174Kernel::V3D ComponentInfo::relativePosition(const size_t componentIndex) const {
175 return Kernel::toV3D(m_componentInfo->relativePosition(componentIndex));
176}
177
178Kernel::Quat ComponentInfo::relativeRotation(const size_t componentIndex) const {
179 return Kernel::toQuat(m_componentInfo->relativeRotation(componentIndex));
180}
181
182void ComponentInfo::setPosition(const std::pair<size_t, size_t> &index, const Kernel::V3D &newPosition) {
183 m_componentInfo->setPosition(index, Kernel::toVector3d(newPosition));
184}
185
186void ComponentInfo::setRotation(const std::pair<size_t, size_t> &index, const Kernel::Quat &newRotation) {
187 m_componentInfo->setRotation(index, Kernel::toQuaterniond(newRotation));
188}
189
190void ComponentInfo::scaleComponent(const size_t componentIndex, const Kernel::V3D &newScaling) {
191 m_componentInfo->scaleComponent(componentIndex, Kernel::toVector3d(newScaling));
192}
193
194void ComponentInfo::scaleComponent(const std::pair<size_t, size_t> &index, const Kernel::V3D &newScaling) {
195 m_componentInfo->scaleComponent(index, Kernel::toVector3d(newScaling));
196}
197
198size_t ComponentInfo::parent(const size_t componentIndex) const { return m_componentInfo->parent(componentIndex); }
199
200bool ComponentInfo::hasParent(const size_t componentIndex) const { return m_componentInfo->hasParent(componentIndex); }
201
202bool ComponentInfo::hasDetectorInfo() const { return m_componentInfo->hasDetectorInfo(); }
203
205
207
208bool ComponentInfo::hasSource() const { return m_componentInfo->hasSource(); }
209
210/*
211 * @brief Check the sources of two componentInfo objects coincide
212 *
213 * @details check both objects either lack or have a source. If the latter,
214 * check their positions differ by less than 1 nm = 1e-9 m.
215 *
216 * @returns true if sources are equivalent
217 */
219 return m_componentInfo->hasEquivalentSource(*(other.m_componentInfo));
220}
221
222bool ComponentInfo::hasSample() const { return m_componentInfo->hasSample(); }
223
224/*
225 * @brief Check the samples of two componentInfo objects coincide
226 *
227 * @details check both objects either lack or have a sample. If the latter,
228 * check their positions differ by less than 1 nm = 1e-9 m.
229 *
230 * @returns true if sources are equivalent
231 */
233 return m_componentInfo->hasEquivalentSample(*(other.m_componentInfo));
234}
235
236bool ComponentInfo::hasDetectors(const size_t componentIndex) const {
237 if (isDetector(componentIndex))
238 return false;
239 const auto range = m_componentInfo->detectorRangeInSubtree(componentIndex);
240 return range.begin() < range.end();
241}
242
243size_t ComponentInfo::source() const { return m_componentInfo->source(); }
244
245size_t ComponentInfo::sample() const { return m_componentInfo->sample(); }
246
247double ComponentInfo::l1() const { return m_componentInfo->l1(); }
248
249size_t ComponentInfo::root() const { return m_componentInfo->root(); }
250
251void ComponentInfo::setPosition(const size_t componentIndex, const Kernel::V3D &newPosition) {
252 m_componentInfo->setPosition(componentIndex, Kernel::toVector3d(newPosition));
253}
254
255void ComponentInfo::setRotation(const size_t componentIndex, const Kernel::Quat &newRotation) {
256 m_componentInfo->setRotation(componentIndex, Kernel::toQuaterniond(newRotation));
257}
258
259const IObject &ComponentInfo::shape(const size_t componentIndex) const { return *(*m_shapes)[componentIndex]; }
260
267std::unordered_map<std::shared_ptr<const IObject>, std::vector<size_t>> ComponentInfo::shapeToComponentIndices() const {
268 std::unordered_map<std::shared_ptr<const IObject>, std::vector<size_t>> result;
269 const auto &shapes = *m_shapes;
270 for (size_t i = 0; i < shapes.size(); ++i) {
271 const auto &currentShape = shapes[i];
272 if (currentShape != nullptr && currentShape->hasValidShape())
273 result[currentShape].emplace_back(i);
274 }
275 return result;
276}
277
278Kernel::V3D ComponentInfo::scaleFactor(const size_t componentIndex) const {
279 return Kernel::toV3D(m_componentInfo->scaleFactor(componentIndex));
280}
281
282const std::string &ComponentInfo::name(const size_t componentIndex) const {
283 return m_componentInfo->name(componentIndex);
284}
285
286void ComponentInfo::setScaleFactor(const size_t componentIndex, const Kernel::V3D &scaleFactor) {
287 m_componentInfo->setScaleFactor(componentIndex, Kernel::toVector3d(scaleFactor));
288}
289
290Kernel::V2D ComponentInfo::sideBySideViewPosition(const size_t componentIndex) const {
291 return Kernel::toV2D(m_componentInfo->sideBySideViewPosition(componentIndex));
292}
293
294bool ComponentInfo::isGridDetector(size_t const componentIndex) const {
295 return m_componentInfo->isGridDetector(componentIndex);
296}
297
298Beamline::PixelGridComponent ComponentInfo::pixelGridComponent(const size_t componentIndex) const {
299 if (!isGridDetector(componentIndex)) {
300 throw std::runtime_error("ComponentType is not Rectangular or Grid in ComponentInfo::pixelGridComponent.");
301 }
302 return m_componentInfo->pixelGridComponent(componentIndex);
303}
304
305size_t ComponentInfo::detectorIndexAtXYZ(const size_t componentIndex, const int x, const int y, const int z) const {
306 return m_componentInfo->detectorIndexAtXYZ(componentIndex, x, y, z);
307}
308
309namespace {
310std::tuple<int, int, int> xyzFillFirstZ(const Beamline::PixelGridComponent &grid, int col, int id) {
311 if (grid.idFillOrder[1] == 'y') {
312 int row = (id / grid.idStepByRow) % grid.nY;
313 int layer = (id / grid.idStepByRow) / grid.nY;
314 return {layer, row, col};
315 }
316 int row = (id / grid.idStepByRow) % grid.nX;
317 int layer = (id / grid.idStepByRow) / grid.nX;
318 return {row, layer, col};
319}
320
321std::tuple<int, int, int> xyzFillFirstY(const Beamline::PixelGridComponent &grid, int col, int id) {
322 if (grid.idFillOrder[1] == 'z') {
323 int row = (id / grid.idStepByRow) % grid.nZ;
324 int layer = (id / grid.idStepByRow) / grid.nZ;
325 return {layer, col, row};
326 }
327 int row = (id / grid.idStepByRow) % grid.nX;
328 int layer = (id / grid.idStepByRow) / grid.nX;
329 return {row, col, layer};
330}
331
332std::tuple<int, int, int> xyzFillFirstX(const Beamline::PixelGridComponent &grid, int col, int id) {
333 if (grid.idFillOrder[1] == 'y') {
334 int row = (id / grid.idStepByRow) % grid.nY;
335 int layer = (id / grid.idStepByRow) / grid.nY;
336 return {col, row, layer};
337 }
338 int row = (id / grid.idStepByRow) % grid.nZ;
339 int layer = (id / grid.idStepByRow) / grid.nZ;
340 return {col, layer, row};
341}
342} // namespace
343
352std::tuple<int, int, int> ComponentInfo::xyzForDetectorID(const size_t componentIndex, const detid_t detectorID) const {
353 const auto grid = pixelGridComponent(componentIndex);
354
355 const int id = detectorID - grid.idStart;
356 if (grid.idStepByRow == 0 || grid.idStep == 0)
357 return {-1, -1, -1};
358 const int col = (id % grid.idStepByRow) / grid.idStep;
359
360 if (grid.idFillOrder[0] == 'z')
361 return xyzFillFirstZ(grid, col, id);
362 if (grid.idFillOrder[0] == 'y')
363 return xyzFillFirstY(grid, col, id);
364 return xyzFillFirstX(grid, col, id);
365}
366
367double ComponentInfo::solidAngle(const size_t componentIndex, const Geometry::SolidAngleParams &params) const {
368 if (!hasValidShape(componentIndex))
369 throw Kernel::Exception::NullPointerException("ComponentInfo::solidAngle", "shape");
370 // This is the observer position in the shape's coordinate system.
371 const Kernel::V3D relativeObserver = toShapeFrame(params.observer(), *m_componentInfo, componentIndex);
372 const Kernel::V3D scaleFactorAtIndex = this->scaleFactor(componentIndex);
373 const auto paramsWithRelativeObserver = params.copyWithNewObserver(relativeObserver);
374 if ((scaleFactorAtIndex - Kernel::V3D(1.0, 1.0, 1.0)).norm() < 1e-12)
375 return shape(componentIndex).solidAngle(paramsWithRelativeObserver);
376 else {
377 // This function will scale the object shape when calculating the solid
378 // angle.
379 return shape(componentIndex).solidAngle(paramsWithRelativeObserver, scaleFactorAtIndex);
380 }
381}
382
401 Geometry::BoundingBox &mutableBB,
402 const bool excludeMonitors) const {
403
404 auto panel = quadrilateralComponent(index);
405 mutableBB.grow(componentBoundingBox(panel.bottomLeft, reference, excludeMonitors));
406 mutableBB.grow(componentBoundingBox(panel.topRight, reference, excludeMonitors));
407 mutableBB.grow(componentBoundingBox(panel.topLeft, reference, excludeMonitors));
408 mutableBB.grow(componentBoundingBox(panel.bottomRight, reference, excludeMonitors));
409}
410
422 const bool excludeMonitors) const {
423 mutableBB.grow(componentBoundingBox(index, reference, excludeMonitors));
424}
425
436 const bool excludeMonitors) const {
437 // Check that we have a valid shape here
438 if (componentType(index) == Beamline::ComponentType::Infinite) {
439 return BoundingBox(); // Return null bounding box
440 }
441 if (excludeMonitors) {
442 // skip monitors
443 if (isDetector(index) && m_componentInfo->isMonitor(index)) {
444 return BoundingBox();
445 }
446 // skip other components such as choppers, etc
447 if (componentType(index) == Beamline::ComponentType::Generic) {
448 return BoundingBox();
449 }
450 }
451 if (!hasValidShape(index)) {
452 return BoundingBox(this->position(index).X(), this->position(index).Y(), this->position(index).Z(),
453 this->position(index).X(), this->position(index).Y(), this->position(index).Z());
454 } else {
455 const auto &s = this->shape(index);
456 BoundingBox absoluteBB = s.getBoundingBox();
457
458 // modify in place for speed
459 const Eigen::Vector3d scaleFactorAtIndex = m_componentInfo->scaleFactor(index);
460 // Scale
461 absoluteBB.xMin() *= scaleFactorAtIndex[0];
462 absoluteBB.xMax() *= scaleFactorAtIndex[0];
463 absoluteBB.yMin() *= scaleFactorAtIndex[1];
464 absoluteBB.yMax() *= scaleFactorAtIndex[1];
465 absoluteBB.zMin() *= scaleFactorAtIndex[2];
466 absoluteBB.zMax() *= scaleFactorAtIndex[2];
467 // Rotate
468 (this->rotation(index))
469 .rotateBB(absoluteBB.xMin(), absoluteBB.yMin(), absoluteBB.zMin(), absoluteBB.xMax(), absoluteBB.yMax(),
470 absoluteBB.zMax());
471
472 // Shift
473 const Eigen::Vector3d localPos = m_componentInfo->position(index);
474 absoluteBB.xMin() += localPos[0];
475 absoluteBB.xMax() += localPos[0];
476 absoluteBB.yMin() += localPos[1];
477 absoluteBB.yMax() += localPos[1];
478 absoluteBB.zMin() += localPos[2];
479 absoluteBB.zMax() += localPos[2];
480
481 if (reference && !reference->isAxisAligned()) { // copy coordinate system
482
483 std::vector<Kernel::V3D> coordSystem;
484 coordSystem.assign(reference->getCoordSystem().begin(), reference->getCoordSystem().end());
485
486 // realign to reference coordinate system
487 absoluteBB.realign(&coordSystem);
488 }
489 return absoluteBB;
490 }
491}
492
504BoundingBox ComponentInfo::boundingBox(const size_t componentIndex, const BoundingBox *reference,
505 const bool excludeMonitors) const {
506 if (isDetector(componentIndex) || componentType(componentIndex) == Beamline::ComponentType::Infinite) {
507 return componentBoundingBox(componentIndex, reference, excludeMonitors);
508 }
509
510 BoundingBox absoluteBB;
511 const auto compFlag = componentType(componentIndex);
512
513 auto parentFlag = Beamline::ComponentType::Generic;
514 if (size() > 1)
515 parentFlag = componentType(parent(componentIndex));
516
517 if (hasSource() && componentIndex == source()) {
518 // Do nothing. Source is not considered part of the beamline for bounding
519 // box calculations.
520 } else if (compFlag == Beamline::ComponentType::Unstructured) {
521 for (const auto &childIndex : this->children(componentIndex)) {
522 absoluteBB.grow(boundingBox(childIndex, reference, excludeMonitors));
523 }
524 } else if (compFlag == Beamline::ComponentType::Grid) {
525 for (const auto &childIndex : this->children(componentIndex)) {
526 growBoundingBoxAsRectuangularBank(childIndex, reference, absoluteBB, excludeMonitors);
527 }
528 } else if (compFlag == Beamline::ComponentType::Rectangular || compFlag == Beamline::ComponentType::Structured ||
529 parentFlag == Beamline::ComponentType::Grid) {
530 growBoundingBoxAsRectuangularBank(componentIndex, reference, absoluteBB, excludeMonitors);
531 } else if (compFlag == Beamline::ComponentType::OutlineComposite) {
532 growBoundingBoxAsOutline(componentIndex, reference, absoluteBB, excludeMonitors);
533 } else {
534 // General case
535 absoluteBB.grow(componentBoundingBox(componentIndex, reference, excludeMonitors));
536 }
537 return absoluteBB;
538}
539
540Beamline::ComponentType ComponentInfo::componentType(const size_t componentIndex) const {
541 return m_componentInfo->componentType(componentIndex);
542}
543
544void ComponentInfo::setScanInterval(const std::pair<Types::Core::DateAndTime, Types::Core::DateAndTime> &interval) {
545 m_componentInfo->setScanInterval({interval.first.totalNanoseconds(), interval.second.totalNanoseconds()});
546}
547
548size_t ComponentInfo::scanCount() const { return m_componentInfo->scanCount(); }
549
550void ComponentInfo::merge(const ComponentInfo &other) { m_componentInfo->merge(*other.m_componentInfo); }
551
553
555
557
559
560size_t ComponentInfo::findBankParent(size_t index, const std::string &bankPart) const {
561 constexpr size_t noBankParent{0}; // index 0 will always be a dectector and never a bank
562 // if this component is a bank, return the parent
563 if (name(index).starts_with(bankPart)) {
564 return parent(index);
565 }
566 // check if the children components begin with bankPart
567 auto indexChildren = children(index);
568 if (indexChildren.empty()) {
569 return noBankParent;
570 }
571 // if they do, we found the bank parent
572 if (name(indexChildren[0]).starts_with(bankPart)) {
573 return index;
574 }
575 // if not, check the grandchildren
576 for (size_t const child : indexChildren) {
577 size_t j = findBankParent(child, bankPart);
578 if (j != noBankParent) {
579 return j;
580 }
581 }
582 return noBankParent;
583}
584
587std::string ComponentInfo::fullName(const size_t componentIndex) const {
588 std::vector<size_t> ancestry{componentIndex};
589 for (size_t index = componentIndex; hasParent(index);) {
590 index = parent(index);
591 ancestry.emplace_back(index);
592 }
593 std::string result;
594 for (auto it = ancestry.crbegin(); it != ancestry.crend(); ++it) {
595 if (it != ancestry.crbegin()) {
596 result += "/";
597 }
598 result += name(*it);
599 }
600 return result;
601}
602
612size_t ComponentInfo::indexOfFullName(const std::string &fullName) const {
613 if (fullName.empty() || size() == 0) {
614 return invalidIndex;
615 }
616
617 size_t current = root();
618 size_t segmentStart = 0;
619 bool first = true;
620 while (segmentStart <= fullName.size()) {
621 const auto separator = fullName.find('/', segmentStart);
622 const auto segment =
623 fullName.substr(segmentStart, separator == std::string::npos ? std::string::npos : separator - segmentStart);
624 if (first) {
625 // The leading segment names the root itself, as fullName() writes it.
626 if (name(current) != segment) {
627 return invalidIndex;
628 }
629 first = false;
630 } else {
631 auto const &candidates = children(current);
632 auto const found =
633 std::find_if(candidates.cbegin(), candidates.cend(), [&](size_t child) { return name(child) == segment; });
634 if (found == candidates.cend()) {
635 return invalidIndex;
636 }
637 current = *found;
638 }
639 if (separator == std::string::npos) {
640 break;
641 }
642 segmentStart = separator + 1;
643 }
644 return current;
645}
646
647template <class T>
648std::vector<T> ComponentInfo::getParameter(size_t componentIndex, const std::string &name, bool recursive) const {
649 std::vector<T> result;
650 if (m_parameterInfo) {
651 Parameter_sptr const param = recursive ? m_parameterInfo->getRecursive(*this, componentIndex, name)
652 : m_parameterInfo->get(componentIndex, name);
653 if (param) {
654 result.emplace_back(param->value<T>());
655 }
656 }
657 return result;
658}
659
660bool ComponentInfo::hasParameter(const size_t componentIndex, const std::string &name, bool recursive) const {
661 bool result = false;
662 if (m_parameterInfo) {
663 // Recursively walk the ParameterInfo to search for name
664 result = recursive ? static_cast<bool>(m_parameterInfo->getRecursive(*this, componentIndex, name))
665 : m_parameterInfo->contains(componentIndex, name);
666 }
667 return result;
668}
669
670std::set<std::string> ComponentInfo::getParameterNames(const size_t componentIndex, bool recursive) const {
671 std::set<std::string> result;
672 if (m_parameterInfo) {
673 // Unlike the single-parameter lookups, this searches for all instances in component tree
674 result = m_parameterInfo->names(componentIndex);
675 if (recursive && hasParent(componentIndex)) {
676 auto const parentNames = getParameterNames(parent(componentIndex), true);
677 result.insert(parentNames.cbegin(), parentNames.cend());
678 }
679 }
680 return result;
681}
682
684 if (!m_parameterInfo) {
685 m_parameterInfo = std::make_shared<ParameterInfo>();
686 }
687 return *m_parameterInfo;
688}
689
690template <class T>
691void ComponentInfo::addTypedParameter(const size_t componentIndex, const std::string &type, const std::string &name,
692 const T &value, const std::string *const pDescription,
693 const std::string &pVisible) {
694 auto parameter = ParameterFactory::create(type, name, pVisible);
695 auto typedParameter = std::dynamic_pointer_cast<ParameterType<T>>(parameter);
696 if (!typedParameter) {
697 throw std::invalid_argument("ComponentInfo: parameter type '" + type + "' does not match the value supplied for '" +
698 name + "'");
699 }
700 typedParameter->setValue(value);
701 if (pDescription) {
702 parameter->setDescription(*pDescription);
703 }
704 mutableParameterInfo().add(componentIndex, parameter);
705}
706
707void ComponentInfo::addParameter(const size_t componentIndex, const std::string &type, const std::string &name,
708 const std::string &value, const std::string *const pDescription,
709 const std::string &pVisible) {
710 auto parameter = ParameterFactory::create(type, name, pVisible);
711 // fromString rather than setValue: the value arrives already serialised, and the concrete
712 // parameter type knows how to parse its own form.
713 parameter->fromString(value);
714 if (pDescription) {
715 parameter->setDescription(*pDescription);
716 }
717 mutableParameterInfo().add(componentIndex, parameter);
718}
719
720void ComponentInfo::addDouble(const size_t componentIndex, const std::string &name, double value,
721 const std::string *const pDescription, const std::string &pVisible) {
722 addTypedParameter(componentIndex, ParameterMap::pDouble(), name, value, pDescription, pVisible);
723}
724
725void ComponentInfo::addInt(const size_t componentIndex, const std::string &name, int value,
726 const std::string *const pDescription, const std::string &pVisible) {
727 addTypedParameter(componentIndex, ParameterMap::pInt(), name, value, pDescription, pVisible);
728}
729
730void ComponentInfo::addBool(const size_t componentIndex, const std::string &name, bool value,
731 const std::string *const pDescription, const std::string &pVisible) {
732 addTypedParameter(componentIndex, ParameterMap::pBool(), name, value, pDescription, pVisible);
733}
734
735void ComponentInfo::addString(const size_t componentIndex, const std::string &name, const std::string &value,
736 const std::string *const pDescription, const std::string &pVisible) {
737 addTypedParameter(componentIndex, ParameterMap::pString(), name, value, pDescription, pVisible);
738}
739
740void ComponentInfo::addV3D(const size_t componentIndex, const std::string &name, const Kernel::V3D &value,
741 const std::string *const pDescription) {
742 addTypedParameter(componentIndex, ParameterMap::pV3D(), name, value, pDescription, "true");
743}
744
745void ComponentInfo::addQuat(const size_t componentIndex, const std::string &name, const Kernel::Quat &value,
746 const std::string *const pDescription) {
747 addTypedParameter(componentIndex, ParameterMap::pQuat(), name, value, pDescription, "true");
748}
749
750void ComponentInfo::addFittingParameter(const size_t componentIndex, const std::string &name,
751 const std::string &fittingFunction, const std::string &value,
752 const std::string *const pDescription, const std::string &pVisible) {
753 auto parameter = ParameterFactory::create("fitting", name, pVisible);
754 parameter->fromString(value);
755 if (pDescription) {
756 parameter->setDescription(*pDescription);
757 }
758 mutableParameterInfo().addFittingParameter(componentIndex, parameter, fittingFunction);
759}
760
761void ComponentInfo::clearParameter(const size_t componentIndex, const std::string &name) {
762 if (m_parameterInfo) {
763 m_parameterInfo->clearParametersByName(componentIndex, name);
764 }
765}
766
767const ParameterInfo::ComponentParameters &ComponentInfo::parameters(const size_t componentIndex) const {
768 static ParameterInfo::ComponentParameters const empty;
769 return m_parameterInfo ? m_parameterInfo->parameters(componentIndex) : empty;
770}
771
772std::vector<double> ComponentInfo::getNumberParameter(const size_t componentIndex, const std::string &name,
773 bool recursive) const {
774 return getParameter<double>(componentIndex, name, recursive);
775}
776
777std::vector<int> ComponentInfo::getIntParameter(const size_t componentIndex, const std::string &name,
778 bool recursive) const {
779 return getParameter<int>(componentIndex, name, recursive);
780}
781
782std::vector<bool> ComponentInfo::getBoolParameter(const size_t componentIndex, const std::string &name,
783 bool recursive) const {
784 return getParameter<bool>(componentIndex, name, recursive);
785}
786
787std::vector<std::string> ComponentInfo::getStringParameter(const size_t componentIndex, const std::string &name,
788 bool recursive) const {
789 return getParameter<std::string>(componentIndex, name, recursive);
790}
791
792double ComponentInfo::getFittingParameter(const size_t componentIndex, const std::string &name, double xvalue) const {
793 if (!m_parameterInfo)
794 throw std::runtime_error("Parameters are not available in component=" + this->name(componentIndex));
795 Parameter_sptr parameter = m_parameterInfo->getRecursive(*this, componentIndex, name, "fitting");
796 if (!parameter)
797 throw std::runtime_error("Fitting parameter=" + name +
798 " could not be extracted from component=" + this->name(componentIndex));
799 try {
800 const auto &fitParam = parameter->value<FitParameter>();
801 return fitParam.getValue(xvalue);
802 } catch (...) {
803 throw std::runtime_error("Unable to get lookup table for parameter=" + name +
804 " from component=" + this->name(componentIndex));
805 }
806}
807
812 const size_t n = size();
813 // Beamline::ComponentInfo holds all the per-component arrays
814 const size_t beamlineMem = m_componentInfo->getMemorySize();
815 // m_componentIds: shared_ptr<const vector<IComponent*>> — count the heap-allocated vector object + its buffer
816 const size_t componentIdsMem = sizeof(std::vector<Geometry::IComponent *>) + n * sizeof(Geometry::IComponent *);
817 // m_compIDToIndex: shared_ptr<const unordered_map<IComponent const*, size_t>>
818 // Count the heap-allocated map object + each node (key + value + ~2 pointers for bucket/chain overhead)
819 const size_t compIDToIndexMem = sizeof(std::unordered_map<Geometry::IComponent const *, size_t>) +
820 n * (sizeof(Geometry::IComponent const *) + sizeof(size_t) + 2 * sizeof(void *));
821 // m_shapes: shared_ptr<vector<shared_ptr<const IObject>>>
822 // IObject shapes are shared; count the vector object + buffer of shared_ptrs, not the shapes themselves
823 const size_t shapesMem =
824 m_shapes ? sizeof(*m_shapes) + m_shapes->capacity() * sizeof(std::shared_ptr<const Geometry::IObject>) : 0;
825 return sizeof(*this) + beamlineMem + componentIdsMem + compIDToIndexMem + shapesMem;
826}
827
828} // namespace Mantid::Geometry
std::string name
Definition Run.cpp:60
double value
The value of the point.
Definition FitMW.cpp:51
double position
Definition GetAllEi.cpp:154
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.
Definition BoundingBox.h:33
double xMax() const
Return the maximum value of X.
Definition BoundingBox.h:79
double zMin() const
Return the minimum value of Z.
Definition BoundingBox.h:85
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.
Definition BoundingBox.h:87
double yMax() const
Return the maximum value of Y.
Definition BoundingBox.h:83
bool isAxisAligned() const
Check if it is normal axis aligned bounding box or not.
double xMin() const
Return the minimum value of X.
Definition BoundingBox.h:77
double yMin() const
Return the minimum value of Y.
Definition BoundingBox.h:81
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.
std::vector< int > getIntParameter(const size_t componentIndex, const std::string &name, bool recursive=true) const
bool hasParent(const size_t componentIndex) const
ParameterInfo & mutableParameterInfo()
The store, created on first write if this ComponentInfo was built without one (a bare,...
const ComponentInfoIterator< const ComponentInfo > cend()
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
void clearParameter(const size_t componentIndex, const std::string &name)
Remove every parameter of this name from this component.
std::string fullName(const size_t componentIndex) const
The fully-qualified name of a component ("instrument/bank1/pixel3")
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
void addQuat(const size_t componentIndex, const std::string &name, const Kernel::Quat &value, const std::string *const pDescription=nullptr)
Add or replace a named quaternion parameter at a specific component index.
void addFittingParameter(const size_t componentIndex, const std::string &name, const std::string &fittingFunction, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Add a fitting parameter.
double solidAngle(const size_t componentIndex, const Geometry::SolidAngleParams &params) 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::vector< std::string > getStringParameter(const size_t componentIndex, const std::string &name, bool recursive=true) const
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
bool hasParameter(const size_t componentIndex, const std::string &name, bool recursive=true) const
Returns empty (or false) if the ComponentInfo was built without parameters or the parameter is unset.
void addTypedParameter(const size_t componentIndex, const std::string &type, const std::string &name, const T &value, const std::string *const pDescription, const std::string &pVisible)
Shared implementation of the typed add*() methods.
void merge(const ComponentInfo &other)
bool hasValidShape(const size_t componentIndex) const
std::vector< double > getNumberParameter(const size_t componentIndex, const std::string &name, bool recursive=true) const
double getFittingParameter(const size_t componentIndex, const std::string &name, double xvalue) const
void addString(const size_t componentIndex, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Add or replace a named string parameter at a specific component index.
std::vector< bool > getBoolParameter(const size_t componentIndex, const std::string &name, bool recursive=true) const
Beamline::PixelGridComponent pixelGridComponent(const size_t componentIndex) const
size_t indexOfOrInvalid(Geometry::IComponent const *id) const
The index for a component ID, or invalidIndex if it is not part of this instrument.
std::shared_ptr< ParameterInfo > m_parameterInfo
The instrument's named parameters, keyed by component index.
std::vector< T > getParameter(size_t componentIndex, const std::string &name, bool recursive) 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::set< std::string > getParameterNames(const size_t componentIndex, bool recursive=true) const
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.
void addInt(const size_t componentIndex, const std::string &name, int value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Add or replace a named integer parameter at a specific component index.
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)
void addDouble(const size_t componentIndex, const std::string &name, double value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Add or replace a named double parameter at a specific component index.
static constexpr size_t invalidIndex
Returned by indexOfOrInvalid() for a component ID that is not part of this instrument.
const Geometry::IObject & shape(const size_t componentIndex) const
void setScanInterval(const std::pair< Types::Core::DateAndTime, Types::Core::DateAndTime > &interval)
const ParameterInfo::ComponentParameters & parameters(const size_t componentIndex) const
All parameters on one component, non-recursive, ordered by name.
void addBool(const size_t componentIndex, const std::string &name, bool value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Add or replace a named boolean parameter at a specific component index.
size_t indexOfFullName(const std::string &fullName) const
The component with this fully-qualified name, or invalidIndex if there is none.
QuadrilateralComponent quadrilateralComponent(const size_t componentIndex) const
Beamline::ComponentType componentType(const size_t componentIndex) const
void addV3D(const size_t componentIndex, const std::string &name, const Kernel::V3D &value, const std::string *const pDescription=nullptr)
Add or replace a named vector parameter at a specific component index.
Kernel::V3D scaleFactor(const size_t componentIndex) const
ComponentInfo(const ComponentInfo &other)
Private copy constructor. Do not make public.
void addParameter(const size_t componentIndex, const std::string &type, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Add or replace a named parameter at a specific component index.
Store information about a fitting parameter such as its value if it is constrained or tied.
double getValue(const double &at) const
get paramter value
base class for Geometric IComponent
Definition IComponent.h:53
IObject : Interface for geometry objects.
Definition IObject.h:42
virtual double solidAngle(const SolidAngleParams &params) const =0
static std::shared_ptr< Parameter > create(const std::string &className, const std::string &name, const std::string &visible="true")
Creates an instance of a parameter.
Definition Parameter.cpp:83
ParameterInfo : the named parameters of an instrument, addressed by component index.
bool addFittingParameter(size_t const componentIndex, std::shared_ptr< Parameter > const &parameter, std::string const &fittingFunction)
Add a fitting parameter, deduplicating by (name, function) rather than by name alone so that two func...
void add(size_t const componentIndex, std::shared_ptr< Parameter > const &parameter)
Add a parameter, replacing any existing parameter of the same name on the same component.
std::multimap< std::string, std::shared_ptr< Parameter >, Kernel::CaseInsensitiveStringComparator > ComponentParameters
Parameters of a single component, ordered by name.
static const std::string & pQuat()
static const std::string & pBool()
static const std::string & pV3D()
static const std::string & pDouble()
static const std::string & pString()
static const std::string & pInt()
const SolidAngleParams copyWithNewObserver(Kernel::V3D newObserver) const
const Kernel::V3D & observer() const
Exception thrown when an attempt is made to dereference a null pointer.
Definition Exception.h:305
Class for quaternions.
Definition Quat.h:39
Implements a 2-dimensional vector embedded in a 3D space, i.e.
Definition V2D.h:29
Class for 3D vectors.
Definition V3D.h:34
std::shared_ptr< Parameter > Parameter_sptr
Typedef for the shared pointer.
Definition Parameter.h:198
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.
STL namespace.