Mantid
Loading...
Searching...
No Matches
ParameterMap.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 +
14#include "MantidKernel/Cache.h"
16#include <boost/algorithm/string.hpp>
17#include <cstring>
18#include <nexus/NeXusFile.hpp>
19
20#ifdef _WIN32
21#define strcasecmp _stricmp
22#else
23#include "strings.h"
24#endif
25
26namespace Mantid::Geometry {
27using Kernel::Quat;
28using Kernel::V3D;
29
30namespace {
31// names of common parameter types
32const std::string POS_PARAM_NAME = "pos";
33const std::string POSX_PARAM_NAME = "x";
34const std::string POSY_PARAM_NAME = "y";
35const std::string POSZ_PARAM_NAME = "z";
36
37const std::string ROT_PARAM_NAME = "rot";
38const std::string ROTX_PARAM_NAME = "rotx";
39const std::string ROTY_PARAM_NAME = "roty";
40const std::string ROTZ_PARAM_NAME = "rotz";
41
42const std::string DOUBLE_PARAM_NAME = "double";
43const std::string INT_PARAM_NAME = "int";
44const std::string BOOL_PARAM_NAME = "bool";
45const std::string STRING_PARAM_NAME = "string";
46const std::string V3D_PARAM_NAME = "V3D";
47const std::string QUAT_PARAM_NAME = "Quat";
48
49const std::string SCALE_PARAM_NAME = "sca";
50
51// static logger reference
52Kernel::Logger g_log("ParameterMap");
53
54void checkIsNotMaskingParameter(const std::string &name) {
55 if (name == std::string("masked"))
56 throw std::runtime_error("Masking data (\"masked\") cannot be stored in "
57 "ParameterMap. Use DetectorInfo instead");
58}
59} // namespace
64 : m_cacheLocMap(std::make_unique<Kernel::Cache<const ComponentID, Kernel::V3D>>()),
65 m_cacheRotMap(std::make_unique<Kernel::Cache<const ComponentID, Kernel::Quat>>()) {}
66
68 : m_parameterFileNames(other.m_parameterFileNames), m_map(other.m_map),
69 m_cacheLocMap(std::make_unique<Kernel::Cache<const ComponentID, Kernel::V3D>>(*other.m_cacheLocMap)),
70 m_cacheRotMap(std::make_unique<Kernel::Cache<const ComponentID, Kernel::Quat>>(*other.m_cacheRotMap)),
71 m_instrument(other.m_instrument) {
72 if (m_instrument)
73 std::tie(m_componentInfo, m_detectorInfo) = m_instrument->makeBeamline(*this, &other);
74}
75
76// Defined as default in source for forward declaration with std::unique_ptr.
78
82// Position
83const std::string &ParameterMap::pos() { return POS_PARAM_NAME; }
84
85const std::string &ParameterMap::posx() { return POSX_PARAM_NAME; }
86
87const std::string &ParameterMap::posy() { return POSY_PARAM_NAME; }
88
89const std::string &ParameterMap::posz() { return POSZ_PARAM_NAME; }
90
91// Rotation
92const std::string &ParameterMap::rot() { return ROT_PARAM_NAME; }
93
94const std::string &ParameterMap::rotx() { return ROTX_PARAM_NAME; }
95
96const std::string &ParameterMap::roty() { return ROTY_PARAM_NAME; }
97
98const std::string &ParameterMap::rotz() { return ROTZ_PARAM_NAME; }
99
100// Other types
101const std::string &ParameterMap::pDouble() { return DOUBLE_PARAM_NAME; }
102
103const std::string &ParameterMap::pInt() { return INT_PARAM_NAME; }
104
105const std::string &ParameterMap::pBool() { return BOOL_PARAM_NAME; }
106
107const std::string &ParameterMap::pString() { return STRING_PARAM_NAME; }
108
109const std::string &ParameterMap::pV3D() { return V3D_PARAM_NAME; }
110
111const std::string &ParameterMap::pQuat() { return QUAT_PARAM_NAME; }
112
113// Scale
114const std::string &ParameterMap::scale() { return SCALE_PARAM_NAME; }
115
122bool ParameterMap::operator!=(const ParameterMap &rhs) const { return !(this->operator==(rhs)); }
123
130bool ParameterMap::operator==(const ParameterMap &rhs) const { return diff(rhs, true, false, 0.).empty(); }
131
139const std::string ParameterMap::getDescription(const std::string &compName, const std::string &name) const {
140 pmap_cit it;
141 std::string result;
142 for (it = m_map.begin(); it != m_map.end(); ++it) {
143 if (compName == it->first->getName()) {
144 std::shared_ptr<Parameter> param = get(it->first, name);
145 if (param) {
146 result = param->getDescription();
147 if (!result.empty())
148 return result;
149 }
150 }
151 }
152 return result;
153}
161const std::string ParameterMap::getShortDescription(const std::string &compName, const std::string &name) const {
162 pmap_cit it;
163 std::string result;
164 for (it = m_map.begin(); it != m_map.end(); ++it) {
165 if (compName == it->first->getName()) {
166 std::shared_ptr<Parameter> param = get(it->first, name);
167 if (param) {
168 result = param->getShortDescription();
169 if (!result.empty())
170 return result;
171 }
172 }
173 }
174 return result;
175}
176
177//------------------------------------------------------------------------------------------------
191bool ParameterMap::relErr(double x1, double x2, double errorVal) const {
192 double num = std::fabs(x1 - x2);
193 // how to treat x1<0 and x2 > 0 ? probably this way
194 double den = 0.5 * (std::fabs(x1) + std::fabs(x2));
195 if (den < errorVal)
196 return (num > errorVal);
197
198 return (num / den > errorVal);
199}
200
215const std::string ParameterMap::diff(const ParameterMap &rhs, const bool &firstDiffOnly, const bool relative,
216 const double doubleTolerance) const {
217 if (this == &rhs)
218 return std::string(""); // True for the same object
219
220 // Quick size check
221 if (this->size() != rhs.size()) {
222 return std::string("Number of parameters does not match: ") + std::to_string(this->size()) + " not equal to " +
223 std::to_string(rhs.size());
224 }
225
226 // The map is unordered and the key is only valid at runtime. The
227 // asString method turns the ComponentIDs to full-qualified name identifiers
228 // so we will use the same approach to compare them
229
230 std::unordered_multimap<std::string, Parameter_sptr> thisMap, rhsMap;
231 for (auto &mappair : this->m_map) {
232 thisMap.emplace(mappair.first->getFullName(), mappair.second);
233 }
234 for (auto &mappair : rhs.m_map) {
235 rhsMap.emplace(mappair.first->getFullName(), mappair.second);
236 }
237
238 std::stringstream strOutput;
239 for (auto thisIt = thisMap.cbegin(); thisIt != thisMap.cend(); ++thisIt) {
240 const std::string fullName = thisIt->first;
241 const auto &param = thisIt->second;
242 bool match(false);
243 for (auto rhsIt = rhsMap.cbegin(); rhsIt != rhsMap.cend(); ++rhsIt) {
244 const std::string rhsFullName = rhsIt->first;
245 const auto &rhsParam = rhsIt->second;
246 if ((fullName == rhsFullName) && (param->name() == (rhsParam->name()))) {
247 if ((param->type() == rhsParam->type()) && (rhsParam->type() == "double")) {
248 if (relative) {
249 if (!relErr(param->value<double>(), rhsParam->value<double>(), doubleTolerance))
250 match = true;
251 } else if (std::abs(param->value<double>() - rhsParam->value<double>()) <= doubleTolerance)
252 match = true;
253 } else if (param->asString() == rhsParam->asString()) {
254 match = true;
255 }
256 if (match)
257 break;
258 }
259 }
260
261 if (!match) {
262 // output some information that helps with understanding the mismatch
263 strOutput << "Parameter mismatch LHS=RHS for LHS parameter in component "
264 "with name: "
265 << fullName << ". Parameter name is: " << (*param).name() << " and value: " << (*param).asString()
266 << '\n';
267 bool componentWithSameNameRHS = false;
268 bool parameterWithSameNameRHS = false;
269 for (auto rhsIt = rhsMap.cbegin(); rhsIt != rhsMap.cend(); ++rhsIt) {
270 const std::string rhsFullName = rhsIt->first;
271 if (fullName == rhsFullName) {
272 componentWithSameNameRHS = true;
273 if ((*param).name() == (*rhsIt->second).name()) {
274 parameterWithSameNameRHS = true;
275 strOutput << "RHS param with same name has value: " << (*rhsIt->second).asString() << '\n';
276 }
277 }
278 }
279 if (!componentWithSameNameRHS) {
280 strOutput << "No matching RHS component name\n";
281 }
282 if (componentWithSameNameRHS && !parameterWithSameNameRHS) {
283 strOutput << "Found matching RHS component name but not parameter name\n";
284 }
285 if (firstDiffOnly)
286 return strOutput.str();
287 }
288 }
289 return strOutput.str();
290}
291
296void ParameterMap::clearParametersByName(const std::string &name) {
297 checkIsNotMaskingParameter(name);
298 // Key is component ID so have to search through whole lot
299 for (auto itr = m_map.begin(); itr != m_map.end();) {
300 if (itr->second->name() == name) {
301 PARALLEL_CRITICAL(unsafe_erase) { itr = m_map.unsafe_erase(itr); }
302 } else {
303 ++itr;
304 }
305 }
306 // Check if the caches need invalidating
307 if (name == pos() || name == rot())
309}
310
316void ParameterMap::clearParametersByName(const std::string &name, const IComponent *comp) {
317 checkIsNotMaskingParameter(name);
318 if (!m_map.empty()) {
319 const ComponentID id = comp->getComponentID();
320 auto itrs = m_map.equal_range(id);
321 for (auto it = itrs.first; it != itrs.second;) {
322 if (it->second->name() == name) {
323 PARALLEL_CRITICAL(unsafe_erase) { it = m_map.unsafe_erase(it); }
324 } else {
325 ++it;
326 }
327 }
328
329 // Check if the caches need invalidating
330 if (name == pos() || name == rot())
332 }
333}
334
345void ParameterMap::add(const std::string &type, const IComponent *comp, const std::string &name,
346 const std::string &value, const std::string *const pDescription, const std::string &pVisible) {
347 auto param = ParameterFactory::create(type, name, pVisible);
348 param->fromString(value);
349 this->add(comp, param, pDescription);
350}
351
359void ParameterMap::add(const IComponent *comp, const std::shared_ptr<Parameter> &par,
360 const std::string *const pDescription) {
361 if (!par)
362 return;
363 checkIsNotMaskingParameter(par->name());
364 if (pDescription)
365 par->setDescription(*pDescription);
366
367 auto existing_par = positionOf(comp, par->name().c_str(), "");
368 // As this is only an add method it should really throw if it already
369 // exists.
370 // However, this is old behavior and many things rely on this actually be
371 // an
372 // add/replace-style function
373 if (existing_par != m_map.end()) {
374 std::atomic_store(&(existing_par->second), par);
375 } else {
376// When using Clang & Linux, TBB 4.4 doesn't detect C++11 features.
377// https://software.intel.com/en-us/forums/intel-threading-building-blocks/topic/641658
378#if defined(__clang__) && !defined(__APPLE__)
379#define CLANG_ON_LINUX true
380#else
381#define CLANG_ON_LINUX false
382#endif
383#if TBB_VERSION_MAJOR >= 4 && TBB_VERSION_MINOR >= 4 && !CLANG_ON_LINUX
384 m_map.emplace(comp->getComponentID(), par);
385#else
386 m_map.insert(std::make_pair(comp->getComponentID(), par));
387#endif
388 }
389}
390
400void ParameterMap::addPositionCoordinate(const IComponent *comp, const std::string &name, const double value,
401 const std::string *const pDescription) {
402 Parameter_sptr param = get(comp, pos());
404 if (param) {
405 // so "pos" already defined
406 position = param->value<V3D>();
407 } else {
408 // so "pos" is not defined - therefore get position from component
409 position = comp->getPos();
410 }
411
412 // adjust position
413
414 if (name == posx())
415 position.setX(value);
416 else if (name == posy())
417 position.setY(value);
418 else if (name == posz())
419 position.setZ(value);
420 else {
421 g_log.warning() << "addPositionCoordinate() called with unrecognized "
422 "coordinate symbol: "
423 << name;
424 // set description if one is provided
425 if (pDescription) {
426 param->setDescription(*pDescription);
427 }
428 return;
429 }
430
431 // clear the position cache
433 // finally add or update "pos" parameter
434 addV3D(comp, pos(), position, pDescription);
435}
436
446void ParameterMap::addRotationParam(const IComponent *comp, const std::string &name, const double deg,
447 const std::string *const pDescription) {
448 Parameter_sptr paramRotX = get(comp, rotx());
449 Parameter_sptr paramRotY = get(comp, roty());
450 Parameter_sptr paramRotZ = get(comp, rotz());
451 double rotX, rotY, rotZ;
452
453 if (paramRotX)
454 rotX = paramRotX->value<double>();
455 else
456 rotX = 0.0;
457
458 if (paramRotY)
459 rotY = paramRotY->value<double>();
460 else
461 rotY = 0.0;
462
463 if (paramRotZ)
464 rotZ = paramRotZ->value<double>();
465 else
466 rotZ = 0.0;
467
468 // adjust rotation
469 Quat quat;
470 if (name == rotx()) {
471 addDouble(comp, rotx(), deg);
472 quat = Quat(deg, V3D(1, 0, 0)) * Quat(rotY, V3D(0, 1, 0)) * Quat(rotZ, V3D(0, 0, 1));
473 } else if (name == roty()) {
474 addDouble(comp, roty(), deg);
475 quat = Quat(rotX, V3D(1, 0, 0)) * Quat(deg, V3D(0, 1, 0)) * Quat(rotZ, V3D(0, 0, 1));
476 } else if (name == rotz()) {
477 addDouble(comp, rotz(), deg);
478 quat = Quat(rotX, V3D(1, 0, 0)) * Quat(rotY, V3D(0, 1, 0)) * Quat(deg, V3D(0, 0, 1));
479 } else {
480 g_log.warning() << "addRotationParam() called with unrecognized coordinate symbol: " << name;
481 return;
482 }
483
484 // clear the position cache
486
487 // finally add or update "pos" parameter
488 addQuat(comp, rot(), quat, pDescription);
489}
490
500void ParameterMap::addDouble(const IComponent *comp, const std::string &name, const std::string &value,
501 const std::string *const pDescription, const std::string &pVisible) {
502 add(pDouble(), comp, name, value, pDescription, pVisible);
503}
504
514void ParameterMap::addDouble(const IComponent *comp, const std::string &name, double value,
515 const std::string *const pDescription, const std::string &pVisible) {
516 add(pDouble(), comp, name, value, pDescription, pVisible);
517}
518
528void ParameterMap::addInt(const IComponent *comp, const std::string &name, const std::string &value,
529 const std::string *const pDescription, const std::string &pVisible) {
530 add(pInt(), comp, name, value, pDescription, pVisible);
531}
532
542void ParameterMap::addInt(const IComponent *comp, const std::string &name, int value,
543 const std::string *const pDescription, const std::string &pVisible) {
544 add(pInt(), comp, name, value, pDescription, pVisible);
545}
546
556void ParameterMap::addBool(const IComponent *comp, const std::string &name, const std::string &value,
557 const std::string *const pDescription, const std::string &pVisible) {
558 add(pBool(), comp, name, value, pDescription, pVisible);
559}
569void ParameterMap::addBool(const IComponent *comp, const std::string &name, bool value,
570 const std::string *const pDescription, const std::string &pVisible) {
571 add(pBool(), comp, name, value, pDescription, pVisible);
572}
573
582 const std::string name("masked");
583 auto param = create(pBool(), name);
584 auto typedParam = std::dynamic_pointer_cast<ParameterType<bool>>(param);
585 typedParam->setValue(value);
586
587// When using Clang & Linux, TBB 4.4 doesn't detect C++11 features.
588// https://software.intel.com/en-us/forums/intel-threading-building-blocks/topic/641658
589#if defined(__clang__) && !defined(__APPLE__)
590#define CLANG_ON_LINUX true
591#else
592#define CLANG_ON_LINUX false
593#endif
594#if TBB_VERSION_MAJOR >= 4 && TBB_VERSION_MINOR >= 4 && !CLANG_ON_LINUX
595 m_map.emplace(comp->getComponentID(), param);
596#else
597 m_map.insert(std::make_pair(comp->getComponentID(), param));
598#endif
599}
600
610void ParameterMap::addString(const IComponent *comp, const std::string &name, const std::string &value,
611 const std::string *const pDescription, const std::string &pVisible) {
612 add<std::string>(pString(), comp, name, value, pDescription, pVisible);
613}
614
623void ParameterMap::addV3D(const IComponent *comp, const std::string &name, const std::string &value,
624 const std::string *const pDescription) {
625 add(pV3D(), comp, name, value, pDescription);
627}
628
637void ParameterMap::addV3D(const IComponent *comp, const std::string &name, const V3D &value,
638 const std::string *const pDescription) {
639 add(pV3D(), comp, name, value, pDescription);
641}
642
651void ParameterMap::addQuat(const IComponent *comp, const std::string &name, const Quat &value,
652 const std::string *const pDescription) {
653 add(pQuat(), comp, name, value, pDescription);
655}
656
664bool ParameterMap::contains(const IComponent *comp, const std::string &name, const std::string &type) const {
665 return contains(comp, name.c_str(), type.c_str());
666}
667
676bool ParameterMap::contains(const IComponent *comp, const char *name, const char *type) const {
677 checkIsNotMaskingParameter(name);
678 if (m_map.empty())
679 return false;
680 const ComponentID id = comp->getComponentID();
681 std::pair<pmap_cit, pmap_cit> components = m_map.equal_range(id);
682 bool anytype = (strlen(type) == 0);
683 for (auto itr = components.first; itr != components.second; ++itr) {
684 const auto &param = itr->second;
685 if (strcasecmp(param->nameAsCString(), name) == 0 && (anytype || param->type() == type)) {
686 return true;
687 }
688 }
689 return false;
690}
691
697bool ParameterMap::contains(const IComponent *comp, const Parameter &parameter) const {
698 checkIsNotMaskingParameter(parameter.name());
699 if (m_map.empty() || !comp)
700 return false;
701
702 const ComponentID id = comp->getComponentID();
703 auto it_found = m_map.find(id);
704 if (it_found != m_map.end()) {
705 auto itrs = m_map.equal_range(id);
706 for (auto itr = itrs.first; itr != itrs.second; ++itr) {
707 const Parameter_sptr &param = itr->second;
708 if (*param == parameter)
709 return true;
710 }
711 return false;
712 } else
713 return false;
714}
715
722Parameter_sptr ParameterMap::get(const IComponent *comp, const std::string &name, const std::string &type) const {
723 return get(comp, name.c_str(), type.c_str());
724}
725
733std::shared_ptr<Parameter> ParameterMap::get(const IComponent *comp, const char *name, const char *type) const {
734 checkIsNotMaskingParameter(name);
735 Parameter_sptr result;
736 if (!comp)
737 return result;
738
739 auto itr = positionOf(comp, name, type);
740 if (itr != m_map.end())
741 result = std::atomic_load(&itr->second);
742 return result;
743}
744
752component_map_it ParameterMap::positionOf(const IComponent *comp, const char *name, const char *type) {
753 auto result = m_map.end();
754 if (!comp)
755 return result;
756 const bool anytype = (strlen(type) == 0);
757 if (!m_map.empty()) {
758 const ComponentID id = comp->getComponentID();
759 auto it_found = m_map.find(id);
760 if (it_found != m_map.end()) {
761 auto itrs = m_map.equal_range(id);
762 for (auto itr = itrs.first; itr != itrs.second; ++itr) {
763 const auto &param = itr->second;
764 if (strcasecmp(param->nameAsCString(), name) == 0 && (anytype || param->type() == type)) {
765 result = itr;
766 break;
767 }
768 }
769 }
770 }
771 return result;
772}
773
781component_map_cit ParameterMap::positionOf(const IComponent *comp, const char *name, const char *type) const {
782 auto result = m_map.end();
783 if (!comp)
784 return result;
785 const bool anytype = (strlen(type) == 0);
786 if (!m_map.empty()) {
787 const ComponentID id = comp->getComponentID();
788 auto it_found = m_map.find(id);
789 if (it_found != m_map.end()) {
790 auto itrs = m_map.equal_range(id);
791 for (auto itr = itrs.first; itr != itrs.second; ++itr) {
792 const auto &param = itr->second;
793 if (strcasecmp(param->nameAsCString(), name) == 0 && (anytype || param->type() == type)) {
794 result = itr;
795 break;
796 }
797 }
798 }
799 }
800 return result;
801}
802
808Parameter_sptr ParameterMap::getByType(const IComponent *comp, const std::string &type) const {
809 Parameter_sptr result;
810 if (!m_map.empty()) {
811 const ComponentID id = comp->getComponentID();
812 auto it_found = m_map.find(id);
813 if (it_found != m_map.end() && it_found->first) {
814 auto itrs = m_map.equal_range(id);
815 for (auto itr = itrs.first; itr != itrs.second; ++itr) {
816 const auto &param = itr->second;
817 if (strcasecmp(param->type().c_str(), type.c_str()) == 0) {
818 result = std::atomic_load(&param);
819 break;
820 }
821 } // found->firdst
822 } // it_found != m_map.end()
823 }
824 return result;
825}
826
833Parameter_sptr ParameterMap::getRecursiveByType(const IComponent *comp, const std::string &type) const {
834 std::shared_ptr<const IComponent> compInFocus(comp, NoDeleting());
835 while (compInFocus != nullptr) {
836 Parameter_sptr param = getByType(compInFocus.get(), type);
837 if (param) {
838 return param;
839 }
840 compInFocus = compInFocus->getParent();
841 }
842 // Nothing was found!
843 return Parameter_sptr();
844}
845
854Parameter_sptr ParameterMap::getRecursive(const IComponent *comp, const std::string &name,
855 const std::string &type) const {
856 return getRecursive(comp, name.c_str(), type.c_str());
857}
858
867Parameter_sptr ParameterMap::getRecursive(const IComponent *comp, const char *name, const char *type) const {
868 checkIsNotMaskingParameter(name);
869 Parameter_sptr result = this->get(comp->getComponentID(), name, type);
870 if (result)
871 return result;
872
873 auto parent = comp->getParent();
874 while (parent) {
875 result = this->get(parent->getComponentID(), name, type);
876 if (result)
877 return result;
878 parent = parent->getParent();
879 }
880 return result;
881}
882
891std::string ParameterMap::getString(const IComponent *comp, const std::string &name, bool recursive) const {
892 Parameter_sptr param;
893 if (recursive) {
894 param = getRecursive(comp, name);
895 } else {
896 param = get(comp, name);
897 }
898 if (!param)
899 return "";
900 return param->asString();
901}
902
908std::set<std::string> ParameterMap::names(const IComponent *comp) const {
909 std::set<std::string> paramNames;
910 const ComponentID id = comp->getComponentID();
911 auto it_found = m_map.find(id);
912 if (it_found == m_map.end()) {
913 return paramNames;
914 }
915
916 auto itrs = m_map.equal_range(id);
917 for (auto it = itrs.first; it != itrs.second; ++it) {
918 paramNames.insert(it->second->name());
919 }
920
921 return paramNames;
922}
923
930std::string ParameterMap::asString() const {
931 std::stringstream out;
932 for (const auto &mappair : m_map) {
933 const std::shared_ptr<Parameter> &p = mappair.second;
934 if (p && mappair.first) {
935 const auto *comp = dynamic_cast<const IComponent *>(mappair.first);
936 const auto *det = dynamic_cast<const IDetector *>(comp);
937 if (det) {
938 out << "detID:" << det->getID();
939 } else if (comp) {
940 out << comp->getFullName(); // Use full path name to ensure unambiguous
941 // naming
942 }
943 const auto paramVisible = "visible:" + std::string(p->visible() == 1 ? "true" : "false");
944 out << ';' << p->type() << ';' << p->name() << ';' << p->asString() << ';' << paramVisible << '|';
945 }
946 }
947 return out.str();
948}
949
954 m_cacheLocMap->clear();
955 m_cacheRotMap->clear();
956}
957
961void ParameterMap::setCachedLocation(const IComponent *comp, const V3D &location) const {
962 m_cacheLocMap->setCache(comp->getComponentID(), location);
963}
964
969bool ParameterMap::getCachedLocation(const IComponent *comp, V3D &location) const {
970 return m_cacheLocMap->getCache(comp->getComponentID(), location);
971}
972
977 m_cacheRotMap->setCache(comp->getComponentID(), rotation);
978}
979
985 return m_cacheRotMap->getCache(comp->getComponentID(), rotation);
986}
987
995void ParameterMap::copyFromParameterMap(const IComponent *oldComp, const IComponent *newComp,
996 const ParameterMap *oldPMap) {
997
998 auto oldParameterNames = oldPMap->names(oldComp);
999 for (const auto &oldParameterName : oldParameterNames) {
1000 Parameter_sptr thisParameter = oldPMap->get(oldComp, oldParameterName);
1001// Insert the fetched parameter in the m_map
1002#if TBB_VERSION_MAJOR >= 4 && TBB_VERSION_MINOR >= 4 && !CLANG_ON_LINUX
1003 m_map.emplace(newComp->getComponentID(), std::move(thisParameter));
1004#else
1005 m_map.insert(std::make_pair(newComp->getComponentID(), std::move(thisParameter)));
1006#endif
1007 }
1008}
1009
1010//--------------------------------------------------------------------------------------------
1015void ParameterMap::saveNexus(::NeXus::File *file, const std::string &group) const {
1016 file->makeGroup(group, "NXnote", true);
1017 file->putAttr("version", 1);
1018 file->writeData("author", "");
1019 file->writeData("date", Types::Core::DateAndTime::getCurrentTime().toISO8601String());
1020 file->writeData("description", "A string representation of the parameter "
1021 "map. The format is either: "
1022 "|detID:id-value;param-type;param-name;param-"
1023 "value| for a detector or "
1024 "|comp-name;param-type;param-name;param-value|"
1025 " for other components.");
1026 file->writeData("type", "text/plain");
1027 std::string s = this->asString();
1028 file->writeData("data", s);
1029 file->closeGroup();
1030}
1031
1035const std::vector<std::string> &ParameterMap::getParameterFilenames() const { return m_parameterFileNames; }
1037
1040void ParameterMap::addParameterFilename(const std::string &filename) { m_parameterFileNames.emplace_back(filename); }
1041
1043std::shared_ptr<Parameter> ParameterMap::create(const std::string &className, const std::string &name,
1044 const std::string &visible) const {
1045 return ParameterFactory::create(className, name, visible);
1046}
1047
1054bool ParameterMap::hasDetectorInfo(const Instrument *instrument) const {
1055 if (instrument != m_instrument)
1056 return false;
1057 return static_cast<bool>(m_detectorInfo);
1058}
1059
1063bool ParameterMap::hasComponentInfo(const Instrument *instrument) const {
1064 if (instrument != m_instrument)
1065 return false;
1066 return static_cast<bool>(m_componentInfo);
1067}
1068
1072 throw std::runtime_error("Cannot return reference to NULL DetectorInfo");
1073 return *m_detectorInfo;
1074}
1075
1079 throw std::runtime_error("Cannot return reference to NULL DetectorInfo");
1080 return *m_detectorInfo;
1081}
1082
1086 throw std::runtime_error("Cannot return reference to NULL ComponentInfo");
1087 }
1088 return *m_componentInfo;
1089}
1090
1094 throw std::runtime_error("Cannot return reference to NULL ComponentInfo");
1095 }
1096 return *m_componentInfo;
1097}
1098
1100size_t ParameterMap::detectorIndex(const detid_t detID) const { return m_instrument->detectorIndex(detID); }
1101
1102size_t ParameterMap::componentIndex(const ComponentID componentId) const {
1103 return m_componentInfo->indexOf(componentId);
1104}
1105
1108 if (instrument == m_instrument)
1109 return;
1110 if (!instrument) {
1111 m_componentInfo = nullptr;
1112 m_detectorInfo = nullptr;
1113 return;
1114 }
1115 if (m_instrument)
1116 throw std::logic_error("ParameterMap::setInstrument: Cannot change "
1117 "instrument once it has been set.");
1118 if (instrument->isParametrized())
1119 throw std::logic_error("ParameterMap::setInstrument must be called with "
1120 "base instrument, not a parametrized instrument");
1121 m_instrument = instrument;
1123}
1124
1125} // namespace Mantid::Geometry
const std::vector< double > & rhs
double value
The value of the point.
Definition: FitMW.cpp:51
double position
Definition: GetAllEi.cpp:154
#define PARALLEL_CRITICAL(name)
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
ComponentInfo : Provides a component centric view on to the instrument.
Definition: ComponentInfo.h:40
bool isParametrized() const override
Return true if the Component is, in fact, parametrized (that is - it has a valid parameter map)
Definition: Component.cpp:73
Geometry::DetectorInfo is an intermediate step towards a DetectorInfo that is part of Instrument-2....
Definition: DetectorInfo.h:49
base class for Geometric IComponent
Definition: IComponent.h:51
virtual Kernel::V3D getPos() const =0
Get the position of the IComponent. Tree structure is traverse through the.
virtual std::shared_ptr< const IComponent > getParent() const =0
Return a pointer to the current parent.
virtual ComponentID getComponentID() const =0
Returns the ComponentID - a unique identifier of the component.
Interface class for detector objects.
Definition: IDetector.h:43
virtual detid_t getID() const =0
Get the detector ID.
Base Instrument Class.
Definition: Instrument.h:47
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.
size_t detectorIndex(const detid_t detID) const
Returns the index for a detector ID. Used for accessing DetectorInfo.
Void deleter for shared pointers.
static std::shared_ptr< Parameter > create(const std::string &className, const std::string &name, const std::string &visible="true")
Creates an instance of a parameter.
Definition: Parameter.cpp:83
component_map_it positionOf(const IComponent *comp, const char *name, const char *type)
internal function to get position of the parameter in the parameter map
bool getCachedRotation(const IComponent *comp, Kernel::Quat &rotation) const
Attempts to retrieve a rotation from the rotation cache.
const Geometry::DetectorInfo & detectorInfo() const
Only for use by ExperimentInfo. Returns a reference to the DetectorInfo.
const std::vector< std::string > & getParameterFilenames() const
Returns a list of all the parameter files loaded.
static const std::string & pQuat()
bool getCachedLocation(const IComponent *comp, Kernel::V3D &location) const
Attempts to retrieve a location from the location cache.
void clearPositionSensitiveCaches()
Clears the location, rotation & bounding box caches.
std::unique_ptr< Geometry::DetectorInfo > m_detectorInfo
Pointer to the DetectorInfo wrapper.
Definition: ParameterMap.h:321
bool contains(const IComponent *comp, const std::string &name, const std::string &type="") const
Does the named parameter exist for the given component and type (std::string version)
void copyFromParameterMap(const IComponent *oldComp, const IComponent *newComp, const ParameterMap *oldPMap)
Copy pairs (oldComp->id,Parameter) to the m_map assigning the new newComp->id.
void addInt(const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Adds an int value to the parameter map.
void addPositionCoordinate(const IComponent *comp, const std::string &name, const double value, const std::string *const pDescription=nullptr)
Create or adjust "pos" parameter for a component.
std::shared_ptr< Parameter > getRecursive(const IComponent *comp, const std::string &name, const std::string &type="") const
Use get() recursively to see if can find param in all parents of comp and given type (std::string ver...
void addParameterFilename(const std::string &filename)
adds a parameter filename that has been loaded
static const std::string & scale()
std::shared_ptr< Parameter > getRecursiveByType(const IComponent *comp, const std::string &type) const
Looks recursively upwards in the component tree for the first instance of a parameter with a specifie...
static const std::string & rot()
void setCachedLocation(const IComponent *comp, const Kernel::V3D &location) const
Sets a cached location on the location cache.
const Instrument * m_instrument
Pointer to the owning instrument for translating detector IDs into detector indices when accessing th...
Definition: ParameterMap.h:331
std::string getString(const IComponent *comp, const std::string &name, bool recursive=false) const
Return the value of a parameter as a string.
static const std::string & pBool()
void setCachedRotation(const IComponent *comp, const Kernel::Quat &rotation) const
Sets a cached rotation on the rotation cache.
void clearParametersByName(const std::string &name)
Clear any parameters with the given name.
const std::string getDescription(const std::string &compName, const std::string &name) const
Get the component description by name.
std::shared_ptr< Parameter > getByType(const IComponent *comp, const std::string &type) const
Finds the parameter in the map via the parameter type.
void setInstrument(const Instrument *instrument)
Only for use by Instrument. Sets the pointer to the owning instrument.
Geometry::ComponentInfo & mutableComponentInfo()
Only for use by ExperimentInfo. Returns a reference to the ComponentInfo.
bool operator==(const ParameterMap &rhs) const
Equality comparison operator.
std::shared_ptr< Parameter > create(const std::string &className, const std::string &name, const std::string &visible="true") const
Wrapper for ParameterFactory::create to avoid include in header.
void addString(const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Adds a std::string value to the parameter map.
std::set< std::string > names(const IComponent *comp) const
Returns a set with all parameter names for component.
int size() const
Return the size of the map.
Definition: ParameterMap.h:59
std::vector< std::string > m_parameterFileNames
internal list of parameter files loaded
Definition: ParameterMap.h:310
pmap m_map
internal parameter map instance
Definition: ParameterMap.h:313
static const std::string & pV3D()
std::unique_ptr< Kernel::Cache< const ComponentID, Kernel::V3D > > m_cacheLocMap
internal cache map instance for cached position values
Definition: ParameterMap.h:315
void addDouble(const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Adds a double value to the parameter map.
static const std::string & posz()
std::unique_ptr< Kernel::Cache< const ComponentID, Kernel::Quat > > m_cacheRotMap
internal cache map instance for cached rotation values
Definition: ParameterMap.h:317
bool relErr(double x1, double x2, double errorVal) const
calculate relative error for use in diff
const std::string diff(const ParameterMap &rhs, const bool &firstDiffOnly=false, const bool relative=false, const double doubleTolerance=Kernel::Tolerance) const
Output information that helps understanding the mismatch between two parameter maps.
static const std::string & pDouble()
static const std::string & pos()
Return string to be used in the map.
void addRotationParam(const IComponent *comp, const std::string &name, const double deg, const std::string *const pDescription=nullptr)
Create or adjust "rot" parameter for a component.
ParameterMap()
Default constructor.
std::string asString() const
Returns a string with all component names, parameter names and values.
void addQuat(const IComponent *comp, const std::string &name, const Kernel::Quat &value, const std::string *const pDescription=nullptr)
Adds a Kernel::Quat value to the parameter map.
size_t componentIndex(const Geometry::ComponentID componentId) const
void add(const std::string &type, const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &visible="true")
Method for adding a parameter providing its value as a string.
static const std::string & rotz()
const std::string getShortDescription(const std::string &compName, const std::string &name) const
Get the component tooltip by name.
size_t detectorIndex(const detid_t detID) const
Only for use by Detector. Returns a detector index for a detector ID.
static const std::string & posy()
static const std::string & posx()
static const std::string & pString()
tbb::concurrent_unordered_multimap< ComponentID, std::shared_ptr< Parameter > >::const_iterator pmap_cit
Parameter map iterator typedef.
Definition: ParameterMap.h:50
void addV3D(const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr)
Adds a Kernel::V3D value to the parameter map.
static const std::string & pInt()
void addBool(const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Adds a bool value to the parameter map.
bool operator!=(const ParameterMap &rhs) const
Inquality comparison operator.
bool hasComponentInfo(const Instrument *instrument) const
Only for use by ExperimentInfo.
std::unique_ptr< Geometry::ComponentInfo > m_componentInfo
Pointer to the ComponentInfo wrapper.
Definition: ParameterMap.h:325
static const std::string & rotx()
bool hasDetectorInfo(const Instrument *instrument) const
Only for use by ExperimentInfo.
std::shared_ptr< Parameter > get(const IComponent *comp, const std::string &name, const std::string &type="") const
Get a parameter with a given name and type (std::string version)
void forceUnsafeSetMasked(const IComponent *comp, bool value)
Force adding masking information.
static const std::string & roty()
void saveNexus(::NeXus::File *file, const std::string &group) const
Persist a representation of the Parameter map to the open Nexus file.
const Geometry::ComponentInfo & componentInfo() const
Only for use by ExperimentInfo. Returns a reference to the ComponentInfo.
Geometry::DetectorInfo & mutableDetectorInfo()
Only for use by ExperimentInfo. Returns a reference to the DetectorInfo.
Base class for parameters of an instrument.
Definition: Parameter.h:37
const std::string & name() const
Parameter name.
Definition: Parameter.h:45
Cache is a generic caching storage class.
Definition: Cache.h:27
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
Class for quaternions.
Definition: Quat.h:39
Class for 3D vectors.
Definition: V3D.h:34
tbb::concurrent_unordered_multimap< ComponentID, std::shared_ptr< Parameter > >::const_iterator component_map_cit
Definition: ParameterMap.h:41
std::shared_ptr< Parameter > Parameter_sptr
Typedef for the shared pointer.
Definition: Parameter.h:195
tbb::concurrent_unordered_multimap< ComponentID, std::shared_ptr< Parameter > >::iterator component_map_it
Parameter map iterator typedef.
Definition: ParameterMap.h:40
Mantid::Kernel::Logger g_log("Goniometer")
int32_t detid_t
Typedef for a detector ID.
Definition: SpectrumInfo.h:21
STL namespace.
std::string to_string(const wide_integer< Bits, Signed > &n)