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#include "MantidNexus/NexusFile.h"
25
26#include <algorithm>
27#include <memory>
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//------------------------------------------------------------------------------------------
186 if (m_map) {
187 // Get the base instrument detectors
188 out_map.clear();
189 const auto &in_dets = m_instr->m_detectorCache;
190 // And turn them into parametrized versions
191 for (const auto &in_det : in_dets) {
192 out_map.emplace(std::get<0>(in_det), getDetector(std::get<0>(in_det)));
193 }
194 } else {
195 // You can just return the detector cache directly.
196 out_map.clear();
197 for (const auto &in_det : m_detectorCache)
198 out_map.emplace(std::get<0>(in_det), std::get<1>(in_det));
199 }
200}
201
202//------------------------------------------------------------------------------------------
204std::vector<detid_t> Instrument::getDetectorIDs(bool skipMonitors) const {
205 std::vector<detid_t> out;
206 if (m_map) {
207 const auto &in_dets = m_instr->m_detectorCache;
208 for (const auto &in_det : in_dets)
209 if (!skipMonitors || !std::get<2>(in_det))
210 out.emplace_back(std::get<0>(in_det));
211 } else {
212 const auto &in_dets = m_detectorCache;
213 for (const auto &in_det : in_dets)
214 if (!skipMonitors || !std::get<2>(in_det))
215 out.emplace_back(std::get<0>(in_det));
216 }
217 return out;
218}
219
221std::size_t Instrument::getNumberDetectors(bool skipMonitors) const {
222 std::size_t numDetIDs(0);
223
224 if (m_map) {
225 numDetIDs = m_instr->m_detectorCache.size();
226 } else {
227 numDetIDs = m_detectorCache.size();
228 }
229
230 if (skipMonitors) // this slow, but gets the right answer
231 {
232 std::size_t monitors(0);
233 if (m_map) {
234 const auto &in_dets = m_instr->m_detectorCache;
235 monitors =
236 std::count_if(in_dets.cbegin(), in_dets.cend(), [](const auto &in_det) { return std::get<2>(in_det); });
237 } else {
238 const auto &in_dets = m_detectorCache;
239 monitors =
240 std::count_if(in_dets.cbegin(), in_dets.cend(), [](const auto &in_det) { return std::get<2>(in_det); });
241 }
242 return (numDetIDs - monitors);
243 } else {
244 return numDetIDs;
245 }
246}
247
254 const auto *in_dets = m_map ? &m_instr->m_detectorCache : &m_detectorCache;
255
256 if (in_dets->empty())
257 throw std::runtime_error("No detectors on this instrument. Can't find min/max ids");
258 // Maps are sorted by key. So it is easy to find
259 min = std::get<0>(*in_dets->begin());
260 max = std::get<0>(*in_dets->rbegin());
261}
262
272void Instrument::getDetectorsInBank(std::vector<IDetector_const_sptr> &dets, const IComponent &comp) const {
273 const auto bank = dynamic_cast<const ICompAssembly *>(&comp);
274 if (bank) {
275 // Get a vector of children (recursively)
276 std::vector<std::shared_ptr<const IComponent>> children;
277 bank->getChildren(children, true);
278 std::vector<std::shared_ptr<const IComponent>>::iterator it;
279 for (it = children.begin(); it != children.end(); ++it) {
280 IDetector_const_sptr det = std::dynamic_pointer_cast<const IDetector>(*it);
281 if (det) {
282 dets.emplace_back(det);
283 }
284 }
285 }
286}
287
298void Instrument::getDetectorsInBank(std::vector<IDetector_const_sptr> &dets, const std::string &bankName) const {
299 std::shared_ptr<const IComponent> comp = this->getComponentByName(bankName);
300 if (!comp) {
301 throw Kernel::Exception::NotFoundError("Instrument: Could not find component", bankName);
302 }
303 getDetectorsInBank(dets, *comp);
304}
305
306std::set<detid_t> Instrument::getDetectorIDsInBank(const std::string &bankName) const {
307 std::set<detid_t> detIDs;
308 std::vector<IDetector_const_sptr> detectors;
309 getDetectorsInBank(detectors, bankName);
310
311 for (const auto &det : detectors) {
312 detIDs.emplace(det->getID());
313 }
314 return detIDs;
315}
316
320bool Instrument::hasSource() const { return m_sourceCache; }
321
325bool Instrument::hasSample() const { return m_sampleCache; }
326
331 if (!m_sourceCache) {
332 g_log.warning("In Instrument::getSource(). No source has been set.");
334 } else if (m_map) {
335 auto sourceCache = static_cast<const Instrument *>(m_base)->m_sourceCache;
336 if (dynamic_cast<const ObjComponent *>(sourceCache))
337 return IComponent_const_sptr(new ObjComponent(sourceCache, m_map));
338 else if (dynamic_cast<const CompAssembly *>(sourceCache))
339 return IComponent_const_sptr(new CompAssembly(sourceCache, m_map));
340 else if (dynamic_cast<const Component *>(sourceCache))
341 return IComponent_const_sptr(new Component(sourceCache, m_map));
342 else {
343 g_log.error("In Instrument::getSource(). Source is not a recognised "
344 "component type.");
345 g_log.error("Try to assume it is a Component.");
346 return IComponent_const_sptr(new ObjComponent(sourceCache, m_map));
347 }
348 } else {
350 }
351}
352
357 if (!m_sampleCache) {
358 g_log.warning("In Instrument::getSamplePos(). No SamplePos has been set.");
360 } else if (m_map) {
361 auto sampleCache = static_cast<const Instrument *>(m_base)->m_sampleCache;
362 if (dynamic_cast<const ObjComponent *>(sampleCache))
363 return IComponent_const_sptr(new ObjComponent(sampleCache, m_map));
364 else if (dynamic_cast<const CompAssembly *>(sampleCache))
365 return IComponent_const_sptr(new CompAssembly(sampleCache, m_map));
366 else if (dynamic_cast<const Component *>(sampleCache))
367 return IComponent_const_sptr(new Component(sampleCache, m_map));
368 else {
369 g_log.error("In Instrument::getSamplePos(). SamplePos is not a "
370 "recognised component type.");
371 g_log.error("Try to assume it is a Component.");
372 return IComponent_const_sptr(new ObjComponent(sampleCache, m_map));
373 }
374 } else {
376 }
377}
378
384
385//------------------------------------------------------------------------------------------
390std::shared_ptr<const IComponent> Instrument::getComponentByID(const IComponent *id) const {
391 const auto *base = static_cast<const IComponent *>(id);
392 if (m_map)
393 return ParComponentFactory::create(std::shared_ptr<const IComponent>(base, NoDeleting()), m_map);
394 else
395 return std::shared_ptr<const IComponent>(base, NoDeleting());
396}
397
407std::vector<std::shared_ptr<const IComponent>> Instrument::getAllComponentsWithName(const std::string &cname) const {
408 std::shared_ptr<const IComponent> node = std::shared_ptr<const IComponent>(this, NoDeleting());
409 std::vector<std::shared_ptr<const IComponent>> retVec;
410 // Check the instrument name first
411 if (this->getName() == cname) {
412 retVec.emplace_back(node);
413 }
414 // Same algorithm as used in getComponentByName() but searching the full tree
415 std::deque<std::shared_ptr<const IComponent>> nodeQueue;
416 // Need to be able to enter the while loop
417 nodeQueue.emplace_back(node);
418 while (!nodeQueue.empty()) {
419 node = nodeQueue.front();
420 nodeQueue.pop_front();
421 int nchildren(0);
422 std::shared_ptr<const ICompAssembly> asmb = std::dynamic_pointer_cast<const ICompAssembly>(node);
423 if (asmb) {
424 nchildren = asmb->nelements();
425 }
426 for (int i = 0; i < nchildren; ++i) {
427 std::shared_ptr<const IComponent> comp = (*asmb)[i];
428 if (comp->getName() == cname) {
429 retVec.emplace_back(comp);
430 } else {
431 nodeQueue.emplace_back(comp);
432 }
433 }
434 } // while-end
435
436 // If we have reached here then the search failed
437 return retVec;
438}
439
440namespace {
441// Helpers for accessing m_detectorCache, which is a vector of tuples used as a
442// map. Lookup is by first element in a tuple. Templated to support const and
443// non-const.
444template <class T> auto lower_bound(T &map, const detid_t key) -> decltype(map.begin()) {
445 return std::lower_bound(map.begin(), map.end(), std::make_tuple(key, IDetector_const_sptr(nullptr), false),
446 [](const typename T::value_type &a, const typename T::value_type &b) -> bool {
447 return std::get<0>(a) < std::get<0>(b);
448 });
449}
450
451template <class T> auto find(T &map, const detid_t key) -> decltype(map.begin()) {
452 auto it = lower_bound(map, key);
453 if ((it != map.end()) && (std::get<0>(*it) == key))
454 return it;
455 return map.end();
456}
457} // namespace
458
470 const auto &baseInstr = m_map ? *m_instr : *this;
471 const auto it = find(baseInstr.m_detectorCache, detector_id);
472 if (it == baseInstr.m_detectorCache.end()) {
473 std::stringstream readInt;
474 readInt << detector_id;
475 throw Kernel::Exception::NotFoundError("Instrument: Detector with ID " + readInt.str() + " not found.", "");
476 }
477 IDetector_const_sptr baseDet = std::get<1>(*it);
478
479 if (!m_map)
480 return baseDet;
481
482 auto det = ParComponentFactory::createDetector(baseDet.get(), m_map);
483 return det;
484}
485
491const IDetector *Instrument::getBaseDetector(const detid_t &detector_id) const {
492 auto it = find(m_instr->m_detectorCache, detector_id);
493 if (it == m_instr->m_detectorCache.end()) {
494 return nullptr;
495 }
496 return std::get<1>(*it).get();
497}
498
499bool Instrument::isMonitor(const detid_t &detector_id) const {
500 const auto &baseInstr = m_map ? *m_instr : *this;
501 const auto it = find(baseInstr.m_detectorCache, detector_id);
502 if (it == baseInstr.m_detectorCache.end())
503 return false;
504 return std::get<2>(*it);
505}
506
507bool Instrument::isMonitor(const std::set<detid_t> &detector_ids) const {
508 if (detector_ids.empty())
509 return false;
510
511 return std::any_of(detector_ids.cbegin(), detector_ids.cend(),
512 [this](const auto detector_id) { return isMonitor(detector_id); });
513}
514
521IDetector_const_sptr Instrument::getDetectorG(const std::set<detid_t> &det_ids) const {
522 const size_t ndets(det_ids.size());
523 if (ndets == 1) {
524 return this->getDetector(*det_ids.begin());
525 } else {
526 std::shared_ptr<DetectorGroup> det_group = std::make_shared<DetectorGroup>();
527 for (const auto detID : det_ids) {
528 det_group->addDetector(this->getDetector(detID));
529 }
530 return det_group;
531 }
532}
533
538std::vector<IDetector_const_sptr> Instrument::getDetectors(const std::vector<detid_t> &det_ids) const {
539 std::vector<IDetector_const_sptr> dets_ptr;
540 dets_ptr.reserve(det_ids.size());
541 std::vector<detid_t>::const_iterator it;
542 for (it = det_ids.begin(); it != det_ids.end(); ++it) {
543 dets_ptr.emplace_back(this->getDetector(*it));
544 }
545 return dets_ptr;
546}
547
552std::vector<IDetector_const_sptr> Instrument::getDetectors(const std::set<detid_t> &det_ids) const {
553 std::vector<IDetector_const_sptr> dets_ptr;
554 dets_ptr.reserve(det_ids.size());
555 std::set<detid_t>::const_iterator it;
556 for (it = det_ids.begin(); it != det_ids.end(); ++it) {
557 dets_ptr.emplace_back(this->getDetector(*it));
558 }
559 return dets_ptr;
560}
561
573 if (m_map)
574 throw std::runtime_error("Instrument::markAsSamplePos() called on a "
575 "parametrized Instrument object.");
576
577 auto objComp = dynamic_cast<const IObjComponent *>(comp);
578 if (objComp) {
579 throw std::runtime_error("Instrument::markAsSamplePos() called on an IObjComponent "
580 "object that supports shape definition. Sample is prevented from "
581 "being this type because the shape must only be stored in "
582 "ExperimentInfo::m_sample.");
583 }
584
585 if (!m_sampleCache) {
586 if (comp->getName().empty()) {
587 throw Exception::InstrumentDefinitionError("The sample component is required to have a name.");
588 }
589 m_sampleCache = comp;
590 } else {
591 g_log.warning("Have already added samplePos component to the _sampleCache.");
592 }
593}
594
606 if (m_map)
607 throw std::runtime_error("Instrument::markAsSource() called on a "
608 "parametrized Instrument object.");
609
610 if (!m_sourceCache) {
611 if (comp->getName().empty()) {
612 throw Exception::InstrumentDefinitionError("The source component is required to have a name.");
613 }
614 m_sourceCache = comp;
615 } else {
616 g_log.warning("Have already added source component to the _sourceCache.");
617 }
618}
619
629 if (m_map)
630 throw std::runtime_error("Instrument::markAsDetector() called on a "
631 "parametrized Instrument object.");
632
633 // Create a (non-deleting) shared pointer to it
635 auto it = lower_bound(m_detectorCache, det->getID());
636 // Duplicate detector ids are forbidden
637 if ((it != m_detectorCache.end()) && (std::get<0>(*it) == det->getID())) {
638 raiseDuplicateDetectorError(det->getID());
639 }
640 bool isMonitorFlag = false;
641 m_detectorCache.emplace(it, det->getID(), det_sptr, isMonitorFlag);
642}
643
647 if (m_map)
648 throw std::runtime_error("Instrument::markAsDetector() called on a "
649 "parametrized Instrument object.");
650
651 // Create a (non-deleting) shared pointer to it
653 bool isMonitorFlag = false;
654 m_detectorCache.emplace_back(det->getID(), det_sptr, isMonitorFlag);
655}
656
660 // Detectors (even when different objects) are NOT allowed to have duplicate
661 // ids. This method establishes the presence of duplicates.
662 std::sort(
663 m_detectorCache.begin(), m_detectorCache.end(),
664 [](const std::tuple<detid_t, IDetector_const_sptr, bool> &a,
665 const std::tuple<detid_t, IDetector_const_sptr, bool> &b) -> bool { return std::get<0>(a) < std::get<0>(b); });
666
667 auto resultIt = std::adjacent_find(m_detectorCache.begin(), m_detectorCache.end(),
668 [](const std::tuple<detid_t, IDetector_const_sptr, bool> &a,
669 const std::tuple<detid_t, IDetector_const_sptr, bool> &b) -> bool {
670 return std::get<0>(a) == std::get<0>(b);
671 });
672 if (resultIt != m_detectorCache.end()) {
673 raiseDuplicateDetectorError(std::get<0>(*resultIt));
674 }
675}
676
686 if (m_map)
687 throw std::runtime_error("Instrument::markAsMonitor() called on a "
688 "parametrized Instrument object.");
689
690 // attempt to add monitor to instrument detector cache
691 markAsDetector(det);
692
693 // mark detector as a monitor
694 auto it = find(m_detectorCache, det->getID());
695 std::get<2>(*it) = true;
696}
697
703 if (m_map)
704 throw std::runtime_error("Instrument::removeDetector() called on a "
705 "parameterized Instrument object.");
706
707 const detid_t id = det->getID();
708 // Remove the detector from the detector cache
709 const auto it = find(m_detectorCache, id);
710 m_detectorCache.erase(it);
711
712 // Remove it from the parent assembly (and thus the instrument). Evilness
713 // required here unfortunately.
714 auto *parentAssembly = dynamic_cast<CompAssembly *>(const_cast<IComponent *>(det->getBareParent()));
715 if (parentAssembly) // Should always be true, but check just in case
716 {
717 parentAssembly->remove(det);
718 }
719}
720
724std::vector<detid_t> Instrument::getMonitors() const {
725 // Monitors cannot be parametrized. So just return the base.
726 if (m_map)
727 return m_instr->getMonitors();
728
729 std::vector<detid_t> mons;
730 for (const auto &item : m_detectorCache)
731 if (std::get<2>(item))
732 mons.emplace_back(std::get<0>(item));
733 return mons;
734}
735
741void Instrument::getBoundingBox(BoundingBox &assemblyBox) const {
742 if (m_map) {
743
744 if (m_map->hasComponentInfo(this->baseInstrument().get())) {
745 assemblyBox = m_map->componentInfo().boundingBox(index(), &assemblyBox);
746 return;
747 }
748
749 // Loop over the children and define a box large enough for all of them
750 ComponentID sourceID = getSource()->getComponentID();
751 assemblyBox = BoundingBox(); // this makes the instrument BB always axis aligned
752 int nchildren = nelements();
753 for (int i = 0; i < nchildren; ++i) {
754 IComponent_sptr comp = this->getChild(i);
755 if (comp && comp->getComponentID() != sourceID) {
756 BoundingBox compBox;
757 comp->getBoundingBox(compBox);
758 assemblyBox.grow(compBox);
759 }
760 }
761 } else {
762
763 if (!m_cachedBoundingBox) {
765 ComponentID sourceID = getSource()->getComponentID();
766 // Loop over the children and define a box large enough for all of them
767 for (const auto component : m_children) {
768 BoundingBox compBox;
769 if (component && component->getComponentID() != sourceID) {
770 component->getBoundingBox(compBox);
771 m_cachedBoundingBox->grow(compBox);
772 }
773 }
774 }
775 // Use cached box
776 assemblyBox = *m_cachedBoundingBox;
777 }
778}
779
780std::shared_ptr<const std::vector<IObjComponent_const_sptr>> Instrument::getPlottable() const {
781 if (m_map) {
782 // Get the 'base' plottable components
783 std::shared_ptr<const std::vector<IObjComponent_const_sptr>> objs = m_instr->getPlottable();
784
785 // Get a reference to the underlying vector, casting away the constness so
786 // that we
787 // can modify it to get our result rather than creating another long vector
788 auto &res = const_cast<std::vector<IObjComponent_const_sptr> &>(*objs);
789 const std::vector<IObjComponent_const_sptr>::size_type total = res.size();
790 for (std::vector<IObjComponent_const_sptr>::size_type i = 0; i < total; ++i) {
791 res[i] = std::dynamic_pointer_cast<const Detector>(ParComponentFactory::create(objs->at(i), m_map));
792 }
793 return objs;
794
795 } else {
796 // Base instrument
797 auto res = std::make_shared<std::vector<IObjComponent_const_sptr>>();
798 res->reserve(m_detectorCache.size() + 10);
799 appendPlottable(*this, *res);
800 return res;
801 }
802}
803
804void Instrument::appendPlottable(const CompAssembly &ca, std::vector<IObjComponent_const_sptr> &lst) const {
805 for (int i = 0; i < ca.nelements(); i++) {
806 IComponent *c = ca[i].get();
807 const auto *a = dynamic_cast<CompAssembly *>(c);
808 if (a)
809 appendPlottable(*a, lst);
810 else {
811 auto *d = dynamic_cast<Detector *>(c);
812 auto *o = dynamic_cast<ObjComponent *>(c);
813 if (d)
814 lst.emplace_back(IObjComponent_const_sptr(d, NoDeleting()));
815 else if (o)
816 lst.emplace_back(IObjComponent_const_sptr(o, NoDeleting()));
817 else
818 g_log.error() << "Unknown comp type\n";
819 }
820 }
821}
822
823//------------------------------------------------------------------------------------------------
832void Instrument::getInstrumentParameters(double &l1, Kernel::V3D &beamline, double &beamline_norm,
833 Kernel::V3D &samplePos) const {
834 // Get some positions
835 const IComponent_const_sptr sourceObj = this->getSource();
836 if (sourceObj == nullptr) {
837 throw Exception::InstrumentDefinitionError("Failed to get source component from instrument");
838 }
839 const Kernel::V3D sourcePos = sourceObj->getPos();
840 samplePos = this->getSample()->getPos();
841 beamline = samplePos - sourcePos;
842 beamline_norm = 2.0 * beamline.norm();
843
844 // Get the distance between the source and the sample (assume in metres)
845 IComponent_const_sptr sample = this->getSample();
846 try {
847 l1 = this->getSource()->getDistance(*sample);
848 } catch (Exception::NotFoundError &) {
849 throw Exception::InstrumentDefinitionError("Unable to calculate source-sample distance ", this->getName());
850 }
851}
852
853//--------------------------------------------------------------------------------------------
856void Instrument::setFilename(const std::string &filename) {
857 if (m_map)
858 m_instr->m_filename = filename;
859 else
860 m_filename = filename;
861}
862
865const std::string &Instrument::getFilename() const {
866 if (m_map)
867 return m_instr->getFilename();
868 else
869 return m_filename;
870}
871
873void Instrument::setXmlText(const std::string &XmlText) {
874 if (m_map)
875 m_instr->m_xmlText = XmlText;
876 else
877 m_xmlText = XmlText;
878}
879
881const std::string &Instrument::getXmlText() const {
882 if (m_map)
883 return m_instr->getXmlText();
884 else
885 return m_xmlText;
886}
887
888//--------------------------------------------------------------------------------------------
897void Instrument::saveNexus(Nexus::File *file, const std::string &group) const {
898 file->makeGroup(group, "NXinstrument", true);
899 file->putAttr("version", 1);
900
901 file->writeData("name", getName());
902
903 // XML contents of instrument, as a NX note
904 file->makeGroup("instrument_xml", "NXnote", true);
905 const std::string &xmlText = getXmlText();
906 if (xmlText.empty())
907 g_log.warning() << "Saving Instrument with no XML data. If this was "
908 "instrument data you may not be able to load this data "
909 "back into Mantid, for fitted/analysed data this "
910 "warning can be ignored.\n";
911 file->writeData("data", xmlText);
912 file->writeData("type", "text/xml"); // mimetype
913 file->writeData("description", "XML contents of the instrument IDF file.");
914 file->closeGroup();
915
916 // Now the parameter map, as a NXnote via its saveNexus method
917 if (isParametrized()) {
918 // Map with data extracted from DetectorInfo -> legacy compatible files.
919 const auto &params = makeLegacyParameterMap();
920 params->saveNexus(file, "instrument_parameter_map");
921 }
922
923 // Add physical detector and monitor data
924 auto detmonIDs = getDetectorIDs(false);
925 if (!detmonIDs.empty()) {
926 auto detectorIDs = getDetectorIDs(true);
927 // Add detectors group
928 file->makeGroup("physical_detectors", "NXdetector", true);
929 file->writeData("number_of_detectors", uint64_t(detectorIDs.size()));
930 saveDetectorSetInfoToNexus(file, detectorIDs);
931 file->closeGroup(); // detectors
932
933 // Create Monitor IDs vector
934 std::vector<detid_t> monitorIDs;
935 for (size_t i = 0; i < detmonIDs.size(); i++) {
936 if (isMonitorViaIndex(i))
937 monitorIDs.emplace_back(detmonIDs[i]);
938 }
939
940 // Add Monitors group
941 file->makeGroup("physical_monitors", "NXmonitor", true);
942 file->writeData("number_of_monitors", uint64_t(monitorIDs.size()));
943 saveDetectorSetInfoToNexus(file, monitorIDs);
944 file->closeGroup(); // monitors
945 }
946
947 file->closeGroup();
948}
949
950/* A private helper function so save information about a set of detectors to
951 * Nexus
952 * @param file :: open Nexus file ready to recieve the info about the set of
953 * detectors
954 * a group must be open that has only one call of this function.
955 * @param detIDs :: the dectector IDs of the detectors belonging to the set
956 */
957void Instrument::saveDetectorSetInfoToNexus(Nexus::File *file, const std::vector<detid_t> &detIDs) const {
958
959 size_t nDets = detIDs.size();
960 if (nDets == 0)
961 return;
962 auto detectors = getDetectors(detIDs);
963
965 Kernel::V3D sample_pos;
966 if (sample)
967 sample_pos = sample->getPos();
968
969 std::vector<double> a_angles(nDets);
970 std::vector<double> p_angles(nDets);
971 std::vector<double> distances(nDets);
972
973 for (size_t i = 0; i < nDets; i++) {
974 if (sample) {
975 Kernel::V3D pos = detectors[i]->getPos() - sample_pos;
976 pos.getSpherical(distances[i], p_angles[i], a_angles[i]);
977 } else {
978 a_angles[i] = detectors[i]->getPhi() * 180.0 / M_PI;
979 }
980 }
981 file->writeData("detector_number", detIDs);
982 file->writeData("azimuthal_angle", a_angles);
983 file->openData("azimuthal_angle");
984 file->putAttr("units", "degree");
985 file->closeData();
986 if (sample) {
987 file->writeData("polar_angle", p_angles);
988 file->openData("polar_angle");
989 file->putAttr("units", "degree");
990 file->closeData();
991 file->writeData("distance", distances);
992 file->openData("distance");
993 file->putAttr("units", "metre");
994 file->closeData();
995 }
996}
997
998//--------------------------------------------------------------------------------------------
1003void Instrument::loadNexus(Nexus::File *file, const std::string &group) {
1004 file->openGroup(group, "NXinstrument");
1005 file->closeGroup();
1006}
1007
1012void Instrument::setReferenceFrame(std::shared_ptr<ReferenceFrame> frame) { m_referenceFrame = std::move(frame); }
1013
1018std::shared_ptr<const ReferenceFrame> Instrument::getReferenceFrame() const {
1019 if (m_map) {
1020 return m_instr->getReferenceFrame();
1021 } else {
1022 return m_referenceFrame;
1023 }
1024}
1025
1034void Instrument::setDefaultView(const std::string &type) {
1035 std::string typeUC(type);
1036 std::transform(typeUC.begin(), typeUC.end(), typeUC.begin(), toupper);
1037 if (typeUC == "3D" || typeUC == "CYLINDRICAL_X" || typeUC == "CYLINDRICAL_Y" || typeUC == "CYLINDRICAL_Z" ||
1038 typeUC == "SPHERICAL_X" || typeUC == "SPHERICAL_Y" || typeUC == "SPHERICAL_Z") {
1039 m_defaultView = typeUC;
1040 } else {
1041 m_defaultView = "3D";
1042 g_log.warning() << type << " is not allowed as an instrument view type. Default to \"3D\"" << '\n';
1043 }
1044}
1045
1050void Instrument::setValidFromDate(const Types::Core::DateAndTime &val) {
1051 Types::Core::DateAndTime earliestAllowedDate("1900-01-31 23:59:01");
1052 if (val < earliestAllowedDate) {
1054 "The valid-from <instrument> tag date must be from 1900-01-31 23:59:01 "
1055 "or later",
1056 m_filename);
1057 }
1058 m_ValidFrom = val;
1059}
1060
1062 std::queue<IComponent_const_sptr> compQueue; // Search queue
1064
1065 bool foundRect = false;
1066 bool foundNonRect = false;
1067
1069
1070 while (!compQueue.empty() && !(foundRect && foundNonRect)) {
1071 comp = compQueue.front();
1072 compQueue.pop();
1073
1074 if (!validateComponentProperties(comp))
1075 continue;
1076
1077 if (dynamic_cast<const RectangularDetector *>(comp.get())) {
1078 foundRect = true;
1079 } // If component isn't a ComponentAssembly, we know it is a non-rectangular detector. Otherwise check its children
1080 else if (!addAssemblyChildrenToQueue(compQueue, comp)) {
1081 foundNonRect = true;
1082 }
1083 }
1084
1085 // Found both
1086 if (foundRect && foundNonRect)
1088 // Found only rectangular
1089 else if (foundRect)
1091 // Found only non-rectangular
1092 else
1094}
1095
1097 // Skip source, if has one
1098 if (m_sourceCache && m_sourceCache->getComponentID() == component->getComponentID())
1099 return false;
1100
1101 // Skip sample, if has one
1102 if (m_sampleCache && m_sampleCache->getComponentID() == component->getComponentID())
1103 return false;
1104
1105 // Skip monitors
1106 IDetector_const_sptr detector = std::dynamic_pointer_cast<const IDetector>(component);
1107 if (detector && isMonitor(detector->getID()))
1108 return false;
1109
1110 // skip choppers, slits and supermirrors - HACK!
1111 const auto &name = component->getName();
1112 if (name == "chopper-position" || name.substr(0, 4) == "slit" || name == "supermirror") {
1113 return false;
1114 }
1115
1116 return true;
1117}
1118
1119void Instrument::addInstrumentChildrenToQueue(std::queue<IComponent_const_sptr> &queue) const {
1120 // Add all the direct children of the instrument
1121 for (int i = 0; i < nelements(); i++)
1122 queue.push(getChild(i));
1123}
1124
1127bool Instrument::addAssemblyChildrenToQueue(std::queue<IComponent_const_sptr> &queue,
1128 IComponent_const_sptr component) const {
1129 if (auto const assembly = std::dynamic_pointer_cast<const ICompAssembly>(component)) {
1130 for (int i = 0; i < assembly->nelements(); i++)
1131 queue.push(assembly->getChild(i));
1132 return true;
1133 }
1134 return false;
1135}
1136
1138bool Instrument::isMonitorViaIndex(const size_t index) const {
1139 if (m_map)
1140 return std::get<2>(m_instr->m_detectorCache[index]);
1141 else
1142 return std::get<2>(m_detectorCache[index]);
1143}
1144
1145bool Instrument::isEmptyInstrument() const { return this->nelements() == 0; }
1146
1148size_t Instrument::detectorIndex(const detid_t detID) const {
1149 const auto &baseInstr = m_map ? *m_instr : *this;
1150 const auto it = find(baseInstr.m_detectorCache, detID);
1151 return std::distance(baseInstr.m_detectorCache.cbegin(), it);
1152}
1153
1156std::shared_ptr<ParameterMap> Instrument::makeLegacyParameterMap() const {
1157 auto pmap = std::make_shared<ParameterMap>(*getParameterMap());
1158 // Instrument is only needed for DetectorInfo access so it is not needed. This
1159 // also clears DetectorInfo and ComponentInfo (information will be stored
1160 // directly in pmap so we do not need them).
1161 pmap->setInstrument(nullptr);
1162
1163 const auto &baseInstr = m_map ? *m_instr : *this;
1164
1165 if (!getParameterMap()->hasComponentInfo(&baseInstr))
1166 return pmap;
1167
1168 // Tolerance 1e-9 m with rotation center at a distance of L = 1000 m as in
1169 // Beamline::DetectorInfo::isEquivalent.
1170 constexpr double d_max = 1e-9;
1171 constexpr double L = 1000.0;
1172 constexpr double safety_factor = 2.0;
1173 const double imag_norm_max = sin(d_max / (2.0 * L * safety_factor));
1174
1175 auto transformation = Eigen::Affine3d::Identity();
1176 int64_t oldParentIndex = -1;
1177
1178 const auto &componentInfo = getParameterMap()->componentInfo();
1179 const auto &detectorInfo = getParameterMap()->detectorInfo();
1180 for (size_t i = 0; i < componentInfo.size(); ++i) {
1181
1182 const int64_t parentIndex = componentInfo.parent(i);
1183 const bool makeTransform = parentIndex != oldParentIndex;
1184 bool isDetFixedInBank = false;
1185
1186 if (makeTransform) {
1187 oldParentIndex = parentIndex;
1188 const auto parentPos = toVector3d(componentInfo.position(parentIndex));
1189 const auto invParentRot = toQuaterniond(componentInfo.rotation(parentIndex)).conjugate();
1190
1191 transformation = invParentRot;
1192 transformation.translate(-parentPos);
1193 }
1194
1195 if (componentInfo.isDetector(i)) {
1196
1197 const std::shared_ptr<const IDetector> &baseDet = std::get<1>(baseInstr.m_detectorCache[i]);
1198
1199 isDetFixedInBank = ComponentInfoBankHelpers::isDetectorFixedInBank(componentInfo, i);
1200 if (detectorInfo.isMasked(i)) {
1201 pmap->forceUnsafeSetMasked(baseDet.get(), true);
1202 }
1203
1204 if (makeTransform) {
1205 // Special case: scaling for GridDetectorPixel.
1206 if (isDetFixedInBank) {
1207
1208 size_t panelIndex = componentInfo.parent(parentIndex);
1209 const auto panelID = componentInfo.componentID(panelIndex);
1210
1211 Eigen::Vector3d scale(1, 1, 1);
1212 if (auto scalex = pmap->get(panelID, "scalex"))
1213 scale[0] = 1.0 / scalex->value<double>();
1214 if (auto scaley = pmap->get(panelID, "scaley"))
1215 scale[1] = 1.0 / scaley->value<double>();
1216 transformation.prescale(scale);
1217 }
1218 }
1219 }
1220
1221 const auto componentId = componentInfo.componentID(i);
1222 const IComponent *baseComponent = componentId->getBaseComponent();
1223 // Generic sca scale factors
1224 const auto newScaleFactor = Kernel::toVector3d(componentInfo.scaleFactor(i));
1225 if ((newScaleFactor - toVector3d(baseComponent->getScaleFactor())).norm() >= 1e-9) {
1226 pmap->addV3D(componentId, ParameterMap::scale(), componentInfo.scaleFactor(i));
1227 }
1228
1229 // Undo parent transformation to obtain relative position/rotation.
1230 Eigen::Vector3d relPos = transformation * toVector3d(componentInfo.position(i));
1231 Eigen::Quaterniond relRot = toQuaterniond(componentInfo.relativeRotation(i));
1232
1233 // Tolerance 1e-9 m as in Beamline::DetectorInfo::isEquivalent.
1234 if ((relPos - toVector3d(baseComponent->getRelativePos())).norm() >= 1e-9) {
1235 if (isDetFixedInBank) {
1236 throw std::runtime_error("Cannot create legacy ParameterMap: Position "
1237 "parameters for GridDetectorPixel are "
1238 "not supported");
1239 }
1240 pmap->addV3D(componentId, ParameterMap::pos(), Kernel::toV3D(relPos));
1241 }
1242 if ((relRot * toQuaterniond(baseComponent->getRelativeRot()).conjugate()).vec().norm() >= imag_norm_max) {
1243 pmap->addQuat(componentId, ParameterMap::rot(), Kernel::toQuat(relRot));
1244 }
1245 }
1246
1247 return pmap;
1248}
1249
1257 if (isParametrized())
1258 throw std::logic_error("Instrument::parseTreeAndCacheBeamline must be "
1259 "called with the base instrument, not a "
1260 "parametrized instrument");
1262}
1263
1269std::pair<std::unique_ptr<ComponentInfo>, std::unique_ptr<DetectorInfo>>
1271 // If we have source and it has Beamline objects just copy them
1272 if (source && source->hasComponentInfo(this))
1273 return makeWrappers(pmap, source->componentInfo(), source->detectorInfo());
1274 // If pmap is empty and base instrument has Beamline objects just copy them
1275 if (pmap.empty() && m_componentInfo)
1277 // pmap not empty and/or no cached Beamline objects found
1278 return InstrumentVisitor::makeWrappers(*this, &pmap);
1279}
1280
1282std::pair<std::unique_ptr<ComponentInfo>, std::unique_ptr<DetectorInfo>>
1284 const DetectorInfo &detectorInfo) const {
1285 auto compInfo = componentInfo.cloneWithoutDetectorInfo();
1286 auto detInfo = std::make_unique<DetectorInfo>(detectorInfo);
1287 compInfo->m_componentInfo->setDetectorInfo(detInfo->m_detectorInfo.get());
1288 const auto parInstrument = ParComponentFactory::createInstrument(
1289 std::shared_ptr<const Instrument>(this, NoDeleting()), std::shared_ptr<ParameterMap>(&pmap, NoDeleting()));
1290 detInfo->m_instrument = parInstrument;
1291 return {std::move(compInfo), std::move(detInfo)};
1292}
1293
1294namespace Conversion {
1295
1304double tofToDSpacingFactor(const double l1, const double l2, const double twoTheta, const double offset) {
1305 return Kernel::Units::tofToDSpacingFactor(l1, l2, twoTheta, offset);
1306}
1307
1308double calculateDIFCCorrection(const double l1, const double l2, const double twoTheta, const double offset,
1309 const double binWidth) {
1310 return Kernel::Units::calculateDIFCCorrection(l1, l2, twoTheta, offset, binWidth);
1311}
1312
1313} // namespace Conversion
1314} // namespace Mantid::Geometry
std::string name
Definition Run.cpp:60
std::map< DeltaEMode::Type, std::string > index
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:33
void grow(const BoundingBox &other)
Grow the bounding box so that it also encompasses the given box.
Class for Assembly of geometric components.
std::vector< IComponent * > m_children
the group of child components
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.
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.
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:42
const ParameterMap * m_map
A pointer to const ParameterMap containing the parameters.
Definition Component.h:316
size_t index() const
Helper for legacy access mode. Returns the index of the component.
const IComponent * base() const
Returns the address of the base component.
Definition Component.h:289
bool isParametrized() const override
Return true if the Component is, in fact, parametrized (that is - it has a valid parameter map)
Definition Component.cpp:75
std::string getName() const override
Get the IComponent name.
const Component * m_base
The base component - this is the unmodified component (without the parameters).
Definition Component.h:314
Geometry::DetectorInfo is an intermediate step towards a DetectorInfo that is part of Instrument-2....
This class represents a detector - i.e.
Definition Detector.h:30
Class for Assembly of geometric components.
virtual void getChildren(std::vector< IComponent_const_sptr > &outVector, bool recursive) const =0
Get all children.
base class for Geometric IComponent
Definition IComponent.h:53
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:124
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...
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:313
std::vector< std::shared_ptr< const IComponent > > getAllComponentsWithName(const std::string &cname) const
Returns pointers to all components encountered with the given name.
void markAsSamplePos(const IComponent *)
mark a Component which has already been added to the Instrument (as a child comp.) to be 'the' sample...
std::size_t getNumberDetectors(bool skipMonitors=false) const
IComponent_const_sptr getSource() const
Gets a pointer to the source.
std::string m_xmlText
Contents of the IDF .xml file that was loaded for this instrument.
Definition Instrument.h:316
std::shared_ptr< const IComponent > getComponentByID(const IComponent *id) const
Returns a shared pointer to a component.
bool validateComponentProperties(IComponent_const_sptr component) const
const IComponent * m_sampleCache
Purpose to hold copy of samplePos component.
Definition Instrument.h:276
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.
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...
std::shared_ptr< const Instrument > baseInstrument() const
Pointer to the 'real' instrument, for parametrized instruments.
Instrument()
Default constructor.
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...
std::shared_ptr< const Instrument > m_instr
Pointer to the "real" instrument, for parametrized Instrument.
Definition Instrument.h:302
std::set< detid_t > getDetectorIDsInBank(const std::string &bankName) const
void markAsDetector(const IDetector *)
mark a Component which has already been added to the Instrument (as a child comp.) to be a Detector c...
std::string m_defaultView
Stores the default type of the instrument view: 3D or one of the "unwrapped".
Definition Instrument.h:296
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:326
std::vector< IDetector_const_sptr > getDetectors(const std::vector< detid_t > &det_ids) const
Returns a list of Detectors for the given detectors ids.
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:268
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.
Instrument * clone() const override
Virtual copy constructor.
bool isMonitor(const detid_t &detector_id) const
const std::string & getFilename() const
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.
std::shared_ptr< ParameterMap > getParameterMap() const
Pointer to the NOT const ParameterMap holding the parameters of the modified instrument components.
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.
Kernel::V3D getBeamDirection() const
Gets the beam direction (i.e.
const IComponent * m_sourceCache
Purpose to hold copy of source component.
Definition Instrument.h:272
void saveNexus(Nexus::File *file, const std::string &group) const
Save the instrument to an open NeXus file.
std::vector< detid_t > getMonitors() const
Returns a list containing the detector ids of monitors.
void appendPlottable(const CompAssembly &ca, std::vector< IObjComponent_const_sptr > &lst) const
Add a plottable component.
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.
const std::string & getXmlText() const
std::vector< detid_t > getDetectorIDs(bool skipMonitors=false) const
Return a vector of detector IDs in this instrument.
void getBoundingBox(BoundingBox &assemblyBox) const override
Get the bounding box for this component and store it in the given argument.
std::shared_ptr< const ComponentInfo > m_componentInfo
Pointer to the ComponentInfo object. May be NULL.
Definition Instrument.h:329
std::shared_ptr< const Instrument > m_physicalInstrument
Pointer to the physical instrument, where this differs from the 'neutronic' one (indirect geometry)
Definition Instrument.h:320
std::shared_ptr< const std::vector< IObjComponent_const_sptr > > getPlottable() const
Get pointers to plottable components.
void saveDetectorSetInfoToNexus(Nexus::File *file, const std::vector< detid_t > &detIDs) const
Save information about a set of detectors to Nexus.
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.
void markAsMonitor(const IDetector *)
mark a Component which has already been added to the Instrument (as a child comp.) to be a monitor an...
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.
void markAsSource(const IComponent *)
mark a Component which has already been added to the Instrument (as a child comp.) to be 'the' source...
bool hasSource() const
Checks to see if the Instrument has a source.
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.
std::shared_ptr< ParameterMap > m_map_nonconst
Non-const pointer to the parameter map.
Definition Instrument.h:305
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.
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:323
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...
Types::Core::DateAndTime m_ValidFrom
the date from which the instrument definition begins to be valid.
Definition Instrument.h:308
void setFilename(const std::string &filename)
Set the path to the original IDF .xml file that was loaded for this instrument.
IComponent_const_sptr getSample() const
Gets a pointer to the Sample Position.
void addInstrumentChildrenToQueue(std::queue< IComponent_const_sptr > &queue) const
void loadNexus(Nexus::File *file, const std::string &group)
Load the object from an open NeXus file.
void removeDetector(IDetector *)
Remove a detector from the instrument.
Void deleter for shared pointers.
Object Component class, this class brings together the physical attributes of the component to the po...
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:51
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
Class for 3D vectors.
Definition V3D.h:34
double norm() const noexcept
Definition V3D.h:269
void getSpherical(double &R, double &theta, double &phi) const noexcept
Return the vector's position in spherical coordinates.
Definition V3D.cpp:116
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 calculateDIFCCorrection(const double l1, const double l2, const double twoTheta, const double offset, const double binWidth)
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:167
std::shared_ptr< IComponent > IComponent_sptr
Typedef of a shared pointer to a IComponent.
Definition IComponent.h:165
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.
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 calculateDIFCCorrection(const double l1, const double l2, const double twotheta, const double offset, const double binWidth)
Calculate DIFC in case of logarithmic binning, used in CalculateDIFC with Signed mode.
Definition Unit.cpp:565
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:589
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:352
Eigen::Quaterniond toQuaterniond(const Kernel::Quat &quat)
Converts Kernel::Quat to Eigen::Quaterniond.
int32_t detid_t
Typedef for a detector ID.
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