Mantid
Loading...
Searching...
No Matches
Component.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 +
16
17#include <Poco/SAX/AttributesImpl.h>
18#include <Poco/XML/XMLWriter.h>
19
20#include <utility>
21
22namespace Mantid::Geometry {
23
24using Kernel::Quat;
25using Kernel::V3D;
26
32 : m_parent(nullptr), m_base(dynamic_cast<const Component *>(base)), m_map(map) {
33 if (!m_base) {
34 throw std::invalid_argument("Component::Component() - Cannot construct a "
35 "parameterized component from an invalid base component.");
36 }
37}
38
42Component::Component() : m_parent(nullptr), m_base(nullptr), m_map(nullptr), m_name(), m_pos(), m_rot() {}
43
48Component::Component(std::string name, IComponent *parent)
49 : m_parent(parent), m_base(nullptr), m_map(nullptr), m_name(std::move(name)), m_pos(), m_rot() {}
50
57Component::Component(std::string name, const V3D &position, IComponent *parent)
58 : m_parent(parent), m_base(nullptr), m_map(nullptr), m_name(std::move(name)), m_pos(position), m_rot() {}
59
66Component::Component(std::string name, const V3D &position, const Quat &rotation, IComponent *parent)
67 : m_parent(parent), m_base(nullptr), m_map(nullptr), m_name(std::move(name)), m_pos(position), m_rot(rotation) {}
68
69//------------------------------------------------------------------------------------------------
73bool Component::isParametrized() const { return (m_map != nullptr); }
74
80 // TODO : overload to copy the new pmap
81 // Create a new one with pmap parameter
83 return new Component(*this);
84}
85
90 if (m_map)
91 return ComponentID(const_cast<Component *>(m_base));
92 else
93 return ComponentID(const_cast<Component *>(this));
94}
95
97 if (m_map)
98 return const_cast<const Component *>(m_base);
99 else
100 return const_cast<const Component *>(this);
101}
102
103//-------------------------------------------------------------------------------
108
109//--------------------------------------------------------------------------------------------
113std::shared_ptr<const IComponent> Component::getParent() const {
114 if (this->m_map) {
115 std::shared_ptr<const IComponent> parent = m_base->getParent();
116 return ParComponentFactory::create(parent, m_map);
117 } else
118 return std::shared_ptr<const IComponent>(m_parent, NoDeleting());
119}
120
121//--------------------------------------------------------------------------------------------
129bool Component::isParentNamed(const std::string &expectedName, int maxDepth) const {
130 int depth = 0;
131 const IComponent *parent = m_parent;
132 while (parent && (depth < maxDepth || maxDepth < 0)) {
133 // Correct name? stop searching
134 if (parent->getName() == expectedName)
135 return true;
136 parent = parent->getBareParent();
137 depth++;
138 }
139 return false;
140}
141
142//--------------------------------------------------------------------------------------------
147std::vector<std::shared_ptr<const IComponent>> Component::getAncestors() const {
148 std::vector<std::shared_ptr<const IComponent>> ancs;
149
150 std::shared_ptr<const IComponent> current = this->getParent();
151 while (current) {
152 ancs.emplace_back(current);
153 current = current->getParent();
154 }
155 return ancs;
156}
157
158//--------------------------------------------------------------------------------------------
162void Component::setName(const std::string &s) {
163 if (!m_map)
164 this->m_name = s;
165 else
166 throw Kernel::Exception::NotImplementedError("Component::setName (for Parametrized Component)");
167}
168
169//--------------------------------------------------------------------------------------------
173std::string Component::getName() const {
174 if (m_map)
175 return m_base->getName();
176 else
177 return m_name;
178}
179
183std::string Component::getFullName() const {
184 std::vector<std::shared_ptr<const IComponent>> ancestors = this->getAncestors();
185 if (ancestors.empty()) {
186 return this->getName();
187 } else {
188 std::ostringstream oss;
189 std::vector<std::shared_ptr<const IComponent>>::reverse_iterator rit;
190 for (rit = ancestors.rbegin(); rit < ancestors.rend(); ++rit) {
191 oss << (*rit)->getName() << "/";
192 }
193 oss << this->getName();
194 return oss.str();
195 }
196}
197
204void Component::setPos(double x, double y, double z) {
205 if (!m_map)
206 m_pos = V3D(x, y, z);
207 else
208 throw Kernel::Exception::NotImplementedError("Component::setPos (for Parametrized Component)");
209}
210
215void Component::setPos(const V3D &v) {
216 if (!m_map)
217 m_pos = v;
218 else
219 throw Kernel::Exception::NotImplementedError("Component::setPos (for Parametrized Component)");
220}
221
226void Component::setRot(const Quat &q) {
227 if (!m_map)
228 m_rot = q;
229 else
230 throw Kernel::Exception::NotImplementedError("Component::setRot (for Parametrized Component)");
231}
232
238void Component::translate(double x, double y, double z) {
239 if (!m_map) {
240 m_pos[0] += x;
241 m_pos[1] += y;
242 m_pos[2] += z;
243 } else
244 throw Kernel::Exception::NotImplementedError("Component::translate (for Parametrized Component)");
245}
246
250void Component::translate(const V3D &v) {
251 if (!m_map)
252 m_pos += v;
253 else
254 throw Kernel::Exception::NotImplementedError("Component::translate (for Parametrized Component)");
255}
256
260void Component::rotate(const Quat &r) {
261 if (!m_map)
262 m_rot = m_rot * r;
263 else
264 throw Kernel::Exception::NotImplementedError("Component::rotate (for Parametrized Component)");
265}
266
271void Component::rotate(double angle, const V3D &axis) {
272 (void)angle; // Avoid compiler warning
273 (void)axis; // Avoid compiler warning
274 throw Kernel::Exception::NotImplementedError("Rotate(double angle, const V3D& axis) has not been implemented");
275}
276
283 if (m_map) {
284 if (hasComponentInfo()) {
286 } else {
288 if (par) {
289 return par->value<V3D>();
290 }
291 }
292 }
293 return V3D(1, 1, 1);
294}
295
297size_t Component::index() const { return m_map->componentIndex(this->getComponentID()); }
298
300 const IComponent *root = m_base;
301 while (auto parent = root->getBareParent())
302 root = parent;
303 auto instrument = dynamic_cast<const Instrument *>(root);
304 return m_map->hasComponentInfo(instrument);
305}
306
309 if (m_map) {
310
311 if (hasComponentInfo()) {
313 } else {
314 if (m_map->contains(m_base, "pos")) {
315 return m_map->get(m_base, "pos")->value<V3D>();
316 } else
317 return m_base->m_pos;
318 }
319 } else {
320 return m_pos;
321 }
322}
323
326 if (m_map) {
327 if (hasComponentInfo()) {
328 return m_map->componentInfo().position(index());
329 } else {
330 // We currently have to treat detectors in a different way because
331 // InfoComponentVisitor functionality is incomplete w.r.t DetectorInfo
332
333 // Avoid instantiation of the parent's parameterized object if possible
334 const IComponent *baseParent = m_base->m_parent;
335 if (!baseParent) {
336 return this->getRelativePos();
337 } else {
338 // Avoid instantiation of parent shared pointer if we can
339 V3D absPos = this->getRelativePos();
340 // get the parent rotation, try to get it from the cache first to avoid
341 // instantiaing the class
342
343 Quat parentRot;
344 V3D parentPos;
345 if (!(m_map->getCachedLocation(baseParent, parentPos) && m_map->getCachedRotation(baseParent, parentRot))) {
346 // Couldn't get them from the cache, so I have to instantiate the
347 // class
348 std::shared_ptr<const IComponent> parParent = getParent();
349 if (parParent) {
350 parentRot = parParent->getRotation();
351 parentPos = parParent->getPos();
352 }
353 }
354 parentRot.rotate(absPos);
355 absPos += parentPos;
356 return absPos;
357 }
358 }
359 } else {
360 if (!m_parent) {
361 return m_pos;
362 } else {
363 V3D absPos(m_pos);
364 m_parent->getRotation().rotate(absPos);
365 return absPos + m_parent->getPos();
366 }
367 }
368}
369
372 if (m_map) {
373 if (hasComponentInfo()) {
375 } else {
376 if (m_map->contains(m_base, "rot")) {
377 return m_map->get(m_base, "rot")->value<Quat>();
378 }
379 return m_base->m_rot;
380 }
381 } else {
382 return m_rot;
383 }
384}
385
388 if (m_map) {
389 if (hasComponentInfo()) {
390 return m_map->componentInfo().rotation(index());
391 } else {
392 // Avoid instantiation of the parent's parameterized object if possible
393 const IComponent *baseParent = m_base->m_parent;
394 if (!baseParent) {
395 return getRelativeRot();
396 } else {
397 Quat parentRot;
398 if (!m_map->getCachedRotation(baseParent, parentRot)) {
399 // Get the parent's rotation
400 std::shared_ptr<const IComponent> parParent = getParent();
401 if (parParent) {
402 parentRot = parParent->getRotation();
403 }
404 }
405 return parentRot * getRelativeRot();
406 }
407 }
408 } else {
409 // Not parametrized
410 if (!m_parent)
411 return m_rot;
412 else
413 return m_parent->getRotation() * m_rot;
414 }
415}
416
421double Component::getDistance(const IComponent &comp) const { return getPos().distance(comp.getPos()); }
422
428void Component::getBoundingBox(BoundingBox &boundingBox) const { boundingBox = BoundingBox(); }
429
436std::set<std::string> Component::getParameterNames(bool recursive) const {
437 if (!m_map)
438 return std::set<std::string>();
439
440 std::set<std::string> names = m_map->names(this);
441 if (recursive) {
442 // Walk up the tree and find the parameters attached to the parent
443 // components
444 std::shared_ptr<const IComponent> parent = getParent();
445 if (parent) {
446 std::set<std::string> parentNames = parent->getParameterNames(true);
447 names.insert(parentNames.begin(), parentNames.end());
448 }
449 }
450 return names;
451}
452
459std::map<std::string, ComponentID> Component::getParameterNamesByComponent() const {
460 auto retVal = std::map<std::string, ComponentID>();
461 if (!m_map)
462 return retVal;
463
464 auto names = m_map->names(this);
465 for (const auto &name : names) {
466 retVal.insert(std::pair<std::string, ComponentID>(name, this->getComponentID()));
467 }
468
469 // Walk up the tree and find the parameters attached to the parent components
470 std::shared_ptr<const IComponent> parent = getParent();
471 if (parent) {
472 auto parentNames = parent->getParameterNamesByComponent();
473 // this should discard duplicates
474 retVal.insert(parentNames.begin(), parentNames.end());
475 }
476 return retVal;
477}
478
486bool Component::hasParameter(const std::string &name, bool recursive) const {
487 if (!m_map)
488 return false;
489
490 bool match_found(false);
491 if (m_map->contains(this, name)) {
492 match_found = true;
493 } else if (recursive) {
494 std::shared_ptr<const IComponent> parent = getParent();
495 if (parent) {
496 match_found = parent->hasParameter(name, true);
497 } else {
498 match_found = false;
499 }
500 } else {
501 match_found = false;
502 }
503 return match_found;
504}
505
509void Component::printSelf(std::ostream &os) const {
510 std::shared_ptr<const IComponent> parent = getParent();
511 os << "Name : " << getName() << '\n';
512 os << "Type: " << this->type() << '\n';
513 if (parent)
514 os << "Parent: " << parent->getName() << '\n';
515 else
516 os << "Parent: None\n";
517
518 os << "Position : " << getPos() << '\n';
519 os << "Orientation :" << getRelativeRot() << '\n';
520}
521
527std::ostream &operator<<(std::ostream &os, const Component &comp) {
528 comp.printSelf(os);
529 return os;
530}
531
532//------------------------------------------------------------------------------------------------
535void Component::readXMLAttributes(const Poco::XML::Attributes &attr) {
536 UNUSED_ARG(attr);
537 // std::string pos = attr.getValue("", "pos");
538 // m_pos.fromString(pos);
539 // std::string rot = attr.getValue("", "rot");
540 // m_rot.fromString(rot);
541}
542
543void Component::writeXML(Poco::XML::XMLWriter &writer) const {
544 Poco::XML::AttributesImpl attr;
545 attr.addAttribute("", "pos", "", "", m_pos.toString());
546 writer.startElement("", "Component", "", attr);
547 writer.endElement("", "Component", "");
548}
549
550//------------------------------------------------------------------------------------------------
553void Component::appendXML(std::ostream &xmlStream) const {
554 xmlStream << "<pos>";
555 m_pos.write(xmlStream);
556 xmlStream << "</pos>\n";
557 xmlStream << "<rot>" << m_rot << "</rot>\n";
558}
559
560//--------------------------------------------------------------------------
561// Private methods
562//--------------------------------------------------------------------------
563
570void Component::swap(const Component *base, const ParameterMap *pmap) {
571 m_base = base;
572 m_map = pmap;
573}
585std::string Component::getParamDescription(const std::string &pname, bool recursive) const {
586 if (!m_map) { // no description for non-parameterized components
587 return std::string("");
588 }
589 Parameter_sptr param;
590 if (recursive) {
591 param = m_map->getRecursive(this, pname);
592 } else {
593 param = m_map->get(this, pname);
594 }
595 if (param)
596 return param->getDescription();
597 else
598 return std::string("");
599}
601std::string Component::getDescription() const {
602 auto name = this->getName();
603 return this->getParamDescription(name, false);
604}
605
616std::string Component::getParamShortDescription(const std::string &pname, bool recursive) const {
617 if (!m_map) { // no tooltips for non-parameterized components
618 return std::string("");
619 }
620 Parameter_sptr param;
621 if (recursive) {
622 param = m_map->getRecursive(this, pname);
623 } else {
624 param = m_map->get(this, pname);
625 }
626 if (param)
627 return param->getShortDescription();
628 else
629 return std::string("");
630}
631
635 auto name = this->getName();
636 return this->getParamShortDescription(name, false);
637}
641void Component::setDescription(const std::string &descr) {
642 if (m_map) {
643 std::string name = this->getName();
644 auto param = m_map->getRecursive(this, name);
645 if (param) {
646 param->setDescription(descr);
647 } else {
648 // I see no reason why component's parameter map should be constant.
649 // But as I do not understand why it is constant, let's HACK!
650 (const_cast<ParameterMap *>(m_map))->addString(this, name, "", &descr);
651 }
652 } else
653 throw Kernel::Exception::NotImplementedError("Component::setDescription "
654 "not implemented for "
655 "non-Parametrized Component)");
656}
657
658size_t Component::registerContents(class ComponentVisitor &componentVisitor) const {
659
660 return componentVisitor.registerGenericComponent(*this);
661}
662
663} // namespace Mantid::Geometry
double position
Definition: GetAllEi.cpp:154
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition: System.h:64
A simple structure that defines an axis-aligned cuboid shaped bounding box for a geometrical object.
Definition: BoundingBox.h:34
Kernel::Quat rotation(const size_t componentIndex) const
Kernel::V3D position(const size_t componentIndex) const
Kernel::V3D relativePosition(const size_t componentIndex) const
Kernel::Quat relativeRotation(const size_t componentIndex) const
Kernel::V3D scaleFactor(const size_t componentIndex) const
ComponentVisitor : Visitor for IComponents.
virtual size_t registerGenericComponent(const IComponent &component)=0
Component is a wrapper for a Component which can modify some of its parameters, e....
Definition: Component.h:41
const ParameterMap * m_map
A pointer to const ParameterMap containing the parameters.
Definition: Component.h:307
virtual void writeXML(Poco::XML::XMLWriter &writer) const
Definition: Component.cpp:543
std::map< std::string, ComponentID > getParameterNamesByComponent() const override
return the parameter names and the component they are from
Definition: Component.cpp:459
std::string getParamDescription(const std::string &pname, bool recursive=true) const
Get description of a parameter attached to this component
Definition: Component.cpp:585
void setRot(const Kernel::Quat &) override
Set the orientation Kernel::Quaternion relative to parent (if present)
Definition: Component.cpp:226
std::string getParamShortDescription(const std::string &pname, bool recursive=true) const
Get a component's parameter short description.
Definition: Component.cpp:616
virtual void readXMLAttributes(const Poco::XML::Attributes &attr)
Reads the XML attributes from Poco XML parser.
Definition: Component.cpp:535
size_t index() const
Helper for legacy access mode. Returns the index of the component.
Definition: Component.cpp:297
void setParent(IComponent *) override
Assign a parent IComponent. Previous parent link is lost.
Definition: Component.cpp:107
std::string m_name
Name of the component.
Definition: Component.h:310
Kernel::Quat getRelativeRot() const override
Get the relative Orientation.
Definition: Component.cpp:371
void printSelf(std::ostream &) const override
Prints a text representation of itself.
Definition: Component.cpp:509
Component()
Create Empty Component at Origin, with no orientation and null parent.
Definition: Component.cpp:42
Kernel::V3D m_pos
Position w.
Definition: Component.h:312
Kernel::V3D getRelativePos() const override
Get the position relative to the parent IComponent (absolute if no parent)
Definition: Component.cpp:308
IComponent * clone() const override
Clone method Make a copy of the Component.
Definition: Component.cpp:79
void setName(const std::string &) override
Set the IComponent name.
Definition: Component.cpp:162
virtual void appendXML(std::ostream &xmlStream) const
Append to an open XML string.
Definition: Component.cpp:553
void rotate(const Kernel::Quat &) override
Rotate the IComponent. This is relative to parent.
Definition: Component.cpp:260
void getBoundingBox(BoundingBox &boundingBox) const override
Get the bounding box for this component and store it in the given argument.
Definition: Component.cpp:428
const IComponent * base() const
Returns the address of the base component.
Definition: Component.h:280
std::set< std::string > getParameterNames(bool recursive=true) const override
Return the parameter names.
Definition: Component.cpp:436
virtual size_t registerContents(class ComponentVisitor &componentVisitor) const override
Definition: Component.cpp:658
Kernel::V3D getScaleFactor() const override
Returns the ScaleFactor.
Definition: Component.cpp:282
Kernel::V3D getPos() const override
Get the position of the IComponent. Tree structure is traverse through the.
Definition: Component.cpp:325
std::shared_ptr< const IComponent > getParent() const override
Return a pointer to the current parent. as shared pointer.
Definition: Component.cpp:113
bool isParametrized() const override
Return true if the Component is, in fact, parametrized (that is - it has a valid parameter map)
Definition: Component.cpp:73
const IComponent * m_parent
Parent component in the tree.
Definition: Component.h:300
void swap(const Component *base, const ParameterMap *pmap)
Swap the current references to the un-parameterized component and parameter map for new ones.
Definition: Component.cpp:570
Kernel::Quat m_rot
Orientation.
Definition: Component.h:314
std::string getFullName() const override
Get the full pathname.
Definition: Component.cpp:183
IComponent const * getBaseComponent() const override
Returns const pointer to base component if this component is parametrized.
Definition: Component.cpp:96
double getDistance(const IComponent &) const override
Get the distance to another IComponent.
Definition: Component.cpp:421
std::string getName() const override
Get the IComponent name.
Definition: Component.cpp:173
const Component * m_base
The base component - this is the unmodified component (without the parameters).
Definition: Component.h:305
bool isParentNamed(const std::string &expectedName, int maxDepth=-1) const
Return true if one of the parents of this component is named something.
Definition: Component.cpp:129
Kernel::Quat getRotation() const override
Get the absolute orientation of the IComponent.
Definition: Component.cpp:387
std::vector< std::shared_ptr< const IComponent > > getAncestors() const override
Return an array of all ancestors.
Definition: Component.cpp:147
void setDescription(const std::string &descr)
Set components description.
Definition: Component.cpp:641
void setPos(double, double, double) override
Set the IComponent position, x, y, z respective to parent (if present)
Definition: Component.cpp:204
std::string getDescription() const
Get this component parameter's description – no recursive search within children.
Definition: Component.cpp:601
bool hasParameter(const std::string &name, bool recursive=true) const override
Returns a boolean indicating if the component has the named parameter.
Definition: Component.cpp:486
void translate(const Kernel::V3D &) override
Translate the IComponent (vector form). This is relative to parent if.
Definition: Component.cpp:250
ComponentID getComponentID() const override
Returns the ComponentID - a unique identifier of the component.
Definition: Component.cpp:89
std::string getShortDescription() const
Get a components's short description.
Definition: Component.cpp:634
base class for Geometric IComponent
Definition: IComponent.h:51
virtual Kernel::V3D getPos() const =0
Get the position of the IComponent. Tree structure is traverse through the.
virtual std::string type() const
Returns a string representation of the IComponent type.
Definition: IComponent.h:54
virtual Kernel::Quat getRotation() const =0
Get the absolute orientation of the IComponent.
virtual const IComponent * getBareParent() const =0
Returns the bare pointer to the IComponent parent.
virtual std::string getName() const =0
Get the IComponent name.
Base Instrument Class.
Definition: Instrument.h:47
Void deleter for shared pointers.
static std::shared_ptr< IComponent > create(const std::shared_ptr< const IComponent > &base, const ParameterMap *map)
Create a parameterized component from the given base component and ParameterMap.
bool getCachedRotation(const IComponent *comp, Kernel::Quat &rotation) const
Attempts to retrieve a rotation from the rotation cache.
bool getCachedLocation(const IComponent *comp, Kernel::V3D &location) const
Attempts to retrieve a location from the location cache.
bool contains(const IComponent *comp, const std::string &name, const std::string &type="") const
Does the named parameter exist for the given component and type (std::string version)
std::shared_ptr< Parameter > getRecursive(const IComponent *comp, const std::string &name, const std::string &type="") const
Use get() recursively to see if can find param in all parents of comp and given type (std::string ver...
static const std::string & scale()
std::set< std::string > names(const IComponent *comp) const
Returns a set with all parameter names for component.
size_t componentIndex(const Geometry::ComponentID componentId) const
bool hasComponentInfo(const Instrument *instrument) const
Only for use by ExperimentInfo.
std::shared_ptr< Parameter > get(const IComponent *comp, const std::string &name, const std::string &type="") const
Get a parameter with a given name and type (std::string version)
const Geometry::ComponentInfo & componentInfo() const
Only for use by ExperimentInfo. Returns a reference to the ComponentInfo.
Marks code as not implemented yet.
Definition: Exception.h:138
Class for quaternions.
Definition: Quat.h:39
void rotate(V3D &) const
Rotate a vector.
Definition: Quat.cpp:397
std::vector< double > getRotation(bool check_normalisation=false, bool throw_on_errors=false) const
returns the rotation matrix defined by this quaternion as an 9-point
Definition: Quat.cpp:453
Class for 3D vectors.
Definition: V3D.h:34
double distance(const V3D &v) const noexcept
Calculates the distance between two vectors.
Definition: V3D.h:287
std::string toString() const
Definition: V3D.cpp:340
void write(std::ostream &) const
Write out the point values.
Definition: V3D.cpp:330
std::shared_ptr< Parameter > Parameter_sptr
Typedef for the shared pointer.
Definition: Parameter.h:195
MANTID_GEOMETRY_DLL std::ostream & operator<<(std::ostream &stream, const PointGroup &self)
Returns a streamed representation of the PointGroup object.
Definition: PointGroup.cpp:312
IComponent * ComponentID
Define a type for a unique component identifier.
Definition: IComponent.h:33
Generate a tableworkspace to store the calibration results.
STL namespace.