16#include <boost/algorithm/string.hpp>
18#include <nexus/NeXusFile.hpp>
21#define strcasecmp _stricmp
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";
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";
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";
49const std::string SCALE_PARAM_NAME =
"sca";
52Kernel::Logger
g_log(
"ParameterMap");
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");
68 : m_parameterFileNames(other.m_parameterFileNames), m_map(other.m_map),
71 m_instrument(other.m_instrument) {
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);
146 result = param->getDescription();
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);
168 result = param->getShortDescription();
192 double num = std::fabs(x1 - x2);
194 double den = 0.5 * (std::fabs(x1) + std::fabs(x2));
196 return (num > errorVal);
198 return (num / den > errorVal);
216 const double doubleTolerance)
const {
218 return std::string(
"");
222 return std::string(
"Number of parameters does not match: ") +
std::to_string(this->
size()) +
" not equal to " +
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);
234 for (
auto &mappair :
rhs.m_map) {
235 rhsMap.emplace(mappair.first->getFullName(), mappair.second);
238 std::stringstream strOutput;
239 for (
auto thisIt = thisMap.cbegin(); thisIt != thisMap.cend(); ++thisIt) {
240 const std::string fullName = thisIt->first;
241 const auto ¶m = thisIt->second;
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")) {
249 if (!
relErr(param->value<
double>(), rhsParam->value<
double>(), doubleTolerance))
251 }
else if (std::abs(param->value<
double>() - rhsParam->value<
double>()) <= doubleTolerance)
253 }
else if (param->asString() == rhsParam->asString()) {
263 strOutput <<
"Parameter mismatch LHS=RHS for LHS parameter in component "
265 << fullName <<
". Parameter name is: " << (*param).name() <<
" and value: " << (*param).asString()
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';
279 if (!componentWithSameNameRHS) {
280 strOutput <<
"No matching RHS component name\n";
282 if (componentWithSameNameRHS && !parameterWithSameNameRHS) {
283 strOutput <<
"Found matching RHS component name but not parameter name\n";
286 return strOutput.str();
289 return strOutput.str();
297 checkIsNotMaskingParameter(name);
299 for (
auto itr =
m_map.begin(); itr !=
m_map.end();) {
300 if (itr->second->name() == name) {
307 if (name ==
pos() || name ==
rot())
317 checkIsNotMaskingParameter(name);
318 if (!
m_map.empty()) {
320 auto itrs =
m_map.equal_range(
id);
321 for (
auto it = itrs.first; it != itrs.second;) {
322 if (it->second->name() == name) {
330 if (name ==
pos() || name ==
rot())
346 const std::string &
value,
const std::string *
const pDescription,
const std::string &pVisible) {
348 param->fromString(
value);
349 this->
add(comp, param, pDescription);
360 const std::string *
const pDescription) {
363 checkIsNotMaskingParameter(par->name());
365 par->setDescription(*pDescription);
367 auto existing_par =
positionOf(comp, par->name().c_str(),
"");
373 if (existing_par !=
m_map.end()) {
374 std::atomic_store(&(existing_par->second), par);
378#if defined(__clang__) && !defined(__APPLE__)
379#define CLANG_ON_LINUX true
381#define CLANG_ON_LINUX false
383#if TBB_VERSION_MAJOR >= 4 && TBB_VERSION_MINOR >= 4 && !CLANG_ON_LINUX
401 const std::string *
const pDescription) {
416 else if (name ==
posy())
418 else if (name ==
posz())
421 g_log.
warning() <<
"addPositionCoordinate() called with unrecognized "
422 "coordinate symbol: "
426 param->setDescription(*pDescription);
447 const std::string *
const pDescription) {
451 double rotX, rotY, rotZ;
454 rotX = paramRotX->value<
double>();
459 rotY = paramRotY->value<
double>();
464 rotZ = paramRotZ->value<
double>();
470 if (name ==
rotx()) {
473 }
else if (name ==
roty()) {
476 }
else if (name ==
rotz()) {
480 g_log.
warning() <<
"addRotationParam() called with unrecognized coordinate symbol: " << name;
501 const std::string *
const pDescription,
const std::string &pVisible) {
515 const std::string *
const pDescription,
const std::string &pVisible) {
529 const std::string *
const pDescription,
const std::string &pVisible) {
543 const std::string *
const pDescription,
const std::string &pVisible) {
557 const std::string *
const pDescription,
const std::string &pVisible) {
570 const std::string *
const pDescription,
const std::string &pVisible) {
582 const std::string name(
"masked");
584 auto typedParam = std::dynamic_pointer_cast<ParameterType<bool>>(param);
585 typedParam->setValue(
value);
589#if defined(__clang__) && !defined(__APPLE__)
590#define CLANG_ON_LINUX true
592#define CLANG_ON_LINUX false
594#if TBB_VERSION_MAJOR >= 4 && TBB_VERSION_MINOR >= 4 && !CLANG_ON_LINUX
611 const std::string *
const pDescription,
const std::string &pVisible) {
612 add<std::string>(
pString(), comp, name,
value, pDescription, pVisible);
624 const std::string *
const pDescription) {
638 const std::string *
const pDescription) {
652 const std::string *
const pDescription) {
665 return contains(comp, name.c_str(), type.c_str());
677 checkIsNotMaskingParameter(name);
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 ¶m = itr->second;
685 if (strcasecmp(param->nameAsCString(), name) == 0 && (anytype || param->type() == type)) {
698 checkIsNotMaskingParameter(parameter.
name());
699 if (
m_map.empty() || !comp)
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) {
708 if (*param == parameter)
723 return get(comp, name.c_str(), type.c_str());
734 checkIsNotMaskingParameter(name);
740 if (itr !=
m_map.end())
741 result = std::atomic_load(&itr->second);
753 auto result =
m_map.end();
756 const bool anytype = (strlen(type) == 0);
757 if (!
m_map.empty()) {
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 ¶m = itr->second;
764 if (strcasecmp(param->nameAsCString(), name) == 0 && (anytype || param->type() == type)) {
782 auto result =
m_map.end();
785 const bool anytype = (strlen(type) == 0);
786 if (!
m_map.empty()) {
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 ¶m = itr->second;
793 if (strcasecmp(param->nameAsCString(), name) == 0 && (anytype || param->type() == type)) {
810 if (!
m_map.empty()) {
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 ¶m = itr->second;
817 if (strcasecmp(param->type().c_str(), type.c_str()) == 0) {
818 result = std::atomic_load(¶m);
834 std::shared_ptr<const IComponent> compInFocus(comp,
NoDeleting());
835 while (compInFocus !=
nullptr) {
840 compInFocus = compInFocus->getParent();
855 const std::string &type)
const {
868 checkIsNotMaskingParameter(name);
875 result = this->
get(parent->getComponentID(), name, type);
878 parent = parent->getParent();
896 param =
get(comp, name);
900 return param->asString();
909 std::set<std::string> paramNames;
911 auto it_found =
m_map.find(
id);
912 if (it_found ==
m_map.end()) {
916 auto itrs =
m_map.equal_range(
id);
917 for (
auto it = itrs.first; it != itrs.second; ++it) {
918 paramNames.insert(it->second->name());
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);
938 out <<
"detID:" << det->
getID();
940 out << comp->getFullName();
943 const auto paramVisible =
"visible:" + std::string(p->visible() == 1 ?
"true" :
"false");
944 out <<
';' << p->type() <<
';' << p->name() <<
';' << p->asString() <<
';' << paramVisible <<
'|';
998 auto oldParameterNames = oldPMap->
names(oldComp);
999 for (
const auto &oldParameterName : oldParameterNames) {
1002#if TBB_VERSION_MAJOR >= 4 && TBB_VERSION_MINOR >= 4 && !CLANG_ON_LINUX
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");
1028 file->writeData(
"data", s);
1044 const std::string &visible)
const {
1072 throw std::runtime_error(
"Cannot return reference to NULL DetectorInfo");
1079 throw std::runtime_error(
"Cannot return reference to NULL DetectorInfo");
1086 throw std::runtime_error(
"Cannot return reference to NULL ComponentInfo");
1094 throw std::runtime_error(
"Cannot return reference to NULL ComponentInfo");
1116 throw std::logic_error(
"ParameterMap::setInstrument: Cannot change "
1117 "instrument once it has been set.");
1119 throw std::logic_error(
"ParameterMap::setInstrument must be called with "
1120 "base instrument, not a parametrized instrument");
const std::vector< double > & rhs
double value
The value of the point.
#define PARALLEL_CRITICAL(name)
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
ComponentInfo : Provides a component centric view on to the instrument.
bool isParametrized() const override
Return true if the Component is, in fact, parametrized (that is - it has a valid parameter map)
Geometry::DetectorInfo is an intermediate step towards a DetectorInfo that is part of Instrument-2....
base class for Geometric IComponent
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.
virtual detid_t getID() const =0
Get the detector ID.
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.
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.
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...
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.
std::vector< std::string > m_parameterFileNames
internal list of parameter files loaded
pmap m_map
internal parameter map instance
static const std::string & pV3D()
std::unique_ptr< Kernel::Cache< const ComponentID, Kernel::V3D > > m_cacheLocMap
internal cache map instance for cached position values
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
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.
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.
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.
const std::string & name() const
Parameter name.
Cache is a generic caching storage class.
void warning(const std::string &msg)
Logs at warning level.
tbb::concurrent_unordered_multimap< ComponentID, std::shared_ptr< Parameter > >::const_iterator component_map_cit
std::shared_ptr< Parameter > Parameter_sptr
Typedef for the shared pointer.
tbb::concurrent_unordered_multimap< ComponentID, std::shared_ptr< Parameter > >::iterator component_map_it
Parameter map iterator typedef.
Mantid::Kernel::Logger g_log("Goniometer")
int32_t detid_t
Typedef for a detector ID.
std::string to_string(const wide_integer< Bits, Signed > &n)