18#include "MantidNexus/NexusFile.h"
19#include <boost/algorithm/string.hpp>
24#define strcasecmp _stricmp
35const std::string POS_PARAM_NAME =
"pos";
36const std::string POSX_PARAM_NAME =
"x";
37const std::string POSY_PARAM_NAME =
"y";
38const std::string POSZ_PARAM_NAME =
"z";
40const std::string ROT_PARAM_NAME =
"rot";
41const std::string ROTX_PARAM_NAME =
"rotx";
42const std::string ROTY_PARAM_NAME =
"roty";
43const std::string ROTZ_PARAM_NAME =
"rotz";
45const std::string DOUBLE_PARAM_NAME =
"double";
46const std::string INT_PARAM_NAME =
"int";
47const std::string BOOL_PARAM_NAME =
"bool";
48const std::string STRING_PARAM_NAME =
"string";
49const std::string V3D_PARAM_NAME =
"V3D";
50const std::string QUAT_PARAM_NAME =
"Quat";
52const std::string SCALE_PARAM_NAME =
"sca";
55Kernel::Logger
g_log(
"ParameterMap");
57void checkIsNotMaskingParameter(
const std::string &
name) {
58 if (
name == std::string(
"masked"))
59 throw std::runtime_error(
"Masking data (\"masked\") cannot be stored in "
60 "ParameterMap. Use DetectorInfo instead");
71 : m_parameterFileNames(other.m_parameterFileNames),
72 m_parameterInfo(
std::make_shared<
ParameterInfo>(*other.m_parameterInfo)), m_domainIds(other.m_domainIds),
73 m_domainIndices(other.m_domainIndices), m_stagedIndices(other.m_stagedIndices), m_stagedIds(other.m_stagedIds),
74 m_instrument(other.m_instrument) {
109 if (found != indices.end()) {
110 result = found->second;
120 throw std::invalid_argument(
"ParameterMap: cannot add a parameter to component '" + comp->
getFullName() +
121 "', which is not part of the instrument this map belongs to");
138 throw std::logic_error(
"ParameterMap::entries: the map is not attached to an instrument, so its components "
139 "have no component indices");
141 std::vector<Entry> result;
144 for (
auto const &[parameterName, parameter] : parameters) {
145 static_cast<void>(parameterName);
146 result.emplace_back(
index, parameter);
155 std::shared_ptr<const ComponentIndices> componentIndices) {
161 auto rekeyed = std::make_shared<ParameterInfo>();
163 auto const found = componentIndices->find(oldIds[oldIndex]);
164 if (found == componentIndices->end()) {
167 for (
auto const &[parameterName, parameter] : parameters) {
168 static_cast<void>(parameterName);
171 rekeyed->insert(found->second, parameter);
174 for (
auto const &[key, parameter] :
m_parameterInfo->logfileParameters()) {
175 auto const found = componentIndices->find(oldIds[key.first]);
176 if (found != componentIndices->end()) {
177 rekeyed->addLogfileParameter(found->second, key.second, parameter);
254 static_cast<void>(parameters);
258 result = param->getDescription();
276 static_cast<void>(parameters);
280 result = param->getShortDescription();
304 double num = std::fabs(x1 - x2);
306 double den = 0.5 * (std::fabs(x1) + std::fabs(x2));
308 return (num > errorVal);
310 return (num / den > errorVal);
328 const double doubleTolerance)
const {
330 return std::string(
"");
334 return std::string(
"Number of parameters does not match: ") +
std::to_string(this->
size()) +
" not equal to " +
342 std::unordered_multimap<std::string, Parameter_sptr> thisMap, rhsMap;
343 auto const byFullName = [](
ParameterMap const &map, std::unordered_multimap<std::string, Parameter_sptr> &result) {
346 for (
auto const &[parameterName, parameter] : parameters) {
347 static_cast<void>(parameterName);
348 result.emplace(fullName, parameter);
352 byFullName(*
this, thisMap);
353 byFullName(
rhs, rhsMap);
355 std::stringstream strOutput;
356 for (
auto thisIt = thisMap.cbegin(); thisIt != thisMap.cend(); ++thisIt) {
357 const std::string fullName = thisIt->first;
358 const auto ¶m = thisIt->second;
360 for (
auto rhsIt = rhsMap.cbegin(); rhsIt != rhsMap.cend(); ++rhsIt) {
361 const std::string rhsFullName = rhsIt->first;
362 const auto &rhsParam = rhsIt->second;
363 if ((fullName == rhsFullName) && (param->name() == (rhsParam->name()))) {
364 if ((param->type() == rhsParam->type()) && (rhsParam->type() ==
"double")) {
366 if (!
relErr(param->value<
double>(), rhsParam->value<
double>(), doubleTolerance))
368 }
else if (std::abs(param->value<
double>() - rhsParam->value<
double>()) <= doubleTolerance)
370 }
else if (param->asString() == rhsParam->asString()) {
380 strOutput <<
"Parameter mismatch LHS=RHS for LHS parameter in component "
382 << fullName <<
". Parameter name is: " << (*param).name() <<
" and value: " << (*param).asString()
384 bool componentWithSameNameRHS =
false;
385 bool parameterWithSameNameRHS =
false;
386 for (
auto rhsIt = rhsMap.cbegin(); rhsIt != rhsMap.cend(); ++rhsIt) {
387 const std::string rhsFullName = rhsIt->first;
388 if (fullName == rhsFullName) {
389 componentWithSameNameRHS =
true;
390 if ((*param).name() == (*rhsIt->second).
name()) {
391 parameterWithSameNameRHS =
true;
392 strOutput <<
"RHS param with same name has value: " << (*rhsIt->second).
asString() <<
'\n';
396 if (!componentWithSameNameRHS) {
397 strOutput <<
"No matching RHS component name\n";
399 if (componentWithSameNameRHS && !parameterWithSameNameRHS) {
400 strOutput <<
"Found matching RHS component name but not parameter name\n";
403 return strOutput.str();
406 return strOutput.str();
414 checkIsNotMaskingParameter(
name);
425 checkIsNotMaskingParameter(
name);
443 const std::string &
value,
const std::string *
const pDescription,
const std::string &pVisible) {
445 param->fromString(
value);
446 this->
add(comp, param, pDescription);
457 const std::string *
const pDescription) {
464 const std::string *
const pDescription) {
467 checkIsNotMaskingParameter(par->name());
469 par->setDescription(*pDescription);
478 const std::string &
value,
const std::string *
const pDescription,
const std::string &pVisible) {
480 param->fromString(
value);
499 const std::string &fittingFunction,
const std::string &
value,
500 const std::string *
const pDescription,
const std::string &pVisible) {
505 const std::string &fittingFunction,
const std::string &
value,
506 const std::string *
const pDescription,
const std::string &pVisible) {
507 checkIsNotMaskingParameter(
name);
511 param->fromString(
value);
513 param->setDescription(*pDescription);
519 g_log.
debug() <<
"addFittingParameter: [" << (replaced ?
"replace" :
"insert") <<
"] (name='" <<
name
520 <<
"', function='" << fittingFunction <<
"') on component index " <<
componentIndex <<
'\n';
533 const std::string *
const pDescription) {
553 g_log.
warning() <<
"addPositionCoordinate() called with unrecognized "
554 "coordinate symbol: "
558 param->setDescription(*pDescription);
577 const std::string *
const pDescription) {
581 double rotX, rotY, rotZ;
584 rotX = paramRotX->value<
double>();
589 rotY = paramRotY->value<
double>();
594 rotZ = paramRotZ->value<
double>();
610 g_log.
warning() <<
"addRotationParam() called with unrecognized coordinate symbol: " <<
name;
628 const std::string *
const pDescription,
const std::string &pVisible) {
642 const std::string *
const pDescription,
const std::string &pVisible) {
656 const std::string *
const pDescription,
const std::string &pVisible) {
670 const std::string *
const pDescription,
const std::string &pVisible) {
684 const std::string *
const pDescription,
const std::string &pVisible) {
697 const std::string *
const pDescription,
const std::string &pVisible) {
709 const std::string
name(
"masked");
711 auto typedParam = std::dynamic_pointer_cast<ParameterType<bool>>(param);
712 typedParam->setValue(
value);
729 const std::string *
const pDescription,
const std::string &pVisible) {
742 const std::string *
const pDescription) {
755 const std::string *
const pDescription) {
768 const std::string *
const pDescription) {
792 checkIsNotMaskingParameter(
name);
803 checkIsNotMaskingParameter(parameter.
name());
811 static_cast<void>(storedName);
812 if (param && *param == parameter)
825 return get(comp,
name.c_str(), type.c_str());
836 checkIsNotMaskingParameter(
name);
858 std::shared_ptr<const IComponent> compInFocus(comp,
NoDeleting());
859 while (compInFocus !=
nullptr) {
864 compInFocus = compInFocus->getParent();
879 const std::string &type)
const {
892 checkIsNotMaskingParameter(
name);
899 result = this->
get(parent->getComponentID(),
name, type);
902 parent = parent->getParent();
921 const std::string &fittingFunction)
const {
922 checkIsNotMaskingParameter(
name);
930 std::shared_ptr<const IComponent> parent;
931 while (current !=
nullptr) {
935 static_cast<void>(storedName);
936 if (param->type() ==
"fitting" && strcasecmp(param->nameAsCString(),
name.c_str()) == 0) {
948 current = parent.get();
970 return param->asString();
991 return std::string();
1005 std::stringstream out;
1026 const auto paramVisible =
"visible:" + std::string(parameter.
visible() == 1 ?
"true" :
"false");
1027 return component +
';' + parameter.
type() +
';' + parameter.
name() +
';' + parameter.
asString() +
';' + paramVisible +
1041 auto const oldParameterNames = oldPMap->
names(oldComp);
1043 for (
const auto &oldParameterName : oldParameterNames) {
1057 file->makeGroup(
group,
"NXnote",
true);
1058 file->putAttr(
"version", 1);
1059 file->writeData(
"author",
"");
1060 file->writeData(
"date", Types::Core::DateAndTime::getCurrentTime().toISO8601String());
1061 file->writeData(
"description",
"A string representation of the parameter "
1062 "map. The format is either: "
1063 "|detID:id-value;param-type;param-name;param-"
1064 "value| for a detector or "
1065 "|comp-name;param-type;param-name;param-value|"
1066 " for other components.");
1067 file->writeData(
"type",
"text/plain");
1068 file->writeData(
"data", contents);
1084 const std::string &visible)
const {
1112 throw std::runtime_error(
"Cannot return reference to NULL DetectorInfo");
1119 throw std::runtime_error(
"Cannot return reference to NULL DetectorInfo");
1126 throw std::runtime_error(
"Cannot return reference to NULL ComponentInfo");
1134 throw std::runtime_error(
"Cannot return reference to NULL ComponentInfo");
1142 throw std::runtime_error(
"Cannot return reference to NULL InstrumentMetadata");
1165 throw std::logic_error(
"ParameterMap::setInstrument: Cannot change "
1166 "instrument once it has been set.");
1168 throw std::logic_error(
"ParameterMap::setInstrument must be called with "
1169 "base instrument, not a parametrized instrument");
1173 auto [newComponentInfo, newDetectorInfo] =
1201 std::shared_ptr<const ComponentInfo> physicalComponentInfo;
1202 std::shared_ptr<const DetectorInfo> physicalDetectorInfo;
1208 std::tie(physicalComponentInfo, physicalDetectorInfo) = visitor.
makeWrappers();
1213 physicalDetectorInfo);
1226 const size_t translationMem =
1227 m_stagedIndices.size() * (
sizeof(std::pair<const ComponentID, size_t>) +
sizeof(
void *)) +
1232 [](
size_t acc,
const auto &s) {
return acc + s.capacity(); });
1238 return sizeof(*this) + mapMem + translationMem + fileNamesMem + detectorInfoMem + componentInfoMem;
const std::vector< double > & rhs
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
#define PARALLEL_CRITICAL(name)
ComponentInfo : Provides a component centric view on to the instrument.
std::string fullName(const size_t componentIndex) const
The fully-qualified name of a component ("instrument/bank1/pixel3")
bool isDetector(const size_t componentIndex) const
const std::string & name(const size_t componentIndex) const
static constexpr size_t invalidIndex
Returned by indexOfOrInvalid() for a component ID that is not part of this 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....
const std::vector< detid_t > & detectorIDs() const
Returns a sorted vector of all detector IDs.
Store information about a fitting parameter such as its value if it is constrained or tied.
const std::string & getFunction() const
get function
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.
virtual std::string getFullName() const =0
Get the IComponent full path name.
InstrumentVisitor : Visitor for components with access to Info wrapping features.
std::pair< std::unique_ptr< ComponentInfo >, std::unique_ptr< DetectorInfo > > makeWrappers() const
Make the wrappers from the data collected by walkInstrument(), which must be called first.
std::shared_ptr< const Instrument > getPhysicalInstrument() const
INDIRECT GEOMETRY INSTRUMENTS ONLY: Returns the physical instrument, if one has been specified as dis...
std::pair< std::unique_ptr< ComponentInfo >, std::unique_ptr< DetectorInfo > > makeBeamlineNew(ParameterMap &pmap) const
Return ComponentInfo and DetectorInfo for instrument given by pmap.
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.
const std::string & getFilename() const
const std::string & getDefaultView() const
Get the default type of the instrument view.
const std::string & getDefaultAxis() const
Retrieves from which side the instrument to be viewed from when the instrument viewer first starts,...
const std::string & getXmlText() const
Types::Core::DateAndTime getValidFromDate() const
InstrumentParameterCache & getLogfileCache()
Get information about the parameters described in the instrument definition file and associated param...
Types::Core::DateAndTime getValidToDate() const
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.
ParameterInfo : the named parameters of an instrument, addressed by component index.
Parameter map iterator typedef.
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 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)
std::vector< ComponentID > m_stagedIds
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 rebuildBeamlineFrom(const ParameterMap &source)
Rebuild the 2.0 layers for a map that was copy-constructed from source.
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...
std::shared_ptr< ParameterInfo > rekey(std::shared_ptr< const ComponentIDs > componentIds, std::shared_ptr< const ComponentIndices > componentIndices)
Attach this map to an instrument's component index domain, rekeying its parameters onto the instrumen...
void addParameterFilename(const std::string &filename)
adds a parameter filename that has been loaded
std::shared_ptr< ParameterInfo > m_parameterInfo
The parameter store, owner of the parameter info.
void buildInstrumentMetadata()
Builds m_instrumentMetadata from m_instrument. Requires m_instrument to be set.
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...
std::shared_ptr< Geometry::InstrumentMetadata > m_instrumentMetadata
static const std::string & rot()
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()
Geometry::InstrumentMetadata const & instrumentMetadata() const
Only for use by ExperimentInfo. Returns a reference to the InstrumentMetadata.
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::string componentName(const size_t index) const
The name of the component with this store index.
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.
size_t indexOf(const IComponent *comp) const
Index for a component, or ComponentInfo::invalidIndex if this map holds nothing for it.
std::vector< Entry > entries() const
Every stored parameter with its component's index in the instrument this map belongs to,...
int size() const
Return the size of the map.
std::vector< std::string > m_parameterFileNames
internal list of parameter files loaded
static const std::string & pV3D()
size_t getMemorySize() const
Get the footprint in memory in bytes.
size_t indexForWrite(const IComponent *comp)
As indexOf(), but allocating a staging index for a component of a detached map seen for the first tim...
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::unordered_map< Geometry::IComponent const *, size_t > m_stagedIndices
Staging indices, for the components of a detached map, which has no component indices yet.
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 void saveNexus(Nexus::File *file, const std::string &group, const std::string &contents)
Persist a representation of a Parameter map, as given by asString(), to the open Nexus file.
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::shared_ptr< const ComponentIndices > m_domainIndices
void seedLogfileParameters()
Copies m_instrument's logfile parameters into the store. Requires the beamline to be built.
std::string asString() const
Returns a string with all component names, parameter names and values.
void addFittingParameter(const IComponent *comp, const std::string &name, const std::string &fittingFunction, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Add a fitting parameter.
static std::string asStringEntry(const std::string &component, const Parameter ¶meter)
Returns the asString() entry for one parameter of a component, given as "detID:<id>" or by full name.
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.
std::shared_ptr< Parameter > getRecursiveFittingParameter(const IComponent *comp, const std::string &name, const std::string &fittingFunction) const
Look for a fitting parameter recursively, picking the one whose embedded FitParameter function name m...
static const std::string & rotz()
std::string componentFullName(const size_t index) const
The full name of the component with this store index.
const std::string getShortDescription(const std::string &compName, const std::string &name) const
Get the component tooltip by name.
const std::vector< Geometry::ComponentID > & componentIds() const
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()
std::shared_ptr< Geometry::DetectorInfo > m_detectorInfo
The 2.0 instrument layers, co-owned with the ExperimentInfo that built them.
static const std::string & pString()
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()
std::shared_ptr< Geometry::ComponentInfo > m_componentInfo
std::shared_ptr< const ComponentIDs > m_domainIds
The index domain: the components of the instrument this map is attached to, shared with that instrume...
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.
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()
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 & type() const
Parameter type.
const bool & visible() const
Parameter visibility in InstrumentViewer.
const std::string & name() const
Parameter name.
virtual std::string asString() const
Returns the value of the property as a string.
void debug(const std::string &msg)
Logs at debug level.
void warning(const std::string &msg)
Logs at warning level.
void setX(const double xx) noexcept
Set is x position.
This functor is used as the deleter object of a shared_ptr to effectively erase ownership Raw pointer...
std::shared_ptr< Parameter > Parameter_sptr
Typedef for the shared pointer.
Mantid::Kernel::Logger g_log("Goniometer")
IComponent * ComponentID
Define a type for a unique component identifier.
int32_t detid_t
Typedef for a detector ID.
std::string to_string(const wide_integer< Bits, Signed > &n)