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
221std::vector<detid_t> Instrument::getMonitorIDs() const {
222 // Monitors cannot be parametrized. So just return the base.
223 if (m_map)
224 return m_instr->getMonitorIDs();
225
226 std::vector<detid_t> mons;
227 for (const auto &item : m_detectorCache)
228 if (std::get<2>(item))
229 mons.emplace_back(std::get<0>(item));
230 return mons;
231}
232
234std::size_t Instrument::getNumberDetectors(bool skipMonitors) const {
235 std::size_t numDetIDs(0);
236
237 if (m_map) {
238 numDetIDs = m_instr->m_detectorCache.size();
239 } else {
240 numDetIDs = m_detectorCache.size();
241 }
242
243 if (skipMonitors) // this slow, but gets the right answer
244 {
245 std::size_t monitors(0);
246 if (m_map) {
247 const auto &in_dets = m_instr->m_detectorCache;
248 monitors =
249 std::count_if(in_dets.cbegin(), in_dets.cend(), [](const auto &in_det) { return std::get<2>(in_det); });
250 } else {
251 const auto &in_dets = m_detectorCache;
252 monitors =
253 std::count_if(in_dets.cbegin(), in_dets.cend(), [](const auto &in_det) { return std::get<2>(in_det); });
254 }
255 return (numDetIDs - monitors);
256 } else {
257 return numDetIDs;
258 }
259}
260
267 const auto *in_dets = m_map ? &m_instr->m_detectorCache : &m_detectorCache;
268
269 if (in_dets->empty())
270 throw std::runtime_error("No detectors on this instrument. Can't find min/max ids");
271 // Maps are sorted by key. So it is easy to find
272 min = std::get<0>(*in_dets->begin());
273 max = std::get<0>(*in_dets->rbegin());
274}
275
285void Instrument::getDetectorsInBank(std::vector<IDetector_const_sptr> &dets, const IComponent &comp) const {
286 const auto bank = dynamic_cast<const ICompAssembly *>(&comp);
287 if (bank) {
288 // Get a vector of children (recursively)
289 std::vector<std::shared_ptr<const IComponent>> children;
290 bank->getChildren(children, true);
291 std::vector<std::shared_ptr<const IComponent>>::iterator it;
292 for (it = children.begin(); it != children.end(); ++it) {
293 IDetector_const_sptr det = std::dynamic_pointer_cast<const IDetector>(*it);
294 if (det) {
295 dets.emplace_back(det);
296 }
297 }
298 }
299}
300
311void Instrument::getDetectorsInBank(std::vector<IDetector_const_sptr> &dets, const std::string &bankName) const {
312 std::shared_ptr<const IComponent> comp = this->getComponentByName(bankName);
313 if (!comp) {
314 throw Kernel::Exception::NotFoundError("Instrument: Could not find component", bankName);
315 }
316 getDetectorsInBank(dets, *comp);
317}
318
319std::set<detid_t> Instrument::getDetectorIDsInBank(const std::string &bankName) const {
320 std::set<detid_t> detIDs;
321 std::vector<IDetector_const_sptr> detectors;
322 getDetectorsInBank(detectors, bankName);
323
324 for (const auto &det : detectors) {
325 detIDs.emplace(det->getID());
326 }
327 return detIDs;
328}
329
333bool Instrument::hasSource() const { return m_sourceCache; }
334
338bool Instrument::hasSample() const { return m_sampleCache; }
339
344 if (!m_sourceCache) {
345 g_log.warning("In Instrument::getSource(). No source has been set.");
347 } else if (m_map) {
348 auto sourceCache = static_cast<const Instrument *>(m_base)->m_sourceCache;
349 if (dynamic_cast<const ObjComponent *>(sourceCache))
350 return IComponent_const_sptr(new ObjComponent(sourceCache, m_map));
351 else if (dynamic_cast<const CompAssembly *>(sourceCache))
352 return IComponent_const_sptr(new CompAssembly(sourceCache, m_map));
353 else if (dynamic_cast<const Component *>(sourceCache))
354 return IComponent_const_sptr(new Component(sourceCache, m_map));
355 else {
356 g_log.error("In Instrument::getSource(). Source is not a recognised "
357 "component type.");
358 g_log.error("Try to assume it is a Component.");
359 return IComponent_const_sptr(new ObjComponent(sourceCache, m_map));
360 }
361 } else {
363 }
364}
365
370 if (!m_sampleCache) {
371 g_log.warning("In Instrument::getSamplePos(). No SamplePos has been set.");
373 } else if (m_map) {
374 auto sampleCache = static_cast<const Instrument *>(m_base)->m_sampleCache;
375 if (dynamic_cast<const ObjComponent *>(sampleCache))
376 return IComponent_const_sptr(new ObjComponent(sampleCache, m_map));
377 else if (dynamic_cast<const CompAssembly *>(sampleCache))
378 return IComponent_const_sptr(new CompAssembly(sampleCache, m_map));
379 else if (dynamic_cast<const Component *>(sampleCache))
380 return IComponent_const_sptr(new Component(sampleCache, m_map));
381 else {
382 g_log.error("In Instrument::getSamplePos(). SamplePos is not a "
383 "recognised component type.");
384 g_log.error("Try to assume it is a Component.");
385 return IComponent_const_sptr(new ObjComponent(sampleCache, m_map));
386 }
387 } else {
389 }
390}
391
397
398//------------------------------------------------------------------------------------------
403std::shared_ptr<const IComponent> Instrument::getComponentByID(const IComponent *id) const {
404 const auto *base = static_cast<const IComponent *>(id);
405 if (m_map)
406 return ParComponentFactory::create(std::shared_ptr<const IComponent>(base, NoDeleting()), m_map);
407 else
408 return std::shared_ptr<const IComponent>(base, NoDeleting());
409}
410
420std::vector<std::shared_ptr<const IComponent>> Instrument::getAllComponentsWithName(const std::string &cname) const {
421 std::shared_ptr<const IComponent> node = std::shared_ptr<const IComponent>(this, NoDeleting());
422 std::vector<std::shared_ptr<const IComponent>> retVec;
423 // Check the instrument name first
424 if (this->getName() == cname) {
425 retVec.emplace_back(node);
426 }
427 // Same algorithm as used in getComponentByName() but searching the full tree
428 std::deque<std::shared_ptr<const IComponent>> nodeQueue;
429 // Need to be able to enter the while loop
430 nodeQueue.emplace_back(node);
431 while (!nodeQueue.empty()) {
432 node = nodeQueue.front();
433 nodeQueue.pop_front();
434 int nchildren(0);
435 std::shared_ptr<const ICompAssembly> asmb = std::dynamic_pointer_cast<const ICompAssembly>(node);
436 if (asmb) {
437 nchildren = asmb->nelements();
438 }
439 for (int i = 0; i < nchildren; ++i) {
440 std::shared_ptr<const IComponent> comp = (*asmb)[i];
441 if (comp->getName() == cname) {
442 retVec.emplace_back(comp);
443 } else {
444 nodeQueue.emplace_back(comp);
445 }
446 }
447 } // while-end
448
449 // If we have reached here then the search failed
450 return retVec;
451}
452
453namespace {
454// Helpers for accessing m_detectorCache, which is a vector of tuples used as a
455// map. Lookup is by first element in a tuple. Templated to support const and
456// non-const.
457template <class T> auto lower_bound(T &map, const detid_t key) -> decltype(map.begin()) {
458 return std::lower_bound(map.begin(), map.end(), std::make_tuple(key, IDetector_const_sptr(nullptr), false),
459 [](const typename T::value_type &a, const typename T::value_type &b) -> bool {
460 return std::get<0>(a) < std::get<0>(b);
461 });
462}
463
464template <class T> auto find(T &map, const detid_t key) -> decltype(map.begin()) {
465 auto it = lower_bound(map, key);
466 if ((it != map.end()) && (std::get<0>(*it) == key))
467 return it;
468 return map.end();
469}
470} // namespace
471
483 const auto &baseInstr = m_map ? *m_instr : *this;
484 const auto it = find(baseInstr.m_detectorCache, detector_id);
485 if (it == baseInstr.m_detectorCache.end()) {
486 std::stringstream readInt;
487 readInt << detector_id;
488 throw Kernel::Exception::NotFoundError("Instrument: Detector with ID " + readInt.str() + " not found.", "");
489 }
490 IDetector_const_sptr baseDet = std::get<1>(*it);
491
492 if (!m_map)
493 return baseDet;
494
495 auto det = ParComponentFactory::createDetector(baseDet.get(), m_map);
496 return det;
497}
498
504const IDetector *Instrument::getBaseDetector(const detid_t &detector_id) const {
505 auto it = find(m_instr->m_detectorCache, detector_id);
506 if (it == m_instr->m_detectorCache.end()) {
507 return nullptr;
508 }
509 return std::get<1>(*it).get();
510}
511
512bool Instrument::isMonitor(const detid_t &detector_id) const {
513 const auto &baseInstr = m_map ? *m_instr : *this;
514 const auto it = find(baseInstr.m_detectorCache, detector_id);
515 if (it == baseInstr.m_detectorCache.end())
516 return false;
517 return std::get<2>(*it);
518}
519
520bool Instrument::isMonitor(const std::set<detid_t> &detector_ids) const {
521 if (detector_ids.empty())
522 return false;
523
524 return std::any_of(detector_ids.cbegin(), detector_ids.cend(),
525 [this](const auto detector_id) { return isMonitor(detector_id); });
526}
527
534IDetector_const_sptr Instrument::getDetectorG(const std::set<detid_t> &det_ids) const {
535 const size_t ndets(det_ids.size());
536 if (ndets == 1) {
537 return this->getDetector(*det_ids.begin());
538 } else {
539 std::shared_ptr<DetectorGroup> det_group = std::make_shared<DetectorGroup>();
540 for (const auto detID : det_ids) {
541 det_group->addDetector(this->getDetector(detID));
542 }
543 return det_group;
544 }
545}
546
551std::vector<IDetector_const_sptr> Instrument::getDetectors(const std::vector<detid_t> &det_ids) const {
552 std::vector<IDetector_const_sptr> dets_ptr;
553 dets_ptr.reserve(det_ids.size());
554 std::vector<detid_t>::const_iterator it;
555 for (it = det_ids.begin(); it != det_ids.end(); ++it) {
556 dets_ptr.emplace_back(this->getDetector(*it));
557 }
558 return dets_ptr;
559}
560
565std::vector<IDetector_const_sptr> Instrument::getDetectors(const std::set<detid_t> &det_ids) const {
566 std::vector<IDetector_const_sptr> dets_ptr;
567 dets_ptr.reserve(det_ids.size());
568 std::set<detid_t>::const_iterator it;
569 for (it = det_ids.begin(); it != det_ids.end(); ++it) {
570 dets_ptr.emplace_back(this->getDetector(*it));
571 }
572 return dets_ptr;
573}
574
586 if (m_map)
587 throw std::runtime_error("Instrument::markAsSamplePos() called on a "
588 "parametrized Instrument object.");
589
590 auto objComp = dynamic_cast<const IObjComponent *>(comp);
591 if (objComp) {
592 throw std::runtime_error("Instrument::markAsSamplePos() called on an IObjComponent "
593 "object that supports shape definition. Sample is prevented from "
594 "being this type because the shape must only be stored in "
595 "ExperimentInfo::m_sample.");
596 }
597
598 if (!m_sampleCache) {
599 if (comp->getName().empty()) {
600 throw Exception::InstrumentDefinitionError("The sample component is required to have a name.");
601 }
602 m_sampleCache = comp;
603 } else {
604 g_log.warning("Have already added samplePos component to the _sampleCache.");
605 }
606}
607
619 if (m_map)
620 throw std::runtime_error("Instrument::markAsSource() called on a "
621 "parametrized Instrument object.");
622
623 if (!m_sourceCache) {
624 if (comp->getName().empty()) {
625 throw Exception::InstrumentDefinitionError("The source component is required to have a name.");
626 }
627 m_sourceCache = comp;
628 } else {
629 g_log.warning("Have already added source component to the _sourceCache.");
630 }
631}
632
642 if (m_map)
643 throw std::runtime_error("Instrument::markAsDetector() called on a "
644 "parametrized Instrument object.");
645
646 // Create a (non-deleting) shared pointer to it
648 auto it = lower_bound(m_detectorCache, det->getID());
649 // Duplicate detector ids are forbidden
650 if ((it != m_detectorCache.end()) && (std::get<0>(*it) == det->getID())) {
651 raiseDuplicateDetectorError(det->getID());
652 }
653 bool isMonitorFlag = false;
654 m_detectorCache.emplace(it, det->getID(), det_sptr, isMonitorFlag);
655}
656
660 if (m_map)
661 throw std::runtime_error("Instrument::markAsDetector() called on a "
662 "parametrized Instrument object.");
663
664 // Create a (non-deleting) shared pointer to it
666 bool isMonitorFlag = false;
667 m_detectorCache.emplace_back(det->getID(), det_sptr, isMonitorFlag);
668}
669
673 // Detectors (even when different objects) are NOT allowed to have duplicate
674 // ids. This method establishes the presence of duplicates.
675 std::sort(
676 m_detectorCache.begin(), m_detectorCache.end(),
677 [](const std::tuple<detid_t, IDetector_const_sptr, bool> &a,
678 const std::tuple<detid_t, IDetector_const_sptr, bool> &b) -> bool { return std::get<0>(a) < std::get<0>(b); });
679
680 auto resultIt = std::adjacent_find(m_detectorCache.begin(), m_detectorCache.end(),
681 [](const std::tuple<detid_t, IDetector_const_sptr, bool> &a,
682 const std::tuple<detid_t, IDetector_const_sptr, bool> &b) -> bool {
683 return std::get<0>(a) == std::get<0>(b);
684 });
685 if (resultIt != m_detectorCache.end()) {
686 raiseDuplicateDetectorError(std::get<0>(*resultIt));
687 }
688}
689
699 if (m_map)
700 throw std::runtime_error("Instrument::markAsMonitor() called on a "
701 "parametrized Instrument object.");
702
703 // attempt to add monitor to instrument detector cache
704 markAsDetector(det);
705
706 // mark detector as a monitor
707 auto it = find(m_detectorCache, det->getID());
708 std::get<2>(*it) = true;
709}
710
716 if (m_map)
717 throw std::runtime_error("Instrument::removeDetector() called on a "
718 "parameterized Instrument object.");
719
720 const detid_t id = det->getID();
721 // Remove the detector from the detector cache
722 const auto it = find(m_detectorCache, id);
723 m_detectorCache.erase(it);
724
725 // Remove it from the parent assembly (and thus the instrument). Evilness
726 // required here unfortunately.
727 auto *parentAssembly = dynamic_cast<CompAssembly *>(const_cast<IComponent *>(det->getBareParent()));
728 if (parentAssembly) // Should always be true, but check just in case
729 {
730 parentAssembly->remove(det);
731 }
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 data
922 auto detectorIDs = getDetectorIDs(true);
923 if (!detectorIDs.empty()) {
924 // Add detectors group
925 file->makeGroup("physical_detectors", "NXdetector", true);
926 file->writeData("number_of_detectors", uint64_t(detectorIDs.size()));
927 saveDetectorSetInfoToNexus(file, detectorIDs);
928 file->closeGroup(); // detectors
929 }
930
931 // Add monitor data
932 auto monitorIDs = getMonitorIDs();
933 if (!monitorIDs.empty()) {
934 // Add Monitors group
935 file->makeGroup("physical_monitors", "NXmonitor", true);
936 file->writeData("number_of_monitors", uint64_t(monitorIDs.size()));
937 saveDetectorSetInfoToNexus(file, monitorIDs);
938 file->closeGroup(); // monitors
939 }
940
941 file->closeGroup();
942}
943
944/* A private helper function so save information about a set of detectors to
945 * Nexus
946 * @param file :: open Nexus file ready to recieve the info about the set of
947 * detectors
948 * a group must be open that has only one call of this function.
949 * @param detIDs :: the dectector IDs of the detectors belonging to the set
950 */
951void Instrument::saveDetectorSetInfoToNexus(Nexus::File *file, const std::vector<detid_t> &detIDs) const {
952
953 size_t nDets = detIDs.size();
954 if (nDets == 0)
955 return;
956 auto detectors = getDetectors(detIDs);
957
959 Kernel::V3D sample_pos;
960 if (sample)
961 sample_pos = sample->getPos();
962
963 std::vector<double> a_angles(nDets);
964 std::vector<double> p_angles(nDets);
965 std::vector<double> distances(nDets);
966
967 for (size_t i = 0; i < nDets; i++) {
968 if (sample) {
969 Kernel::V3D pos = detectors[i]->getPos() - sample_pos;
970 pos.getSpherical(distances[i], p_angles[i], a_angles[i]);
971 } else {
972 a_angles[i] = detectors[i]->getPhi() * 180.0 / M_PI;
973 }
974 }
975 file->writeData("detector_number", detIDs);
976 file->writeData("azimuthal_angle", a_angles);
977 file->openData("azimuthal_angle");
978 file->putAttr("units", "degree");
979 file->closeData();
980 if (sample) {
981 file->writeData("polar_angle", p_angles);
982 file->openData("polar_angle");
983 file->putAttr("units", "degree");
984 file->closeData();
985 file->writeData("distance", distances);
986 file->openData("distance");
987 file->putAttr("units", "metre");
988 file->closeData();
989 }
990}
991
992//--------------------------------------------------------------------------------------------
997void Instrument::loadNexus(Nexus::File *file, const std::string &group) {
998 file->openGroup(group, "NXinstrument");
999 file->closeGroup();
1000}
1001
1006void Instrument::setReferenceFrame(std::shared_ptr<ReferenceFrame> frame) { m_referenceFrame = std::move(frame); }
1007
1012std::shared_ptr<const ReferenceFrame> Instrument::getReferenceFrame() const {
1013 if (m_map) {
1014 return m_instr->getReferenceFrame();
1015 } else {
1016 return m_referenceFrame;
1017 }
1018}
1019
1028void Instrument::setDefaultView(const std::string &type) {
1029 std::string typeUC(type);
1030 std::transform(typeUC.begin(), typeUC.end(), typeUC.begin(), toupper);
1031 if (typeUC == "3D" || typeUC == "CYLINDRICAL_X" || typeUC == "CYLINDRICAL_Y" || typeUC == "CYLINDRICAL_Z" ||
1032 typeUC == "SPHERICAL_X" || typeUC == "SPHERICAL_Y" || typeUC == "SPHERICAL_Z") {
1033 m_defaultView = typeUC;
1034 } else {
1035 m_defaultView = "3D";
1036 g_log.warning() << type << " is not allowed as an instrument view type. Default to \"3D\"" << '\n';
1037 }
1038}
1039
1044void Instrument::setValidFromDate(const Types::Core::DateAndTime &val) {
1045 Types::Core::DateAndTime earliestAllowedDate("1900-01-31 23:59:01");
1046 if (val < earliestAllowedDate) {
1048 "The valid-from <instrument> tag date must be from 1900-01-31 23:59:01 "
1049 "or later",
1050 m_filename);
1051 }
1052 m_ValidFrom = val;
1053}
1054
1056 std::queue<IComponent_const_sptr> compQueue; // Search queue
1058
1059 bool foundRect = false;
1060 bool foundNonRect = false;
1061
1063
1064 while (!compQueue.empty() && !(foundRect && foundNonRect)) {
1065 comp = compQueue.front();
1066 compQueue.pop();
1067
1068 if (!validateComponentProperties(comp))
1069 continue;
1070
1071 if (dynamic_cast<const RectangularDetector *>(comp.get())) {
1072 foundRect = true;
1073 } // If component isn't a ComponentAssembly, we know it is a non-rectangular detector. Otherwise check its children
1074 else if (!addAssemblyChildrenToQueue(compQueue, comp)) {
1075 foundNonRect = true;
1076 }
1077 }
1078
1079 // Found both
1080 if (foundRect && foundNonRect)
1082 // Found only rectangular
1083 else if (foundRect)
1085 // Found only non-rectangular
1086 else
1088}
1089
1091 // Skip source, if has one
1092 if (m_sourceCache && m_sourceCache->getComponentID() == component->getComponentID())
1093 return false;
1094
1095 // Skip sample, if has one
1096 if (m_sampleCache && m_sampleCache->getComponentID() == component->getComponentID())
1097 return false;
1098
1099 // Skip monitors
1100 IDetector_const_sptr detector = std::dynamic_pointer_cast<const IDetector>(component);
1101 if (detector && isMonitor(detector->getID()))
1102 return false;
1103
1104 // skip choppers, slits and supermirrors - HACK!
1105 const auto &name = component->getName();
1106 if (name == "chopper-position" || name.substr(0, 4) == "slit" || name == "supermirror") {
1107 return false;
1108 }
1109
1110 return true;
1111}
1112
1113void Instrument::addInstrumentChildrenToQueue(std::queue<IComponent_const_sptr> &queue) const {
1114 // Add all the direct children of the instrument
1115 for (int i = 0; i < nelements(); i++)
1116 queue.push(getChild(i));
1117}
1118
1121bool Instrument::addAssemblyChildrenToQueue(std::queue<IComponent_const_sptr> &queue,
1122 IComponent_const_sptr component) const {
1123 if (auto const assembly = std::dynamic_pointer_cast<const ICompAssembly>(component)) {
1124 for (int i = 0; i < assembly->nelements(); i++)
1125 queue.push(assembly->getChild(i));
1126 return true;
1127 }
1128 return false;
1129}
1130
1132bool Instrument::isMonitorViaIndex(const size_t index) const {
1133 if (m_map)
1134 return std::get<2>(m_instr->m_detectorCache[index]);
1135 else
1136 return std::get<2>(m_detectorCache[index]);
1137}
1138
1139bool Instrument::isEmptyInstrument() const { return this->nelements() == 0; }
1140
1142size_t Instrument::detectorIndex(const detid_t detID) const {
1143 const auto &baseInstr = m_map ? *m_instr : *this;
1144 const auto it = find(baseInstr.m_detectorCache, detID);
1145 return std::distance(baseInstr.m_detectorCache.cbegin(), it);
1146}
1147
1150std::shared_ptr<ParameterMap> Instrument::makeLegacyParameterMap() const {
1151 auto pmap = std::make_shared<ParameterMap>(*getParameterMap());
1152 // Instrument is only needed for DetectorInfo access so it is not needed. This
1153 // also clears DetectorInfo and ComponentInfo (information will be stored
1154 // directly in pmap so we do not need them).
1155 pmap->setInstrument(nullptr);
1156
1157 const auto &baseInstr = m_map ? *m_instr : *this;
1158
1159 if (!getParameterMap()->hasComponentInfo(&baseInstr))
1160 return pmap;
1161
1162 // Tolerance 1e-9 m with rotation center at a distance of L = 1000 m as in
1163 // Beamline::DetectorInfo::isEquivalent.
1164 constexpr double d_max = 1e-9;
1165 constexpr double L = 1000.0;
1166 constexpr double safety_factor = 2.0;
1167 const double imag_norm_max = sin(d_max / (2.0 * L * safety_factor));
1168
1169 auto transformation = Eigen::Affine3d::Identity();
1170 int64_t oldParentIndex = -1;
1171
1172 const auto &componentInfo = getParameterMap()->componentInfo();
1173 const auto &detectorInfo = getParameterMap()->detectorInfo();
1174 for (size_t i = 0; i < componentInfo.size(); ++i) {
1175
1176 const int64_t parentIndex = componentInfo.parent(i);
1177 const bool makeTransform = parentIndex != oldParentIndex;
1178 bool isDetFixedInBank = false;
1179
1180 if (makeTransform) {
1181 oldParentIndex = parentIndex;
1182 const auto parentPos = toVector3d(componentInfo.position(parentIndex));
1183 const auto invParentRot = toQuaterniond(componentInfo.rotation(parentIndex)).conjugate();
1184
1185 transformation = invParentRot;
1186 transformation.translate(-parentPos);
1187 }
1188
1189 if (componentInfo.isDetector(i)) {
1190
1191 const std::shared_ptr<const IDetector> &baseDet = std::get<1>(baseInstr.m_detectorCache[i]);
1192
1193 isDetFixedInBank = ComponentInfoBankHelpers::isDetectorFixedInBank(componentInfo, i);
1194 if (detectorInfo.isMasked(i)) {
1195 pmap->forceUnsafeSetMasked(baseDet.get(), true);
1196 }
1197
1198 if (makeTransform) {
1199 // Special case: scaling for GridDetectorPixel.
1200 if (isDetFixedInBank) {
1201
1202 size_t panelIndex = componentInfo.parent(parentIndex);
1203 const auto panelID = componentInfo.componentID(panelIndex);
1204
1205 Eigen::Vector3d scale(1, 1, 1);
1206 if (auto scalex = pmap->get(panelID, "scalex"))
1207 scale[0] = 1.0 / scalex->value<double>();
1208 if (auto scaley = pmap->get(panelID, "scaley"))
1209 scale[1] = 1.0 / scaley->value<double>();
1210 transformation.prescale(scale);
1211 }
1212 }
1213 }
1214
1215 const auto componentId = componentInfo.componentID(i);
1216 const IComponent *baseComponent = componentId->getBaseComponent();
1217 // Generic sca scale factors
1218 const auto newScaleFactor = Kernel::toVector3d(componentInfo.scaleFactor(i));
1219 if ((newScaleFactor - toVector3d(baseComponent->getScaleFactor())).norm() >= 1e-9) {
1220 pmap->addV3D(componentId, ParameterMap::scale(), componentInfo.scaleFactor(i));
1221 }
1222
1223 // Undo parent transformation to obtain relative position/rotation.
1224 Eigen::Vector3d relPos = transformation * toVector3d(componentInfo.position(i));
1225 Eigen::Quaterniond relRot = toQuaterniond(componentInfo.relativeRotation(i));
1226
1227 // Tolerance 1e-9 m as in Beamline::DetectorInfo::isEquivalent.
1228 if ((relPos - toVector3d(baseComponent->getRelativePos())).norm() >= 1e-9) {
1229 if (isDetFixedInBank) {
1230 throw std::runtime_error(
1231 "Cannot create legacy ParameterMap: Position parameters for GridDetectorPixel are not supported");
1232 }
1233 pmap->addV3D(componentId, ParameterMap::pos(), Kernel::toV3D(relPos));
1234 }
1235 if ((relRot * toQuaterniond(baseComponent->getRelativeRot()).conjugate()).vec().norm() >= imag_norm_max) {
1236 pmap->addQuat(componentId, ParameterMap::rot(), Kernel::toQuat(relRot));
1237 }
1238 }
1239
1240 return pmap;
1241}
1242
1250 if (isParametrized())
1251 throw std::logic_error(
1252 "Instrument::parseTreeAndCacheBeamline must be called with the base instrument, not a parametrized instrument");
1254}
1255
1261std::pair<std::unique_ptr<ComponentInfo>, std::unique_ptr<DetectorInfo>>
1263 // If we have source and it has Beamline objects just copy them
1264 if (source && source->hasComponentInfo(this))
1265 return makeWrappers(pmap, source->componentInfo(), source->detectorInfo());
1266 // If pmap is empty and base instrument has Beamline objects just copy them
1267 if (pmap.empty() && m_componentInfo)
1269 // pmap not empty and/or no cached Beamline objects found
1270 return InstrumentVisitor::makeWrappers(*this, &pmap);
1271}
1272
1274std::pair<std::unique_ptr<ComponentInfo>, std::unique_ptr<DetectorInfo>>
1276 const DetectorInfo &detectorInfo) const {
1277 auto compInfo = componentInfo.cloneWithoutDetectorInfo();
1278 auto detInfo = std::make_unique<DetectorInfo>(detectorInfo);
1279 compInfo->m_componentInfo->setDetectorInfo(detInfo->m_detectorInfo.get());
1280 const auto parInstrument = ParComponentFactory::createInstrument(
1281 std::shared_ptr<const Instrument>(this, NoDeleting()), std::shared_ptr<ParameterMap>(&pmap, NoDeleting()));
1282 detInfo->m_instrument = parInstrument;
1283 return {std::move(compInfo), std::move(detInfo)};
1284}
1285
1286namespace Conversion {
1287
1296double tofToDSpacingFactor(const double l1, const double l2, const double twoTheta, const double offset) {
1297 return Kernel::Units::tofToDSpacingFactor(l1, l2, twoTheta, offset);
1298}
1299
1300double calculateDIFCCorrection(const double l1, const double l2, const double twoTheta, const double offset,
1301 const double binWidth) {
1302 return Kernel::Units::calculateDIFCCorrection(l1, l2, twoTheta, offset, binWidth);
1303}
1304
1305} // namespace Conversion
1306} // 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< detid_t > getMonitorIDs() const
Returns a list containing the detector ids of monitors.
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.
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
Returns a list containing the detector ids of all detectors, optionally skipping monitors.
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