26#include "MantidTypes/Core/DateAndTime.h"
27#include "MantidTypes/Core/DateAndTimeHelpers.h"
29#include <Poco/DOM/DOMParser.h>
30#include <Poco/DOM/DOMWriter.h>
31#include <Poco/DOM/Document.h>
32#include <Poco/DOM/Element.h>
33#include <Poco/DOM/NodeFilter.h>
34#include <Poco/DOM/NodeIterator.h>
35#include <Poco/DOM/NodeList.h>
37#include <Poco/SAX/AttributesImpl.h>
38#include <Poco/String.h>
39#include <Poco/XML/XMLWriter.h>
41#include <boost/regex.hpp>
43#include <unordered_set>
49using Poco::XML::Document;
50using Poco::XML::DOMParser;
51using Poco::XML::Element;
53using Poco::XML::NodeFilter;
54using Poco::XML::NodeIterator;
55using Poco::XML::NodeList;
67 m_hasParameterElement_beenSet(false), m_haveDefaultFacing(false), m_deltaOffsets(false), m_angleConvertConst(1.0),
68 m_indirectPositions(false), m_cachingOption(NoneApplied) {
79 const std::string &xmlText)
81 m_hasParameterElement_beenSet(false), m_haveDefaultFacing(false), m_deltaOffsets(false), m_angleConvertConst(1.0),
82 m_indirectPositions(false), m_cachingOption(NoneApplied) {
96 const std::string &instName,
const std::string &xmlText)
98 m_hasParameterElement_beenSet(false), m_haveDefaultFacing(false), m_deltaOffsets(false), m_angleConvertConst(1.0),
99 m_indirectPositions(false), m_cachingOption(NoneApplied) {
100 initialise(xmlFile->getFileFullPathStr(), instName, xmlText, expectedCacheFile->getFileFullPathStr());
115 const std::string &xmlText,
const std::string &vtpFilename) {
138 if (vtpFilename.empty()) {
141 m_cacheFile = std::make_shared<const IDFObject>(vtpFilename);
161 if (!(xml.empty())) {
180 throw std::invalid_argument(
"Instrument XML string is empty");
186 }
catch (Poco::Exception &exc) {
187 throw std::invalid_argument(exc.displayText() +
". Unable to parse XML");
189 throw std::invalid_argument(
"Unable to parse XML");
202 const std::string &typeName)
const {
206 .append(
"contains more than one type element named ")
209 std::string(
"XML instrument file contains more than one type element named ")
226 Poco::XML::Element *pRootElem = pDoc->documentElement();
228 if (!pRootElem->hasChildNodes()) {
229 g_log.
error(
"Instrument XML contains no root element.");
237 const std::string filename =
m_xmlFile->getFileFullPathStr();
239 std::vector<Element *> typeElems;
240 std::vector<Element *> compElems;
243 if (typeElems.empty()) {
244 g_log.
error(
"XML file: " + filename +
"contains no type elements.");
296 const std::vector<Element *> &typeElems,
298 const size_t numberOfTypes = typeElems.size();
299 for (
size_t iType = 0; iType < numberOfTypes; ++iType) {
300 Element *pTypeElem = typeElems[iType];
301 std::string typeName = pTypeElem->getAttribute(
"name");
305 Poco::AutoPtr<NodeList> pNL_type_combine_into_one_shape =
306 pTypeElem->getElementsByTagName(
"combine-components-into-one-shape");
307 if (pNL_type_combine_into_one_shape->length() > 0) {
327 const std::string &filename,
328 const std::vector<Element *> &compElems) {
329 if (progressReporter)
332 for (
auto pElem : compElems) {
333 if (progressReporter)
334 progressReporter->
report(
"Loading instrument Definition");
345 for (Node *pNode = pElem->firstChild(); pNode !=
nullptr; pNode = pNode->nextSibling()) {
346 auto pChildElem =
dynamic_cast<Element *
>(pNode);
349 if (pChildElem->tagName() ==
"location") {
352 if (
isAssembly(pElem->getAttribute(
"type"))) {
357 }
else if (pChildElem->tagName() ==
"locations") {
377 const std::string &filename)
const {
378 Poco::AutoPtr<NodeList> pNL_location = pElem->getElementsByTagName(
"location");
379 Poco::AutoPtr<NodeList> pNL_locations = pElem->getElementsByTagName(
"locations");
381 if (pNL_location->length() == 0 && pNL_locations->length() == 0) {
382 g_log.
error(std::string(
"A component element must contain at least one "
383 "<location> or <locations> element") +
384 " even if it is just an empty location element of the form "
387 "<location> or <locations> element") +
388 " even if it is just an empty location element of the form "
403 const std::string &filename)
const {
404 if (idList.
counted !=
static_cast<int>(idList.
vec.size())) {
405 std::stringstream ss1, ss2;
406 ss1 << idList.
vec.size();
408 if (!pElem->hasAttribute(
"idlist")) {
409 g_log.
error(
"No detector ID list found for detectors of type " + pElem->getAttribute(
"type"));
410 }
else if (idList.
vec.empty()) {
411 g_log.
error(
"No detector IDs found for detectors in list " + pElem->getAttribute(
"idlist") +
412 "for detectors of type" + pElem->getAttribute(
"type"));
414 g_log.
error(
"The number of detector IDs listed in idlist named " + pElem->getAttribute(
"idlist") +
415 " is larger than the number of detectors listed in type = " + pElem->getAttribute(
"type"));
418 "Number of IDs listed in idlist (=" + ss1.str() +
") is larger than the number of detectors listed in type = " +
419 pElem->getAttribute(
"type") +
" (=" + ss2.str() +
").",
430 Poco::AutoPtr<NodeList> pNL_parameter = pRootElem->getElementsByTagName(
"parameter");
431 unsigned long numParameter = pNL_parameter->length();
437 NodeIterator it(pRootElem, NodeFilter::SHOW_ELEMENT);
438 Node *pNode = it.nextNode();
440 if (pNode->nodeName() ==
"parameter") {
441 auto pParameterElem =
dynamic_cast<Element *
>(pNode);
444 pNode = it.nextNode();
460 const std::string &filename,
461 const std::vector<Element *> &typeElems,
462 const size_t numberOfTypes) {
463 for (
size_t iType = 0; iType < numberOfTypes; ++iType) {
464 Element *pTypeElem = typeElems[iType];
465 std::string typeName = pTypeElem->getAttribute(
"name");
469 Poco::AutoPtr<NodeList> pNL_type_combine_into_one_shape =
470 pTypeElem->getElementsByTagName(
"combine-components-into-one-shape");
471 if (pNL_type_combine_into_one_shape->length() == 0)
484 if (
auto csgObj = std::dynamic_pointer_cast<CSGObject>(
mapTypeNameToShape[typeName])) {
485 csgObj->setName(
static_cast<int>(iType));
500 Element *pTypeElem,
const std::string &typeName) {
501 Poco::AutoPtr<NodeList> pNL_local = pTypeElem->getElementsByTagName(
"component");
502 if (pNL_local->length() == 0) {
509 if (
auto csgObj = std::dynamic_pointer_cast<CSGObject>(
mapTypeNameToShape[typeName])) {
510 csgObj->setName(
static_cast<int>(iType));
514 if (pTypeElem->hasAttribute(
"outline")) {
515 pTypeElem->setAttribute(
"object_created",
"no");
528 std::vector<Element *> &typeElems,
529 std::vector<Element *> &compElems)
const {
530 for (
auto pNode = pRootElem->firstChild(); pNode !=
nullptr; pNode = pNode->nextSibling()) {
531 auto pElem =
dynamic_cast<Element *
>(pNode);
533 if (pElem->tagName() ==
"type")
534 typeElems.emplace_back(pElem);
535 else if (pElem->tagName() ==
"component")
536 compElems.emplace_back(pElem);
557 const Poco::XML::Element *pCompElem,
IdList &idList) {
562 const Element *pRootLocationsElem = pLocationsDoc->documentElement();
563 const bool assembly =
isAssembly(pCompElem->getAttribute(
"type"));
565 auto *pElem =
dynamic_cast<Poco::XML::Element *
>(pRootLocationsElem->firstChild());
568 if (pElem->tagName() !=
"location") {
569 pElem =
dynamic_cast<Poco::XML::Element *
>(pElem->nextSibling());
579 pElem =
dynamic_cast<Poco::XML::Element *
>(pElem->nextSibling());
594 Poco::XML::DOMWriter writer;
595 writer.setNewLine(
"\n");
596 writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT);
599 std::ofstream outFile(outFilename.c_str());
600 writer.writeNode(outFile, pDoc);
605 if (pElem->hasAttribute(
name)) {
606 const std::string &
value = pElem->getAttribute(
name);
607 if (!
value.empty()) {
609 return std::stod(
value);
611 std::stringstream msg;
612 msg <<
"failed to convert \"" <<
value <<
"\" to double for xml attribute \"" <<
name
613 <<
"\" - using 0. instead";
636 const double angleConvertConst,
const bool deltaOffsets) {
640 if (pElem->hasAttribute(
"rot")) {
641 double rotAngle = angleConvertConst *
attrToDouble(pElem,
"rot");
647 if (pElem->hasAttribute(
"axis-x"))
648 axis_x = std::stod(pElem->getAttribute(
"axis-x"));
649 if (pElem->hasAttribute(
"axis-y"))
650 axis_y = std::stod(pElem->getAttribute(
"axis-y"));
651 if (pElem->hasAttribute(
"axis-z"))
652 axis_z = std::stod(pElem->getAttribute(
"axis-z"));
660 Element *pRecursive =
nullptr;
661 Element *tElem = pElem->getChildElement(
"trans");
662 Element *rElem = pElem->getChildElement(
"rot");
663 bool stillTransElement =
true;
664 bool firstRound =
true;
665 while (stillTransElement) {
670 }
else if (pRecursive !=
nullptr) {
671 tElem = pRecursive->getChildElement(
"trans");
672 rElem = pRecursive->getChildElement(
"rot");
675 if (tElem && rElem) {
680 if (!tElem && !rElem) {
681 stillTransElement =
false;
694 compToGetRot.
setPos(posTrans);
704 double rotAngle = angleConvertConst *
attrToDouble(rElem,
"val");
710 if (rElem->hasAttribute(
"axis-x"))
711 axis_x = std::stod(rElem->getAttribute(
"axis-x"));
712 if (rElem->hasAttribute(
"axis-y"))
713 axis_y = std::stod(rElem->getAttribute(
"axis-y"));
714 if (rElem->hasAttribute(
"axis-z"))
715 axis_z = std::stod(rElem->getAttribute(
"axis-z"));
727 const Poco::XML::Element *pCompElem) {
732 auto pViewLocElem = pCompElem->getChildElement(
"side-by-side-view-location");
755 const Poco::XML::Element *pElem,
756 const double angleConvertConst,
757 const bool deltaOffsets) {
761 if (pElem->hasAttribute(
"r") || pElem->hasAttribute(
"t") || pElem->hasAttribute(
"p") || pElem->hasAttribute(
"R") ||
762 pElem->hasAttribute(
"theta") || pElem->hasAttribute(
"phi")) {
765 double theta = angleConvertConst *
attrToDouble(pElem,
"t");
766 double phi = angleConvertConst *
attrToDouble(pElem,
"p");
768 if (pElem->hasAttribute(
"R"))
770 if (pElem->hasAttribute(
"theta"))
771 theta = angleConvertConst *
attrToDouble(pElem,
"theta");
772 if (pElem->hasAttribute(
"phi"))
786 std::map<const Geometry::IComponent *, SphVec>::iterator it;
796 theta += parent.theta;
799 parentPos.
spherical(parent.r, parent.theta, parent.phi);
815 retVal = absPos - parentPos;
843 if (((pLocElem->tagName()) !=
"location") && ((pLocElem->tagName()) !=
"locations")) {
844 const std::string &tagname = pLocElem->tagName();
845 g_log.
error(
"Argument to function getParentComponent must be a pointer to "
846 "an XML element with tag name location or locations.");
847 throw std::logic_error(std::string(
"Argument to function getParentComponent must be a pointer "
848 "to an XML element") +
849 "with tag name location or locations." +
" The tag name is " + tagname);
855 Node *pCompNode = pLocElem->parentNode();
858 if (pCompNode->nodeType() == 1) {
859 pCompElem =
static_cast<Element *
>(pCompNode);
860 if ((pCompElem->tagName()) !=
"component") {
861 g_log.
error(
"Argument to function getParentComponent must be a XML "
862 "element sitting inside a component element.");
863 throw std::logic_error(
"Argument to function getParentComponent must be "
864 "a XML element sitting inside a component "
868 g_log.
error(
"Argument to function getParentComponent must be a XML element "
869 "whos parent is an element.");
870 throw std::logic_error(
"Argument to function getParentComponent must be a "
871 "XML element whos parent is an element.");
890 const Poco::XML::Element *pCompElem) {
893 if (pElem->hasAttribute(
"name"))
894 retVal = pElem->getAttribute(
"name");
895 else if (pCompElem->hasAttribute(
"name")) {
896 retVal = pCompElem->getAttribute(
"name");
898 retVal = pCompElem->getAttribute(
"type");
909 const std::string filename =
m_xmlFile->getFileFullPathStr();
911 if (!pRootElem->hasAttribute(
"valid-from")) {
915 DateAndTime
d(pRootElem->getAttribute(
"valid-from"));
923 if (!pRootElem->hasAttribute(
"valid-to")) {
924 DateAndTime
d = DateAndTime::getCurrentTime();
931 DateAndTime
d(pRootElem->getAttribute(
"valid-to"));
944 }
else if (input ==
"y") {
946 }
else if (input ==
"z") {
949 std::stringstream msg;
950 msg <<
"Cannot create \"" << label <<
"\" with axis direction other than \"x\", \"y\", or \"z\", found \"" << input
971 Element *offsetElement = defaults->getChildElement(
"offsets");
973 offsets = offsetElement->getAttribute(
"spherical");
974 if (offsets ==
"delta")
978 Element *defaultFacingElement = defaults->getChildElement(
"components-are-facing");
979 if (defaultFacingElement) {
986 Element *defaultView = defaults->getChildElement(
"default-view");
988 m_instrument->setDefaultViewAxis(defaultView->getAttribute(
"axis-view"));
989 if (defaultView->hasAttribute(
"view")) {
990 m_instrument->setDefaultView(defaultView->getAttribute(
"view"));
995 Element *angleUnit = defaults->getChildElement(
"angle");
997 if (angleUnit->getAttribute(
"unit") ==
"radian") {
999 std::map<std::string, std::string> &units =
m_instrument->getLogfileUnit();
1000 units[
"angle"] =
"radian";
1008 if (defaults->getChildElement(
"indirect-neutronic-positions"))
1015 Element *referenceFrameElement = defaults->getChildElement(
"reference-frame");
1017 if (referenceFrameElement) {
1018 using Poco::XML::XMLString;
1020 Element *upElement = referenceFrameElement->getChildElement(
"pointing-up");
1021 Element *alongElement = referenceFrameElement->getChildElement(
"along-beam");
1022 Element *handednessElement = referenceFrameElement->getChildElement(
"handedness");
1023 Element *originElement = referenceFrameElement->getChildElement(
"origin");
1024 Element *thetaSignElement = referenceFrameElement->getChildElement(
"theta-sign");
1027 XMLString s_alongBeam(
"z");
1028 XMLString s_pointingUp(
"y");
1029 XMLString s_handedness(
"right");
1034 s_alongBeam = alongElement->getAttribute(
"axis");
1037 s_pointingUp = upElement->getAttribute(
"axis");
1039 if (handednessElement) {
1040 s_handedness = handednessElement->getAttribute(
"val");
1042 if (originElement) {
1043 s_origin = originElement->getAttribute(
"val");
1047 XMLString s_thetaSign(s_pointingUp);
1048 if (thetaSignElement) {
1049 s_thetaSign = thetaSignElement->getAttribute(
"axis");
1060 std::make_shared<ReferenceFrame>(pointingUp, alongBeam, thetaSign, handedness, s_origin));
1067 Poco::AutoPtr<NodeList> pNLexclude = location->getElementsByTagName(
"exclude");
1068 unsigned long numberExcludeEle = pNLexclude->length();
1069 std::vector<std::string> newExcludeList;
1070 for (
unsigned long i = 0; i < numberExcludeEle; i++) {
1071 auto *pExElem =
static_cast<Element *
>(pNLexclude->item(i));
1072 if (pExElem->hasAttribute(
"sub-part"))
1073 newExcludeList.emplace_back(pExElem->getAttribute(
"sub-part"));
1076 return newExcludeList;
1095 const Poco::XML::Element *pCompElem,
IdList &idList) {
1096 const std::string filename =
m_xmlFile->getFileFullPathStr();
1106 if (pCompElem->hasAttribute(
"idlist")) {
1107 std::string idlist = pCompElem->getAttribute(
"idlist");
1109 if (idlist != idList.
idname) {
1110 Element *pFound = pCompElem->ownerDocument()->getElementById(idlist,
"idname");
1112 if (pFound ==
nullptr) {
1114 "No <idlist> with name idname=\"" + idlist +
"\" present in instrument definition file.", filename);
1128 Element *pType =
getTypeElement[pCompElem->getAttribute(
"type")];
1129 std::string category;
1130 if (pType->hasAttribute(
"is"))
1131 category = pType->getAttribute(
"is");
1132 if (category ==
"SamplePos" || category ==
"samplePos") {
1134 }
else if (pType->hasAttribute(
"outline") && pType->getAttribute(
"outline") !=
"no") {
1154 if (category ==
"SamplePos" || category ==
"samplePos") {
1157 if (category ==
"Source" || category ==
"source") {
1163 Element *neutronic = pLocElem->getChildElement(
"neutronic");
1171 NodeIterator it(pType, NodeFilter::SHOW_ELEMENT);
1173 Node *pNode = it.nextNode();
1175 if (pNode->nodeName() ==
"location") {
1178 const Element *pElem =
static_cast<Element *
>(pNode);
1185 auto inExcluded = find(excludeList.cbegin(), excludeList.cend(),
1187 if (inExcluded == excludeList.end()) {
1198 if (pNode->nodeName() ==
"locations") {
1199 const Element *pLocationsElems =
static_cast<Element *
>(pNode);
1205 pNode = it.nextNode();
1209 if (pType->hasAttribute(
"outline") && pType->getAttribute(
"outline") !=
"no") {
1212 throw std::logic_error(
"Failed to cast ICompAssembly object to ObjCompAssembly");
1214 if (pType->getAttribute(
"object_created") ==
"no") {
1215 pType->setAttribute(
"object_created",
"yes");
1216 std::shared_ptr<Geometry::IObject>
obj = objAss->createOutline();
1220 pType->setAttribute(
"outline",
"no");
1221 g_log.
warning() <<
"Failed to create outline object for assembly " << pType->getAttribute(
"name") <<
'\n';
1230 const Poco::XML::Element *pLocElem,
1231 const Poco::XML::Element *pCompElem,
1232 const std::string &filename,
IdList &idList,
1233 const std::string &category) {
1241 if (idList.
counted >=
static_cast<int>(idList.
vec.size())) {
1242 std::stringstream ss1, ss2;
1243 ss1 << idList.
vec.size();
1245 if (idList.
idname.empty()) {
1246 g_log.
error(
"No list of detector IDs found for location element " +
name);
1249 }
else if (idList.
vec.empty()) {
1250 g_log.
error(
"No detector IDs found for detectors in list " + idList.
idname);
1252 g_log.
error(
"The number of detector IDs listed in idlist named " + idList.
idname +
1253 " is less then the number of detectors");
1256 "Number of IDs listed in idlist (=" + ss1.str() +
") is less than the number of detectors.", filename);
1259 std::string typeName = pCompElem->getAttribute(
"type");
1265 parent->
add(detector);
1280 m_neutronicPos[detector] = pLocElem->getChildElement(
"neutronic");
1284 if (pCompElem->hasAttribute(
"mark-as") || pLocElem->hasAttribute(
"mark-as")) {
1285 g_log.
warning() <<
"Attribute 'mark-as' is a deprecated attribute in "
1286 "Instrument Definition File."
1287 <<
" Please see the deprecated section of "
1288 "docs.mantidproject.org/concepts/InstrumentDefinitionFile for how to remove this "
1289 "warning message\n";
1293 if (category ==
"Monitor" || category ==
"monitor")
1297 if ((pCompElem->hasAttribute(
"mark-as") && pCompElem->getAttribute(
"mark-as") ==
"monitor") ||
1298 (pLocElem->hasAttribute(
"mark-as") && pLocElem->getAttribute(
"mark-as") ==
"monitor")) {
1305 std::stringstream convert;
1306 convert << detector->
getID();
1308 "Detector with ID = " + convert.str() +
" present more then once in XML instrument file", filename);
1320 const Poco::XML::Element *pCompElem,
const std::string &filename,
1321 const Poco::XML::Element *pType) {
1345 std::string idfillorder;
1346 int idstepbyrow = 0;
1352 const std::string shapeType = pType->getAttribute(
"type");
1355 if (pType->hasAttribute(
"xpixels"))
1356 xpixels = std::stoi(pType->getAttribute(
"xpixels"));
1360 if (pType->hasAttribute(
"ypixels"))
1361 ypixels = std::stoi(pType->getAttribute(
"ypixels"));
1365 if (pType->hasAttribute(
"zpixels"))
1366 zpixels = std::stoi(pType->getAttribute(
"zpixels"));
1372 if (pCompElem->hasAttribute(
"idstart"))
1373 idstart = std::stoi(pCompElem->getAttribute(
"idstart"));
1374 if (pCompElem->hasAttribute(
"idfillorder"))
1375 idfillorder = pCompElem->getAttribute(
"idfillorder");
1377 if (!idfillorder.empty() && idfillorder[0] ==
'x')
1378 idstepbyrow = xpixels;
1379 else if (!idfillorder.empty() && idfillorder[0] ==
'y')
1380 idstepbyrow = ypixels;
1382 idstepbyrow = zpixels;
1384 if (pCompElem->hasAttribute(
"idstepbyrow")) {
1385 idstepbyrow = std::stoi(pCompElem->getAttribute(
"idstepbyrow"));
1388 if (pCompElem->hasAttribute(
"idstep"))
1389 idstep = std::stoi(pCompElem->getAttribute(
"idstep"));
1394 bank->initialize(shape, xpixels, xstart, xstep, ypixels, ystart, ystep, zpixels, zstart, zstep, idstart, idfillorder,
1395 idstepbyrow, idstep);
1400 for (
int z = 0;
z < bank->nelements(); ++
z) {
1401 auto zLayer = std::dynamic_pointer_cast<Geometry::ICompAssembly>((*bank)[
z]);
1402 for (
int x = 0;
x < zLayer->nelements(); ++
x) {
1403 auto xColumn = std::dynamic_pointer_cast<Geometry::ICompAssembly>((*zLayer)[
x]);
1404 for (
int y = 0;
y < xColumn->nelements(); ++
y) {
1405 std::shared_ptr<Geometry::Detector> detector = std::dynamic_pointer_cast<Geometry::Detector>((*xColumn)[
y]);
1408 auto *comp =
static_cast<IComponent *
>(detector.get());
1412 m_instrument->markAsDetectorIncomplete(detector.get());
1419 " in XML instrument file" + filename);
1424 const Poco::XML::Element *pLocElem,
1425 const Poco::XML::Element *pCompElem,
1426 const std::string &filename,
1427 const Poco::XML::Element *pType) {
1449 bool idfillbyfirst_y =
true;
1450 int idstepbyrow = 0;
1456 const std::string shapeType = pType->getAttribute(
"type");
1460 if (pType->hasAttribute(
"xpixels"))
1461 xpixels = std::stoi(pType->getAttribute(
"xpixels"));
1465 if (pType->hasAttribute(
"ypixels"))
1466 ypixels = std::stoi(pType->getAttribute(
"ypixels"));
1472 if (pCompElem->hasAttribute(
"idstart"))
1473 idstart = std::stoi(pCompElem->getAttribute(
"idstart"));
1474 if (pCompElem->hasAttribute(
"idfillbyfirst"))
1475 idfillbyfirst_y = (pCompElem->getAttribute(
"idfillbyfirst") ==
"y");
1477 if (idfillbyfirst_y)
1478 idstepbyrow = ypixels;
1480 idstepbyrow = xpixels;
1481 if (pCompElem->hasAttribute(
"idstepbyrow")) {
1482 idstepbyrow = std::stoi(pCompElem->getAttribute(
"idstepbyrow"));
1485 if (pCompElem->hasAttribute(
"idstep"))
1486 idstep = std::stoi(pCompElem->getAttribute(
"idstep"));
1491 bank->initialize(shape, xpixels, xstart, xstep, ypixels, ystart, ystep, idstart, idfillbyfirst_y, idstepbyrow,
1497 for (
int x = 0;
x < bank->nelements();
x++) {
1498 std::shared_ptr<Geometry::ICompAssembly> xColumn = std::dynamic_pointer_cast<Geometry::ICompAssembly>((*bank)[
x]);
1499 for (
int y = 0;
y < xColumn->nelements();
y++) {
1500 std::shared_ptr<Geometry::Detector> detector = std::dynamic_pointer_cast<Geometry::Detector>((*xColumn)[
y]);
1503 auto *comp =
static_cast<IComponent *
>(detector.get());
1507 m_instrument->markAsDetectorIncomplete(detector.get());
1513 name +
" in XML instrument file" + filename);
1518 const Poco::XML::Element *pLocElem,
1519 const Poco::XML::Element *pCompElem,
1520 const std::string &filename,
1521 const Poco::XML::Element *pType) {
1542 bool idfillbyfirst_y =
true;
1543 int idstepbyrow = 0;
1545 std::vector<double> xValues;
1546 std::vector<double> yValues;
1548 std::string typeName = pType->getAttribute(
"name");
1550 if (pType->hasAttribute(
"xpixels"))
1551 xpixels = std::stoi(pType->getAttribute(
"xpixels"));
1552 if (pType->hasAttribute(
"ypixels"))
1553 ypixels = std::stoi(pType->getAttribute(
"ypixels"));
1557 if (pCompElem->hasAttribute(
"idstart"))
1558 idstart = std::stoi(pCompElem->getAttribute(
"idstart"));
1559 if (pCompElem->hasAttribute(
"idfillbyfirst"))
1560 idfillbyfirst_y = (pCompElem->getAttribute(
"idfillbyfirst") ==
"y");
1562 if (idfillbyfirst_y)
1563 idstepbyrow = ypixels;
1565 idstepbyrow = xpixels;
1566 if (pCompElem->hasAttribute(
"idstepbyrow")) {
1567 idstepbyrow = std::stoi(pCompElem->getAttribute(
"idstepbyrow"));
1570 if (pCompElem->hasAttribute(
"idstep"))
1571 idstep = std::stoi(pCompElem->getAttribute(
"idstep"));
1574 Element *pElem =
nullptr;
1575 NodeIterator tags(pCompElem->ownerDocument(), NodeFilter::SHOW_ELEMENT);
1576 Node *pNode = tags.nextNode();
1579 auto *check =
static_cast<Element *
>(pNode);
1580 if (pNode->nodeName() ==
"type" && check->hasAttribute(
"is")) {
1581 std::string is = check->getAttribute(
"is");
1588 pNode = tags.nextNode();
1591 if (pElem ==
nullptr)
1595 Poco::AutoPtr<NodeList> pNL = pElem->getElementsByTagName(
"vertex");
1596 if (pNL->length() == 0)
1599 NodeIterator it(pElem, NodeFilter::SHOW_ELEMENT);
1601 pNode = it.nextNode();
1604 if (pNode->nodeName() ==
"vertex") {
1605 auto *pVertElem =
static_cast<Element *
>(pNode);
1607 if (pVertElem->hasAttribute(
"x"))
1609 if (pVertElem->hasAttribute(
"y"))
1613 pNode = it.nextNode();
1616 V3D zVector(0, 0, 1);
1617 bool isZBeam =
m_instrument->getReferenceFrame()->isVectorPointingAlongBeam(zVector);
1619 bank->initialize(xpixels, ypixels, std::move(xValues), std::move(yValues), isZBeam, idstart, idfillbyfirst_y,
1620 idstepbyrow, idstep);
1625 for (
int x = 0;
x < bank->nelements();
x++) {
1626 std::shared_ptr<Geometry::ICompAssembly> xColumn = std::dynamic_pointer_cast<Geometry::ICompAssembly>((*bank)[
x]);
1627 for (
int y = 0;
y < xColumn->nelements();
y++) {
1628 std::shared_ptr<Geometry::Detector> detector = std::dynamic_pointer_cast<Geometry::Detector>((*xColumn)[
y]);
1631 auto *comp =
static_cast<IComponent *
>(detector.get());
1635 m_instrument->markAsDetectorIncomplete(detector.get());
1641 name +
" in XML instrument file" + filename);
1665 const Poco::XML::Element *pCompElem,
IdList &idList) {
1666 const std::string filename =
m_xmlFile->getFileFullPathStr();
1673 if (pCompElem->hasAttribute(
"idlist")) {
1674 std::string idlist = pCompElem->getAttribute(
"idlist");
1676 if (idlist != idList.
idname) {
1677 Element *pFound = pCompElem->ownerDocument()->getElementById(idlist,
"idname");
1679 if (pFound ==
nullptr) {
1681 "No <idlist> with name idname=\"" + idlist +
"\" present in instrument definition file.", filename);
1694 std::string typeName = pCompElem->getAttribute(
"type");
1697 std::string category;
1698 if (pType->hasAttribute(
"is"))
1699 category = pType->getAttribute(
"is");
1701 static const boost::regex exp(
"Detector|detector|Monitor|monitor");
1710 }
else if (boost::regex_match(category, exp)) {
1716 if (category ==
"SamplePos" || category ==
"samplePos") {
1729 if (category ==
"Source" || category ==
"source") {
1758 const std::string filename =
m_xmlFile->getFileFullPathStr();
1760 if ((pE->tagName()) !=
"idlist") {
1761 g_log.
error(
"Argument to function createIdList must be a pointer to an XML "
1762 "element with tag name idlist.");
1763 throw std::logic_error(
"Argument to function createIdList must be a "
1764 "pointer to an XML element with tag name idlist.");
1769 idList.
idname = pE->getAttribute(
"idname");
1775 if (pE->hasAttribute(
"start")) {
1776 int startID = std::stoi(pE->getAttribute(
"start"));
1779 if (pE->hasAttribute(
"end"))
1780 endID = std::stoi(pE->getAttribute(
"end"));
1785 if (pE->hasAttribute(
"step"))
1786 increment = std::stoi(pE->getAttribute(
"step"));
1788 if (0 == increment) {
1789 std::stringstream ss;
1790 ss <<
"The step element cannot be zero, got start: " << startID <<
", end: " << endID <<
", step: " << increment;
1795 int steps = (endID - startID) / increment;
1797 std::stringstream ss;
1798 ss <<
"The start, end, and step elements do not allow a single id in "
1801 ss <<
"start: " << startID <<
", end: " << endID <<
", step: " << increment;
1806 idList.
vec.reserve(steps);
1807 for (
int i = startID; i != endID + increment; i += increment) {
1808 idList.
vec.emplace_back(i);
1813 Poco::AutoPtr<NodeList> pNL = pE->getElementsByTagName(
"id");
1815 if (pNL->length() == 0) {
1822 NodeIterator it(pE, NodeFilter::SHOW_ELEMENT);
1824 Node *pNode = it.nextNode();
1826 if (pNode->nodeName() ==
"id") {
1827 auto *pIDElem =
static_cast<Element *
>(pNode);
1829 if (pIDElem->hasAttribute(
"val")) {
1830 int valID = std::stoi(pIDElem->getAttribute(
"val"));
1831 idList.
vec.emplace_back(valID);
1832 }
else if (pIDElem->hasAttribute(
"start")) {
1833 int startID = std::stoi(pIDElem->getAttribute(
"start"));
1836 if (pIDElem->hasAttribute(
"end"))
1837 endID = std::stoi(pIDElem->getAttribute(
"end"));
1842 if (pIDElem->hasAttribute(
"step"))
1843 increment = std::stoi(pIDElem->getAttribute(
"step"));
1846 if (0 == increment) {
1847 std::stringstream ss;
1848 ss <<
"The step element cannot be zero, found step: " << increment;
1852 int numSteps = (endID - startID) / increment;
1854 std::stringstream ss;
1855 ss <<
"The start, end, and step elements do not allow a single "
1857 "in the idlist entry - ";
1858 ss <<
"start: " << startID <<
", end: " << endID <<
", step: " << increment;
1863 idList.
vec.reserve(numSteps);
1864 for (
int i = startID; i != endID + increment; i += increment) {
1865 idList.
vec.emplace_back(i);
1869 "id subelement of idlist " + std::string(
"element wrongly specified in XML instrument file"), filename);
1873 pNode = it.nextNode();
1888 const std::string filename =
m_xmlFile->getFileFullPathStr();
1928 const auto facingDirLength = facingDirection.
norm();
1929 if (facingDirLength == 0.0)
1931 facingDirection /= facingDirLength;
1939 R.
rotate(facingDirection);
1942 const auto normalLength = normal.
norm();
1943 if (normalLength == 0.) {
1946 normal /= normalLength;
1948 double theta = (180.0 / M_PI) * facingDirection.
angle(
z);
1950 if (normal.
norm() > 0.0)
1969 if (pElem->hasAttribute(
"r") || pElem->hasAttribute(
"t") || pElem->hasAttribute(
"p") || pElem->hasAttribute(
"R") ||
1970 pElem->hasAttribute(
"theta") || pElem->hasAttribute(
"phi")) {
1975 if (pElem->hasAttribute(
"R"))
1977 if (pElem->hasAttribute(
"theta"))
1979 if (pElem->hasAttribute(
"phi"))
2011 if ((pElem->tagName()) !=
"location") {
2012 g_log.
error(
"Second argument to function setLocation must be a pointer to "
2013 "an XML element with tag name location.");
2014 throw std::logic_error(
"Second argument to function setLocation must be a "
2015 "pointer to an XML element with tag name location.");
2018 Element *facingElem = pElem->getChildElement(
"facing");
2023 if (facingElem->hasAttribute(
"rot")) {
2034 if (facingElem->hasAttribute(
"val"))
2065 const std::string filename =
m_xmlFile->getFileFullPathStr();
2074 Poco::AutoPtr<NodeList> pNL_comp = pElem->childNodes();
2075 unsigned long pNL_comp_length = pNL_comp->length();
2077 for (
unsigned long i = 0; i < pNL_comp_length; i++) {
2080 if (!((pNL_comp->item(i))->nodeType() == Node::ELEMENT_NODE && ((pNL_comp->item(i))->nodeName()) ==
"parameter"))
2083 auto *pParamElem =
static_cast<Element *
>(pNL_comp->item(i));
2085 if (!pParamElem->hasAttribute(
"name"))
2087 "XML element with name or type = " + comp->
getName() +
2088 " contain <parameter> element with no name attribute in XML "
2092 std::string paramName = pParamElem->getAttribute(
"name");
2094 if (paramName ==
"rot" || paramName ==
"pos") {
2096 <<
" contains <parameter> element with name=\"" << paramName <<
"\"."
2097 <<
" This is a reserved Mantid keyword. Please use other name, "
2098 <<
"and see docs.mantidproject.org/concepts/InstrumentDefinitionFile for list of reserved "
2100 <<
" This parameter is ignored";
2104 std::string visible =
"true";
2105 if (pParamElem->hasAttribute(
"visible")) {
2106 visible = pParamElem->getAttribute(
"visible");
2109 DateAndTime validityDate;
2111 if (requestedDate.empty()) {
2112 validityDate = DateAndTime::getCurrentTime();
2114 validityDate.setFromISO8601(requestedDate);
2117 std::string logfileID;
2120 DateAndTime validFrom;
2121 DateAndTime validTo;
2123 std::string type =
"double";
2124 std::string extractSingleValueAs =
"mean";
2127 Poco::AutoPtr<NodeList> pNLvalue = pParamElem->getElementsByTagName(
"value");
2128 size_t numberValueEle = pNLvalue->length();
2129 Element *pValueElem;
2131 Poco::AutoPtr<NodeList> pNLlogfile = pParamElem->getElementsByTagName(
"logfile");
2132 size_t numberLogfileEle = pNLlogfile->length();
2133 Element *pLogfileElem;
2135 Poco::AutoPtr<NodeList> pNLLookUp = pParamElem->getElementsByTagName(
"lookuptable");
2136 size_t numberLookUp = pNLLookUp->length();
2138 Poco::AutoPtr<NodeList> pNLFormula = pParamElem->getElementsByTagName(
"formula");
2139 size_t numberFormula = pNLFormula->length();
2141 if ((numberValueEle > 0 && numberLogfileEle + numberLookUp + numberFormula > 0) ||
2142 (numberValueEle == 0 && numberLogfileEle + numberLookUp + numberFormula > 1)) {
2144 <<
" contains <parameter> element where the value of the "
2145 <<
"parameter has been specified more than once. See "
2146 <<
"docs.mantidproject.org/concepts/InstrumentDefinitionFile for how the value of the "
2147 <<
"parameter is set in this case.";
2150 if (numberValueEle + numberLogfileEle + numberLookUp + numberFormula == 0) {
2152 <<
" contains <parameter> for which no value is specified."
2153 <<
" See docs.mantidproject.org/concepts/InstrumentDefinitionFile for how to set the value"
2154 <<
" of a parameter. This parameter is ignored.";
2158 DateAndTime currentValidFrom;
2159 DateAndTime currentValidTo;
2160 currentValidFrom.setToMinimum();
2161 currentValidTo.setToMaximum();
2165 if (numberValueEle >= 1) {
2166 bool hasValue =
false;
2168 for (
unsigned long j = 0; j < numberValueEle; ++j) {
2169 pValueElem =
static_cast<Element *
>(pNLvalue->item(j));
2171 if (!pValueElem->hasAttribute((
"val")))
2174 validFrom.setToMinimum();
2175 if (pValueElem->hasAttribute(
"valid-from"))
2176 validFrom.setFromISO8601(pValueElem->getAttribute(
"valid-from"));
2178 validTo.setToMaximum();
2179 if (pValueElem->hasAttribute(
"valid-to"))
2180 validTo.setFromISO8601(pValueElem->getAttribute(
"valid-to"));
2182 if (validFrom <= validityDate && validityDate <= validTo &&
2183 (validFrom > currentValidFrom || (validFrom == currentValidFrom && validTo <= currentValidTo))) {
2185 currentValidFrom = validFrom;
2186 currentValidTo = validTo;
2190 value = pValueElem->getAttribute(
"val");
2195 "XML element with name or type = " + comp->
getName() +
2196 " contains <parameter> element with invalid syntax for its "
2197 "subelement <value>. Correct syntax is <value val=\"\"/>",
2201 }
else if (numberLogfileEle >= 1) {
2203 pLogfileElem =
static_cast<Element *
>(pNLlogfile->item(0));
2204 if (!pLogfileElem->hasAttribute(
"id"))
2206 "XML element with name or type = " + comp->
getName() +
2207 " contains <parameter> element with invalid syntax for its "
2208 "subelement logfile>." +
2209 " Correct syntax is <logfile id=\"\"/>",
2211 logfileID = pLogfileElem->getAttribute(
"id");
2213 if (pLogfileElem->hasAttribute(
"eq"))
2214 eq = pLogfileElem->getAttribute(
"eq");
2215 if (pLogfileElem->hasAttribute(
"extract-single-value-as"))
2216 extractSingleValueAs = pLogfileElem->getAttribute(
"extract-single-value-as");
2219 if (pParamElem->hasAttribute(
"type"))
2220 type = pParamElem->getAttribute(
"type");
2225 Poco::AutoPtr<NodeList> pNLFixed = pParamElem->getElementsByTagName(
"fixed");
2226 size_t numberFixed = pNLFixed->length();
2227 if (numberFixed >= 1) {
2233 std::string fittingFunction;
2236 if (type ==
"fitting") {
2237 size_t found = paramName.find(
':');
2238 if (found != std::string::npos) {
2240 size_t index = paramName.find(
':', found + 1);
2241 if (
index != std::string::npos) {
2242 g_log.
error() <<
"Fitting <parameter> in instrument definition file defined "
2244 <<
" more than one column character :. One must used.\n";
2246 fittingFunction = paramName.substr(0, found);
2247 paramName = paramName.substr(found + 1, paramName.size());
2253 std::ostringstream str;
2254 str << paramName <<
"=" <<
value;
2260 std::vector<std::string> constraint(2,
"");
2262 Poco::AutoPtr<NodeList> pNLMin = pParamElem->getElementsByTagName(
"min");
2263 size_t numberMin = pNLMin->length();
2264 Poco::AutoPtr<NodeList> pNLMax = pParamElem->getElementsByTagName(
"max");
2265 size_t numberMax = pNLMax->length();
2267 if (numberMin >= 1) {
2268 auto *pMin =
static_cast<Element *
>(pNLMin->item(0));
2269 constraint[0] = pMin->getAttribute(
"val");
2271 if (numberMax >= 1) {
2272 auto *pMax =
static_cast<Element *
>(pNLMax->item(0));
2273 constraint[1] = pMax->getAttribute(
"val");
2278 std::string penaltyFactor;
2280 Poco::AutoPtr<NodeList> pNL_penaltyFactor = pParamElem->getElementsByTagName(
"penalty-factor");
2281 size_t numberPenaltyFactor = pNL_penaltyFactor->length();
2283 if (numberPenaltyFactor >= 1) {
2284 auto *pPenaltyFactor =
static_cast<Element *
>(pNL_penaltyFactor->item(0));
2285 penaltyFactor = pPenaltyFactor->getAttribute(
"val");
2290 std::vector<std::string> allowedUnits = UnitFactory::Instance().getKeys();
2292 std::shared_ptr<Interpolation> interpolation = std::make_shared<Interpolation>();
2294 if (numberLookUp >= 1) {
2295 auto *pLookUp =
static_cast<Element *
>(pNLLookUp->item(0));
2297 if (pLookUp->hasAttribute(
"interpolation"))
2298 interpolation->setMethod(pLookUp->getAttribute(
"interpolation"));
2299 if (pLookUp->hasAttribute(
"x-unit")) {
2300 std::vector<std::string>::iterator it;
2301 it = find(allowedUnits.begin(), allowedUnits.end(), pLookUp->getAttribute(
"x-unit"));
2302 if (it == allowedUnits.end()) {
2303 g_log.
warning() <<
"x-unit used with interpolation table must be "
2304 "one of the recognised units "
2305 <<
" see http://docs.mantidproject.org/concepts/UnitFactory";
2307 interpolation->setXUnit(pLookUp->getAttribute(
"x-unit"));
2309 if (pLookUp->hasAttribute(
"y-unit")) {
2310 std::vector<std::string>::iterator it;
2311 it = find(allowedUnits.begin(), allowedUnits.end(), pLookUp->getAttribute(
"y-unit"));
2312 if (it == allowedUnits.end()) {
2313 g_log.
warning() <<
"y-unit used with interpolation table must be "
2314 "one of the recognised units "
2315 <<
" see http://docs.mantidproject.org/concepts/UnitFactory";
2317 interpolation->setYUnit(pLookUp->getAttribute(
"y-unit"));
2320 Poco::AutoPtr<NodeList> pNLpoint = pLookUp->getElementsByTagName(
"point");
2321 unsigned long numberPoint = pNLpoint->length();
2323 for (
unsigned long j = 0; j < numberPoint; j++) {
2324 const auto *pPoint =
static_cast<Element *
>(pNLpoint->item(j));
2327 interpolation->addPoint(
x,
y);
2333 std::string formula;
2334 std::string formulaUnit;
2335 std::string resultUnit;
2337 if (numberFormula >= 1) {
2338 auto *pFormula =
static_cast<Element *
>(pNLFormula->item(0));
2339 formula = pFormula->getAttribute(
"eq");
2340 if (pFormula->hasAttribute(
"unit")) {
2341 std::vector<std::string>::iterator it;
2342 it = find(allowedUnits.begin(), allowedUnits.end(), pFormula->getAttribute(
"unit"));
2343 if (it == allowedUnits.end()) {
2344 g_log.
warning() <<
"unit attribute used with formula must be one "
2345 "of the recognized units "
2346 <<
" see http://docs.mantidproject.org/concepts/UnitFactory";
2348 formulaUnit = pFormula->getAttribute(
"unit");
2350 if (pFormula->hasAttribute(
"result-unit"))
2351 resultUnit = pFormula->getAttribute(
"result-unit");
2354 std::string description;
2356 Poco::AutoPtr<NodeList> pNLDescription = pParamElem->getElementsByTagName(
"description");
2357 size_t numberDescription = pNLDescription->length();
2359 if (numberDescription >= 1) {
2361 auto *pDescription =
static_cast<Element *
>(pNLDescription->item(0));
2362 description = pDescription->getAttribute(
"is");
2365 auto cacheKey = std::make_pair(paramName, comp);
2366 auto cacheValue = std::make_shared<XMLInstrumentParameter>(
2367 logfileID,
value, interpolation, formula, formulaUnit, resultUnit, paramName, type, tie, constraint,
2368 penaltyFactor, fittingFunction, extractSingleValueAs, eq, comp,
m_angleConvertConst, description, visible);
2369 auto inserted = logfileCache.emplace(cacheKey, cacheValue);
2370 if (!inserted.second) {
2371 logfileCache[cacheKey] = cacheValue;
2392 const std::string &requestedDate) {
2395 std::map<std::string, std::string> &units = instrument->getLogfileUnit();
2396 std::map<std::string, std::string>::iterator unit_it;
2397 unit_it = units.find(
"angle");
2398 if (unit_it != units.end())
2399 if (unit_it->second ==
"radian")
2402 const std::string elemName =
"component-link";
2403 Poco::AutoPtr<NodeList> pNL_link = pRootElem->getElementsByTagName(elemName);
2404 unsigned long numberLinks = pNL_link->length();
2407 progress->
resetNumSteps(
static_cast<int64_t
>(numberLinks), 0.0, 0.95);
2409 Node *curNode = pRootElem->firstChild();
2411 if (curNode->nodeType() == Node::ELEMENT_NODE && curNode->nodeName() == elemName) {
2412 auto *curElem =
static_cast<Element *
>(curNode);
2417 progress->
report(
"Loading parameters");
2420 std::string
id = curElem->getAttribute(
"id");
2421 std::string
name = curElem->getAttribute(
"name");
2422 std::vector<std::shared_ptr<const Geometry::IComponent>> sharedIComp;
2425 if (
id.length() > 0) {
2427 std::stringstream(
id) >> detid;
2428 std::shared_ptr<const Geometry::IComponent> detector = instrument->getDetector(
static_cast<detid_t>(detid));
2433 g_log.
error() <<
"Error whilst loading parameters. No detector "
2436 g_log.
error() <<
"Please check that your detectors' ids are correct.\n";
2440 sharedIComp.emplace_back(detector);
2445 if (
name.length() > 0) {
2446 auto comp = std::dynamic_pointer_cast<const IComponent>(detector);
2448 bool consistent = (comp->getFullName() ==
name || comp->getName() ==
name);
2450 g_log.
warning() <<
"Error whilst loading parameters. Name '" <<
name <<
"' does not match id '" << detid
2452 g_log.
warning() <<
"Parameters have been applied to detector with id '" << detid
2453 <<
"'. Please check the name is correct.\n";
2460 if (
name.find(
'/', 0) == std::string::npos) {
2463 sharedIComp = instrument->getAllComponentsWithName(
name);
2465 std::shared_ptr<const Geometry::IComponent> shared = instrument->getComponentByName(
name);
2466 sharedIComp.emplace_back(shared);
2470 for (
auto &ptr : sharedIComp) {
2471 std::shared_ptr<const Geometry::Component> sharedComp =
2472 std::dynamic_pointer_cast<const Geometry::Component>(ptr);
2475 if (sharedComp->isParametrized()) {
2476 setLogfile(sharedComp->base(), curElem, instrument->getLogfileCache(), requestedDate);
2478 setLogfile(ptr.get(), curElem, instrument->getLogfileCache(), requestedDate);
2483 curNode = curNode->nextSibling();
2492 const std::string cacheFullPath = cacheToApply->getFileFullPathStr();
2495 std::map<std::string, std::shared_ptr<Geometry::IObject>>::iterator objItr;
2496 std::shared_ptr<Mantid::Geometry::vtkGeometryCacheReader> reader(
2500 if (
auto csgObj = std::dynamic_pointer_cast<CSGObject>(((*objItr).second))) {
2501 csgObj->setVtkGeometryCacheReader(reader);
2519 Poco::File dir = usedCache->getParentDirectory();
2520 if (dir.path().empty() || !dir.exists() || !dir.canWrite()) {
2521 usedCache = std::move(fallBackCache);
2523 g_log.
information() <<
"Geometrycache directory is read only, writing cache "
2524 "to system temp.\n";
2526 }
catch (Poco::FileNotFoundException &) {
2527 g_log.
error() <<
"Unable to find instrument definition while attempting to "
2529 throw std::runtime_error(
"Unable to find instrument definition while "
2530 "attempting to write cache.\n");
2532 const std::string cacheFullPath = usedCache->getFileFullPathStr();
2533 g_log.
notice() <<
"Creating cache in " << cacheFullPath <<
"\n";
2535 std::map<std::string, std::shared_ptr<Geometry::IObject>>::iterator objItr;
2536 std::shared_ptr<Mantid::Geometry::vtkGeometryCacheWriter> writer(
2540 if (
auto csgObj = std::dynamic_pointer_cast<CSGObject>(((*objItr).second))) {
2541 csgObj->setVtkGeometryCacheWriter(writer);
2545 return cachingOption;
2562 }
else if (fallBackCache->exists()) {
2568 return cachingOption;
2581 auto physical = std::make_unique<Instrument>(*
m_instrument);
2583 m_instrument->setPhysicalInstrument(std::move(physical));
2588 if (component.second) {
2594 if (component.second->hasAttribute(
"type") &&
dynamic_cast<ObjComponent *
>(component.first)) {
2595 const Poco::XML::XMLString shapeName = component.second->getAttribute(
"type");
2599 auto objCmpt =
dynamic_cast<ObjComponent *
>(component.first);
2601 objCmpt->
setShape(shapeIt->second);
2610 auto *det =
dynamic_cast<Detector *
>(component.first);
2635 std::map<std::string, Poco::XML::Element *> &getTypeElement) {
2638 if (pElem->tagName() !=
"type")
2640 "must be a pointer to an XML "
2641 "element with tag name type.");
2644 Poco::AutoPtr<NodeList> pNLccioh = pElem->getElementsByTagName(
"combine-components-into-one-shape");
2645 if (pNLccioh->length() == 0) {
2647 "element with tag name type,") +
2648 " which contain a <combine-components-into-one-shape> element.");
2652 Poco::AutoPtr<NodeList> pNLalg = pElem->getElementsByTagName(
"algebra");
2653 if (pNLalg->length() == 0) {
2655 " includes a <combine-components-into-one-shape> element. See "
2656 "docs.mantidproject.org/concepts/InstrumentDefinitionFile.");
2660 Poco::AutoPtr<NodeList> pNL = pElem->getElementsByTagName(
"location");
2661 unsigned long numLocation = pNL->length();
2662 if (numLocation == 0) {
2665 " includes a <combine-components-into-one-shape> element. See "
2666 "docs.mantidproject.org/concepts/InstrumentDefinitionFile.");
2670 Poco::AutoPtr<NodeList> pNL_TransRot = pElem->getElementsByTagName(
"translate-rotate-combined-shape-to");
2671 const Element *pTransRot =
nullptr;
2672 if (pNL_TransRot->length() == 1) {
2673 pTransRot =
static_cast<Element *
>(pNL_TransRot->item(0));
2680 std::unordered_set<Element *> allComponentInType;
2681 std::vector<std::string> allLocationName;
2682 for (
unsigned long i = 0; i < numLocation; i++) {
2683 auto *pLoc =
static_cast<Element *
>(pNL->item(i));
2692 std::string locationElementName = pLoc->getAttribute(
"name");
2693 if (std::find(allLocationName.begin(), allLocationName.end(), locationElementName) == allLocationName.end())
2694 allLocationName.emplace_back(locationElementName);
2697 std::string(
"Names in a <type> element containing ") +
2698 "a <combine-components-into-one-shape> element must be unique. " +
"Here error is that " +
2699 locationElementName +
2700 " appears at least twice. See docs.mantidproject.org/concepts/InstrumentDefinitionFile.");
2703 auto baseCoor = std::make_unique<CompAssembly>(
"base");
2718 baseCoor = std::make_unique<CompAssembly>(
"base");
2728 Poco::AutoPtr<Document> pDoc;
2730 pDoc = pParser.parseString(cuboidStr);
2735 Element *pCuboid = pDoc->documentElement();
2736 Poco::AutoPtr<Node> fisse = (pElem->ownerDocument())->importNode(pCuboid,
true);
2737 pElem->appendChild(fisse);
2739 allComponentInType.insert(pCompElem);
2743 for (
const auto &component : allComponentInType)
2744 pElem->removeChild(component);
2756 const Poco::XML::Element *cuboidEle,
2757 const std::string &cuboidName) {
2758 Element *pElem_lfb =
getShapeElement(cuboidEle,
"left-front-bottom-point");
2759 Element *pElem_lft =
getShapeElement(cuboidEle,
"left-front-top-point");
2760 Element *pElem_lbb =
getShapeElement(cuboidEle,
"left-back-bottom-point");
2761 Element *pElem_rfb =
getShapeElement(cuboidEle,
"right-front-bottom-point");
2775 std::ostringstream obj_str;
2777 obj_str <<
"<cuboid id=\"" << cuboidName <<
"\">";
2778 obj_str <<
"<left-front-bottom-point ";
2779 obj_str <<
"x=\"" << p_lfb.
X();
2780 obj_str <<
"\" y=\"" << p_lfb.
Y();
2781 obj_str <<
"\" z=\"" << p_lfb.
Z();
2783 obj_str <<
"<left-front-top-point ";
2784 obj_str <<
"x=\"" << p_lft.
X();
2785 obj_str <<
"\" y=\"" << p_lft.
Y();
2786 obj_str <<
"\" z=\"" << p_lft.
Z();
2788 obj_str <<
"<left-back-bottom-point ";
2789 obj_str <<
"x=\"" << p_lbb.
X();
2790 obj_str <<
"\" y=\"" << p_lbb.
Y();
2791 obj_str <<
"\" z=\"" << p_lbb.
Z();
2793 obj_str <<
"<right-front-bottom-point ";
2794 obj_str <<
"x=\"" << p_rfb.
X();
2795 obj_str <<
"\" y=\"" << p_rfb.
Y();
2796 obj_str <<
"\" z=\"" << p_rfb.
Z();
2798 obj_str <<
"</cuboid>";
2800 return obj_str.str();
2810 comp->
add(dummyComp);
2828 const std::string &cuboidName) {
2830 Poco::AutoPtr<Document> pDoc;
2832 pDoc = pParser.parseString(cuboidXML);
2837 Element *pCuboid = pDoc->documentElement();
2851Poco::AutoPtr<Poco::XML::Document>
2854 size_t nElements(0);
2855 if (pElem->hasAttribute(
"n-elements")) {
2856 auto n = boost::lexical_cast<int>(
Strings::strip(pElem->getAttribute(
"n-elements")));
2861 nElements =
static_cast<size_t>(
n);
2865 "docs.mantidproject.org/concepts/InstrumentDefinitionFile.");
2869 if (pElem->hasAttribute(
"name")) {
2870 name = pElem->getAttribute(
"name");
2873 int nameCountStart(0);
2874 if (pElem->hasAttribute(
"name-count-start")) {
2875 nameCountStart = boost::lexical_cast<int>(
Strings::strip(pElem->getAttribute(
"name-count-start")));
2878 int nameCountIncrement(1);
2879 if (pElem->hasAttribute(
"name-count-increment")) {
2880 nameCountIncrement = boost::lexical_cast<int>(
Strings::strip(pElem->getAttribute(
"name-count-increment")));
2882 if (nameCountIncrement <= 0)
2887 std::set<std::string> rangeAttrs = {
"x",
"y",
"z",
"r",
"t",
"p",
"rot"};
2892 std::set<std::string> rotAttrs = {
"axis-x",
"axis-y",
"axis-z"};
2895 std::set<std::string> allAttrs;
2896 allAttrs.insert(rangeAttrs.begin(), rangeAttrs.end());
2897 allAttrs.insert(rotAttrs.begin(), rotAttrs.end());
2903 std::map<std::string, double> attrValues;
2906 for (
const auto &attr : allAttrs) {
2907 if (pElem->hasAttribute(attr)) {
2908 attrValues[attr] = boost::lexical_cast<double>(
Strings::strip(pElem->getAttribute(attr)));
2913 std::map<std::string, double> rangeAttrSteps;
2916 for (
const auto &rangeAttr : rangeAttrs) {
2917 std::string endAttr = rangeAttr +
"-end";
2918 if (pElem->hasAttribute(endAttr)) {
2919 if (attrValues.find(rangeAttr) == attrValues.end()) {
2923 double from = attrValues[rangeAttr];
2924 auto to = boost::lexical_cast<double>(
Strings::strip(pElem->getAttribute(endAttr)));
2926 rangeAttrSteps[rangeAttr] = (to - from) / (
static_cast<double>(nElements) - 1);
2930 Poco::AutoPtr<Document> pDoc =
new Document;
2931 Poco::AutoPtr<Element> pRoot = pDoc->createElement(
"expansion-of-locations-element");
2932 pDoc->appendChild(pRoot);
2934 for (
size_t i = 0; i < nElements; ++i) {
2935 Poco::AutoPtr<Element> pLoc = pDoc->createElement(
"location");
2937 if (!
name.empty()) {
2939 pLoc->setAttribute(
"name",
name +
std::to_string(nameCountStart + (i * nameCountIncrement)));
2943 for (
auto &attrValue : attrValues) {
2944 pLoc->setAttribute(attrValue.first, boost::lexical_cast<std::string>(attrValue.second));
2947 if (rangeAttrSteps.find(attrValue.first) != rangeAttrSteps.end()) {
2948 attrValue.second += rangeAttrSteps[attrValue.first];
2952 pRoot->appendChild(pLoc);
2966 if (!filename.empty()) {
2967 Poco::Path path(ConfigService::Instance().getVTPFileDirectory());
2968 path.makeDirectory();
2969 path.append(filename +
".vtp");
2970 retVal = path.toString();
2986 const std::string &
name) {
2989 Poco::AutoPtr<NodeList> pNL = pElem->getElementsByTagName(
name);
2990 if (pNL->length() != 1) {
2991 throw std::invalid_argument(
"XML element: <" + pElem->tagName() +
2992 "> must contain exactly one sub-element with name: <" +
name +
">.");
2994 auto *retVal =
static_cast<Element *
>(pNL->item(0));
3006 if (pElem->hasAttribute(
"R") || pElem->hasAttribute(
"theta") || pElem->hasAttribute(
"phi")) {
3012 }
else if (pElem->hasAttribute(
"r") || pElem->hasAttribute(
"t") || pElem->hasAttribute(
"p"))
3053 const Poco::XML::Element *pLocElem,
3054 std::map<std::string, Poco::XML::Element *> &getTypeElement,
3070 Element *pType =
getTypeElement[pCompElem->getAttribute(
"type")];
3078 Poco::AutoPtr<NodeList> pNL = pType->getElementsByTagName(
"location");
3079 if (pNL->length() == 0) {
3080 return pType->getAttribute(
"name");
3081 }
else if (pNL->length() == 1) {
3082 const auto *pElem =
static_cast<Element *
>(pNL->item(0));
3086 std::string(
"When using <combine-components-into-one-shape> ") +
3087 " the containing component elements are not allowed to contain "
3088 "multiple nested components. See docs.mantidproject.org/concepts/InstrumentDefinitionFile.");
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
double obj
the value of the quadratic function
Class for Assembly of geometric components.
Kernel::V3D getPos() const override
Gets the absolute position of the Parametrized CompAssembly This attempts to read the cached position...
Component is a wrapper for a Component which can modify some of its parameters, e....
void setRot(const Kernel::Quat &) override
Set the orientation Kernel::Quaternion relative to parent (if present)
void setParent(IComponent *) override
Assign a parent IComponent. Previous parent link is lost.
Kernel::V3D getPos() const override
Get the position of the IComponent. Tree structure is traverse through the.
void setPos(double, double, double) override
Set the IComponent position, x, y, z respective to parent (if present)
This class represents a detector - i.e.
detid_t getID() const override
Gets the detector id.
GridDetector is a type of CompAssembly, an assembly of components.
static bool compareName(const std::string &proposedMatch)
Matches name to Structured Detector.
Class for Assembly of geometric components.
virtual int add(IComponent *)=0
Add a component to the assembly.
base class for Geometric IComponent
virtual Kernel::V3D getPos() const =0
Get the position of the IComponent. Tree structure is traverse through the.
virtual void setSideBySideViewPos(const Kernel::V2D &)=0
virtual void setPos(double, double, double)=0
Set the IComponent position, x, y, z respective to parent (if present)
virtual std::shared_ptr< const IComponent > getParent() const =0
Return a pointer to the current parent.
virtual Kernel::Quat getRotation() const =0
Get the absolute orientation of the IComponent.
virtual void translate(const Kernel::V3D &)=0
Copy the Rotation from another IComponent.
virtual void rotate(const Kernel::Quat &)=0
Rotate the IComponent. This is relative to parent.
virtual std::string getName() const =0
Get the IComponent name.
Creates an instrument data from a XML instrument description file.
bool m_deltaOffsets
Flag to indicate whether offsets given in spherical coordinates are to be added to the current positi...
void appendLocations(Geometry::ICompAssembly *parent, const Poco::XML::Element *pLocElems, const Poco::XML::Element *pCompElem, IdList &idList)
Append <locations> in a locations element.
void createNeutronicInstrument()
If appropriate, creates a second instrument containing neutronic detector positions.
std::shared_ptr< Instrument > parseXML(Kernel::ProgressBase *progressReporter)
Parse XML contents.
void createStructuredDetector(Geometry::ICompAssembly *parent, const Poco::XML::Element *pLocElem, const Poco::XML::Element *pCompElem, const std::string &filename, const Poco::XML::Element *pType)
void adjustTypesContainingCombineComponentsElement(ShapeFactory &shapeCreator, const std::string &filename, const std::vector< Poco::XML::Element * > &typeElems, size_t numberOfTypes)
Adjust each type which contains a <combine-components-into-one-shape> element.
void getTypeAndComponentPointers(const Poco::XML::Element *pRootElem, std::vector< Poco::XML::Element * > &typeElems, std::vector< Poco::XML::Element * > &compElems) const
Populate vectors of pointers to type and component xml elements.
void throwIfTypeNameNotUnique(const std::string &filename, const std::string &typeName) const
Throw exception if type name is not unique in the IDF.
std::map< const Geometry::IComponent *, SphVec > m_tempPosHolder
Map to store positions of parent components in spherical coordinates.
void createDetectorOrMonitor(Geometry::ICompAssembly *parent, const Poco::XML::Element *pLocElem, const Poco::XML::Element *pCompElem, const std::string &filename, IdList &idList, const std::string &category)
std::string translateRotateXMLcuboid(Geometry::ICompAssembly *comp, const Poco::XML::Element *cuboidEle, const std::string &cuboidName)
Returns a translated and rotated <cuboid> element.
void createRectangularDetector(Geometry::ICompAssembly *parent, const Poco::XML::Element *pLocElem, const Poco::XML::Element *pCompElem, const std::string &filename, const Poco::XML::Element *pType)
double m_angleConvertConst
when this const equals 1 it means that angle=degree (default) is set in IDF otherwise if this const e...
void appendLeaf(Geometry::ICompAssembly *parent, const Poco::XML::Element *pLocElem, const Poco::XML::Element *pCompElem, IdList &idList)
Add XML element to parent assuming the element contains no other component elements.
std::string getMangledName()
Handle used in the singleton constructor for instrument file should append the value file sha-1 check...
void setComponentLinks(std::shared_ptr< Geometry::Instrument > &instrument, Poco::XML::Element *pRootElem, Kernel::ProgressBase *progress=nullptr, const std::string &requestedDate=std::string())
Add/overwrite any parameters specified in instrument with param values specified in <component-link> ...
void adjust(Poco::XML::Element *pElem, const std::map< std::string, bool > &isTypeAssembly, std::map< std::string, Poco::XML::Element * > &getTypeElement)
Takes as input a <type> element containing a <combine-components-into-one-shape>, and adjust the <typ...
bool m_haveDefaultFacing
True if defaults->components-are-facing is set in instrument def. file.
void setLocation(Geometry::IComponent *comp, const Poco::XML::Element *pElem, const double angleConvertConst, const bool deltaOffsets=false)
Set location (position) of comp as specified in XML location element.
Kernel::V3D m_defaultFacing
Hold default facing position.
CachingOption getAppliedCachingOption() const
Get the applied caching option.
std::map< Geometry::IComponent *, Poco::XML::Element * > m_neutronicPos
A map containing the neutronic position for each detector.
void checkComponentContainsLocationElement(Poco::XML::Element *pElem, const std::string &filename) const
Check component has a <location> or <locations> element.
Kernel::V3D parseFacingElementToV3D(Poco::XML::Element *pElem)
Parse position of facing element to V3D.
void collateTypeInformation(const std::string &filename, const std::vector< Poco::XML::Element * > &typeElems, ShapeFactory &shapeCreator)
Collect some information about types for later use.
IDFObject_const_sptr m_cacheFile
Input vtp file.
void setSideBySideViewLocation(Geometry::IComponent *comp, const Poco::XML::Element *pCompElem)
Set location (position) of comp as specified in XML side-by-side-view-location element.
std::shared_ptr< Geometry::Instrument > m_instrument
For convenience added pointer to instrument here.
InstrumentDefinitionParser()
Default Constructor - not very functional in this state.
CachingOption writeAndApplyCache(IDFObject_const_sptr firstChoiceCache, IDFObject_const_sptr fallBackCache)
Write out a cache file.
Kernel::V3D parsePosition(Poco::XML::Element *pElem)
Get position coordinates from XML element.
void makeXYplaneFaceComponent(Geometry::IComponent *&in, const Geometry::ObjComponent *facing)
Make the shape defined in 1st argument face the component in the second argument.
Kernel::V3D getRelativeTranslation(const Geometry::IComponent *comp, const Poco::XML::Element *pElem, const double angleConvertConst, const bool deltaOffsets=false)
Calculate the position of comp relative to its parent from info provided by <location> element.
std::vector< Poco::XML::Element * > m_hasParameterElement
Holds all the xml elements that have a <parameter> child element.
void setFacing(Geometry::IComponent *comp, const Poco::XML::Element *pElem)
Set facing of comp as specified in XML facing element.
void readDefaults(Poco::XML::Element *defaults)
Reads the contents of the <defaults> element to set member variables,.
Poco::AutoPtr< Poco::XML::Document > m_pDoc
XML document is lazy loaded.
void populateIdList(Poco::XML::Element *pE, IdList &idList)
Method for populating IdList.
std::map< std::string, std::shared_ptr< Geometry::IObject > > mapTypeNameToShape
map which maps the type name to a shared pointer to a geometric shape
void createShapeIfTypeIsNotAnAssembly(Mantid::Geometry::ShapeFactory &shapeCreator, size_t iType, Poco::XML::Element *pTypeElem, const std::string &typeName)
Record type as an assembly if it contains a component, otherwise create a shape for it.
std::map< std::string, bool > isTypeAssembly
map which holds names of types and whether or not they are categorized as being assemblies,...
void setLogfile(const Geometry::IComponent *comp, const Poco::XML::Element *pElem, InstrumentParameterCache &logfileCache, const std::string &requestedDate=std::string())
Set parameter/logfile info (if any) associated with component.
void createGridDetector(Geometry::ICompAssembly *parent, const Poco::XML::Element *pLocElem, const Poco::XML::Element *pCompElem, const std::string &filename, const Poco::XML::Element *pType)
const std::string createVTPFileName()
creates a vtp filename from a given xml filename
void parseLocationsForEachTopLevelComponent(Kernel::ProgressBase *progressReporter, const std::string &filename, const std::vector< Poco::XML::Element * > &compElems)
Aggregate locations and IDs for components.
static Poco::XML::Element * getParentComponent(const Poco::XML::Element *pLocElem)
Get parent component element of location element.
std::map< std::string, Poco::XML::Element * > getTypeElement
map which holds names of types and pointers to these type for fast retrieval in code
Poco::XML::Element * getShapeElement(const Poco::XML::Element *pElem, const std::string &name)
Return a subelement of an XML element.
void appendAssembly(Geometry::ICompAssembly *parent, const Poco::XML::Element *pLocElem, const Poco::XML::Element *pCompElem, IdList &idList)
Add XML element to parent assuming the element contains other component elements.
std::vector< std::string > buildExcludeList(const Poco::XML::Element *const location)
void createVectorOfElementsContainingAParameterElement(Poco::XML::Element *pRootElem)
Create a vector of elements which contain a <parameter>
std::string getShapeCoorSysComp(Geometry::ICompAssembly *parent, const Poco::XML::Element *pLocElem, std::map< std::string, Poco::XML::Element * > &getTypeElement, Geometry::ICompAssembly *&endAssembly)
This method returns the parent appended which its child components and also name of type of the last ...
CachingOption setupGeometryCache()
Reads in or creates the geometry cache ('vtp') file.
void setValidityRange(const Poco::XML::Element *pRootElem)
Check the validity range and add it to the instrument object.
bool m_hasParameterElement_beenSet
has m_hasParameterElement been set - used when public method setComponentLinks is used
IDFObject_const_sptr m_xmlFile
Input xml file.
double attrToDouble(const Poco::XML::Element *pElem, const std::string &name)
return 0 if the attribute doesn't exist.
void initialise(const std::string &filename, const std::string &instName, const std::string &xmlText, const std::string &vtpFilename)
shared Constructor logic
Poco::AutoPtr< Poco::XML::Document > convertLocationsElement(const Poco::XML::Element *pElem)
Take as input a <locations> element.
std::vector< Geometry::ObjComponent * > m_facingComponent
Container to hold all detectors and monitors added to the instrument.
std::string m_instName
Name of the instrument.
Kernel::V3D getAbsolutPositionInCompCoorSys(Geometry::ICompAssembly *comp, Kernel::V3D)
return absolute position of point which is set relative to the coordinate system of the input compone...
static std::string getNameOfLocationElement(const Poco::XML::Element *pElem, const Poco::XML::Element *pCompElem)
get name of location element
Poco::AutoPtr< Poco::XML::Document > getDocument()
lazy loads the document and returns a pointer
bool isAssembly(const std::string &) const
Return true if assembly, false if not assembly and throws exception if string not in assembly.
bool m_sideBySideViewLocation_exists
Store if xml text contains side-by-side-view-location string.
bool m_indirectPositions
Flag to indicate whether IDF contains physical & neutronic positions.
void checkIdListExistsAndDefinesEnoughIDs(const IdList &idList, Poco::XML::Element *pElem, const std::string &filename) const
Check IdList.
CachingOption m_cachingOption
Caching applied.
void saveDOM_Tree(const std::string &outFilename)
Save DOM tree to xml file.
void applyCache(const IDFObject_const_sptr &cacheToApply)
Reads from a cache file.
Class for Assembly of geometric components.
Object Component class, this class brings together the physical attributes of the component to the po...
void setShape(std::shared_ptr< const IObject > newShape)
Set a new shape on the component void setShape(std::shared_ptr<const IObject> newShape);.
RectangularDetector is a type of CompAssembly, an assembly of components.
static bool compareName(const std::string &proposedMatch)
Matches name to Structured Detector.
Class originally intended to be used with the DataHandling 'LoadInstrument' algorithm.
std::shared_ptr< CSGObject > createShape(Poco::XML::Element *pElem)
Creates a geometric object from a DOM-element-node pointing to an element whose child nodes contain t...
StructuredDetector is a type of CompAssembly, an assembly of components.
static bool compareName(const std::string &proposedMatch)
Matches name to Structured Detector.
Reads the Geometry Cache from the file to the Object.
Writes the Geometry from Object to Cache.
Exception for when an item is already in a collection.
Exception for errors associated with the instrument definition.
The Logger class is in charge of the publishing messages from the framework through various channels.
void notice(const std::string &msg)
Logs at notice level.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
void resetNumSteps(int64_t nsteps, double start, double end)
Change the number of steps between start/end.
virtual bool hasCancellationBeenRequested() const
Override so that the reporter can inform whether a cancellation request has been used.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
void inverse()
Inverse a quaternion (in the sense of rotation inversion)
void rotate(V3D &) const
Rotate a vector.
Implements a 2-dimensional vector embedded in a 3D space, i.e.
constexpr double X() const noexcept
Get x.
constexpr V3D cross_prod(const V3D &v) const noexcept
Cross product (this * argument)
constexpr double Y() const noexcept
Get y.
void spherical(const double R, const double theta, const double phi) noexcept
Sets the vector position based on spherical coordinates.
double angle(const V3D &) const
Angle between this and another vector.
double norm() const noexcept
constexpr double Z() const noexcept
Get z.
Handedness
Type to distingusih between l and r handedness.
std::map< std::pair< std::string, const IComponent * >, std::shared_ptr< XMLInstrumentParameter > > InstrumentParameterCache
Convenience typedef.
Mantid::Kernel::Logger g_log("Goniometer")
std::shared_ptr< const AbstractIDFObject > IDFObject_const_sptr
PointingAlong axisNameToAxisType(const std::string &label, const std::string &input)
std::shared_ptr< Instrument > Instrument_sptr
Shared pointer to an instrument object.
PointingAlong
Type to describe pointing along options.
MANTID_KERNEL_DLL std::string sha1FromString(const std::string &input)
create a SHA-1 checksum from a string
MANTID_KERNEL_DLL std::string strip(const std::string &A)
strip pre/post spaces
std::string toString(const T &value)
Convert values to strings.
MANTID_KERNEL_DLL V3D normalize(V3D v)
Normalizes a V3D.
Helper class which provides the Collimation Length for SANS instruments.
int32_t detid_t
Typedef for a detector ID.
std::string to_string(const wide_integer< Bits, Signed > &n)
Structure for holding detector IDs.
std::vector< int > vec
list of detector IDs
int counted
Used to count the number of detector encounted so far.
std::string idname
name of idlist
Stripped down vector that holds position in terms of spherical coordinates, Needed when processing in...