Mantid
Loading...
Searching...
No Matches
Instrument.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/DetectorInfo.h"
21#include "MantidKernel/Logger.h"
23#include "MantidKernel/Unit.h"
24
25#include <algorithm>
26#include <memory>
27#include <nexus/NeXusFile.hpp>
28#include <queue>
29#include <utility>
30
31using namespace Mantid::Kernel;
34
35namespace Mantid::Geometry {
36
37namespace {
38Kernel::Logger g_log("Instrument");
39
40void raiseDuplicateDetectorError(const size_t detectorId) {
41 std::stringstream sstream;
42 sstream << "Instrument Definition corrupt. Detector with ID " << detectorId << " already exists.";
43 throw Exception::InstrumentDefinitionError(sstream.str());
44}
45} // namespace
46
49 : CompAssembly(), m_detectorCache(), m_sourceCache(nullptr), m_sampleCache(nullptr), m_defaultView("3D"),
50 m_defaultViewAxis("Z+"), m_referenceFrame(new ReferenceFrame) {}
51
53Instrument::Instrument(const std::string &name)
54 : CompAssembly(name), m_detectorCache(), m_sourceCache(nullptr), m_sampleCache(nullptr), m_defaultView("3D"),
55 m_defaultViewAxis("Z+"), m_referenceFrame(new ReferenceFrame) {}
56
61Instrument::Instrument(const std::shared_ptr<const Instrument> &instr, const std::shared_ptr<ParameterMap> &map)
62 : CompAssembly(instr.get(), map.get()), m_sourceCache(instr->m_sourceCache), m_sampleCache(instr->m_sampleCache),
63 m_defaultView(instr->m_defaultView), m_defaultViewAxis(instr->m_defaultViewAxis), m_instr(instr),
64 m_map_nonconst(map), m_ValidFrom(instr->m_ValidFrom), m_ValidTo(instr->m_ValidTo),
65 m_referenceFrame(new ReferenceFrame) {
66 // Note that we do not copy m_detectorInfo and m_componentInfo into the
67 // parametrized instrument since the ParameterMap will make a copy, if
68 // applicable.
69}
70
77 : CompAssembly(instr), m_sourceCache(nullptr), m_sampleCache(nullptr), /* Should only be temporarily null */
78 m_logfileCache(instr.m_logfileCache), m_logfileUnit(instr.m_logfileUnit), m_defaultView(instr.m_defaultView),
79 m_defaultViewAxis(instr.m_defaultViewAxis), m_instr(), m_map_nonconst(), /* Should not be parameterized */
80 m_ValidFrom(instr.m_ValidFrom), m_ValidTo(instr.m_ValidTo), m_referenceFrame(instr.m_referenceFrame) {
81 // Note that we do not copy m_detectorInfo and m_componentInfo into the new
82 // instrument since they are only non-NULL for the base instrument, which
83 // should usually not be copied.
84
85 // Now we need to fill the detector, source and sample caches with pointers
86 // into the new instrument
87 std::vector<IComponent_const_sptr> children;
88 getChildren(children, true);
89 std::vector<IComponent_const_sptr>::const_iterator it;
90 for (it = children.begin(); it != children.end(); ++it) {
91 // First check if the current component is a detector and add to cache if it
92 // is
93 if (const IDetector *det = dynamic_cast<const Detector *>(it->get())) {
94 if (instr.isMonitor(det->getID()))
95 markAsMonitor(det);
96 else
97 markAsDetector(det);
98 continue;
99 }
100 // Now check whether the current component is the source or sample.
101 // As the majority of components will be detectors, we will rarely get to
102 // here
103 if (const auto *obj = dynamic_cast<const Component *>(it->get())) {
104 const std::string objName = obj->getName();
105 // This relies on the source and sample having a unique name.
106 // I think the way our instrument definition files work ensures this is
107 // the case.
108 if (objName == instr.m_sourceCache->getName()) {
110 continue;
111 }
112 if (objName == instr.m_sampleCache->getName()) {
114 continue;
115 }
116 }
117 }
118}
119
121Instrument *Instrument::clone() const { return new Instrument(*this); }
122
125 if (m_map)
126 return m_instr;
127 else
128 throw std::runtime_error("Instrument::baseInstrument() called for a "
129 "non-parametrized instrument.");
130}
131
138 if (m_map)
139 return m_map_nonconst;
140 else
141 throw std::runtime_error("Instrument::getParameterMap() called for a "
142 "non-parametrized instrument.");
143}
144
152 if (m_map) {
153 if (m_instr->getPhysicalInstrument()) {
154 // A physical instrument should use the same parameter map as the 'main'
155 // instrument. This constructor automatically sets the instrument as the
156 // owning instrument in the ParameterMap. We need to undo this immediately
157 // since the ParameterMap must always be owned by the neutronic
158 // instrument.
159 return std::make_shared<Instrument>(m_instr->getPhysicalInstrument(), m_map_nonconst);
160 } else {
161 return Instrument_const_sptr();
162 }
163 } else {
165 }
166}
167
173void Instrument::setPhysicalInstrument(std::unique_ptr<Instrument> physInst) {
174 if (!m_map) {
175 physInst->m_isPhysicalInstrument = true;
176 m_physicalInstrument = std::move(physInst);
177 } else
178 throw std::runtime_error("Instrument::setPhysicalInstrument() called on a "
179 "parametrized instrument.");
180}
181
182//------------------------------------------------------------------------------------------
187 if (m_map) {
188 // Get the base instrument detectors
189 out_map.clear();
190 const auto &in_dets = m_instr->m_detectorCache;
191 // And turn them into parametrized versions
192 for (const auto &in_det : in_dets) {
193 out_map.emplace(std::get<0>(in_det), getDetector(std::get<0>(in_det)));
194 }
195 } else {
196 // You can just return the detector cache directly.
197 out_map.clear();
198 for (const auto &in_det : m_detectorCache)
199 out_map.emplace(std::get<0>(in_det), std::get<1>(in_det));
200 }
201}
202
203//------------------------------------------------------------------------------------------
205std::vector<detid_t> Instrument::getDetectorIDs(bool skipMonitors) const {
206 std::vector<detid_t> out;
207 if (m_map) {
208 const auto &in_dets = m_instr->m_detectorCache;
209 for (const auto &in_det : in_dets)
210 if (!skipMonitors || !std::get<2>(in_det))
211 out.emplace_back(std::get<0>(in_det));
212 } else {
213 const auto &in_dets = m_detectorCache;
214 for (const auto &in_det : in_dets)
215 if (!skipMonitors || !std::get<2>(in_det))
216 out.emplace_back(std::get<0>(in_det));
217 }
218 return out;
219}
220
222std::size_t Instrument::getNumberDetectors(bool skipMonitors) const {
223 std::size_t numDetIDs(0);
224
225 if (m_map) {
226 numDetIDs = m_instr->m_detectorCache.size();
227 } else {
228 numDetIDs = m_detectorCache.size();
229 }
230
231 if (skipMonitors) // this slow, but gets the right answer
232 {
233 std::size_t monitors(0);
234 if (m_map) {
235 const auto &in_dets = m_instr->m_detectorCache;
236 for (const auto &in_det : in_dets)
237 if (std::get<2>(in_det))
238 monitors += 1;
239 } else {
240 const auto &in_dets = m_detectorCache;
241 for (const auto &in_det : in_dets)
242 if (std::get<2>(in_det))
243 monitors += 1;
244 }
245 return (numDetIDs - monitors);
246 } else {
247 return numDetIDs;
248 }
249}
250
257 const auto *in_dets = m_map ? &m_instr->m_detectorCache : &m_detectorCache;
258
259 if (in_dets->empty())
260 throw std::runtime_error("No detectors on this instrument. Can't find min/max ids");
261 // Maps are sorted by key. So it is easy to find
262 min = std::get<0>(*in_dets->begin());
263 max = std::get<0>(*in_dets->rbegin());
264}
265
275void Instrument::getDetectorsInBank(std::vector<IDetector_const_sptr> &dets, const IComponent &comp) const {
276 const auto bank = dynamic_cast<const ICompAssembly *>(&comp);
277 if (bank) {
278 // Get a vector of children (recursively)
279 std::vector<std::shared_ptr<const IComponent>> children;
280 bank->getChildren(children, true);
281 std::vector<std::shared_ptr<const IComponent>>::iterator it;
282 for (it = children.begin(); it != children.end(); ++it) {
283 IDetector_const_sptr det = std::dynamic_pointer_cast<const IDetector>(*it);
284 if (det) {
285 dets.emplace_back(det);
286 }
287 }
288 }
289}
290
301void Instrument::getDetectorsInBank(std::vector<IDetector_const_sptr> &dets, const std::string &bankName) const {
302 std::shared_ptr<const IComponent> comp = this->getComponentByName(bankName);
303 if (!comp) {
304 throw Kernel::Exception::NotFoundError("Could not find component", bankName);
305 }
306 getDetectorsInBank(dets, *comp);
307}
308
312bool Instrument::hasSource() const { return m_sourceCache; }
313
317bool Instrument::hasSample() const { return m_sampleCache; }
318
323 if (!m_sourceCache) {
324 g_log.warning("In Instrument::getSource(). No source has been set.");
326 } else if (m_map) {
327 auto sourceCache = static_cast<const Instrument *>(m_base)->m_sourceCache;
328 if (dynamic_cast<const ObjComponent *>(sourceCache))
329 return IComponent_const_sptr(new ObjComponent(sourceCache, m_map));
330 else if (dynamic_cast<const CompAssembly *>(sourceCache))
331 return IComponent_const_sptr(new CompAssembly(sourceCache, m_map));
332 else if (dynamic_cast<const Component *>(sourceCache))
333 return IComponent_const_sptr(new Component(sourceCache, m_map));
334 else {
335 g_log.error("In Instrument::getSource(). Source is not a recognised "
336 "component type.");
337 g_log.error("Try to assume it is a Component.");
338 return IComponent_const_sptr(new ObjComponent(sourceCache, m_map));
339 }
340 } else {
342 }
343}
344
349 if (!m_sampleCache) {
350 g_log.warning("In Instrument::getSamplePos(). No SamplePos has been set.");
352 } else if (m_map) {
353 auto sampleCache = static_cast<const Instrument *>(m_base)->m_sampleCache;
354 if (dynamic_cast<const ObjComponent *>(sampleCache))
355 return IComponent_const_sptr(new ObjComponent(sampleCache, m_map));
356 else if (dynamic_cast<const CompAssembly *>(sampleCache))
357 return IComponent_const_sptr(new CompAssembly(sampleCache, m_map));
358 else if (dynamic_cast<const Component *>(sampleCache))
359 return IComponent_const_sptr(new Component(sampleCache, m_map));
360 else {
361 g_log.error("In Instrument::getSamplePos(). SamplePos is not a "
362 "recognised component type.");
363 g_log.error("Try to assume it is a Component.");
364 return IComponent_const_sptr(new ObjComponent(sampleCache, m_map));
365 }
366 } else {
368 }
369}
370
376
377//------------------------------------------------------------------------------------------
382std::shared_ptr<const IComponent> Instrument::getComponentByID(const IComponent *id) const {
383 const auto *base = static_cast<const IComponent *>(id);
384 if (m_map)
385 return ParComponentFactory::create(std::shared_ptr<const IComponent>(base, NoDeleting()), m_map);
386 else
387 return std::shared_ptr<const IComponent>(base, NoDeleting());
388}
389
399std::vector<std::shared_ptr<const IComponent>> Instrument::getAllComponentsWithName(const std::string &cname) const {
400 std::shared_ptr<const IComponent> node = std::shared_ptr<const IComponent>(this, NoDeleting());
401 std::vector<std::shared_ptr<const IComponent>> retVec;
402 // Check the instrument name first
403 if (this->getName() == cname) {
404 retVec.emplace_back(node);
405 }
406 // Same algorithm as used in getComponentByName() but searching the full tree
407 std::deque<std::shared_ptr<const IComponent>> nodeQueue;
408 // Need to be able to enter the while loop
409 nodeQueue.emplace_back(node);
410 while (!nodeQueue.empty()) {
411 node = nodeQueue.front();
412 nodeQueue.pop_front();
413 int nchildren(0);
414 std::shared_ptr<const ICompAssembly> asmb = std::dynamic_pointer_cast<const ICompAssembly>(node);
415 if (asmb) {
416 nchildren = asmb->nelements();
417 }
418 for (int i = 0; i < nchildren; ++i) {
419 std::shared_ptr<const IComponent> comp = (*asmb)[i];
420 if (comp->getName() == cname) {
421 retVec.emplace_back(comp);
422 } else {
423 nodeQueue.emplace_back(comp);
424 }
425 }
426 } // while-end
427
428 // If we have reached here then the search failed
429 return retVec;
430}
431
432namespace {
433// Helpers for accessing m_detectorCache, which is a vector of tuples used as a
434// map. Lookup is by first element in a tuple. Templated to support const and
435// non-const.
436template <class T> auto lower_bound(T &map, const detid_t key) -> decltype(map.begin()) {
437 return std::lower_bound(map.begin(), map.end(), std::make_tuple(key, IDetector_const_sptr(nullptr), false),
438 [](const typename T::value_type &a, const typename T::value_type &b) -> bool {
439 return std::get<0>(a) < std::get<0>(b);
440 });
441}
442
443template <class T> auto find(T &map, const detid_t key) -> decltype(map.begin()) {
444 auto it = lower_bound(map, key);
445 if ((it != map.end()) && (std::get<0>(*it) == key))
446 return it;
447 return map.end();
448}
449} // namespace
450
462 const auto &baseInstr = m_map ? *m_instr : *this;
463 const auto it = find(baseInstr.m_detectorCache, detector_id);
464 if (it == baseInstr.m_detectorCache.end()) {
465 std::stringstream readInt;
466 readInt << detector_id;
467 throw Kernel::Exception::NotFoundError("Instrument: Detector with ID " + readInt.str() + " not found.", "");
468 }
469 IDetector_const_sptr baseDet = std::get<1>(*it);
470
471 if (!m_map)
472 return baseDet;
473
474 auto det = ParComponentFactory::createDetector(baseDet.get(), m_map);
475 return det;
476}
477
483const IDetector *Instrument::getBaseDetector(const detid_t &detector_id) const {
484 auto it = find(m_instr->m_detectorCache, detector_id);
485 if (it == m_instr->m_detectorCache.end()) {
486 return nullptr;
487 }
488 return std::get<1>(*it).get();
489}
490
491bool Instrument::isMonitor(const detid_t &detector_id) const {
492 const auto &baseInstr = m_map ? *m_instr : *this;
493 const auto it = find(baseInstr.m_detectorCache, detector_id);
494 if (it == baseInstr.m_detectorCache.end())
495 return false;
496 return std::get<2>(*it);
497}
498
499bool Instrument::isMonitor(const std::set<detid_t> &detector_ids) const {
500 if (detector_ids.empty())
501 return false;
502
503 return std::any_of(detector_ids.cbegin(), detector_ids.cend(),
504 [this](const auto detector_id) { return isMonitor(detector_id); });
505}
506
513IDetector_const_sptr Instrument::getDetectorG(const std::set<detid_t> &det_ids) const {
514 const size_t ndets(det_ids.size());
515 if (ndets == 1) {
516 return this->getDetector(*det_ids.begin());
517 } else {
518 std::shared_ptr<DetectorGroup> det_group = std::make_shared<DetectorGroup>();
519 for (const auto detID : det_ids) {
520 det_group->addDetector(this->getDetector(detID));
521 }
522 return det_group;
523 }
524}
525
530std::vector<IDetector_const_sptr> Instrument::getDetectors(const std::vector<detid_t> &det_ids) const {
531 std::vector<IDetector_const_sptr> dets_ptr;
532 dets_ptr.reserve(det_ids.size());
533 std::vector<detid_t>::const_iterator it;
534 for (it = det_ids.begin(); it != det_ids.end(); ++it) {
535 dets_ptr.emplace_back(this->getDetector(*it));
536 }
537 return dets_ptr;
538}
539
544std::vector<IDetector_const_sptr> Instrument::getDetectors(const std::set<detid_t> &det_ids) const {
545 std::vector<IDetector_const_sptr> dets_ptr;
546 dets_ptr.reserve(det_ids.size());
547 std::set<detid_t>::const_iterator it;
548 for (it = det_ids.begin(); it != det_ids.end(); ++it) {
549 dets_ptr.emplace_back(this->getDetector(*it));
550 }
551 return dets_ptr;
552}
553
565 if (m_map)
566 throw std::runtime_error("Instrument::markAsSamplePos() called on a "
567 "parametrized Instrument object.");
568
569 auto objComp = dynamic_cast<const IObjComponent *>(comp);
570 if (objComp) {
571 throw std::runtime_error("Instrument::markAsSamplePos() called on an IObjComponent "
572 "object that supports shape definition. Sample is prevented from "
573 "being this type because the shape must only be stored in "
574 "ExperimentInfo::m_sample.");
575 }
576
577 if (!m_sampleCache) {
578 if (comp->getName().empty()) {
579 throw Exception::InstrumentDefinitionError("The sample component is required to have a name.");
580 }
581 m_sampleCache = comp;
582 } else {
583 g_log.warning("Have already added samplePos component to the _sampleCache.");
584 }
585}
586
598 if (m_map)
599 throw std::runtime_error("Instrument::markAsSource() called on a "
600 "parametrized Instrument object.");
601
602 if (!m_sourceCache) {
603 if (comp->getName().empty()) {
604 throw Exception::InstrumentDefinitionError("The source component is required to have a name.");
605 }
606 m_sourceCache = comp;
607 } else {
608 g_log.warning("Have already added source component to the _sourceCache.");
609 }
610}
611
621 if (m_map)
622 throw std::runtime_error("Instrument::markAsDetector() called on a "
623 "parametrized Instrument object.");
624
625 // Create a (non-deleting) shared pointer to it
627 auto it = lower_bound(m_detectorCache, det->getID());
628 // Duplicate detector ids are forbidden
629 if ((it != m_detectorCache.end()) && (std::get<0>(*it) == det->getID())) {
630 raiseDuplicateDetectorError(det->getID());
631 }
632 bool isMonitor = false;
633 m_detectorCache.emplace(it, det->getID(), det_sptr, isMonitor);
634}
635
639 if (m_map)
640 throw std::runtime_error("Instrument::markAsDetector() called on a "
641 "parametrized Instrument object.");
642
643 // Create a (non-deleting) shared pointer to it
645 bool isMonitor = false;
646 m_detectorCache.emplace_back(det->getID(), det_sptr, isMonitor);
647}
648
652 // Detectors (even when different objects) are NOT allowed to have duplicate
653 // ids. This method establishes the presence of duplicates.
654 std::sort(
655 m_detectorCache.begin(), m_detectorCache.end(),
656 [](const std::tuple<detid_t, IDetector_const_sptr, bool> &a,
657 const std::tuple<detid_t, IDetector_const_sptr, bool> &b) -> bool { return std::get<0>(a) < std::get<0>(b); });
658
659 auto resultIt = std::adjacent_find(m_detectorCache.begin(), m_detectorCache.end(),
660 [](const std::tuple<detid_t, IDetector_const_sptr, bool> &a,
661 const std::tuple<detid_t, IDetector_const_sptr, bool> &b) -> bool {
662 return std::get<0>(a) == std::get<0>(b);
663 });
664 if (resultIt != m_detectorCache.end()) {
665 raiseDuplicateDetectorError(std::get<0>(*resultIt));
666 }
667}
668
678 if (m_map)
679 throw std::runtime_error("Instrument::markAsMonitor() called on a "
680 "parametrized Instrument object.");
681
682 // attempt to add monitor to instrument detector cache
683 markAsDetector(det);
684
685 // mark detector as a monitor
686 auto it = find(m_detectorCache, det->getID());
687 std::get<2>(*it) = true;
688}
689
695 if (m_map)
696 throw std::runtime_error("Instrument::removeDetector() called on a "
697 "parameterized Instrument object.");
698
699 const detid_t id = det->getID();
700 // Remove the detector from the detector cache
701 const auto it = find(m_detectorCache, id);
702 m_detectorCache.erase(it);
703
704 // Remove it from the parent assembly (and thus the instrument). Evilness
705 // required here unfortunately.
706 auto *parentAssembly = dynamic_cast<CompAssembly *>(const_cast<IComponent *>(det->getBareParent()));
707 if (parentAssembly) // Should always be true, but check just in case
708 {
709 parentAssembly->remove(det);
710 }
711}
712
716std::vector<detid_t> Instrument::getMonitors() const {
717 // Monitors cannot be parametrized. So just return the base.
718 if (m_map)
719 return m_instr->getMonitors();
720
721 std::vector<detid_t> mons;
722 for (const auto &item : m_detectorCache)
723 if (std::get<2>(item))
724 mons.emplace_back(std::get<0>(item));
725 return mons;
726}
727
733void Instrument::getBoundingBox(BoundingBox &assemblyBox) const {
734 if (m_map) {
735
736 if (m_map->hasComponentInfo(this->baseInstrument().get())) {
737 assemblyBox = m_map->componentInfo().boundingBox(index(), &assemblyBox);
738 return;
739 }
740
741 // Loop over the children and define a box large enough for all of them
742 ComponentID sourceID = getSource()->getComponentID();
743 assemblyBox = BoundingBox(); // this makes the instrument BB always axis aligned
744 int nchildren = nelements();
745 for (int i = 0; i < nchildren; ++i) {
746 IComponent_sptr comp = this->getChild(i);
747 if (comp && comp->getComponentID() != sourceID) {
748 BoundingBox compBox;
749 comp->getBoundingBox(compBox);
750 assemblyBox.grow(compBox);
751 }
752 }
753 } else {
754
755 if (!m_cachedBoundingBox) {
757 ComponentID sourceID = getSource()->getComponentID();
758 // Loop over the children and define a box large enough for all of them
759 for (auto component : m_children) {
760 BoundingBox compBox;
761 if (component && component->getComponentID() != sourceID) {
762 component->getBoundingBox(compBox);
763 m_cachedBoundingBox->grow(compBox);
764 }
765 }
766 }
767 // Use cached box
768 assemblyBox = *m_cachedBoundingBox;
769 }
770}
771
772std::shared_ptr<const std::vector<IObjComponent_const_sptr>> Instrument::getPlottable() const {
773 if (m_map) {
774 // Get the 'base' plottable components
775 std::shared_ptr<const std::vector<IObjComponent_const_sptr>> objs = m_instr->getPlottable();
776
777 // Get a reference to the underlying vector, casting away the constness so
778 // that we
779 // can modify it to get our result rather than creating another long vector
780 auto &res = const_cast<std::vector<IObjComponent_const_sptr> &>(*objs);
781 const std::vector<IObjComponent_const_sptr>::size_type total = res.size();
782 for (std::vector<IObjComponent_const_sptr>::size_type i = 0; i < total; ++i) {
783 res[i] = std::dynamic_pointer_cast<const Detector>(ParComponentFactory::create(objs->at(i), m_map));
784 }
785 return objs;
786
787 } else {
788 // Base instrument
789 auto res = std::make_shared<std::vector<IObjComponent_const_sptr>>();
790 res->reserve(m_detectorCache.size() + 10);
791 appendPlottable(*this, *res);
792 return res;
793 }
794}
795
796void Instrument::appendPlottable(const CompAssembly &ca, std::vector<IObjComponent_const_sptr> &lst) const {
797 for (int i = 0; i < ca.nelements(); i++) {
798 IComponent *c = ca[i].get();
799 auto *a = dynamic_cast<CompAssembly *>(c);
800 if (a)
801 appendPlottable(*a, lst);
802 else {
803 auto *d = dynamic_cast<Detector *>(c);
804 auto *o = dynamic_cast<ObjComponent *>(c);
805 if (d)
806 lst.emplace_back(IObjComponent_const_sptr(d, NoDeleting()));
807 else if (o)
808 lst.emplace_back(IObjComponent_const_sptr(o, NoDeleting()));
809 else
810 g_log.error() << "Unknown comp type\n";
811 }
812 }
813}
814
815//------------------------------------------------------------------------------------------------
824void Instrument::getInstrumentParameters(double &l1, Kernel::V3D &beamline, double &beamline_norm,
825 Kernel::V3D &samplePos) const {
826 // Get some positions
827 const IComponent_const_sptr sourceObj = this->getSource();
828 if (sourceObj == nullptr) {
829 throw Exception::InstrumentDefinitionError("Failed to get source component from instrument");
830 }
831 const Kernel::V3D sourcePos = sourceObj->getPos();
832 samplePos = this->getSample()->getPos();
833 beamline = samplePos - sourcePos;
834 beamline_norm = 2.0 * beamline.norm();
835
836 // Get the distance between the source and the sample (assume in metres)
837 IComponent_const_sptr sample = this->getSample();
838 try {
839 l1 = this->getSource()->getDistance(*sample);
840 } catch (Exception::NotFoundError &) {
841 throw Exception::InstrumentDefinitionError("Unable to calculate source-sample distance ", this->getName());
842 }
843}
844
845//--------------------------------------------------------------------------------------------
848void Instrument::setFilename(const std::string &filename) {
849 if (m_map)
850 m_instr->m_filename = filename;
851 else
852 m_filename = filename;
853}
854
857const std::string &Instrument::getFilename() const {
858 if (m_map)
859 return m_instr->getFilename();
860 else
861 return m_filename;
862}
863
865void Instrument::setXmlText(const std::string &XmlText) {
866 if (m_map)
867 m_instr->m_xmlText = XmlText;
868 else
869 m_xmlText = XmlText;
870}
871
873const std::string &Instrument::getXmlText() const {
874 if (m_map)
875 return m_instr->getXmlText();
876 else
877 return m_xmlText;
878}
879
880//--------------------------------------------------------------------------------------------
889void Instrument::saveNexus(::NeXus::File *file, const std::string &group) const {
890 file->makeGroup(group, "NXinstrument", true);
891 file->putAttr("version", 1);
892
893 file->writeData("name", getName());
894
895 // XML contents of instrument, as a NX note
896 file->makeGroup("instrument_xml", "NXnote", true);
897 const std::string &xmlText = getXmlText();
898 if (xmlText.empty())
899 g_log.warning() << "Saving Instrument with no XML data. If this was "
900 "instrument data you may not be able to load this data "
901 "back into Mantid, for fitted/analysed data this "
902 "warning can be ignored.\n";
903 file->writeData("data", xmlText);
904 file->writeData("type", "text/xml"); // mimetype
905 file->writeData("description", "XML contents of the instrument IDF file.");
906 file->closeGroup();
907
908 // Now the parameter map, as a NXnote via its saveNexus method
909 if (isParametrized()) {
910 // Map with data extracted from DetectorInfo -> legacy compatible files.
911 const auto &params = makeLegacyParameterMap();
912 params->saveNexus(file, "instrument_parameter_map");
913 }
914
915 // Add physical detector and monitor data
916 auto detectorIDs = getDetectorIDs(true);
917 auto detmonIDs = getDetectorIDs(false);
918 if (!detmonIDs.empty()) {
919 // Add detectors group
920 file->makeGroup("physical_detectors", "NXdetector", true);
921 file->writeData("number_of_detectors", uint64_t(detectorIDs.size()));
922 saveDetectorSetInfoToNexus(file, detectorIDs);
923 file->closeGroup(); // detectors
924
925 // Create Monitor IDs vector
926 std::vector<detid_t> monitorIDs;
927 for (size_t i = 0; i < detmonIDs.size(); i++) {
928 if (isMonitorViaIndex(i))
929 monitorIDs.emplace_back(detmonIDs[i]);
930 }
931
932 // Add Monitors group
933 file->makeGroup("physical_monitors", "NXmonitor", true);
934 file->writeData("number_of_monitors", uint64_t(monitorIDs.size()));
935 saveDetectorSetInfoToNexus(file, monitorIDs);
936 file->closeGroup(); // monitors
937 }
938
939 file->closeGroup();
940}
941
942/* A private helper function so save information about a set of detectors to
943 * Nexus
944 * @param file :: open Nexus file ready to recieve the info about the set of
945 * detectors
946 * a group must be open that has only one call of this function.
947 * @param detIDs :: the dectector IDs of the detectors belonging to the set
948 */
949void Instrument::saveDetectorSetInfoToNexus(::NeXus::File *file, const std::vector<detid_t> &detIDs) const {
950
951 size_t nDets = detIDs.size();
952 if (nDets == 0)
953 return;
954 auto detectors = getDetectors(detIDs);
955
957 Kernel::V3D sample_pos;
958 if (sample)
959 sample_pos = sample->getPos();
960
961 std::vector<double> a_angles(nDets);
962 std::vector<double> p_angles(nDets);
963 std::vector<double> distances(nDets);
964
965 for (size_t i = 0; i < nDets; i++) {
966 if (sample) {
967 Kernel::V3D pos = detectors[i]->getPos() - sample_pos;
968 pos.getSpherical(distances[i], p_angles[i], a_angles[i]);
969 } else {
970 a_angles[i] = detectors[i]->getPhi() * 180.0 / M_PI;
971 }
972 }
973 file->writeData("detector_number", detIDs);
974 file->writeData("azimuthal_angle", a_angles);
975 file->openData("azimuthal_angle");
976 file->putAttr("units", "degree");
977 file->closeData();
978 if (sample) {
979 file->writeData("polar_angle", p_angles);
980 file->openData("polar_angle");
981 file->putAttr("units", "degree");
982 file->closeData();
983 file->writeData("distance", distances);
984 file->openData("distance");
985 file->putAttr("units", "metre");
986 file->closeData();
987 }
988}
989
990//--------------------------------------------------------------------------------------------
995void Instrument::loadNexus(::NeXus::File *file, const std::string &group) {
996 file->openGroup(group, "NXinstrument");
997 file->closeGroup();
998}
999
1004void Instrument::setReferenceFrame(std::shared_ptr<ReferenceFrame> frame) { m_referenceFrame = std::move(frame); }
1005
1010std::shared_ptr<const ReferenceFrame> Instrument::getReferenceFrame() const {
1011 if (m_map) {
1012 return m_instr->getReferenceFrame();
1013 } else {
1014 return m_referenceFrame;
1015 }
1016}
1017
1026void Instrument::setDefaultView(const std::string &type) {
1027 std::string typeUC(type);
1028 std::transform(typeUC.begin(), typeUC.end(), typeUC.begin(), toupper);
1029 if (typeUC == "3D" || typeUC == "CYLINDRICAL_X" || typeUC == "CYLINDRICAL_Y" || typeUC == "CYLINDRICAL_Z" ||
1030 typeUC == "SPHERICAL_X" || typeUC == "SPHERICAL_Y" || typeUC == "SPHERICAL_Z") {
1031 m_defaultView = typeUC;
1032 } else {
1033 m_defaultView = "3D";
1034 g_log.warning() << type << " is not allowed as an instrument view type. Default to \"3D\"" << '\n';
1035 }
1036}
1037
1042void Instrument::setValidFromDate(const Types::Core::DateAndTime &val) {
1043 Types::Core::DateAndTime earliestAllowedDate("1900-01-31 23:59:01");
1044 if (val < earliestAllowedDate) {
1046 "The valid-from <instrument> tag date must be from 1900-01-31 23:59:01 "
1047 "or later",
1048 m_filename);
1049 }
1050 m_ValidFrom = val;
1051}
1052
1054 std::queue<IComponent_const_sptr> compQueue; // Search queue
1056
1057 bool foundRect = false;
1058 bool foundNonRect = false;
1059
1061
1062 while (!compQueue.empty() && !(foundRect && foundNonRect)) {
1063 comp = compQueue.front();
1064 compQueue.pop();
1065
1066 if (!validateComponentProperties(comp))
1067 continue;
1068
1069 if (dynamic_cast<const RectangularDetector *>(comp.get())) {
1070 foundRect = true;
1071 } // If component isn't a ComponentAssembly, we know it is a non-rectangular detector. Otherwise check its children
1072 else if (!addAssemblyChildrenToQueue(compQueue, comp)) {
1073 foundNonRect = true;
1074 }
1075 }
1076
1077 // Found both
1078 if (foundRect && foundNonRect)
1080 // Found only rectangular
1081 else if (foundRect)
1083 // Found only non-rectangular
1084 else
1086}
1087
1088std::vector<RectangularDetector_const_sptr> Instrument::findRectDetectors() const {
1089 std::queue<IComponent_const_sptr> compQueue; // Search queue
1091
1092 std::vector<RectangularDetector_const_sptr> detectors;
1093
1095
1096 while (!compQueue.empty()) {
1097 comp = compQueue.front();
1098 compQueue.pop();
1099
1100 if (!validateComponentProperties(comp))
1101 continue;
1102
1103 if (auto const detector = std::dynamic_pointer_cast<const RectangularDetector>(comp)) {
1104 detectors.push_back(detector);
1105 } else {
1106 // If component is a ComponentAssembly, we add its children to the queue to check if they're Rectangular Detectors
1107 addAssemblyChildrenToQueue(compQueue, comp);
1108 }
1109 }
1110 return detectors;
1111}
1112
1114 // Skip source, if has one
1115 if (m_sourceCache && m_sourceCache->getComponentID() == component->getComponentID())
1116 return false;
1117
1118 // Skip sample, if has one
1119 if (m_sampleCache && m_sampleCache->getComponentID() == component->getComponentID())
1120 return false;
1121
1122 // Skip monitors
1123 IDetector_const_sptr detector = std::dynamic_pointer_cast<const IDetector>(component);
1124 if (detector && isMonitor(detector->getID()))
1125 return false;
1126
1127 // skip choppers, slits and supermirrors - HACK!
1128 const auto &name = component->getName();
1129 if (name == "chopper-position" || name.substr(0, 4) == "slit" || name == "supermirror") {
1130 return false;
1131 }
1132
1133 return true;
1134}
1135
1136void Instrument::addInstrumentChildrenToQueue(std::queue<IComponent_const_sptr> &queue) const {
1137 // Add all the direct children of the instrument
1138 for (int i = 0; i < nelements(); i++)
1139 queue.push(getChild(i));
1140}
1141
1144bool Instrument::addAssemblyChildrenToQueue(std::queue<IComponent_const_sptr> &queue,
1145 IComponent_const_sptr component) const {
1146 if (auto const assembly = std::dynamic_pointer_cast<const ICompAssembly>(component)) {
1147 for (int i = 0; i < assembly->nelements(); i++)
1148 queue.push(assembly->getChild(i));
1149 return true;
1150 }
1151 return false;
1152}
1153
1155bool Instrument::isMonitorViaIndex(const size_t index) const {
1156 if (m_map)
1157 return std::get<2>(m_instr->m_detectorCache[index]);
1158 else
1159 return std::get<2>(m_detectorCache[index]);
1160}
1161
1162bool Instrument::isEmptyInstrument() const { return this->nelements() == 0; }
1163
1165 // invalidate cache
1166 return CompAssembly::add(component);
1167}
1168
1170size_t Instrument::detectorIndex(const detid_t detID) const {
1171 const auto &baseInstr = m_map ? *m_instr : *this;
1172 const auto it = find(baseInstr.m_detectorCache, detID);
1173 return std::distance(baseInstr.m_detectorCache.cbegin(), it);
1174}
1175
1178std::shared_ptr<ParameterMap> Instrument::makeLegacyParameterMap() const {
1179 auto pmap = std::make_shared<ParameterMap>(*getParameterMap());
1180 // Instrument is only needed for DetectorInfo access so it is not needed. This
1181 // also clears DetectorInfo and ComponentInfo (information will be stored
1182 // directly in pmap so we do not need them).
1183 pmap->setInstrument(nullptr);
1184
1185 const auto &baseInstr = m_map ? *m_instr : *this;
1186
1187 if (!getParameterMap()->hasComponentInfo(&baseInstr))
1188 return pmap;
1189
1190 // Tolerance 1e-9 m with rotation center at a distance of L = 1000 m as in
1191 // Beamline::DetectorInfo::isEquivalent.
1192 constexpr double d_max = 1e-9;
1193 constexpr double L = 1000.0;
1194 constexpr double safety_factor = 2.0;
1195 const double imag_norm_max = sin(d_max / (2.0 * L * safety_factor));
1196
1197 Eigen::Affine3d transformation;
1198 int64_t oldParentIndex = -1;
1199
1200 const auto &componentInfo = getParameterMap()->componentInfo();
1201 const auto &detectorInfo = getParameterMap()->detectorInfo();
1202 for (size_t i = 0; i < componentInfo.size(); ++i) {
1203
1204 const int64_t parentIndex = componentInfo.parent(i);
1205 const bool makeTransform = parentIndex != oldParentIndex;
1206 bool isDetFixedInBank = false;
1207
1208 if (makeTransform) {
1209 oldParentIndex = parentIndex;
1210 const auto parentPos = toVector3d(componentInfo.position(parentIndex));
1211 const auto invParentRot = toQuaterniond(componentInfo.rotation(parentIndex)).conjugate();
1212
1213 transformation = invParentRot;
1214 transformation.translate(-parentPos);
1215 }
1216
1217 if (componentInfo.isDetector(i)) {
1218
1219 const std::shared_ptr<const IDetector> &baseDet = std::get<1>(baseInstr.m_detectorCache[i]);
1220
1221 isDetFixedInBank = ComponentInfoBankHelpers::isDetectorFixedInBank(componentInfo, i);
1222 if (detectorInfo.isMasked(i)) {
1223 pmap->forceUnsafeSetMasked(baseDet.get(), true);
1224 }
1225
1226 if (makeTransform) {
1227 // Special case: scaling for GridDetectorPixel.
1228 if (isDetFixedInBank) {
1229
1230 size_t panelIndex = componentInfo.parent(parentIndex);
1231 const auto panelID = componentInfo.componentID(panelIndex);
1232
1233 Eigen::Vector3d scale(1, 1, 1);
1234 if (auto scalex = pmap->get(panelID, "scalex"))
1235 scale[0] = 1.0 / scalex->value<double>();
1236 if (auto scaley = pmap->get(panelID, "scaley"))
1237 scale[1] = 1.0 / scaley->value<double>();
1238 transformation.prescale(scale);
1239 }
1240 }
1241 }
1242
1243 const auto componentId = componentInfo.componentID(i);
1244 const IComponent *baseComponent = componentId->getBaseComponent();
1245 // Generic sca scale factors
1246 const auto newScaleFactor = Kernel::toVector3d(componentInfo.scaleFactor(i));
1247 if ((newScaleFactor - toVector3d(baseComponent->getScaleFactor())).norm() >= 1e-9) {
1248 pmap->addV3D(componentId, ParameterMap::scale(), componentInfo.scaleFactor(i));
1249 }
1250
1251 // Undo parent transformation to obtain relative position/rotation.
1252 Eigen::Vector3d relPos = transformation * toVector3d(componentInfo.position(i));
1253 Eigen::Quaterniond relRot = toQuaterniond(componentInfo.relativeRotation(i));
1254
1255 // Tolerance 1e-9 m as in Beamline::DetectorInfo::isEquivalent.
1256 if ((relPos - toVector3d(baseComponent->getRelativePos())).norm() >= 1e-9) {
1257 if (isDetFixedInBank) {
1258 throw std::runtime_error("Cannot create legacy ParameterMap: Position "
1259 "parameters for GridDetectorPixel are "
1260 "not supported");
1261 }
1262 pmap->addV3D(componentId, ParameterMap::pos(), Kernel::toV3D(relPos));
1263 }
1264 if ((relRot * toQuaterniond(baseComponent->getRelativeRot()).conjugate()).vec().norm() >= imag_norm_max) {
1265 pmap->addQuat(componentId, ParameterMap::rot(), Kernel::toQuat(relRot));
1266 }
1267 }
1268
1269 return pmap;
1270}
1271
1279 if (isParametrized())
1280 throw std::logic_error("Instrument::parseTreeAndCacheBeamline must be "
1281 "called with the base instrument, not a "
1282 "parametrized instrument");
1284}
1285
1291std::pair<std::unique_ptr<ComponentInfo>, std::unique_ptr<DetectorInfo>>
1293 // If we have source and it has Beamline objects just copy them
1294 if (source && source->hasComponentInfo(this))
1295 return makeWrappers(pmap, source->componentInfo(), source->detectorInfo());
1296 // If pmap is empty and base instrument has Beamline objects just copy them
1297 if (pmap.empty() && m_componentInfo)
1299 // pmap not empty and/or no cached Beamline objects found
1300 return InstrumentVisitor::makeWrappers(*this, &pmap);
1301}
1302
1304std::pair<std::unique_ptr<ComponentInfo>, std::unique_ptr<DetectorInfo>>
1306 const DetectorInfo &detectorInfo) const {
1307 auto compInfo = componentInfo.cloneWithoutDetectorInfo();
1308 auto detInfo = std::make_unique<DetectorInfo>(detectorInfo);
1309 compInfo->m_componentInfo->setDetectorInfo(detInfo->m_detectorInfo.get());
1310 const auto parInstrument = ParComponentFactory::createInstrument(
1311 std::shared_ptr<const Instrument>(this, NoDeleting()), std::shared_ptr<ParameterMap>(&pmap, NoDeleting()));
1312 detInfo->m_instrument = parInstrument;
1313 return {std::move(compInfo), std::move(detInfo)};
1314}
1315
1316namespace Conversion {
1317
1326double tofToDSpacingFactor(const double l1, const double l2, const double twoTheta, const double offset) {
1327 return Kernel::Units::tofToDSpacingFactor(l1, l2, twoTheta, offset);
1328}
1329
1330} // namespace Conversion
1331} // namespace Mantid::Geometry
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
double obj
the value of the quadratic function
A simple structure that defines an axis-aligned cuboid shaped bounding box for a geometrical object.
Definition: BoundingBox.h:34
void grow(const BoundingBox &other)
Grow the bounding box so that it also encompasses the given box.
Class for Assembly of geometric components.
Definition: CompAssembly.h:31
std::vector< IComponent * > m_children
the group of child components
Definition: CompAssembly.h:98
void getChildren(std::vector< IComponent_const_sptr > &outVector, bool recursive) const override
Returns a vector of all children contained.
BoundingBox * m_cachedBoundingBox
A cached bounding box.
Definition: CompAssembly.h:101
int add(IComponent *) override
Add a component to the assembly.
std::shared_ptr< const IComponent > getComponentByName(const std::string &cname, int nlevels=0) const override
Returns a pointer to the first component of assembly encountered with the given name.
int remove(IComponent *)
Remove a component from the assembly.
Kernel::V3D getPos() const override
Gets the absolute position of the Parametrized CompAssembly This attempts to read the cached position...
CompAssembly()
Empty constructor.
int nelements() const override
Return the number of elements in the assembly.
ComponentInfo : Provides a component centric view on to the instrument.
Definition: ComponentInfo.h:40
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::unique_ptr< ComponentInfo > cloneWithoutDetectorInfo() const
Clone current instance but not the DetectorInfo non-owned parts.
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
size_t index() const
Helper for legacy access mode. Returns the index of the component.
Definition: Component.cpp:297
const IComponent * base() const
Returns the address of the base component.
Definition: Component.h:280
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
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
Geometry::DetectorInfo is an intermediate step towards a DetectorInfo that is part of Instrument-2....
Definition: DetectorInfo.h:49
This class represents a detector - i.e.
Definition: Detector.h:30
Class for Assembly of geometric components.
Definition: ICompAssembly.h:30
virtual void getChildren(std::vector< IComponent_const_sptr > &outVector, bool recursive) const =0
Get all children.
base class for Geometric IComponent
Definition: IComponent.h:51
virtual IComponent const * getBaseComponent() const =0
Returns const pointer to base component if this component is parametrized.
virtual Kernel::V3D getScaleFactor() const
Gets the scaling factor of the object for the Object Component.
Definition: IComponent.h:118
virtual ComponentID getComponentID() const =0
Returns the ComponentID - a unique identifier of the component.
virtual Kernel::Quat getRelativeRot() const =0
Get the relative Orientation.
virtual Kernel::V3D getRelativePos() const =0
Get the position relative to the parent IComponent (absolute if no parent)
virtual const IComponent * getBareParent() const =0
Returns the bare pointer to the IComponent parent.
virtual std::string getName() const =0
Get the IComponent name.
Interface class for detector objects.
Definition: IDetector.h:43
virtual detid_t getID() const =0
Get the detector ID.
Object Component class, this class brings together the physical attributes of the component to the po...
Definition: IObjComponent.h:37
std::pair< std::unique_ptr< ComponentInfo >, std::unique_ptr< DetectorInfo > > makeWrappers() const
Base Instrument Class.
Definition: Instrument.h:47
ContainsState containsRectDetectors() const
Check whether instrument contains rectangular detectors.
std::string m_filename
Path to the original IDF .xml file that was loaded for this instrument.
Definition: Instrument.h:289
std::vector< std::shared_ptr< const IComponent > > getAllComponentsWithName(const std::string &cname) const
Returns pointers to all components encountered with the given name.
Definition: Instrument.cpp:399
void markAsSamplePos(const IComponent *)
mark a Component which has already been added to the Instrument (as a child comp.) to be 'the' sample...
Definition: Instrument.cpp:564
std::size_t getNumberDetectors(bool skipMonitors=false) const
Definition: Instrument.cpp:222
IComponent_const_sptr getSource() const
Gets a pointer to the source.
Definition: Instrument.cpp:322
std::string m_xmlText
Contents of the IDF .xml file that was loaded for this instrument.
Definition: Instrument.h:292
std::shared_ptr< const IComponent > getComponentByID(const IComponent *id) const
Returns a shared pointer to a component.
Definition: Instrument.cpp:382
bool validateComponentProperties(IComponent_const_sptr component) const
const IComponent * m_sampleCache
Purpose to hold copy of samplePos component.
Definition: Instrument.h:252
void getInstrumentParameters(double &l1, Kernel::V3D &beamline, double &beamline_norm, Kernel::V3D &samplePos) const
Get several instrument parameters used in tof to D-space conversion.
Definition: Instrument.cpp:824
std::pair< std::unique_ptr< ComponentInfo >, std::unique_ptr< DetectorInfo > > makeWrappers(ParameterMap &pmap, const ComponentInfo &componentInfo, const DetectorInfo &detectorInfo) const
Sets up links between m_detectorInfo, m_componentInfo, and m_instrument.
const IDetector * getBaseDetector(const detid_t &detector_id) const
Gets a pointer to the base (non-parametrized) detector from its ID returns null if the detector has n...
Definition: Instrument.cpp:483
std::shared_ptr< const Instrument > baseInstrument() const
Pointer to the 'real' instrument, for parametrized instruments.
Definition: Instrument.cpp:124
Instrument()
Default constructor.
Definition: Instrument.cpp:48
ContainsState
To determine whether the instrument contains elements of some type.
Definition: Instrument.h:203
void parseTreeAndCacheBeamline()
Parse the instrument tree and create ComponentInfo and DetectorInfo.
std::shared_ptr< const Instrument > getPhysicalInstrument() const
INDIRECT GEOMETRY INSTRUMENTS ONLY: Returns the physical instrument, if one has been specified as dis...
Definition: Instrument.cpp:151
std::shared_ptr< const Instrument > m_instr
Pointer to the "real" instrument, for parametrized Instrument.
Definition: Instrument.h:278
void markAsDetector(const IDetector *)
mark a Component which has already been added to the Instrument (as a child comp.) to be a Detector c...
Definition: Instrument.cpp:620
std::string m_defaultView
Stores the default type of the instrument view: 3D or one of the "unwrapped".
Definition: Instrument.h:272
void loadNexus(::NeXus::File *file, const std::string &group)
Load the object from an open NeXus file.
Definition: Instrument.cpp:995
std::pair< std::unique_ptr< ComponentInfo >, std::unique_ptr< DetectorInfo > > makeBeamline(ParameterMap &pmap, const ParameterMap *source=nullptr) const
Return ComponentInfo and DetectorInfo for instrument given by pmap.
std::shared_ptr< const DetectorInfo > m_detectorInfo
Pointer to the DetectorInfo object. May be NULL.
Definition: Instrument.h:302
std::vector< IDetector_const_sptr > getDetectors(const std::vector< detid_t > &det_ids) const
Returns a list of Detectors for the given detectors ids.
Definition: Instrument.cpp:530
std::shared_ptr< ParameterMap > makeLegacyParameterMap() const
Returns a legacy ParameterMap, containing information that is now stored in DetectorInfo (masking,...
std::vector< std::tuple< detid_t, IDetector_const_sptr, bool > > m_detectorCache
Map which holds detector-IDs and pointers to detector components, and monitor flags.
Definition: Instrument.h:244
size_t detectorIndex(const detid_t detID) const
Returns the index for a detector ID. Used for accessing DetectorInfo.
void setValidFromDate(const Types::Core::DateAndTime &val)
Set the date from which the instrument definition begins to be valid.
void setXmlText(const std::string &XmlText)
Set the Contents of the IDF .xml file that was loaded for this instrument.
Definition: Instrument.cpp:865
void saveNexus(::NeXus::File *file, const std::string &group) const
Save the instrument to an open NeXus file.
Definition: Instrument.cpp:889
Instrument * clone() const override
Virtual copy constructor.
Definition: Instrument.cpp:121
std::vector< RectangularDetector_const_sptr > findRectDetectors() const
bool isMonitor(const detid_t &detector_id) const
Definition: Instrument.cpp:491
const std::string & getFilename() const
Definition: Instrument.cpp:857
bool isMonitorViaIndex(const size_t index) const
Temporary helper for refactoring. Argument is index, not ID!
void setPhysicalInstrument(std::unique_ptr< Instrument >)
INDIRECT GEOMETRY INSTRUMENTS ONLY: Sets the physical instrument.
Definition: Instrument.cpp:173
std::shared_ptr< ParameterMap > getParameterMap() const
Pointer to the NOT const ParameterMap holding the parameters of the modified instrument components.
Definition: Instrument.cpp:137
void saveDetectorSetInfoToNexus(::NeXus::File *file, const std::vector< detid_t > &detIDs) const
Save information about a set of detectors to Nexus.
Definition: Instrument.cpp:949
std::shared_ptr< IComponent > getChild(const int i) const override
Get a pointer to the ith component within the assembly. Easier to use than.
bool hasSample() const
Checks to see if the Instrument has a sample.
Definition: Instrument.cpp:317
Kernel::V3D getBeamDirection() const
Gets the beam direction (i.e.
Definition: Instrument.cpp:375
const IComponent * m_sourceCache
Purpose to hold copy of source component.
Definition: Instrument.h:248
std::vector< detid_t > getMonitors() const
Returns a list containing the detector ids of monitors.
Definition: Instrument.cpp:716
void appendPlottable(const CompAssembly &ca, std::vector< IObjComponent_const_sptr > &lst) const
Add a plottable component.
Definition: Instrument.cpp:796
std::string type() const override
String description of the type of component.
Definition: Instrument.h:50
void markAsDetectorIncomplete(const IDetector *)
As markAsDetector but without the required sorting.
Definition: Instrument.cpp:638
const std::string & getXmlText() const
Definition: Instrument.cpp:873
std::vector< detid_t > getDetectorIDs(bool skipMonitors=false) const
Return a vector of detector IDs in this instrument.
Definition: Instrument.cpp:205
void getBoundingBox(BoundingBox &assemblyBox) const override
Get the bounding box for this component and store it in the given argument.
Definition: Instrument.cpp:733
std::shared_ptr< const ComponentInfo > m_componentInfo
Pointer to the ComponentInfo object. May be NULL.
Definition: Instrument.h:305
std::shared_ptr< const Instrument > m_physicalInstrument
Pointer to the physical instrument, where this differs from the 'neutronic' one (indirect geometry)
Definition: Instrument.h:296
virtual int add(IComponent *component) override
Add a component to the instrument.
std::shared_ptr< const std::vector< IObjComponent_const_sptr > > getPlottable() const
Get pointers to plottable components.
Definition: Instrument.cpp:772
IDetector_const_sptr getDetectorG(const std::set< detid_t > &det_ids) const
Returns a pointer to the geometrical object for the given set of IDs.
Definition: Instrument.cpp:513
void markAsMonitor(const IDetector *)
mark a Component which has already been added to the Instrument (as a child comp.) to be a monitor an...
Definition: Instrument.cpp:677
void getDetectorsInBank(std::vector< IDetector_const_sptr > &dets, const IComponent &comp) const
Fill a vector with all the detectors contained (at any depth) in a named component.
Definition: Instrument.cpp:275
void markAsSource(const IComponent *)
mark a Component which has already been added to the Instrument (as a child comp.) to be 'the' source...
Definition: Instrument.cpp:597
bool hasSource() const
Checks to see if the Instrument has a source.
Definition: Instrument.cpp:312
void setReferenceFrame(std::shared_ptr< ReferenceFrame > frame)
Set reference Frame.
void getMinMaxDetectorIDs(detid_t &min, detid_t &max) const
Get the minimum and maximum (inclusive) detector IDs.
Definition: Instrument.cpp:256
std::shared_ptr< ParameterMap > m_map_nonconst
Non-const pointer to the parameter map.
Definition: Instrument.h:281
void setDefaultView(const std::string &type)
Set the default type of the instrument view.
std::shared_ptr< const ReferenceFrame > getReferenceFrame() const
Get refernce Frame.
void markAsDetectorFinalize()
Sorts the detector cache.
Definition: Instrument.cpp:651
bool addAssemblyChildrenToQueue(std::queue< IComponent_const_sptr > &queue, IComponent_const_sptr component) const
If component is a ComponentAssembly, we add its children to the queue to check if they're Rectangular...
std::shared_ptr< ReferenceFrame > m_referenceFrame
Pointer to the reference frame object.
Definition: Instrument.h:299
IDetector_const_sptr getDetector(const detid_t &detector_id) const
Gets a pointer to the detector from its ID Note that for getting the detector associated with a spect...
Definition: Instrument.cpp:461
Types::Core::DateAndTime m_ValidFrom
the date from which the instrument definition begins to be valid.
Definition: Instrument.h:284
void setFilename(const std::string &filename)
Set the path to the original IDF .xml file that was loaded for this instrument.
Definition: Instrument.cpp:848
IComponent_const_sptr getSample() const
Gets a pointer to the Sample Position.
Definition: Instrument.cpp:348
void addInstrumentChildrenToQueue(std::queue< IComponent_const_sptr > &queue) const
void removeDetector(IDetector *)
Remove a detector from the instrument.
Definition: Instrument.cpp:694
Void deleter for shared pointers.
Object Component class, this class brings together the physical attributes of the component to the po...
Definition: ObjComponent.h:33
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.
static std::shared_ptr< Instrument > createInstrument(const std::shared_ptr< const Instrument > &base, const std::shared_ptr< ParameterMap > &map)
Create a parameterized instrument from the given base and ParameterMap.
static std::shared_ptr< IDetector > createDetector(const IDetector *base, const ParameterMap *map)
Create a parameterized detector from the given base component and ParameterMap and return a shared_pt...
const Geometry::DetectorInfo & detectorInfo() const
Only for use by ExperimentInfo. Returns a reference to the DetectorInfo.
static const std::string & scale()
static const std::string & rot()
static const std::string & pos()
Return string to be used in the map.
bool hasComponentInfo(const Instrument *instrument) const
Only for use by ExperimentInfo.
const Geometry::ComponentInfo & componentInfo() const
Only for use by ExperimentInfo. Returns a reference to the ComponentInfo.
RectangularDetector is a type of CompAssembly, an assembly of components.
ReferenceFrame : Holds reference frame information from the geometry description file.
Exception for errors associated with the instrument definition.
Definition: Exception.h:220
Exception for when an item is not found in a collection.
Definition: Exception.h:145
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition: Logger.h:52
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
Class for 3D vectors.
Definition: V3D.h:34
double norm() const noexcept
Definition: V3D.h:263
void getSpherical(double &R, double &theta, double &phi) const noexcept
Return the vector's position in spherical coordinates.
Definition: V3D.cpp:117
MANTID_GEOMETRY_DLL bool isDetectorFixedInBank(const ComponentInfo &compInfo, const size_t detIndex)
Tests whether or not the detector is within a fixed bank.
MANTID_GEOMETRY_DLL double tofToDSpacingFactor(const double l1, const double l2, const double twoTheta, const double offset)
Calculate and return conversion factor from tof to d-spacing.
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
Definition: IComponent.h:161
std::shared_ptr< IComponent > IComponent_sptr
Typedef of a shared pointer to a IComponent.
Definition: IComponent.h:159
Mantid::Kernel::Logger g_log("Goniometer")
std::shared_ptr< const IObjComponent > IObjComponent_const_sptr
Shared pointer to IObjComponent (const version)
std::shared_ptr< ParameterMap > ParameterMap_sptr
ParameterMap shared pointer typedef.
Definition: ParameterMap.h:335
std::shared_ptr< const Mantid::Geometry::IDetector > IDetector_const_sptr
Shared pointer to IDetector (const version)
Definition: IDetector.h:102
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
MANTID_KERNEL_DLL double tofToDSpacingFactor(const double l1, const double l2, const double twoTheta, const double offset)
Calculate and return conversion factor from tof to d-spacing.
Definition: Unit.cpp:568
Kernel::Quat toQuat(const Eigen::Quaterniond &quat)
Converts Eigen::Quaterniond to Kernel::Quat.
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...
MANTID_KERNEL_DLL V3D normalize(V3D v)
Normalizes a V3D.
Definition: V3D.h:341
Eigen::Quaterniond toQuaterniond(const Kernel::Quat &quat)
Converts Kernel::Quat to Eigen::Quaterniond.
int32_t detid_t
Typedef for a detector ID.
Definition: SpectrumInfo.h:21
std::map< detid_t, Geometry::IDetector_const_sptr > detid2det_map
Typedef of a map from detector ID to detector shared pointer.
Definition: Instrument.h:27
Generate a tableworkspace to store the calibration results.
adjust instrument component position and orientation
: detector size scale at y-direction