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 is
92 if (const IDetector *det = dynamic_cast<const Detector *>(it->get())) {
93 if (instr.isMonitor(det->getID()))
94 markAsMonitor(det);
95 else
96 markAsDetector(det);
97 continue;
98 }
99 // Now check whether the current component is the source or sample.
100 // As the majority of components will be detectors, we will rarely get to here
101 if (const auto *obj = dynamic_cast<const Component *>(it->get())) {
102 const std::string objName = obj->getName();
103 // This relies on the source and sample having a unique name.
104 // I think the way our instrument definition files work ensures this is
105 // the case.
106 if (objName == instr.m_sourceCache->getName()) {
108 continue;
109 }
110 if (objName == instr.m_sampleCache->getName()) {
112 continue;
113 }
114 }
115 }
116}
117
119Instrument *Instrument::clone() const { return new Instrument(*this); }
120
123 if (m_map)
124 return m_instr;
125 else
126 throw std::runtime_error("Instrument::baseInstrument() called for a "
127 "non-parametrized instrument.");
128}
129
136 if (m_map)
137 return m_map_nonconst;
138 else
139 throw std::runtime_error("Instrument::getParameterMap() called for a "
140 "non-parametrized instrument.");
141}
142
150 if (m_map) {
151 if (m_instr->getPhysicalInstrument()) {
152 // A physical instrument should use the same parameter map as the 'main'
153 // instrument. This constructor automatically sets the instrument as the
154 // owning instrument in the ParameterMap. We need to undo this immediately
155 // since the ParameterMap must always be owned by the neutronic
156 // instrument.
157 return std::make_shared<Instrument>(m_instr->getPhysicalInstrument(), m_map_nonconst);
158 } else {
159 return Instrument_const_sptr();
160 }
161 } else {
163 }
164}
165
171void Instrument::setPhysicalInstrument(std::unique_ptr<Instrument> physInst) {
172 if (!m_map) {
173 physInst->m_isPhysicalInstrument = true;
174 m_physicalInstrument = std::move(physInst);
175 } else
176 throw std::runtime_error("Instrument::setPhysicalInstrument() called on a "
177 "parametrized instrument.");
178}
179
180//------------------------------------------------------------------------------------------
184 if (m_map) {
185 // Get the base instrument detectors
186 out_map.clear();
187 const auto &in_dets = m_instr->m_detectorCache;
188 // And turn them into parametrized versions
189 for (const auto &in_det : in_dets) {
190 out_map.emplace(std::get<0>(in_det), getDetector(std::get<0>(in_det)));
191 }
192 } else {
193 // You can just return the detector cache directly.
194 out_map.clear();
195 for (const auto &in_det : m_detectorCache)
196 out_map.emplace(std::get<0>(in_det), std::get<1>(in_det));
197 }
198}
199
200//------------------------------------------------------------------------------------------
202std::vector<detid_t> Instrument::getDetectorIDs(bool skipMonitors) const {
203 std::vector<detid_t> out;
204 if (m_map) {
205 const auto &in_dets = m_instr->m_detectorCache;
206 for (const auto &in_det : in_dets)
207 if (!skipMonitors || !std::get<2>(in_det))
208 out.emplace_back(std::get<0>(in_det));
209 } else {
210 const auto &in_dets = m_detectorCache;
211 for (const auto &in_det : in_dets)
212 if (!skipMonitors || !std::get<2>(in_det))
213 out.emplace_back(std::get<0>(in_det));
214 }
215 return out;
216}
217
219std::size_t Instrument::getNumberDetectors(bool skipMonitors) const {
220 std::size_t numDetIDs(0);
221
222 if (m_map) {
223 numDetIDs = m_instr->m_detectorCache.size();
224 } else {
225 numDetIDs = m_detectorCache.size();
226 }
227
228 if (skipMonitors) // this slow, but gets the right answer
229 {
230 std::size_t monitors(0);
231 if (m_map) {
232 const auto &in_dets = m_instr->m_detectorCache;
233 monitors =
234 std::count_if(in_dets.cbegin(), in_dets.cend(), [](const auto &in_det) { return std::get<2>(in_det); });
235 } else {
236 const auto &in_dets = m_detectorCache;
237 monitors =
238 std::count_if(in_dets.cbegin(), in_dets.cend(), [](const auto &in_det) { return std::get<2>(in_det); });
239 }
240 return (numDetIDs - monitors);
241 } else {
242 return numDetIDs;
243 }
244}
245
252 const auto *in_dets = m_map ? &m_instr->m_detectorCache : &m_detectorCache;
253
254 if (in_dets->empty())
255 throw std::runtime_error("No detectors on this instrument. Can't find min/max ids");
256 // Maps are sorted by key. So it is easy to find
257 min = std::get<0>(*in_dets->begin());
258 max = std::get<0>(*in_dets->rbegin());
259}
260
270void Instrument::getDetectorsInBank(std::vector<IDetector_const_sptr> &dets, const IComponent &comp) const {
271 const auto bank = dynamic_cast<const ICompAssembly *>(&comp);
272 if (bank) {
273 // Get a vector of children (recursively)
274 std::vector<std::shared_ptr<const IComponent>> children;
275 bank->getChildren(children, true);
276 std::vector<std::shared_ptr<const IComponent>>::iterator it;
277 for (it = children.begin(); it != children.end(); ++it) {
278 IDetector_const_sptr det = std::dynamic_pointer_cast<const IDetector>(*it);
279 if (det) {
280 dets.emplace_back(det);
281 }
282 }
283 }
284}
285
296void Instrument::getDetectorsInBank(std::vector<IDetector_const_sptr> &dets, const std::string &bankName) const {
297 std::shared_ptr<const IComponent> comp = this->getComponentByName(bankName);
298 if (!comp) {
299 throw Kernel::Exception::NotFoundError("Instrument: Could not find component", bankName);
300 }
301 getDetectorsInBank(dets, *comp);
302}
303
304std::set<detid_t> Instrument::getDetectorIDsInBank(const std::string &bankName) const {
305 std::set<detid_t> detIDs;
306 std::vector<IDetector_const_sptr> detectors;
307 getDetectorsInBank(detectors, bankName);
308
309 for (const auto &det : detectors) {
310 detIDs.emplace(det->getID());
311 }
312 return detIDs;
313}
314
318bool Instrument::hasSource() const { return m_sourceCache; }
319
323bool Instrument::hasSample() const { return m_sampleCache; }
324
329 if (!m_sourceCache) {
330 g_log.warning("In Instrument::getSource(). No source has been set.");
332 } else if (m_map) {
333 auto sourceCache = static_cast<const Instrument *>(m_base)->m_sourceCache;
334 if (dynamic_cast<const ObjComponent *>(sourceCache))
335 return IComponent_const_sptr(new ObjComponent(sourceCache, m_map));
336 else if (dynamic_cast<const CompAssembly *>(sourceCache))
337 return IComponent_const_sptr(new CompAssembly(sourceCache, m_map));
338 else if (dynamic_cast<const Component *>(sourceCache))
339 return IComponent_const_sptr(new Component(sourceCache, m_map));
340 else {
341 g_log.error("In Instrument::getSource(). Source is not a recognised "
342 "component type.");
343 g_log.error("Try to assume it is a Component.");
344 return IComponent_const_sptr(new ObjComponent(sourceCache, m_map));
345 }
346 } else {
348 }
349}
350
355 if (!m_sampleCache) {
356 g_log.warning("In Instrument::getSamplePos(). No SamplePos has been set.");
358 } else if (m_map) {
359 auto sampleCache = static_cast<const Instrument *>(m_base)->m_sampleCache;
360 if (dynamic_cast<const ObjComponent *>(sampleCache))
361 return IComponent_const_sptr(new ObjComponent(sampleCache, m_map));
362 else if (dynamic_cast<const CompAssembly *>(sampleCache))
363 return IComponent_const_sptr(new CompAssembly(sampleCache, m_map));
364 else if (dynamic_cast<const Component *>(sampleCache))
365 return IComponent_const_sptr(new Component(sampleCache, m_map));
366 else {
367 g_log.error("In Instrument::getSamplePos(). SamplePos is not a "
368 "recognised component type.");
369 g_log.error("Try to assume it is a Component.");
370 return IComponent_const_sptr(new ObjComponent(sampleCache, m_map));
371 }
372 } else {
374 }
375}
376
382
383//------------------------------------------------------------------------------------------
388std::shared_ptr<const IComponent> Instrument::getComponentByID(const IComponent *id) const {
389 const auto *base = static_cast<const IComponent *>(id);
390 if (m_map)
391 return ParComponentFactory::create(std::shared_ptr<const IComponent>(base, NoDeleting()), m_map);
392 else
393 return std::shared_ptr<const IComponent>(base, NoDeleting());
394}
395
405std::vector<std::shared_ptr<const IComponent>> Instrument::getAllComponentsWithName(const std::string &cname) const {
406 std::shared_ptr<const IComponent> node = std::shared_ptr<const IComponent>(this, NoDeleting());
407 std::vector<std::shared_ptr<const IComponent>> retVec;
408 // Check the instrument name first
409 if (this->getName() == cname) {
410 retVec.emplace_back(node);
411 }
412 // Same algorithm as used in getComponentByName() but searching the full tree
413 std::deque<std::shared_ptr<const IComponent>> nodeQueue;
414 // Need to be able to enter the while loop
415 nodeQueue.emplace_back(node);
416 while (!nodeQueue.empty()) {
417 node = nodeQueue.front();
418 nodeQueue.pop_front();
419 int nchildren(0);
420 std::shared_ptr<const ICompAssembly> asmb = std::dynamic_pointer_cast<const ICompAssembly>(node);
421 if (asmb) {
422 nchildren = asmb->nelements();
423 }
424 for (int i = 0; i < nchildren; ++i) {
425 std::shared_ptr<const IComponent> comp = (*asmb)[i];
426 if (comp->getName() == cname) {
427 retVec.emplace_back(comp);
428 } else {
429 nodeQueue.emplace_back(comp);
430 }
431 }
432 } // while-end
433
434 // If we have reached here then the search failed
435 return retVec;
436}
437
438namespace {
439// Helpers for accessing m_detectorCache, which is a vector of tuples used as a
440// map. Lookup is by first element in a tuple. Templated to support const and
441// non-const.
442template <class T> auto lower_bound(T &map, const detid_t key) -> decltype(map.begin()) {
443 return std::lower_bound(map.begin(), map.end(), std::make_tuple(key, IDetector_const_sptr(nullptr), false),
444 [](const typename T::value_type &a, const typename T::value_type &b) -> bool {
445 return std::get<0>(a) < std::get<0>(b);
446 });
447}
448
449template <class T> auto find(T &map, const detid_t key) -> decltype(map.begin()) {
450 auto it = lower_bound(map, key);
451 if ((it != map.end()) && (std::get<0>(*it) == key))
452 return it;
453 return map.end();
454}
455} // namespace
456
468 const auto &baseInstr = m_map ? *m_instr : *this;
469 const auto it = find(baseInstr.m_detectorCache, detector_id);
470 if (it == baseInstr.m_detectorCache.end()) {
471 std::stringstream readInt;
472 readInt << detector_id;
473 throw Kernel::Exception::NotFoundError("Instrument: Detector with ID " + readInt.str() + " not found.", "");
474 }
475 IDetector_const_sptr baseDet = std::get<1>(*it);
476
477 if (!m_map)
478 return baseDet;
479
480 auto det = ParComponentFactory::createDetector(baseDet.get(), m_map);
481 return det;
482}
483
489const IDetector *Instrument::getBaseDetector(const detid_t &detector_id) const {
490 auto it = find(m_instr->m_detectorCache, detector_id);
491 if (it == m_instr->m_detectorCache.end()) {
492 return nullptr;
493 }
494 return std::get<1>(*it).get();
495}
496
497bool Instrument::isMonitor(const detid_t &detector_id) const {
498 const auto &baseInstr = m_map ? *m_instr : *this;
499 const auto it = find(baseInstr.m_detectorCache, detector_id);
500 if (it == baseInstr.m_detectorCache.end())
501 return false;
502 return std::get<2>(*it);
503}
504
505bool Instrument::isMonitor(const std::set<detid_t> &detector_ids) const {
506 if (detector_ids.empty())
507 return false;
508
509 return std::any_of(detector_ids.cbegin(), detector_ids.cend(),
510 [this](const auto detector_id) { return isMonitor(detector_id); });
511}
512
519IDetector_const_sptr Instrument::getDetectorG(const std::set<detid_t> &det_ids) const {
520 const size_t ndets(det_ids.size());
521 if (ndets == 1) {
522 return this->getDetector(*det_ids.begin());
523 } else {
524 std::shared_ptr<DetectorGroup> det_group = std::make_shared<DetectorGroup>();
525 for (const auto detID : det_ids) {
526 det_group->addDetector(this->getDetector(detID));
527 }
528 return det_group;
529 }
530}
531
536std::vector<IDetector_const_sptr> Instrument::getDetectors(const std::vector<detid_t> &det_ids) const {
537 std::vector<IDetector_const_sptr> dets_ptr;
538 dets_ptr.reserve(det_ids.size());
539 std::vector<detid_t>::const_iterator it;
540 for (it = det_ids.begin(); it != det_ids.end(); ++it) {
541 dets_ptr.emplace_back(this->getDetector(*it));
542 }
543 return dets_ptr;
544}
545
550std::vector<IDetector_const_sptr> Instrument::getDetectors(const std::set<detid_t> &det_ids) const {
551 std::vector<IDetector_const_sptr> dets_ptr;
552 dets_ptr.reserve(det_ids.size());
553 std::set<detid_t>::const_iterator it;
554 for (it = det_ids.begin(); it != det_ids.end(); ++it) {
555 dets_ptr.emplace_back(this->getDetector(*it));
556 }
557 return dets_ptr;
558}
559
571 if (m_map)
572 throw std::runtime_error("Instrument::markAsSamplePos() called on a "
573 "parametrized Instrument object.");
574
575 auto objComp = dynamic_cast<const IObjComponent *>(comp);
576 if (objComp) {
577 throw std::runtime_error("Instrument::markAsSamplePos() called on an IObjComponent "
578 "object that supports shape definition. Sample is prevented from "
579 "being this type because the shape must only be stored in "
580 "ExperimentInfo::m_sample.");
581 }
582
583 if (!m_sampleCache) {
584 if (comp->getName().empty()) {
585 throw Exception::InstrumentDefinitionError("The sample component is required to have a name.");
586 }
587 m_sampleCache = comp;
588 } else {
589 g_log.warning("Have already added samplePos component to the _sampleCache.");
590 }
591}
592
604 if (m_map)
605 throw std::runtime_error("Instrument::markAsSource() called on a "
606 "parametrized Instrument object.");
607
608 if (!m_sourceCache) {
609 if (comp->getName().empty()) {
610 throw Exception::InstrumentDefinitionError("The source component is required to have a name.");
611 }
612 m_sourceCache = comp;
613 } else {
614 g_log.warning("Have already added source component to the _sourceCache.");
615 }
616}
617
627 if (m_map)
628 throw std::runtime_error("Instrument::markAsDetector() called on a "
629 "parametrized Instrument object.");
630
631 // Create a (non-deleting) shared pointer to it
633 auto it = lower_bound(m_detectorCache, det->getID());
634 // Duplicate detector ids are forbidden
635 if ((it != m_detectorCache.end()) && (std::get<0>(*it) == det->getID())) {
636 raiseDuplicateDetectorError(det->getID());
637 }
638 bool isMonitorFlag = false;
639 m_detectorCache.emplace(it, det->getID(), det_sptr, isMonitorFlag);
640}
641
645 if (m_map)
646 throw std::runtime_error("Instrument::markAsDetector() called on a "
647 "parametrized Instrument object.");
648
649 // Create a (non-deleting) shared pointer to it
651 bool isMonitorFlag = false;
652 m_detectorCache.emplace_back(det->getID(), det_sptr, isMonitorFlag);
653}
654
658 // Detectors (even when different objects) are NOT allowed to have duplicate
659 // ids. This method establishes the presence of duplicates.
660 std::sort(
661 m_detectorCache.begin(), m_detectorCache.end(),
662 [](const std::tuple<detid_t, IDetector_const_sptr, bool> &a,
663 const std::tuple<detid_t, IDetector_const_sptr, bool> &b) -> bool { return std::get<0>(a) < std::get<0>(b); });
664
665 auto resultIt = std::adjacent_find(m_detectorCache.begin(), m_detectorCache.end(),
666 [](const std::tuple<detid_t, IDetector_const_sptr, bool> &a,
667 const std::tuple<detid_t, IDetector_const_sptr, bool> &b) -> bool {
668 return std::get<0>(a) == std::get<0>(b);
669 });
670 if (resultIt != m_detectorCache.end()) {
671 raiseDuplicateDetectorError(std::get<0>(*resultIt));
672 }
673}
674
684 if (m_map)
685 throw std::runtime_error("Instrument::markAsMonitor() called on a "
686 "parametrized Instrument object.");
687
688 // attempt to add monitor to instrument detector cache
689 markAsDetector(det);
690
691 // mark detector as a monitor
692 auto it = find(m_detectorCache, det->getID());
693 std::get<2>(*it) = true;
694}
695
701 if (m_map)
702 throw std::runtime_error("Instrument::removeDetector() called on a "
703 "parameterized Instrument object.");
704
705 const detid_t id = det->getID();
706 // Remove the detector from the detector cache
707 const auto it = find(m_detectorCache, id);
708 m_detectorCache.erase(it);
709
710 // Remove it from the parent assembly (and thus the instrument). Evilness
711 // required here unfortunately.
712 auto *parentAssembly = dynamic_cast<CompAssembly *>(const_cast<IComponent *>(det->getBareParent()));
713 if (parentAssembly) // Should always be true, but check just in case
714 {
715 parentAssembly->remove(det);
716 }
717}
718
722std::vector<detid_t> Instrument::getMonitors() const {
723 // Monitors cannot be parametrized. So just return the base.
724 if (m_map)
725 return m_instr->getMonitors();
726
727 std::vector<detid_t> mons;
728 for (const auto &item : m_detectorCache)
729 if (std::get<2>(item))
730 mons.emplace_back(std::get<0>(item));
731 return mons;
732}
733
739void Instrument::getBoundingBox(BoundingBox &assemblyBox) const {
740 if (m_map) {
741
742 if (m_map->hasComponentInfo(this->baseInstrument().get())) {
743 assemblyBox = m_map->componentInfo().boundingBox(index(), &assemblyBox);
744 return;
745 }
746
747 // Loop over the children and define a box large enough for all of them
748 ComponentID sourceID = getSource()->getComponentID();
749 assemblyBox = BoundingBox(); // this makes the instrument BB always axis aligned
750 int nchildren = nelements();
751 for (int i = 0; i < nchildren; ++i) {
752 IComponent_sptr comp = this->getChild(i);
753 if (comp && comp->getComponentID() != sourceID) {
754 BoundingBox compBox;
755 comp->getBoundingBox(compBox);
756 assemblyBox.grow(compBox);
757 }
758 }
759 } else {
760
761 if (!m_cachedBoundingBox) {
763 ComponentID sourceID = getSource()->getComponentID();
764 // Loop over the children and define a box large enough for all of them
765 for (const auto component : m_children) {
766 BoundingBox compBox;
767 if (component && component->getComponentID() != sourceID) {
768 component->getBoundingBox(compBox);
769 m_cachedBoundingBox->grow(compBox);
770 }
771 }
772 }
773 // Use cached box
774 assemblyBox = *m_cachedBoundingBox;
775 }
776}
777
778std::shared_ptr<const std::vector<IObjComponent_const_sptr>> Instrument::getPlottable() const {
779 if (m_map) {
780 // Get the 'base' plottable components
781 std::shared_ptr<const std::vector<IObjComponent_const_sptr>> objs = m_instr->getPlottable();
782
783 // Get a reference to the underlying vector, casting away the constness so
784 // that we
785 // can modify it to get our result rather than creating another long vector
786 auto &res = const_cast<std::vector<IObjComponent_const_sptr> &>(*objs);
787 const std::vector<IObjComponent_const_sptr>::size_type total = res.size();
788 for (std::vector<IObjComponent_const_sptr>::size_type i = 0; i < total; ++i) {
789 res[i] = std::dynamic_pointer_cast<const Detector>(ParComponentFactory::create(objs->at(i), m_map));
790 }
791 return objs;
792
793 } else {
794 // Base instrument
795 auto res = std::make_shared<std::vector<IObjComponent_const_sptr>>();
796 res->reserve(m_detectorCache.size() + 10);
797 appendPlottable(*this, *res);
798 return res;
799 }
800}
801
802void Instrument::appendPlottable(const CompAssembly &ca, std::vector<IObjComponent_const_sptr> &lst) const {
803 for (int i = 0; i < ca.nelements(); i++) {
804 IComponent *c = ca[i].get();
805 const auto *a = dynamic_cast<CompAssembly *>(c);
806 if (a)
807 appendPlottable(*a, lst);
808 else {
809 auto *d = dynamic_cast<Detector *>(c);
810 auto *o = dynamic_cast<ObjComponent *>(c);
811 if (d)
812 lst.emplace_back(IObjComponent_const_sptr(d, NoDeleting()));
813 else if (o)
814 lst.emplace_back(IObjComponent_const_sptr(o, NoDeleting()));
815 else
816 g_log.error() << "Unknown comp type\n";
817 }
818 }
819}
820
821//------------------------------------------------------------------------------------------------
830void Instrument::getInstrumentParameters(double &l1, Kernel::V3D &beamline, double &beamline_norm,
831 Kernel::V3D &samplePos) const {
832 // Get some positions
833 const IComponent_const_sptr sourceObj = this->getSource();
834 if (sourceObj == nullptr) {
835 throw Exception::InstrumentDefinitionError("Failed to get source component from instrument");
836 }
837 const Kernel::V3D sourcePos = sourceObj->getPos();
838 samplePos = this->getSample()->getPos();
839 beamline = samplePos - sourcePos;
840 beamline_norm = 2.0 * beamline.norm();
841
842 // Get the distance between the source and the sample (assume in metres)
843 IComponent_const_sptr sample = this->getSample();
844 try {
845 l1 = this->getSource()->getDistance(*sample);
846 } catch (Exception::NotFoundError &) {
847 throw Exception::InstrumentDefinitionError("Unable to calculate source-sample distance ", this->getName());
848 }
849}
850
851//--------------------------------------------------------------------------------------------
854void Instrument::setFilename(const std::string &filename) {
855 if (m_map)
856 m_instr->m_filename = filename;
857 else
858 m_filename = filename;
859}
860
863const std::string &Instrument::getFilename() const {
864 if (m_map)
865 return m_instr->getFilename();
866 else
867 return m_filename;
868}
869
871void Instrument::setXmlText(const std::string &XmlText) {
872 if (m_map)
873 m_instr->m_xmlText = XmlText;
874 else
875 m_xmlText = XmlText;
876}
877
879const std::string &Instrument::getXmlText() const {
880 if (m_map)
881 return m_instr->getXmlText();
882 else
883 return m_xmlText;
884}
885
886//--------------------------------------------------------------------------------------------
895void Instrument::saveNexus(Nexus::File *file, const std::string &group) const {
896 file->makeGroup(group, "NXinstrument", true);
897 file->putAttr("version", 1);
898
899 file->writeData("name", getName());
900
901 // XML contents of instrument, as a NX note
902 file->makeGroup("instrument_xml", "NXnote", true);
903 const std::string &xmlText = getXmlText();
904 if (xmlText.empty())
905 g_log.warning() << "Saving Instrument with no XML data. If this was "
906 "instrument data you may not be able to load this data "
907 "back into Mantid, for fitted/analysed data this "
908 "warning can be ignored.\n";
909 file->writeData("data", xmlText);
910 file->writeData("type", "text/xml"); // mimetype
911 file->writeData("description", "XML contents of the instrument IDF file.");
912 file->closeGroup();
913
914 // Now the parameter map, as a NXnote via its saveNexus method
915 if (isParametrized()) {
916 // Map with data extracted from DetectorInfo -> legacy compatible files.
917 const auto &params = makeLegacyParameterMap();
918 params->saveNexus(file, "instrument_parameter_map");
919 }
920
921 // Add physical detector and monitor data
922 auto detmonIDs = getDetectorIDs(false);
923 if (!detmonIDs.empty()) {
924 auto detectorIDs = getDetectorIDs(true);
925 // Add detectors group
926 file->makeGroup("physical_detectors", "NXdetector", true);
927 file->writeData("number_of_detectors", uint64_t(detectorIDs.size()));
928 saveDetectorSetInfoToNexus(file, detectorIDs);
929 file->closeGroup(); // detectors
930
931 // Create Monitor IDs vector
932 std::vector<detid_t> monitorIDs;
933 for (size_t i = 0; i < detmonIDs.size(); i++) {
934 if (isMonitorViaIndex(i))
935 monitorIDs.emplace_back(detmonIDs[i]);
936 }
937
938 // Add Monitors group
939 file->makeGroup("physical_monitors", "NXmonitor", true);
940 file->writeData("number_of_monitors", uint64_t(monitorIDs.size()));
941 saveDetectorSetInfoToNexus(file, monitorIDs);
942 file->closeGroup(); // monitors
943 }
944
945 file->closeGroup();
946}
947
948/* A private helper function so save information about a set of detectors to
949 * Nexus
950 * @param file :: open Nexus file ready to recieve the info about the set of
951 * detectors
952 * a group must be open that has only one call of this function.
953 * @param detIDs :: the dectector IDs of the detectors belonging to the set
954 */
955void Instrument::saveDetectorSetInfoToNexus(Nexus::File *file, const std::vector<detid_t> &detIDs) const {
956
957 size_t nDets = detIDs.size();
958 if (nDets == 0)
959 return;
960 auto detectors = getDetectors(detIDs);
961
963 Kernel::V3D sample_pos;
964 if (sample)
965 sample_pos = sample->getPos();
966
967 std::vector<double> a_angles(nDets);
968 std::vector<double> p_angles(nDets);
969 std::vector<double> distances(nDets);
970
971 for (size_t i = 0; i < nDets; i++) {
972 if (sample) {
973 Kernel::V3D pos = detectors[i]->getPos() - sample_pos;
974 pos.getSpherical(distances[i], p_angles[i], a_angles[i]);
975 } else {
976 a_angles[i] = detectors[i]->getPhi() * 180.0 / M_PI;
977 }
978 }
979 file->writeData("detector_number", detIDs);
980 file->writeData("azimuthal_angle", a_angles);
981 file->openData("azimuthal_angle");
982 file->putAttr("units", "degree");
983 file->closeData();
984 if (sample) {
985 file->writeData("polar_angle", p_angles);
986 file->openData("polar_angle");
987 file->putAttr("units", "degree");
988 file->closeData();
989 file->writeData("distance", distances);
990 file->openData("distance");
991 file->putAttr("units", "metre");
992 file->closeData();
993 }
994}
995
996//--------------------------------------------------------------------------------------------
1001void Instrument::loadNexus(Nexus::File *file, const std::string &group) {
1002 file->openGroup(group, "NXinstrument");
1003 file->closeGroup();
1004}
1005
1010void Instrument::setReferenceFrame(std::shared_ptr<ReferenceFrame> frame) { m_referenceFrame = std::move(frame); }
1011
1016std::shared_ptr<const ReferenceFrame> Instrument::getReferenceFrame() const {
1017 if (m_map) {
1018 return m_instr->getReferenceFrame();
1019 } else {
1020 return m_referenceFrame;
1021 }
1022}
1023
1032void Instrument::setDefaultView(const std::string &type) {
1033 std::string typeUC(type);
1034 std::transform(typeUC.begin(), typeUC.end(), typeUC.begin(), toupper);
1035 if (typeUC == "3D" || typeUC == "CYLINDRICAL_X" || typeUC == "CYLINDRICAL_Y" || typeUC == "CYLINDRICAL_Z" ||
1036 typeUC == "SPHERICAL_X" || typeUC == "SPHERICAL_Y" || typeUC == "SPHERICAL_Z") {
1037 m_defaultView = typeUC;
1038 } else {
1039 m_defaultView = "3D";
1040 g_log.warning() << type << " is not allowed as an instrument view type. Default to \"3D\"" << '\n';
1041 }
1042}
1043
1048void Instrument::setValidFromDate(const Types::Core::DateAndTime &val) {
1049 Types::Core::DateAndTime earliestAllowedDate("1900-01-31 23:59:01");
1050 if (val < earliestAllowedDate) {
1052 "The valid-from <instrument> tag date must be from 1900-01-31 23:59:01 "
1053 "or later",
1054 m_filename);
1055 }
1056 m_ValidFrom = val;
1057}
1058
1060 std::queue<IComponent_const_sptr> compQueue; // Search queue
1062
1063 bool foundRect = false;
1064 bool foundNonRect = false;
1065
1067
1068 while (!compQueue.empty() && !(foundRect && foundNonRect)) {
1069 comp = compQueue.front();
1070 compQueue.pop();
1071
1072 if (!validateComponentProperties(comp))
1073 continue;
1074
1075 if (dynamic_cast<const RectangularDetector *>(comp.get())) {
1076 foundRect = true;
1077 } // If component isn't a ComponentAssembly, we know it is a non-rectangular detector. Otherwise check its children
1078 else if (!addAssemblyChildrenToQueue(compQueue, comp)) {
1079 foundNonRect = true;
1080 }
1081 }
1082
1083 // Found both
1084 if (foundRect && foundNonRect)
1086 // Found only rectangular
1087 else if (foundRect)
1089 // Found only non-rectangular
1090 else
1092}
1093
1095 // Skip source, if has one
1096 if (m_sourceCache && m_sourceCache->getComponentID() == component->getComponentID())
1097 return false;
1098
1099 // Skip sample, if has one
1100 if (m_sampleCache && m_sampleCache->getComponentID() == component->getComponentID())
1101 return false;
1102
1103 // Skip monitors
1104 IDetector_const_sptr detector = std::dynamic_pointer_cast<const IDetector>(component);
1105 if (detector && isMonitor(detector->getID()))
1106 return false;
1107
1108 // skip choppers, slits and supermirrors - HACK!
1109 const auto &name = component->getName();
1110 if (name == "chopper-position" || name.substr(0, 4) == "slit" || name == "supermirror") {
1111 return false;
1112 }
1113
1114 return true;
1115}
1116
1117void Instrument::addInstrumentChildrenToQueue(std::queue<IComponent_const_sptr> &queue) const {
1118 // Add all the direct children of the instrument
1119 for (int i = 0; i < nelements(); i++)
1120 queue.push(getChild(i));
1121}
1122
1125bool Instrument::addAssemblyChildrenToQueue(std::queue<IComponent_const_sptr> &queue,
1126 IComponent_const_sptr component) const {
1127 if (auto const assembly = std::dynamic_pointer_cast<const ICompAssembly>(component)) {
1128 for (int i = 0; i < assembly->nelements(); i++)
1129 queue.push(assembly->getChild(i));
1130 return true;
1131 }
1132 return false;
1133}
1134
1136bool Instrument::isMonitorViaIndex(const size_t index) const {
1137 if (m_map)
1138 return std::get<2>(m_instr->m_detectorCache[index]);
1139 else
1140 return std::get<2>(m_detectorCache[index]);
1141}
1142
1143bool Instrument::isEmptyInstrument() const { return this->nelements() == 0; }
1144
1146size_t Instrument::detectorIndex(const detid_t detID) const {
1147 const auto &baseInstr = m_map ? *m_instr : *this;
1148 const auto it = find(baseInstr.m_detectorCache, detID);
1149 return std::distance(baseInstr.m_detectorCache.cbegin(), it);
1150}
1151
1154std::shared_ptr<ParameterMap> Instrument::makeLegacyParameterMap() const {
1155 auto pmap = std::make_shared<ParameterMap>(*getParameterMap());
1156 // Instrument is only needed for DetectorInfo access so it is not needed. This
1157 // also clears DetectorInfo and ComponentInfo (information will be stored
1158 // directly in pmap so we do not need them).
1159 pmap->setInstrument(nullptr);
1160
1161 const auto &baseInstr = m_map ? *m_instr : *this;
1162
1163 if (!getParameterMap()->hasComponentInfo(&baseInstr))
1164 return pmap;
1165
1166 // Tolerance 1e-9 m with rotation center at a distance of L = 1000 m as in
1167 // Beamline::DetectorInfo::isEquivalent.
1168 constexpr double d_max = 1e-9;
1169 constexpr double L = 1000.0;
1170 constexpr double safety_factor = 2.0;
1171 const double imag_norm_max = sin(d_max / (2.0 * L * safety_factor));
1172
1173 auto transformation = Eigen::Affine3d::Identity();
1174 int64_t oldParentIndex = -1;
1175
1176 const auto &componentInfo = getParameterMap()->componentInfo();
1177 const auto &detectorInfo = getParameterMap()->detectorInfo();
1178 for (size_t i = 0; i < componentInfo.size(); ++i) {
1179
1180 const int64_t parentIndex = componentInfo.parent(i);
1181 const bool makeTransform = parentIndex != oldParentIndex;
1182 bool isDetFixedInBank = false;
1183
1184 if (makeTransform) {
1185 oldParentIndex = parentIndex;
1186 const auto parentPos = toVector3d(componentInfo.position(parentIndex));
1187 const auto invParentRot = toQuaterniond(componentInfo.rotation(parentIndex)).conjugate();
1188
1189 transformation = invParentRot;
1190 transformation.translate(-parentPos);
1191 }
1192
1193 if (componentInfo.isDetector(i)) {
1194
1195 const std::shared_ptr<const IDetector> &baseDet = std::get<1>(baseInstr.m_detectorCache[i]);
1196
1197 isDetFixedInBank = ComponentInfoBankHelpers::isDetectorFixedInBank(componentInfo, i);
1198 if (detectorInfo.isMasked(i)) {
1199 pmap->forceUnsafeSetMasked(baseDet.get(), true);
1200 }
1201
1202 if (makeTransform) {
1203 // Special case: scaling for GridDetectorPixel.
1204 if (isDetFixedInBank) {
1205
1206 size_t panelIndex = componentInfo.parent(parentIndex);
1207 const auto panelID = componentInfo.componentID(panelIndex);
1208
1209 Eigen::Vector3d scale(1, 1, 1);
1210 if (auto scalex = pmap->get(panelID, "scalex"))
1211 scale[0] = 1.0 / scalex->value<double>();
1212 if (auto scaley = pmap->get(panelID, "scaley"))
1213 scale[1] = 1.0 / scaley->value<double>();
1214 transformation.prescale(scale);
1215 }
1216 }
1217 }
1218
1219 const auto componentId = componentInfo.componentID(i);
1220 const IComponent *baseComponent = componentId->getBaseComponent();
1221 // Generic sca scale factors
1222 const auto newScaleFactor = Kernel::toVector3d(componentInfo.scaleFactor(i));
1223 if ((newScaleFactor - toVector3d(baseComponent->getScaleFactor())).norm() >= 1e-9) {
1224 pmap->addV3D(componentId, ParameterMap::scale(), componentInfo.scaleFactor(i));
1225 }
1226
1227 // Undo parent transformation to obtain relative position/rotation.
1228 Eigen::Vector3d relPos = transformation * toVector3d(componentInfo.position(i));
1229 Eigen::Quaterniond relRot = toQuaterniond(componentInfo.relativeRotation(i));
1230
1231 // Tolerance 1e-9 m as in Beamline::DetectorInfo::isEquivalent.
1232 if ((relPos - toVector3d(baseComponent->getRelativePos())).norm() >= 1e-9) {
1233 if (isDetFixedInBank) {
1234 throw std::runtime_error(
1235 "Cannot create legacy ParameterMap: Position parameters for GridDetectorPixel are not supported");
1236 }
1237 pmap->addV3D(componentId, ParameterMap::pos(), Kernel::toV3D(relPos));
1238 }
1239 if ((relRot * toQuaterniond(baseComponent->getRelativeRot()).conjugate()).vec().norm() >= imag_norm_max) {
1240 pmap->addQuat(componentId, ParameterMap::rot(), Kernel::toQuat(relRot));
1241 }
1242 }
1243
1244 return pmap;
1245}
1246
1254 if (isParametrized())
1255 throw std::logic_error(
1256 "Instrument::parseTreeAndCacheBeamline must be called with the base instrument, not a parametrized instrument");
1258}
1259
1265std::pair<std::unique_ptr<ComponentInfo>, std::unique_ptr<DetectorInfo>>
1267 // If we have source and it has Beamline objects just copy them
1268 if (source && source->hasComponentInfo(this))
1269 return makeWrappers(pmap, source->componentInfo(), source->detectorInfo());
1270 // If pmap is empty and base instrument has Beamline objects just copy them
1271 if (pmap.empty() && m_componentInfo)
1273 // pmap not empty and/or no cached Beamline objects found
1274 return InstrumentVisitor::makeWrappers(*this, &pmap);
1275}
1276
1278std::pair<std::unique_ptr<ComponentInfo>, std::unique_ptr<DetectorInfo>>
1280 const DetectorInfo &detectorInfo) const {
1281 auto compInfo = componentInfo.cloneWithoutDetectorInfo();
1282 auto detInfo = std::make_unique<DetectorInfo>(detectorInfo);
1283 compInfo->m_componentInfo->setDetectorInfo(detInfo->m_detectorInfo.get());
1284 const auto parInstrument = ParComponentFactory::createInstrument(
1285 std::shared_ptr<const Instrument>(this, NoDeleting()), std::shared_ptr<ParameterMap>(&pmap, NoDeleting()));
1286 detInfo->m_instrument = parInstrument;
1287 return {std::move(compInfo), std::move(detInfo)};
1288}
1289
1290namespace Conversion {
1291
1300double tofToDSpacingFactor(const double l1, const double l2, const double twoTheta, const double offset) {
1301 return Kernel::Units::tofToDSpacingFactor(l1, l2, twoTheta, offset);
1302}
1303
1304double calculateDIFCCorrection(const double l1, const double l2, const double twoTheta, const double offset,
1305 const double binWidth) {
1306 return Kernel::Units::calculateDIFCCorrection(l1, l2, twoTheta, offset, binWidth);
1307}
1308
1309} // namespace Conversion
1310} // 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:48
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:316
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:319
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:279
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:204
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:305
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:299
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:329
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:271
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:275
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:51
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:332
std::shared_ptr< const Instrument > m_physicalInstrument
Pointer to the physical instrument, where this differs from the 'neutronic' one (indirect geometry)
Definition Instrument.h:323
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:308
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:326
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:311
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.
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
This functor is used as the deleter object of a shared_ptr to effectively erase ownership Raw pointer...
Definition IComponent.h:173
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