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
309bool Instrument::hasSource() const { return m_sourceCache; }
310
314bool Instrument::hasSample() const { return m_sampleCache; }
315
320 if (!m_sourceCache) {
321 g_log.warning("In Instrument::getSource(). No source has been set.");
323 } else if (m_map) {
324 auto sourceCache = static_cast<const Instrument *>(m_base)->m_sourceCache;
325 if (dynamic_cast<const ObjComponent *>(sourceCache))
326 return IComponent_const_sptr(new ObjComponent(sourceCache, m_map));
327 else if (dynamic_cast<const CompAssembly *>(sourceCache))
328 return IComponent_const_sptr(new CompAssembly(sourceCache, m_map));
329 else if (dynamic_cast<const Component *>(sourceCache))
330 return IComponent_const_sptr(new Component(sourceCache, m_map));
331 else {
332 g_log.error("In Instrument::getSource(). Source is not a recognised "
333 "component type.");
334 g_log.error("Try to assume it is a Component.");
335 return IComponent_const_sptr(new ObjComponent(sourceCache, m_map));
336 }
337 } else {
339 }
340}
341
346 if (!m_sampleCache) {
347 g_log.warning("In Instrument::getSamplePos(). No SamplePos has been set.");
349 } else if (m_map) {
350 auto sampleCache = static_cast<const Instrument *>(m_base)->m_sampleCache;
351 if (dynamic_cast<const ObjComponent *>(sampleCache))
352 return IComponent_const_sptr(new ObjComponent(sampleCache, m_map));
353 else if (dynamic_cast<const CompAssembly *>(sampleCache))
354 return IComponent_const_sptr(new CompAssembly(sampleCache, m_map));
355 else if (dynamic_cast<const Component *>(sampleCache))
356 return IComponent_const_sptr(new Component(sampleCache, m_map));
357 else {
358 g_log.error("In Instrument::getSamplePos(). SamplePos is not a "
359 "recognised component type.");
360 g_log.error("Try to assume it is a Component.");
361 return IComponent_const_sptr(new ObjComponent(sampleCache, m_map));
362 }
363 } else {
365 }
366}
367
373
374//------------------------------------------------------------------------------------------
379std::shared_ptr<const IComponent> Instrument::getComponentByID(const IComponent *id) const {
380 const auto *base = static_cast<const IComponent *>(id);
381 if (m_map)
382 return ParComponentFactory::create(std::shared_ptr<const IComponent>(base, NoDeleting()), m_map);
383 else
384 return std::shared_ptr<const IComponent>(base, NoDeleting());
385}
386
396std::vector<std::shared_ptr<const IComponent>> Instrument::getAllComponentsWithName(const std::string &cname) const {
397 std::shared_ptr<const IComponent> node = std::shared_ptr<const IComponent>(this, NoDeleting());
398 std::vector<std::shared_ptr<const IComponent>> retVec;
399 // Check the instrument name first
400 if (this->getName() == cname) {
401 retVec.emplace_back(node);
402 }
403 // Same algorithm as used in getComponentByName() but searching the full tree
404 std::deque<std::shared_ptr<const IComponent>> nodeQueue;
405 // Need to be able to enter the while loop
406 nodeQueue.emplace_back(node);
407 while (!nodeQueue.empty()) {
408 node = nodeQueue.front();
409 nodeQueue.pop_front();
410 int nchildren(0);
411 std::shared_ptr<const ICompAssembly> asmb = std::dynamic_pointer_cast<const ICompAssembly>(node);
412 if (asmb) {
413 nchildren = asmb->nelements();
414 }
415 for (int i = 0; i < nchildren; ++i) {
416 std::shared_ptr<const IComponent> comp = (*asmb)[i];
417 if (comp->getName() == cname) {
418 retVec.emplace_back(comp);
419 } else {
420 nodeQueue.emplace_back(comp);
421 }
422 }
423 } // while-end
424
425 // If we have reached here then the search failed
426 return retVec;
427}
428
429namespace {
430// Helpers for accessing m_detectorCache, which is a vector of tuples used as a
431// map. Lookup is by first element in a tuple. Templated to support const and
432// non-const.
433template <class T> auto lower_bound(T &map, const detid_t key) -> decltype(map.begin()) {
434 return std::lower_bound(map.begin(), map.end(), std::make_tuple(key, IDetector_const_sptr(nullptr), false),
435 [](const typename T::value_type &a, const typename T::value_type &b) -> bool {
436 return std::get<0>(a) < std::get<0>(b);
437 });
438}
439
440template <class T> auto find(T &map, const detid_t key) -> decltype(map.begin()) {
441 auto it = lower_bound(map, key);
442 if ((it != map.end()) && (std::get<0>(*it) == key))
443 return it;
444 return map.end();
445}
446} // namespace
447
459 const auto &baseInstr = m_map ? *m_instr : *this;
460 const auto it = find(baseInstr.m_detectorCache, detector_id);
461 if (it == baseInstr.m_detectorCache.end()) {
462 std::stringstream readInt;
463 readInt << detector_id;
464 throw Kernel::Exception::NotFoundError("Instrument: Detector with ID " + readInt.str() + " not found.", "");
465 }
466 IDetector_const_sptr baseDet = std::get<1>(*it);
467
468 if (!m_map)
469 return baseDet;
470
471 auto det = ParComponentFactory::createDetector(baseDet.get(), m_map);
472 return det;
473}
474
480const IDetector *Instrument::getBaseDetector(const detid_t &detector_id) const {
481 auto it = find(m_instr->m_detectorCache, detector_id);
482 if (it == m_instr->m_detectorCache.end()) {
483 return nullptr;
484 }
485 return std::get<1>(*it).get();
486}
487
488bool Instrument::isMonitor(const detid_t &detector_id) const {
489 const auto &baseInstr = m_map ? *m_instr : *this;
490 const auto it = find(baseInstr.m_detectorCache, detector_id);
491 if (it == baseInstr.m_detectorCache.end())
492 return false;
493 return std::get<2>(*it);
494}
495
496bool Instrument::isMonitor(const std::set<detid_t> &detector_ids) const {
497 if (detector_ids.empty())
498 return false;
499
500 return std::any_of(detector_ids.cbegin(), detector_ids.cend(),
501 [this](const auto detector_id) { return isMonitor(detector_id); });
502}
503
510IDetector_const_sptr Instrument::getDetectorG(const std::set<detid_t> &det_ids) const {
511 const size_t ndets(det_ids.size());
512 if (ndets == 1) {
513 return this->getDetector(*det_ids.begin());
514 } else {
515 std::shared_ptr<DetectorGroup> det_group = std::make_shared<DetectorGroup>();
516 for (const auto detID : det_ids) {
517 det_group->addDetector(this->getDetector(detID));
518 }
519 return det_group;
520 }
521}
522
527std::vector<IDetector_const_sptr> Instrument::getDetectors(const std::vector<detid_t> &det_ids) const {
528 std::vector<IDetector_const_sptr> dets_ptr;
529 dets_ptr.reserve(det_ids.size());
530 std::vector<detid_t>::const_iterator it;
531 for (it = det_ids.begin(); it != det_ids.end(); ++it) {
532 dets_ptr.emplace_back(this->getDetector(*it));
533 }
534 return dets_ptr;
535}
536
541std::vector<IDetector_const_sptr> Instrument::getDetectors(const std::set<detid_t> &det_ids) const {
542 std::vector<IDetector_const_sptr> dets_ptr;
543 dets_ptr.reserve(det_ids.size());
544 std::set<detid_t>::const_iterator it;
545 for (it = det_ids.begin(); it != det_ids.end(); ++it) {
546 dets_ptr.emplace_back(this->getDetector(*it));
547 }
548 return dets_ptr;
549}
550
562 if (m_map)
563 throw std::runtime_error("Instrument::markAsSamplePos() called on a "
564 "parametrized Instrument object.");
565
566 auto objComp = dynamic_cast<const IObjComponent *>(comp);
567 if (objComp) {
568 throw std::runtime_error("Instrument::markAsSamplePos() called on an IObjComponent "
569 "object that supports shape definition. Sample is prevented from "
570 "being this type because the shape must only be stored in "
571 "ExperimentInfo::m_sample.");
572 }
573
574 if (!m_sampleCache) {
575 if (comp->getName().empty()) {
576 throw Exception::InstrumentDefinitionError("The sample component is required to have a name.");
577 }
578 m_sampleCache = comp;
579 } else {
580 g_log.warning("Have already added samplePos component to the _sampleCache.");
581 }
582}
583
595 if (m_map)
596 throw std::runtime_error("Instrument::markAsSource() called on a "
597 "parametrized Instrument object.");
598
599 if (!m_sourceCache) {
600 if (comp->getName().empty()) {
601 throw Exception::InstrumentDefinitionError("The source component is required to have a name.");
602 }
603 m_sourceCache = comp;
604 } else {
605 g_log.warning("Have already added source component to the _sourceCache.");
606 }
607}
608
618 if (m_map)
619 throw std::runtime_error("Instrument::markAsDetector() called on a "
620 "parametrized Instrument object.");
621
622 // Create a (non-deleting) shared pointer to it
624 auto it = lower_bound(m_detectorCache, det->getID());
625 // Duplicate detector ids are forbidden
626 if ((it != m_detectorCache.end()) && (std::get<0>(*it) == det->getID())) {
627 raiseDuplicateDetectorError(det->getID());
628 }
629 bool isMonitorFlag = false;
630 m_detectorCache.emplace(it, det->getID(), det_sptr, isMonitorFlag);
631}
632
636 if (m_map)
637 throw std::runtime_error("Instrument::markAsDetector() called on a "
638 "parametrized Instrument object.");
639
640 // Create a (non-deleting) shared pointer to it
642 bool isMonitorFlag = false;
643 m_detectorCache.emplace_back(det->getID(), det_sptr, isMonitorFlag);
644}
645
649 // Detectors (even when different objects) are NOT allowed to have duplicate
650 // ids. This method establishes the presence of duplicates.
651 std::sort(
652 m_detectorCache.begin(), m_detectorCache.end(),
653 [](const std::tuple<detid_t, IDetector_const_sptr, bool> &a,
654 const std::tuple<detid_t, IDetector_const_sptr, bool> &b) -> bool { return std::get<0>(a) < std::get<0>(b); });
655
656 auto resultIt = std::adjacent_find(m_detectorCache.begin(), m_detectorCache.end(),
657 [](const std::tuple<detid_t, IDetector_const_sptr, bool> &a,
658 const std::tuple<detid_t, IDetector_const_sptr, bool> &b) -> bool {
659 return std::get<0>(a) == std::get<0>(b);
660 });
661 if (resultIt != m_detectorCache.end()) {
662 raiseDuplicateDetectorError(std::get<0>(*resultIt));
663 }
664}
665
675 if (m_map)
676 throw std::runtime_error("Instrument::markAsMonitor() called on a "
677 "parametrized Instrument object.");
678
679 // attempt to add monitor to instrument detector cache
680 markAsDetector(det);
681
682 // mark detector as a monitor
683 auto it = find(m_detectorCache, det->getID());
684 std::get<2>(*it) = true;
685}
686
692 if (m_map)
693 throw std::runtime_error("Instrument::removeDetector() called on a "
694 "parameterized Instrument object.");
695
696 const detid_t id = det->getID();
697 // Remove the detector from the detector cache
698 const auto it = find(m_detectorCache, id);
699 m_detectorCache.erase(it);
700
701 // Remove it from the parent assembly (and thus the instrument). Evilness
702 // required here unfortunately.
703 auto *parentAssembly = dynamic_cast<CompAssembly *>(const_cast<IComponent *>(det->getBareParent()));
704 if (parentAssembly) // Should always be true, but check just in case
705 {
706 parentAssembly->remove(det);
707 }
708}
709
713std::vector<detid_t> Instrument::getMonitors() const {
714 // Monitors cannot be parametrized. So just return the base.
715 if (m_map)
716 return m_instr->getMonitors();
717
718 std::vector<detid_t> mons;
719 for (const auto &item : m_detectorCache)
720 if (std::get<2>(item))
721 mons.emplace_back(std::get<0>(item));
722 return mons;
723}
724
730void Instrument::getBoundingBox(BoundingBox &assemblyBox) const {
731 if (m_map) {
732
733 if (m_map->hasComponentInfo(this->baseInstrument().get())) {
734 assemblyBox = m_map->componentInfo().boundingBox(index(), &assemblyBox);
735 return;
736 }
737
738 // Loop over the children and define a box large enough for all of them
739 ComponentID sourceID = getSource()->getComponentID();
740 assemblyBox = BoundingBox(); // this makes the instrument BB always axis aligned
741 int nchildren = nelements();
742 for (int i = 0; i < nchildren; ++i) {
743 IComponent_sptr comp = this->getChild(i);
744 if (comp && comp->getComponentID() != sourceID) {
745 BoundingBox compBox;
746 comp->getBoundingBox(compBox);
747 assemblyBox.grow(compBox);
748 }
749 }
750 } else {
751
752 if (!m_cachedBoundingBox) {
754 ComponentID sourceID = getSource()->getComponentID();
755 // Loop over the children and define a box large enough for all of them
756 for (const auto component : m_children) {
757 BoundingBox compBox;
758 if (component && component->getComponentID() != sourceID) {
759 component->getBoundingBox(compBox);
760 m_cachedBoundingBox->grow(compBox);
761 }
762 }
763 }
764 // Use cached box
765 assemblyBox = *m_cachedBoundingBox;
766 }
767}
768
769std::shared_ptr<const std::vector<IObjComponent_const_sptr>> Instrument::getPlottable() const {
770 if (m_map) {
771 // Get the 'base' plottable components
772 std::shared_ptr<const std::vector<IObjComponent_const_sptr>> objs = m_instr->getPlottable();
773
774 // Get a reference to the underlying vector, casting away the constness so
775 // that we
776 // can modify it to get our result rather than creating another long vector
777 auto &res = const_cast<std::vector<IObjComponent_const_sptr> &>(*objs);
778 const std::vector<IObjComponent_const_sptr>::size_type total = res.size();
779 for (std::vector<IObjComponent_const_sptr>::size_type i = 0; i < total; ++i) {
780 res[i] = std::dynamic_pointer_cast<const Detector>(ParComponentFactory::create(objs->at(i), m_map));
781 }
782 return objs;
783
784 } else {
785 // Base instrument
786 auto res = std::make_shared<std::vector<IObjComponent_const_sptr>>();
787 res->reserve(m_detectorCache.size() + 10);
788 appendPlottable(*this, *res);
789 return res;
790 }
791}
792
793void Instrument::appendPlottable(const CompAssembly &ca, std::vector<IObjComponent_const_sptr> &lst) const {
794 for (int i = 0; i < ca.nelements(); i++) {
795 IComponent *c = ca[i].get();
796 const auto *a = dynamic_cast<CompAssembly *>(c);
797 if (a)
798 appendPlottable(*a, lst);
799 else {
800 auto *d = dynamic_cast<Detector *>(c);
801 auto *o = dynamic_cast<ObjComponent *>(c);
802 if (d)
803 lst.emplace_back(IObjComponent_const_sptr(d, NoDeleting()));
804 else if (o)
805 lst.emplace_back(IObjComponent_const_sptr(o, NoDeleting()));
806 else
807 g_log.error() << "Unknown comp type\n";
808 }
809 }
810}
811
812//------------------------------------------------------------------------------------------------
821void Instrument::getInstrumentParameters(double &l1, Kernel::V3D &beamline, double &beamline_norm,
822 Kernel::V3D &samplePos) const {
823 // Get some positions
824 const IComponent_const_sptr sourceObj = this->getSource();
825 if (sourceObj == nullptr) {
826 throw Exception::InstrumentDefinitionError("Failed to get source component from instrument");
827 }
828 const Kernel::V3D sourcePos = sourceObj->getPos();
829 samplePos = this->getSample()->getPos();
830 beamline = samplePos - sourcePos;
831 beamline_norm = 2.0 * beamline.norm();
832
833 // Get the distance between the source and the sample (assume in metres)
834 IComponent_const_sptr sample = this->getSample();
835 try {
836 l1 = this->getSource()->getDistance(*sample);
837 } catch (Exception::NotFoundError &) {
838 throw Exception::InstrumentDefinitionError("Unable to calculate source-sample distance ", this->getName());
839 }
840}
841
842//--------------------------------------------------------------------------------------------
845void Instrument::setFilename(const std::string &filename) {
846 if (m_map)
847 m_instr->m_filename = filename;
848 else
849 m_filename = filename;
850}
851
854const std::string &Instrument::getFilename() const {
855 if (m_map)
856 return m_instr->getFilename();
857 else
858 return m_filename;
859}
860
862void Instrument::setXmlText(const std::string &XmlText) {
863 if (m_map)
864 m_instr->m_xmlText = XmlText;
865 else
866 m_xmlText = XmlText;
867}
868
870const std::string &Instrument::getXmlText() const {
871 if (m_map)
872 return m_instr->getXmlText();
873 else
874 return m_xmlText;
875}
876
877//--------------------------------------------------------------------------------------------
886void Instrument::saveNexus(Nexus::File *file, const std::string &group) const {
887 file->makeGroup(group, "NXinstrument", true);
888 file->putAttr("version", 1);
889
890 file->writeData("name", getName());
891
892 // XML contents of instrument, as a NX note
893 file->makeGroup("instrument_xml", "NXnote", true);
894 const std::string &xmlText = getXmlText();
895 if (xmlText.empty())
896 g_log.warning() << "Saving Instrument with no XML data. If this was "
897 "instrument data you may not be able to load this data "
898 "back into Mantid, for fitted/analysed data this "
899 "warning can be ignored.\n";
900 file->writeData("data", xmlText);
901 file->writeData("type", "text/xml"); // mimetype
902 file->writeData("description", "XML contents of the instrument IDF file.");
903 file->closeGroup();
904
905 // Now the parameter map, as a NXnote via its saveNexus method
906 if (isParametrized()) {
907 // Map with data extracted from DetectorInfo -> legacy compatible files.
908 const auto &params = makeLegacyParameterMap();
909 params->saveNexus(file, "instrument_parameter_map");
910 }
911
912 // Add physical detector and monitor data
913 auto detmonIDs = getDetectorIDs(false);
914 if (!detmonIDs.empty()) {
915 auto detectorIDs = getDetectorIDs(true);
916 // Add detectors group
917 file->makeGroup("physical_detectors", "NXdetector", true);
918 file->writeData("number_of_detectors", uint64_t(detectorIDs.size()));
919 saveDetectorSetInfoToNexus(file, detectorIDs);
920 file->closeGroup(); // detectors
921
922 // Create Monitor IDs vector
923 std::vector<detid_t> monitorIDs;
924 for (size_t i = 0; i < detmonIDs.size(); i++) {
925 if (isMonitorViaIndex(i))
926 monitorIDs.emplace_back(detmonIDs[i]);
927 }
928
929 // Add Monitors group
930 file->makeGroup("physical_monitors", "NXmonitor", true);
931 file->writeData("number_of_monitors", uint64_t(monitorIDs.size()));
932 saveDetectorSetInfoToNexus(file, monitorIDs);
933 file->closeGroup(); // monitors
934 }
935
936 file->closeGroup();
937}
938
939/* A private helper function so save information about a set of detectors to
940 * Nexus
941 * @param file :: open Nexus file ready to recieve the info about the set of
942 * detectors
943 * a group must be open that has only one call of this function.
944 * @param detIDs :: the dectector IDs of the detectors belonging to the set
945 */
946void Instrument::saveDetectorSetInfoToNexus(Nexus::File *file, const std::vector<detid_t> &detIDs) const {
947
948 size_t nDets = detIDs.size();
949 if (nDets == 0)
950 return;
951 auto detectors = getDetectors(detIDs);
952
954 Kernel::V3D sample_pos;
955 if (sample)
956 sample_pos = sample->getPos();
957
958 std::vector<double> a_angles(nDets);
959 std::vector<double> p_angles(nDets);
960 std::vector<double> distances(nDets);
961
962 for (size_t i = 0; i < nDets; i++) {
963 if (sample) {
964 Kernel::V3D pos = detectors[i]->getPos() - sample_pos;
965 pos.getSpherical(distances[i], p_angles[i], a_angles[i]);
966 } else {
967 a_angles[i] = detectors[i]->getPhi() * 180.0 / M_PI;
968 }
969 }
970 file->writeData("detector_number", detIDs);
971 file->writeData("azimuthal_angle", a_angles);
972 file->openData("azimuthal_angle");
973 file->putAttr("units", "degree");
974 file->closeData();
975 if (sample) {
976 file->writeData("polar_angle", p_angles);
977 file->openData("polar_angle");
978 file->putAttr("units", "degree");
979 file->closeData();
980 file->writeData("distance", distances);
981 file->openData("distance");
982 file->putAttr("units", "metre");
983 file->closeData();
984 }
985}
986
987//--------------------------------------------------------------------------------------------
992void Instrument::loadNexus(Nexus::File *file, const std::string &group) {
993 file->openGroup(group, "NXinstrument");
994 file->closeGroup();
995}
996
1001void Instrument::setReferenceFrame(std::shared_ptr<ReferenceFrame> frame) { m_referenceFrame = std::move(frame); }
1002
1007std::shared_ptr<const ReferenceFrame> Instrument::getReferenceFrame() const {
1008 if (m_map) {
1009 return m_instr->getReferenceFrame();
1010 } else {
1011 return m_referenceFrame;
1012 }
1013}
1014
1023void Instrument::setDefaultView(const std::string &type) {
1024 std::string typeUC(type);
1025 std::transform(typeUC.begin(), typeUC.end(), typeUC.begin(), toupper);
1026 if (typeUC == "3D" || typeUC == "CYLINDRICAL_X" || typeUC == "CYLINDRICAL_Y" || typeUC == "CYLINDRICAL_Z" ||
1027 typeUC == "SPHERICAL_X" || typeUC == "SPHERICAL_Y" || typeUC == "SPHERICAL_Z") {
1028 m_defaultView = typeUC;
1029 } else {
1030 m_defaultView = "3D";
1031 g_log.warning() << type << " is not allowed as an instrument view type. Default to \"3D\"" << '\n';
1032 }
1033}
1034
1039void Instrument::setValidFromDate(const Types::Core::DateAndTime &val) {
1040 Types::Core::DateAndTime earliestAllowedDate("1900-01-31 23:59:01");
1041 if (val < earliestAllowedDate) {
1043 "The valid-from <instrument> tag date must be from 1900-01-31 23:59:01 "
1044 "or later",
1045 m_filename);
1046 }
1047 m_ValidFrom = val;
1048}
1049
1051 std::queue<IComponent_const_sptr> compQueue; // Search queue
1053
1054 bool foundRect = false;
1055 bool foundNonRect = false;
1056
1058
1059 while (!compQueue.empty() && !(foundRect && foundNonRect)) {
1060 comp = compQueue.front();
1061 compQueue.pop();
1062
1063 if (!validateComponentProperties(comp))
1064 continue;
1065
1066 if (dynamic_cast<const RectangularDetector *>(comp.get())) {
1067 foundRect = true;
1068 } // If component isn't a ComponentAssembly, we know it is a non-rectangular detector. Otherwise check its children
1069 else if (!addAssemblyChildrenToQueue(compQueue, comp)) {
1070 foundNonRect = true;
1071 }
1072 }
1073
1074 // Found both
1075 if (foundRect && foundNonRect)
1077 // Found only rectangular
1078 else if (foundRect)
1080 // Found only non-rectangular
1081 else
1083}
1084
1086 // Skip source, if has one
1087 if (m_sourceCache && m_sourceCache->getComponentID() == component->getComponentID())
1088 return false;
1089
1090 // Skip sample, if has one
1091 if (m_sampleCache && m_sampleCache->getComponentID() == component->getComponentID())
1092 return false;
1093
1094 // Skip monitors
1095 IDetector_const_sptr detector = std::dynamic_pointer_cast<const IDetector>(component);
1096 if (detector && isMonitor(detector->getID()))
1097 return false;
1098
1099 // skip choppers, slits and supermirrors - HACK!
1100 const auto &name = component->getName();
1101 if (name == "chopper-position" || name.substr(0, 4) == "slit" || name == "supermirror") {
1102 return false;
1103 }
1104
1105 return true;
1106}
1107
1108void Instrument::addInstrumentChildrenToQueue(std::queue<IComponent_const_sptr> &queue) const {
1109 // Add all the direct children of the instrument
1110 for (int i = 0; i < nelements(); i++)
1111 queue.push(getChild(i));
1112}
1113
1116bool Instrument::addAssemblyChildrenToQueue(std::queue<IComponent_const_sptr> &queue,
1117 IComponent_const_sptr component) const {
1118 if (auto const assembly = std::dynamic_pointer_cast<const ICompAssembly>(component)) {
1119 for (int i = 0; i < assembly->nelements(); i++)
1120 queue.push(assembly->getChild(i));
1121 return true;
1122 }
1123 return false;
1124}
1125
1127bool Instrument::isMonitorViaIndex(const size_t index) const {
1128 if (m_map)
1129 return std::get<2>(m_instr->m_detectorCache[index]);
1130 else
1131 return std::get<2>(m_detectorCache[index]);
1132}
1133
1134bool Instrument::isEmptyInstrument() const { return this->nelements() == 0; }
1135
1137size_t Instrument::detectorIndex(const detid_t detID) const {
1138 const auto &baseInstr = m_map ? *m_instr : *this;
1139 const auto it = find(baseInstr.m_detectorCache, detID);
1140 return std::distance(baseInstr.m_detectorCache.cbegin(), it);
1141}
1142
1145std::shared_ptr<ParameterMap> Instrument::makeLegacyParameterMap() const {
1146 auto pmap = std::make_shared<ParameterMap>(*getParameterMap());
1147 // Instrument is only needed for DetectorInfo access so it is not needed. This
1148 // also clears DetectorInfo and ComponentInfo (information will be stored
1149 // directly in pmap so we do not need them).
1150 pmap->setInstrument(nullptr);
1151
1152 const auto &baseInstr = m_map ? *m_instr : *this;
1153
1154 if (!getParameterMap()->hasComponentInfo(&baseInstr))
1155 return pmap;
1156
1157 // Tolerance 1e-9 m with rotation center at a distance of L = 1000 m as in
1158 // Beamline::DetectorInfo::isEquivalent.
1159 constexpr double d_max = 1e-9;
1160 constexpr double L = 1000.0;
1161 constexpr double safety_factor = 2.0;
1162 const double imag_norm_max = sin(d_max / (2.0 * L * safety_factor));
1163
1164 auto transformation = Eigen::Affine3d::Identity();
1165 int64_t oldParentIndex = -1;
1166
1167 const auto &componentInfo = getParameterMap()->componentInfo();
1168 const auto &detectorInfo = getParameterMap()->detectorInfo();
1169 for (size_t i = 0; i < componentInfo.size(); ++i) {
1170
1171 const int64_t parentIndex = componentInfo.parent(i);
1172 const bool makeTransform = parentIndex != oldParentIndex;
1173 bool isDetFixedInBank = false;
1174
1175 if (makeTransform) {
1176 oldParentIndex = parentIndex;
1177 const auto parentPos = toVector3d(componentInfo.position(parentIndex));
1178 const auto invParentRot = toQuaterniond(componentInfo.rotation(parentIndex)).conjugate();
1179
1180 transformation = invParentRot;
1181 transformation.translate(-parentPos);
1182 }
1183
1184 if (componentInfo.isDetector(i)) {
1185
1186 const std::shared_ptr<const IDetector> &baseDet = std::get<1>(baseInstr.m_detectorCache[i]);
1187
1188 isDetFixedInBank = ComponentInfoBankHelpers::isDetectorFixedInBank(componentInfo, i);
1189 if (detectorInfo.isMasked(i)) {
1190 pmap->forceUnsafeSetMasked(baseDet.get(), true);
1191 }
1192
1193 if (makeTransform) {
1194 // Special case: scaling for GridDetectorPixel.
1195 if (isDetFixedInBank) {
1196
1197 size_t panelIndex = componentInfo.parent(parentIndex);
1198 const auto panelID = componentInfo.componentID(panelIndex);
1199
1200 Eigen::Vector3d scale(1, 1, 1);
1201 if (auto scalex = pmap->get(panelID, "scalex"))
1202 scale[0] = 1.0 / scalex->value<double>();
1203 if (auto scaley = pmap->get(panelID, "scaley"))
1204 scale[1] = 1.0 / scaley->value<double>();
1205 transformation.prescale(scale);
1206 }
1207 }
1208 }
1209
1210 const auto componentId = componentInfo.componentID(i);
1211 const IComponent *baseComponent = componentId->getBaseComponent();
1212 // Generic sca scale factors
1213 const auto newScaleFactor = Kernel::toVector3d(componentInfo.scaleFactor(i));
1214 if ((newScaleFactor - toVector3d(baseComponent->getScaleFactor())).norm() >= 1e-9) {
1215 pmap->addV3D(componentId, ParameterMap::scale(), componentInfo.scaleFactor(i));
1216 }
1217
1218 // Undo parent transformation to obtain relative position/rotation.
1219 Eigen::Vector3d relPos = transformation * toVector3d(componentInfo.position(i));
1220 Eigen::Quaterniond relRot = toQuaterniond(componentInfo.relativeRotation(i));
1221
1222 // Tolerance 1e-9 m as in Beamline::DetectorInfo::isEquivalent.
1223 if ((relPos - toVector3d(baseComponent->getRelativePos())).norm() >= 1e-9) {
1224 if (isDetFixedInBank) {
1225 throw std::runtime_error("Cannot create legacy ParameterMap: Position "
1226 "parameters for GridDetectorPixel are "
1227 "not supported");
1228 }
1229 pmap->addV3D(componentId, ParameterMap::pos(), Kernel::toV3D(relPos));
1230 }
1231 if ((relRot * toQuaterniond(baseComponent->getRelativeRot()).conjugate()).vec().norm() >= imag_norm_max) {
1232 pmap->addQuat(componentId, ParameterMap::rot(), Kernel::toQuat(relRot));
1233 }
1234 }
1235
1236 return pmap;
1237}
1238
1246 if (isParametrized())
1247 throw std::logic_error("Instrument::parseTreeAndCacheBeamline must be "
1248 "called with the base instrument, not a "
1249 "parametrized instrument");
1251}
1252
1258std::pair<std::unique_ptr<ComponentInfo>, std::unique_ptr<DetectorInfo>>
1260 // If we have source and it has Beamline objects just copy them
1261 if (source && source->hasComponentInfo(this))
1262 return makeWrappers(pmap, source->componentInfo(), source->detectorInfo());
1263 // If pmap is empty and base instrument has Beamline objects just copy them
1264 if (pmap.empty() && m_componentInfo)
1266 // pmap not empty and/or no cached Beamline objects found
1267 return InstrumentVisitor::makeWrappers(*this, &pmap);
1268}
1269
1271std::pair<std::unique_ptr<ComponentInfo>, std::unique_ptr<DetectorInfo>>
1273 const DetectorInfo &detectorInfo) const {
1274 auto compInfo = componentInfo.cloneWithoutDetectorInfo();
1275 auto detInfo = std::make_unique<DetectorInfo>(detectorInfo);
1276 compInfo->m_componentInfo->setDetectorInfo(detInfo->m_detectorInfo.get());
1277 const auto parInstrument = ParComponentFactory::createInstrument(
1278 std::shared_ptr<const Instrument>(this, NoDeleting()), std::shared_ptr<ParameterMap>(&pmap, NoDeleting()));
1279 detInfo->m_instrument = parInstrument;
1280 return {std::move(compInfo), std::move(detInfo)};
1281}
1282
1283namespace Conversion {
1284
1293double tofToDSpacingFactor(const double l1, const double l2, const double twoTheta, const double offset) {
1294 return Kernel::Units::tofToDSpacingFactor(l1, l2, twoTheta, offset);
1295}
1296
1297double calculateDIFCCorrection(const double l1, const double l2, const double twoTheta, const double offset,
1298 const double binWidth) {
1299 return Kernel::Units::calculateDIFCCorrection(l1, l2, twoTheta, offset, binWidth);
1300}
1301
1302} // namespace Conversion
1303} // 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:312
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:315
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:275
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:202
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:301
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:295
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:325
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:267
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:271
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:328
std::shared_ptr< const Instrument > m_physicalInstrument
Pointer to the physical instrument, where this differs from the 'neutronic' one (indirect geometry)
Definition Instrument.h:319
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:304
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:322
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:307
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