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>
36#include <Poco/SAX/AttributesImpl.h>
37#include <Poco/String.h>
38#include <Poco/XML/XMLWriter.h>
40#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.");
298 const std::vector<Element *> &typeElems,
300 const size_t numberOfTypes = typeElems.size();
301 for (
size_t iType = 0; iType < numberOfTypes; ++iType) {
302 Element *pTypeElem = typeElems[iType];
303 std::string typeName = pTypeElem->getAttribute(
"name");
307 Poco::AutoPtr<NodeList> pNL_type_combine_into_one_shape =
308 pTypeElem->getElementsByTagName(
"combine-components-into-one-shape");
309 if (pNL_type_combine_into_one_shape->length() > 0) {
329 const std::string &filename,
330 const std::vector<Element *> &compElems) {
331 if (progressReporter)
334 for (
auto pElem : compElems) {
335 if (progressReporter)
336 progressReporter->
report(
"Loading instrument Definition");
347 for (Node *pNode = pElem->firstChild(); pNode !=
nullptr; pNode = pNode->nextSibling()) {
348 auto pChildElem =
dynamic_cast<Element *
>(pNode);
351 if (pChildElem->tagName() ==
"location") {
354 if (
isAssembly(pElem->getAttribute(
"type"))) {
359 }
else if (pChildElem->tagName() ==
"locations") {
379 const std::string &filename)
const {
380 Poco::AutoPtr<NodeList> pNL_location = pElem->getElementsByTagName(
"location");
381 Poco::AutoPtr<NodeList> pNL_locations = pElem->getElementsByTagName(
"locations");
383 if (pNL_location->length() == 0 && pNL_locations->length() == 0) {
384 g_log.
error(std::string(
"A component element must contain at least one "
385 "<location> or <locations> element") +
386 " even if it is just an empty location element of the form "
389 "<location> or <locations> element") +
390 " even if it is just an empty location element of the form "
405 const std::string &filename)
const {
406 if (idList.
counted !=
static_cast<int>(idList.
vec.size())) {
407 std::stringstream ss1, ss2;
408 ss1 << idList.
vec.size();
410 if (!pElem->hasAttribute(
"idlist")) {
411 g_log.
error(
"No detector ID list found for detectors of type " + pElem->getAttribute(
"type"));
412 }
else if (idList.
vec.empty()) {
413 g_log.
error(
"No detector IDs found for detectors in list " + pElem->getAttribute(
"idlist") +
414 "for detectors of type" + pElem->getAttribute(
"type"));
416 g_log.
error(
"The number of detector IDs listed in idlist named " + pElem->getAttribute(
"idlist") +
417 " is larger than the number of detectors listed in type = " + pElem->getAttribute(
"type"));
420 "Number of IDs listed in idlist (=" + ss1.str() +
") is larger than the number of detectors listed in type = " +
421 pElem->getAttribute(
"type") +
" (=" + ss2.str() +
").",
432 Poco::AutoPtr<NodeList> pNL_parameter = pRootElem->getElementsByTagName(
"parameter");
433 unsigned long numParameter = pNL_parameter->length();
439 NodeIterator it(pRootElem, NodeFilter::SHOW_ELEMENT);
440 Node *pNode = it.nextNode();
442 if (pNode->nodeName() ==
"parameter") {
443 auto pParameterElem =
dynamic_cast<Element *
>(pNode);
446 pNode = it.nextNode();
462 const std::string &filename,
463 const std::vector<Element *> &typeElems,
464 const size_t numberOfTypes) {
465 for (
size_t iType = 0; iType < numberOfTypes; ++iType) {
466 Element *pTypeElem = typeElems[iType];
467 std::string typeName = pTypeElem->getAttribute(
"name");
471 Poco::AutoPtr<NodeList> pNL_type_combine_into_one_shape =
472 pTypeElem->getElementsByTagName(
"combine-components-into-one-shape");
473 if (pNL_type_combine_into_one_shape->length() == 0)
486 if (
auto csgObj = std::dynamic_pointer_cast<CSGObject>(
mapTypeNameToShape[typeName])) {
487 csgObj->setName(
static_cast<int>(iType));
502 Element *pTypeElem,
const std::string &typeName) {
503 Poco::AutoPtr<NodeList> pNL_local = pTypeElem->getElementsByTagName(
"component");
504 if (pNL_local->length() == 0) {
511 if (
auto csgObj = std::dynamic_pointer_cast<CSGObject>(
mapTypeNameToShape[typeName])) {
512 csgObj->setName(
static_cast<int>(iType));
516 if (pTypeElem->hasAttribute(
"outline")) {
517 pTypeElem->setAttribute(
"object_created",
"no");
530 std::vector<Element *> &typeElems,
531 std::vector<Element *> &compElems)
const {
532 for (
auto pNode = pRootElem->firstChild(); pNode !=
nullptr; pNode = pNode->nextSibling()) {
533 auto pElem =
dynamic_cast<Element *
>(pNode);
535 if (pElem->tagName() ==
"type")
536 typeElems.emplace_back(pElem);
537 else if (pElem->tagName() ==
"component")
538 compElems.emplace_back(pElem);
559 const Poco::XML::Element *pCompElem,
IdList &idList) {
564 const Element *pRootLocationsElem = pLocationsDoc->documentElement();
565 const bool assembly =
isAssembly(pCompElem->getAttribute(
"type"));
567 auto *pElem =
dynamic_cast<Poco::XML::Element *
>(pRootLocationsElem->firstChild());
570 if (pElem->tagName() !=
"location") {
571 pElem =
dynamic_cast<Poco::XML::Element *
>(pElem->nextSibling());
581 pElem =
dynamic_cast<Poco::XML::Element *
>(pElem->nextSibling());
596 Poco::XML::DOMWriter writer;
597 writer.setNewLine(
"\n");
598 writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT);
601 std::ofstream outFile(outFilename.c_str());
602 writer.writeNode(outFile, pDoc);
607 if (pElem->hasAttribute(
name)) {
608 const std::string &
value = pElem->getAttribute(
name);
609 if (!
value.empty()) {
611 return std::stod(
value);
613 std::stringstream msg;
614 msg <<
"failed to convert \"" <<
value <<
"\" to double for xml attribute \"" <<
name
615 <<
"\" - using 0. instead";
638 const double angleConvertConst,
const bool deltaOffsets) {
642 if (pElem->hasAttribute(
"rot")) {
643 double rotAngle = angleConvertConst *
attrToDouble(pElem,
"rot");
649 if (pElem->hasAttribute(
"axis-x"))
650 axis_x = std::stod(pElem->getAttribute(
"axis-x"));
651 if (pElem->hasAttribute(
"axis-y"))
652 axis_y = std::stod(pElem->getAttribute(
"axis-y"));
653 if (pElem->hasAttribute(
"axis-z"))
654 axis_z = std::stod(pElem->getAttribute(
"axis-z"));
662 Element *pRecursive =
nullptr;
663 Element *tElem = pElem->getChildElement(
"trans");
664 Element *rElem = pElem->getChildElement(
"rot");
665 bool stillTransElement =
true;
666 bool firstRound =
true;
667 while (stillTransElement) {
672 }
else if (pRecursive !=
nullptr) {
673 tElem = pRecursive->getChildElement(
"trans");
674 rElem = pRecursive->getChildElement(
"rot");
677 if (tElem && rElem) {
682 if (!tElem && !rElem) {
683 stillTransElement =
false;
696 compToGetRot.
setPos(posTrans);
706 double rotAngle = angleConvertConst *
attrToDouble(rElem,
"val");
712 if (rElem->hasAttribute(
"axis-x"))
713 axis_x = std::stod(rElem->getAttribute(
"axis-x"));
714 if (rElem->hasAttribute(
"axis-y"))
715 axis_y = std::stod(rElem->getAttribute(
"axis-y"));
716 if (rElem->hasAttribute(
"axis-z"))
717 axis_z = std::stod(rElem->getAttribute(
"axis-z"));
729 const Poco::XML::Element *pCompElem) {
734 auto pViewLocElem = pCompElem->getChildElement(
"side-by-side-view-location");
757 const Poco::XML::Element *pElem,
758 const double angleConvertConst,
759 const bool deltaOffsets) {
763 if (pElem->hasAttribute(
"r") || pElem->hasAttribute(
"t") || pElem->hasAttribute(
"p") || pElem->hasAttribute(
"R") ||
764 pElem->hasAttribute(
"theta") || pElem->hasAttribute(
"phi")) {
767 double theta = angleConvertConst *
attrToDouble(pElem,
"t");
768 double phi = angleConvertConst *
attrToDouble(pElem,
"p");
770 if (pElem->hasAttribute(
"R"))
772 if (pElem->hasAttribute(
"theta"))
773 theta = angleConvertConst *
attrToDouble(pElem,
"theta");
774 if (pElem->hasAttribute(
"phi"))
788 std::map<const Geometry::IComponent *, SphVec>::iterator it;
798 theta += parent.theta;
801 parentPos.
spherical(parent.r, parent.theta, parent.phi);
817 retVal = absPos - parentPos;
845 if (((pLocElem->tagName()) !=
"location") && ((pLocElem->tagName()) !=
"locations")) {
846 const std::string &tagname = pLocElem->tagName();
847 g_log.
error(
"Argument to function getParentComponent must be a pointer to "
848 "an XML element with tag name location or locations.");
849 throw std::logic_error(std::string(
"Argument to function getParentComponent must be a pointer "
850 "to an XML element") +
851 "with tag name location or locations." +
" The tag name is " + tagname);
857 Node *pCompNode = pLocElem->parentNode();
860 if (pCompNode->nodeType() == 1) {
861 pCompElem =
static_cast<Element *
>(pCompNode);
862 if ((pCompElem->tagName()) !=
"component") {
863 g_log.
error(
"Argument to function getParentComponent must be a XML "
864 "element sitting inside a component element.");
865 throw std::logic_error(
"Argument to function getParentComponent must be "
866 "a XML element sitting inside a component "
870 g_log.
error(
"Argument to function getParentComponent must be a XML element "
871 "whos parent is an element.");
872 throw std::logic_error(
"Argument to function getParentComponent must be a "
873 "XML element whos parent is an element.");
892 const Poco::XML::Element *pCompElem) {
895 if (pElem->hasAttribute(
"name"))
896 retVal = pElem->getAttribute(
"name");
897 else if (pCompElem->hasAttribute(
"name")) {
898 retVal = pCompElem->getAttribute(
"name");
900 retVal = pCompElem->getAttribute(
"type");
911 const std::string filename =
m_xmlFile->getFileFullPathStr();
913 if (!pRootElem->hasAttribute(
"valid-from")) {
917 DateAndTime
d(pRootElem->getAttribute(
"valid-from"));
925 if (!pRootElem->hasAttribute(
"valid-to")) {
926 DateAndTime
d = DateAndTime::getCurrentTime();
933 DateAndTime
d(pRootElem->getAttribute(
"valid-to"));
946 }
else if (input ==
"y") {
948 }
else if (input ==
"z") {
951 std::stringstream msg;
952 msg <<
"Cannot create \"" << label <<
"\" with axis direction other than \"x\", \"y\", or \"z\", found \"" << input
973 Element *offsetElement = defaults->getChildElement(
"offsets");
975 offsets = offsetElement->getAttribute(
"spherical");
976 if (offsets ==
"delta")
980 Element *defaultFacingElement = defaults->getChildElement(
"components-are-facing");
981 if (defaultFacingElement) {
988 Element *defaultView = defaults->getChildElement(
"default-view");
990 m_instrument->setDefaultViewAxis(defaultView->getAttribute(
"axis-view"));
991 if (defaultView->hasAttribute(
"view")) {
992 m_instrument->setDefaultView(defaultView->getAttribute(
"view"));
997 Element *angleUnit = defaults->getChildElement(
"angle");
999 if (angleUnit->getAttribute(
"unit") ==
"radian") {
1001 std::map<std::string, std::string> &units =
m_instrument->getLogfileUnit();
1002 units[
"angle"] =
"radian";
1010 if (defaults->getChildElement(
"indirect-neutronic-positions"))
1017 Element *referenceFrameElement = defaults->getChildElement(
"reference-frame");
1019 if (referenceFrameElement) {
1020 using Poco::XML::XMLString;
1022 Element *upElement = referenceFrameElement->getChildElement(
"pointing-up");
1023 Element *alongElement = referenceFrameElement->getChildElement(
"along-beam");
1024 Element *handednessElement = referenceFrameElement->getChildElement(
"handedness");
1025 Element *originElement = referenceFrameElement->getChildElement(
"origin");
1026 Element *thetaSignElement = referenceFrameElement->getChildElement(
"theta-sign");
1029 XMLString s_alongBeam(
"z");
1030 XMLString s_pointingUp(
"y");
1031 XMLString s_handedness(
"right");
1036 s_alongBeam = alongElement->getAttribute(
"axis");
1039 s_pointingUp = upElement->getAttribute(
"axis");
1041 if (handednessElement) {
1042 s_handedness = handednessElement->getAttribute(
"val");
1044 if (originElement) {
1045 s_origin = originElement->getAttribute(
"val");
1049 XMLString s_thetaSign(s_pointingUp);
1050 if (thetaSignElement) {
1051 s_thetaSign = thetaSignElement->getAttribute(
"axis");
1062 std::make_shared<ReferenceFrame>(pointingUp, alongBeam, thetaSign, handedness, s_origin));
1069 Poco::AutoPtr<NodeList> pNLexclude = location->getElementsByTagName(
"exclude");
1070 unsigned long numberExcludeEle = pNLexclude->length();
1071 std::vector<std::string> newExcludeList;
1072 for (
unsigned long i = 0; i < numberExcludeEle; i++) {
1073 auto *pExElem =
static_cast<Element *
>(pNLexclude->item(i));
1074 if (pExElem->hasAttribute(
"sub-part"))
1075 newExcludeList.emplace_back(pExElem->getAttribute(
"sub-part"));
1078 return newExcludeList;
1097 const Poco::XML::Element *pCompElem,
IdList &idList) {
1098 const std::string filename =
m_xmlFile->getFileFullPathStr();
1108 if (pCompElem->hasAttribute(
"idlist")) {
1109 std::string idlist = pCompElem->getAttribute(
"idlist");
1111 if (idlist != idList.
idname) {
1112 Element *pFound = pCompElem->ownerDocument()->getElementById(idlist,
"idname");
1114 if (pFound ==
nullptr) {
1116 "No <idlist> with name idname=\"" + idlist +
"\" present in instrument definition file.", filename);
1130 Element *pType =
getTypeElement[pCompElem->getAttribute(
"type")];
1131 std::string category;
1132 if (pType->hasAttribute(
"is"))
1133 category = pType->getAttribute(
"is");
1134 if (category ==
"SamplePos" || category ==
"samplePos") {
1136 }
else if (pType->hasAttribute(
"outline") && pType->getAttribute(
"outline") !=
"no") {
1156 if (category ==
"SamplePos" || category ==
"samplePos") {
1159 if (category ==
"Source" || category ==
"source") {
1165 Element *neutronic = pLocElem->getChildElement(
"neutronic");
1173 NodeIterator it(pType, NodeFilter::SHOW_ELEMENT);
1175 Node *pNode = it.nextNode();
1177 if (pNode->nodeName() ==
"location") {
1180 const Element *pElem =
static_cast<Element *
>(pNode);
1187 auto inExcluded = find(excludeList.cbegin(), excludeList.cend(),
1189 if (inExcluded == excludeList.end()) {
1200 if (pNode->nodeName() ==
"locations") {
1201 const Element *pLocationsElems =
static_cast<Element *
>(pNode);
1207 pNode = it.nextNode();
1211 if (pType->hasAttribute(
"outline") && pType->getAttribute(
"outline") !=
"no") {
1214 throw std::logic_error(
"Failed to cast ICompAssembly object to ObjCompAssembly");
1216 if (pType->getAttribute(
"object_created") ==
"no") {
1217 pType->setAttribute(
"object_created",
"yes");
1218 std::shared_ptr<Geometry::IObject>
obj = objAss->createOutline();
1222 pType->setAttribute(
"outline",
"no");
1223 g_log.
warning() <<
"Failed to create outline object for assembly " << pType->getAttribute(
"name") <<
'\n';
1232 const Poco::XML::Element *pLocElem,
1233 const Poco::XML::Element *pCompElem,
1234 const std::string &filename,
IdList &idList,
1235 const std::string &category) {
1243 if (idList.
counted >=
static_cast<int>(idList.
vec.size())) {
1244 std::stringstream ss1, ss2;
1245 ss1 << idList.
vec.size();
1247 if (idList.
idname.empty()) {
1248 g_log.
error(
"No list of detector IDs found for location element " +
name);
1251 }
else if (idList.
vec.empty()) {
1252 g_log.
error(
"No detector IDs found for detectors in list " + idList.
idname);
1254 g_log.
error(
"The number of detector IDs listed in idlist named " + idList.
idname +
1255 " is less then the number of detectors");
1258 "Number of IDs listed in idlist (=" + ss1.str() +
") is less than the number of detectors.", filename);
1261 std::string typeName = pCompElem->getAttribute(
"type");
1267 parent->
add(detector);
1282 m_neutronicPos[detector] = pLocElem->getChildElement(
"neutronic");
1286 if (pCompElem->hasAttribute(
"mark-as") || pLocElem->hasAttribute(
"mark-as")) {
1287 g_log.
warning() <<
"Attribute 'mark-as' is a deprecated attribute in "
1288 "Instrument Definition File."
1289 <<
" Please see the deprecated section of "
1290 "docs.mantidproject.org/concepts/InstrumentDefinitionFile for how to remove this "
1291 "warning message\n";
1295 if (category ==
"Monitor" || category ==
"monitor") {
1299 if ((pCompElem->hasAttribute(
"mark-as") && pCompElem->getAttribute(
"mark-as") ==
"monitor") ||
1300 (pLocElem->hasAttribute(
"mark-as") && pLocElem->getAttribute(
"mark-as") ==
"monitor")) {
1308 std::stringstream convert;
1309 convert << detector->
getID();
1311 "Detector with ID = " + convert.str() +
" present more then once in XML instrument file", filename);
1323 const Poco::XML::Element *pCompElem,
const std::string &filename,
1324 const Poco::XML::Element *pType) {
1348 std::string idfillorder;
1349 int idstepbyrow = 0;
1355 const std::string shapeType = pType->getAttribute(
"type");
1358 if (pType->hasAttribute(
"xpixels"))
1359 xpixels = std::stoi(pType->getAttribute(
"xpixels"));
1363 if (pType->hasAttribute(
"ypixels"))
1364 ypixels = std::stoi(pType->getAttribute(
"ypixels"));
1368 if (pType->hasAttribute(
"zpixels"))
1369 zpixels = std::stoi(pType->getAttribute(
"zpixels"));
1375 if (pCompElem->hasAttribute(
"idstart"))
1376 idstart = std::stoi(pCompElem->getAttribute(
"idstart"));
1377 if (pCompElem->hasAttribute(
"idfillorder"))
1378 idfillorder = pCompElem->getAttribute(
"idfillorder");
1380 if (!idfillorder.empty() && idfillorder[0] ==
'x')
1381 idstepbyrow = xpixels;
1382 else if (!idfillorder.empty() && idfillorder[0] ==
'y')
1383 idstepbyrow = ypixels;
1385 idstepbyrow = zpixels;
1387 if (pCompElem->hasAttribute(
"idstepbyrow")) {
1388 idstepbyrow = std::stoi(pCompElem->getAttribute(
"idstepbyrow"));
1391 if (pCompElem->hasAttribute(
"idstep"))
1392 idstep = std::stoi(pCompElem->getAttribute(
"idstep"));
1397 bank->initialize(shape, xpixels, xstart, xstep, ypixels, ystart, ystep, zpixels, zstart, zstep, idstart, idfillorder,
1398 idstepbyrow, idstep);
1403 for (
int z = 0;
z < bank->nelements(); ++
z) {
1404 auto zLayer = std::dynamic_pointer_cast<Geometry::ICompAssembly>((*bank)[
z]);
1405 for (
int x = 0;
x < zLayer->nelements(); ++
x) {
1406 auto xColumn = std::dynamic_pointer_cast<Geometry::ICompAssembly>((*zLayer)[
x]);
1407 for (
int y = 0;
y < xColumn->nelements(); ++
y) {
1408 std::shared_ptr<Geometry::Detector> detector = std::dynamic_pointer_cast<Geometry::Detector>((*xColumn)[
y]);
1411 auto *comp =
static_cast<IComponent *
>(detector.get());
1415 m_instrument->markAsDetectorIncomplete(detector.get());
1422 " in XML instrument file" + filename);
1427 const Poco::XML::Element *pLocElem,
1428 const Poco::XML::Element *pCompElem,
1429 const std::string &filename,
1430 const Poco::XML::Element *pType) {
1452 bool idfillbyfirst_y =
true;
1453 int idstepbyrow = 0;
1459 const std::string shapeType = pType->getAttribute(
"type");
1463 if (pType->hasAttribute(
"xpixels"))
1464 xpixels = std::stoi(pType->getAttribute(
"xpixels"));
1468 if (pType->hasAttribute(
"ypixels"))
1469 ypixels = std::stoi(pType->getAttribute(
"ypixels"));
1475 if (pCompElem->hasAttribute(
"idstart"))
1476 idstart = std::stoi(pCompElem->getAttribute(
"idstart"));
1477 if (pCompElem->hasAttribute(
"idfillbyfirst"))
1478 idfillbyfirst_y = (pCompElem->getAttribute(
"idfillbyfirst") ==
"y");
1480 if (idfillbyfirst_y)
1481 idstepbyrow = ypixels;
1483 idstepbyrow = xpixels;
1484 if (pCompElem->hasAttribute(
"idstepbyrow")) {
1485 idstepbyrow = std::stoi(pCompElem->getAttribute(
"idstepbyrow"));
1488 if (pCompElem->hasAttribute(
"idstep"))
1489 idstep = std::stoi(pCompElem->getAttribute(
"idstep"));
1494 bank->initialize(shape, xpixels, xstart, xstep, ypixels, ystart, ystep, idstart, idfillbyfirst_y, idstepbyrow,
1500 for (
int x = 0;
x < bank->nelements();
x++) {
1501 std::shared_ptr<Geometry::ICompAssembly> xColumn = std::dynamic_pointer_cast<Geometry::ICompAssembly>((*bank)[
x]);
1502 for (
int y = 0;
y < xColumn->nelements();
y++) {
1503 std::shared_ptr<Geometry::Detector> detector = std::dynamic_pointer_cast<Geometry::Detector>((*xColumn)[
y]);
1506 auto *comp =
static_cast<IComponent *
>(detector.get());
1510 m_instrument->markAsDetectorIncomplete(detector.get());
1516 name +
" in XML instrument file" + filename);
1521 const Poco::XML::Element *pLocElem,
1522 const Poco::XML::Element *pCompElem,
1523 const std::string &filename,
1524 const Poco::XML::Element *pType) {
1545 bool idfillbyfirst_y =
true;
1546 int idstepbyrow = 0;
1548 std::vector<double> xValues;
1549 std::vector<double> yValues;
1551 std::string typeName = pType->getAttribute(
"name");
1553 if (pType->hasAttribute(
"xpixels"))
1554 xpixels = std::stoi(pType->getAttribute(
"xpixels"));
1555 if (pType->hasAttribute(
"ypixels"))
1556 ypixels = std::stoi(pType->getAttribute(
"ypixels"));
1560 if (pCompElem->hasAttribute(
"idstart"))
1561 idstart = std::stoi(pCompElem->getAttribute(
"idstart"));
1562 if (pCompElem->hasAttribute(
"idfillbyfirst"))
1563 idfillbyfirst_y = (pCompElem->getAttribute(
"idfillbyfirst") ==
"y");
1565 if (idfillbyfirst_y)
1566 idstepbyrow = ypixels;
1568 idstepbyrow = xpixels;
1569 if (pCompElem->hasAttribute(
"idstepbyrow")) {
1570 idstepbyrow = std::stoi(pCompElem->getAttribute(
"idstepbyrow"));
1573 if (pCompElem->hasAttribute(
"idstep"))
1574 idstep = std::stoi(pCompElem->getAttribute(
"idstep"));
1577 Element *pElem =
nullptr;
1578 NodeIterator tags(pCompElem->ownerDocument(), NodeFilter::SHOW_ELEMENT);
1579 Node *pNode = tags.nextNode();
1582 auto *check =
static_cast<Element *
>(pNode);
1583 if (pNode->nodeName() ==
"type" && check->hasAttribute(
"is")) {
1584 std::string is = check->getAttribute(
"is");
1591 pNode = tags.nextNode();
1594 if (pElem ==
nullptr)
1598 Poco::AutoPtr<NodeList> pNL = pElem->getElementsByTagName(
"vertex");
1599 if (pNL->length() == 0)
1602 NodeIterator it(pElem, NodeFilter::SHOW_ELEMENT);
1604 pNode = it.nextNode();
1607 if (pNode->nodeName() ==
"vertex") {
1608 auto *pVertElem =
static_cast<Element *
>(pNode);
1610 if (pVertElem->hasAttribute(
"x"))
1612 if (pVertElem->hasAttribute(
"y"))
1616 pNode = it.nextNode();
1619 V3D zVector(0, 0, 1);
1620 bool isZBeam =
m_instrument->getReferenceFrame()->isVectorPointingAlongBeam(zVector);
1622 bank->initialize(xpixels, ypixels, std::move(xValues), std::move(yValues), isZBeam, idstart, idfillbyfirst_y,
1623 idstepbyrow, idstep);
1628 for (
int x = 0;
x < bank->nelements();
x++) {
1629 std::shared_ptr<Geometry::ICompAssembly> xColumn = std::dynamic_pointer_cast<Geometry::ICompAssembly>((*bank)[
x]);
1630 for (
int y = 0;
y < xColumn->nelements();
y++) {
1631 std::shared_ptr<Geometry::Detector> detector = std::dynamic_pointer_cast<Geometry::Detector>((*xColumn)[
y]);
1634 auto *comp =
static_cast<IComponent *
>(detector.get());
1638 m_instrument->markAsDetectorIncomplete(detector.get());
1644 name +
" in XML instrument file" + filename);
1668 const Poco::XML::Element *pCompElem,
IdList &idList) {
1669 const std::string filename =
m_xmlFile->getFileFullPathStr();
1676 if (pCompElem->hasAttribute(
"idlist")) {
1677 std::string idlist = pCompElem->getAttribute(
"idlist");
1679 if (idlist != idList.
idname) {
1680 Element *pFound = pCompElem->ownerDocument()->getElementById(idlist,
"idname");
1682 if (pFound ==
nullptr) {
1684 "No <idlist> with name idname=\"" + idlist +
"\" present in instrument definition file.", filename);
1697 std::string typeName = pCompElem->getAttribute(
"type");
1700 std::string category;
1701 if (pType->hasAttribute(
"is"))
1702 category = pType->getAttribute(
"is");
1704 static const boost::regex exp(
"Detector|detector|Monitor|monitor");
1713 }
else if (boost::regex_match(category, exp)) {
1719 if (category ==
"SamplePos" || category ==
"samplePos") {
1732 if (category ==
"Source" || category ==
"source") {
1761 const std::string filename =
m_xmlFile->getFileFullPathStr();
1763 if ((pE->tagName()) !=
"idlist") {
1764 g_log.
error(
"Argument to function createIdList must be a pointer to an XML "
1765 "element with tag name idlist.");
1766 throw std::logic_error(
"Argument to function createIdList must be a "
1767 "pointer to an XML element with tag name idlist.");
1772 idList.
idname = pE->getAttribute(
"idname");
1778 if (pE->hasAttribute(
"start")) {
1779 int startID = std::stoi(pE->getAttribute(
"start"));
1782 if (pE->hasAttribute(
"end"))
1783 endID = std::stoi(pE->getAttribute(
"end"));
1788 if (pE->hasAttribute(
"step"))
1789 increment = std::stoi(pE->getAttribute(
"step"));
1791 if (0 == increment) {
1792 std::stringstream ss;
1793 ss <<
"The step element cannot be zero, got start: " << startID <<
", end: " << endID <<
", step: " << increment;
1798 int steps = (endID - startID) / increment;
1800 std::stringstream ss;
1801 ss <<
"The start, end, and step elements do not allow a single id in "
1804 ss <<
"start: " << startID <<
", end: " << endID <<
", step: " << increment;
1809 idList.
vec.reserve(steps);
1810 for (
int i = startID; i != endID + increment; i += increment) {
1811 idList.
vec.emplace_back(i);
1816 Poco::AutoPtr<NodeList> pNL = pE->getElementsByTagName(
"id");
1818 if (pNL->length() == 0) {
1825 NodeIterator it(pE, NodeFilter::SHOW_ELEMENT);
1827 Node *pNode = it.nextNode();
1829 if (pNode->nodeName() ==
"id") {
1830 auto *pIDElem =
static_cast<Element *
>(pNode);
1832 if (pIDElem->hasAttribute(
"val")) {
1833 int valID = std::stoi(pIDElem->getAttribute(
"val"));
1834 idList.
vec.emplace_back(valID);
1835 }
else if (pIDElem->hasAttribute(
"start")) {
1836 int startID = std::stoi(pIDElem->getAttribute(
"start"));
1839 if (pIDElem->hasAttribute(
"end"))
1840 endID = std::stoi(pIDElem->getAttribute(
"end"));
1845 if (pIDElem->hasAttribute(
"step"))
1846 increment = std::stoi(pIDElem->getAttribute(
"step"));
1849 if (0 == increment) {
1850 std::stringstream ss;
1851 ss <<
"The step element cannot be zero, found step: " << increment;
1855 int numSteps = (endID - startID) / increment;
1857 std::stringstream ss;
1858 ss <<
"The start, end, and step elements do not allow a single "
1860 "in the idlist entry - ";
1861 ss <<
"start: " << startID <<
", end: " << endID <<
", step: " << increment;
1866 idList.
vec.reserve(numSteps);
1867 for (
int i = startID; i != endID + increment; i += increment) {
1868 idList.
vec.emplace_back(i);
1872 "id subelement of idlist " + std::string(
"element wrongly specified in XML instrument file"), filename);
1876 pNode = it.nextNode();
1891 const std::string filename =
m_xmlFile->getFileFullPathStr();
1931 const auto facingDirLength = facingDirection.
norm();
1932 if (facingDirLength == 0.0)
1934 facingDirection /= facingDirLength;
1942 R.
rotate(facingDirection);
1945 const auto normalLength = normal.
norm();
1946 if (normalLength == 0.) {
1949 normal /= normalLength;
1951 double theta = (180.0 / M_PI) * facingDirection.
angle(
z);
1953 if (normal.
norm() > 0.0)
1972 if (pElem->hasAttribute(
"r") || pElem->hasAttribute(
"t") || pElem->hasAttribute(
"p") || pElem->hasAttribute(
"R") ||
1973 pElem->hasAttribute(
"theta") || pElem->hasAttribute(
"phi")) {
1978 if (pElem->hasAttribute(
"R"))
1980 if (pElem->hasAttribute(
"theta"))
1982 if (pElem->hasAttribute(
"phi"))
2014 if ((pElem->tagName()) !=
"location") {
2015 g_log.
error(
"Second argument to function setLocation must be a pointer to "
2016 "an XML element with tag name location.");
2017 throw std::logic_error(
"Second argument to function setLocation must be a "
2018 "pointer to an XML element with tag name location.");
2021 Element *facingElem = pElem->getChildElement(
"facing");
2026 if (facingElem->hasAttribute(
"rot")) {
2037 if (facingElem->hasAttribute(
"val"))
2068 const std::string filename =
m_xmlFile->getFileFullPathStr();
2077 Poco::AutoPtr<NodeList> pNL_comp = pElem->childNodes();
2078 unsigned long pNL_comp_length = pNL_comp->length();
2080 for (
unsigned long i = 0; i < pNL_comp_length; i++) {
2083 if (!((pNL_comp->item(i))->nodeType() == Node::ELEMENT_NODE && ((pNL_comp->item(i))->nodeName()) ==
"parameter"))
2086 auto *pParamElem =
static_cast<Element *
>(pNL_comp->item(i));
2088 if (!pParamElem->hasAttribute(
"name"))
2090 "XML element with name or type = " + comp->
getName() +
2091 " contain <parameter> element with no name attribute in XML "
2095 std::string paramName = pParamElem->getAttribute(
"name");
2097 if (paramName ==
"rot" || paramName ==
"pos") {
2099 <<
" contains <parameter> element with name=\"" << paramName <<
"\"."
2100 <<
" This is a reserved Mantid keyword. Please use other name, "
2101 <<
"and see docs.mantidproject.org/concepts/InstrumentDefinitionFile for list of reserved "
2103 <<
" This parameter is ignored";
2107 std::string visible =
"true";
2108 if (pParamElem->hasAttribute(
"visible")) {
2109 visible = pParamElem->getAttribute(
"visible");
2112 DateAndTime validityDate;
2114 if (requestedDate.empty()) {
2115 validityDate = DateAndTime::getCurrentTime();
2117 validityDate.setFromISO8601(requestedDate);
2120 std::string logfileID;
2123 DateAndTime validFrom;
2124 DateAndTime validTo;
2126 std::string type =
"double";
2127 std::string extractSingleValueAs =
"mean";
2130 Poco::AutoPtr<NodeList> pNLvalue = pParamElem->getElementsByTagName(
"value");
2131 size_t numberValueEle = pNLvalue->length();
2132 Element *pValueElem;
2134 Poco::AutoPtr<NodeList> pNLlogfile = pParamElem->getElementsByTagName(
"logfile");
2135 size_t numberLogfileEle = pNLlogfile->length();
2136 Element *pLogfileElem;
2138 Poco::AutoPtr<NodeList> pNLLookUp = pParamElem->getElementsByTagName(
"lookuptable");
2139 size_t numberLookUp = pNLLookUp->length();
2141 Poco::AutoPtr<NodeList> pNLFormula = pParamElem->getElementsByTagName(
"formula");
2142 size_t numberFormula = pNLFormula->length();
2144 if ((numberValueEle > 0 && numberLogfileEle + numberLookUp + numberFormula > 0) ||
2145 (numberValueEle == 0 && numberLogfileEle + numberLookUp + numberFormula > 1)) {
2147 <<
" contains <parameter> element where the value of the "
2148 <<
"parameter has been specified more than once. See "
2149 <<
"docs.mantidproject.org/concepts/InstrumentDefinitionFile for how the value of the "
2150 <<
"parameter is set in this case.";
2153 if (numberValueEle + numberLogfileEle + numberLookUp + numberFormula == 0) {
2155 <<
" contains <parameter> for which no value is specified."
2156 <<
" See docs.mantidproject.org/concepts/InstrumentDefinitionFile for how to set the value"
2157 <<
" of a parameter. This parameter is ignored.";
2161 DateAndTime currentValidFrom;
2162 DateAndTime currentValidTo;
2163 currentValidFrom.setToMinimum();
2164 currentValidTo.setToMaximum();
2168 if (numberValueEle >= 1) {
2169 bool hasValue =
false;
2171 for (
unsigned long j = 0; j < numberValueEle; ++j) {
2172 pValueElem =
static_cast<Element *
>(pNLvalue->item(j));
2174 if (!pValueElem->hasAttribute((
"val")))
2177 validFrom.setToMinimum();
2178 if (pValueElem->hasAttribute(
"valid-from"))
2179 validFrom.setFromISO8601(pValueElem->getAttribute(
"valid-from"));
2181 validTo.setToMaximum();
2182 if (pValueElem->hasAttribute(
"valid-to"))
2183 validTo.setFromISO8601(pValueElem->getAttribute(
"valid-to"));
2185 if (validFrom <= validityDate && validityDate <= validTo &&
2186 (validFrom > currentValidFrom || (validFrom == currentValidFrom && validTo <= currentValidTo))) {
2188 currentValidFrom = validFrom;
2189 currentValidTo = validTo;
2193 value = pValueElem->getAttribute(
"val");
2198 "XML element with name or type = " + comp->
getName() +
2199 " contains <parameter> element with invalid syntax for its "
2200 "subelement <value>. Correct syntax is <value val=\"\"/>",
2204 }
else if (numberLogfileEle >= 1) {
2206 pLogfileElem =
static_cast<Element *
>(pNLlogfile->item(0));
2207 if (!pLogfileElem->hasAttribute(
"id"))
2209 "XML element with name or type = " + comp->
getName() +
2210 " contains <parameter> element with invalid syntax for its "
2211 "subelement logfile>." +
2212 " Correct syntax is <logfile id=\"\"/>",
2214 logfileID = pLogfileElem->getAttribute(
"id");
2216 if (pLogfileElem->hasAttribute(
"eq"))
2217 eq = pLogfileElem->getAttribute(
"eq");
2218 if (pLogfileElem->hasAttribute(
"extract-single-value-as"))
2219 extractSingleValueAs = pLogfileElem->getAttribute(
"extract-single-value-as");
2222 if (pParamElem->hasAttribute(
"type"))
2223 type = pParamElem->getAttribute(
"type");
2228 Poco::AutoPtr<NodeList> pNLFixed = pParamElem->getElementsByTagName(
"fixed");
2229 size_t numberFixed = pNLFixed->length();
2230 if (numberFixed >= 1) {
2236 std::string fittingFunction;
2239 if (type ==
"fitting") {
2240 size_t found = paramName.find(
':');
2241 if (found != std::string::npos) {
2243 size_t index = paramName.find(
':', found + 1);
2244 if (
index != std::string::npos) {
2245 g_log.
error() <<
"Fitting <parameter> in instrument definition file defined "
2247 <<
" more than one column character :. One must used.\n";
2249 fittingFunction = paramName.substr(0, found);
2250 paramName = paramName.substr(found + 1, paramName.size());
2256 std::ostringstream str;
2257 str << paramName <<
"=" <<
value;
2263 std::vector<std::string> constraint(2,
"");
2265 Poco::AutoPtr<NodeList> pNLMin = pParamElem->getElementsByTagName(
"min");
2266 size_t numberMin = pNLMin->length();
2267 Poco::AutoPtr<NodeList> pNLMax = pParamElem->getElementsByTagName(
"max");
2268 size_t numberMax = pNLMax->length();
2270 if (numberMin >= 1) {
2271 auto *pMin =
static_cast<Element *
>(pNLMin->item(0));
2272 constraint[0] = pMin->getAttribute(
"val");
2274 if (numberMax >= 1) {
2275 auto *pMax =
static_cast<Element *
>(pNLMax->item(0));
2276 constraint[1] = pMax->getAttribute(
"val");
2281 std::string penaltyFactor;
2283 Poco::AutoPtr<NodeList> pNL_penaltyFactor = pParamElem->getElementsByTagName(
"penalty-factor");
2284 size_t numberPenaltyFactor = pNL_penaltyFactor->length();
2286 if (numberPenaltyFactor >= 1) {
2287 auto *pPenaltyFactor =
static_cast<Element *
>(pNL_penaltyFactor->item(0));
2288 penaltyFactor = pPenaltyFactor->getAttribute(
"val");
2293 std::vector<std::string> allowedUnits = UnitFactory::Instance().getKeys();
2295 std::shared_ptr<Interpolation> interpolation = std::make_shared<Interpolation>();
2297 if (numberLookUp >= 1) {
2298 auto *pLookUp =
static_cast<Element *
>(pNLLookUp->item(0));
2300 if (pLookUp->hasAttribute(
"interpolation"))
2301 interpolation->setMethod(pLookUp->getAttribute(
"interpolation"));
2302 if (pLookUp->hasAttribute(
"x-unit")) {
2303 std::vector<std::string>::iterator it;
2304 it = find(allowedUnits.begin(), allowedUnits.end(), pLookUp->getAttribute(
"x-unit"));
2305 if (it == allowedUnits.end()) {
2306 g_log.
warning() <<
"x-unit used with interpolation table must be "
2307 "one of the recognised units "
2308 <<
" see http://docs.mantidproject.org/concepts/UnitFactory";
2310 interpolation->setXUnit(pLookUp->getAttribute(
"x-unit"));
2312 if (pLookUp->hasAttribute(
"y-unit")) {
2313 std::vector<std::string>::iterator it;
2314 it = find(allowedUnits.begin(), allowedUnits.end(), pLookUp->getAttribute(
"y-unit"));
2315 if (it == allowedUnits.end()) {
2316 g_log.
warning() <<
"y-unit used with interpolation table must be "
2317 "one of the recognised units "
2318 <<
" see http://docs.mantidproject.org/concepts/UnitFactory";
2320 interpolation->setYUnit(pLookUp->getAttribute(
"y-unit"));
2323 Poco::AutoPtr<NodeList> pNLpoint = pLookUp->getElementsByTagName(
"point");
2324 unsigned long numberPoint = pNLpoint->length();
2326 for (
unsigned long j = 0; j < numberPoint; j++) {
2327 const auto *pPoint =
static_cast<Element *
>(pNLpoint->item(j));
2330 interpolation->addPoint(
x,
y);
2336 std::string formula;
2337 std::string formulaUnit;
2338 std::string resultUnit;
2340 if (numberFormula >= 1) {
2341 auto *pFormula =
static_cast<Element *
>(pNLFormula->item(0));
2342 formula = pFormula->getAttribute(
"eq");
2343 if (pFormula->hasAttribute(
"unit")) {
2344 std::vector<std::string>::iterator it;
2345 it = find(allowedUnits.begin(), allowedUnits.end(), pFormula->getAttribute(
"unit"));
2346 if (it == allowedUnits.end()) {
2347 g_log.
warning() <<
"unit attribute used with formula must be one "
2348 "of the recognized units "
2349 <<
" see http://docs.mantidproject.org/concepts/UnitFactory";
2351 formulaUnit = pFormula->getAttribute(
"unit");
2353 if (pFormula->hasAttribute(
"result-unit"))
2354 resultUnit = pFormula->getAttribute(
"result-unit");
2357 std::string description;
2359 Poco::AutoPtr<NodeList> pNLDescription = pParamElem->getElementsByTagName(
"description");
2360 size_t numberDescription = pNLDescription->length();
2362 if (numberDescription >= 1) {
2364 auto *pDescription =
static_cast<Element *
>(pNLDescription->item(0));
2365 description = pDescription->getAttribute(
"is");
2372 const std::string cacheParamKey = fittingFunction.empty() ? paramName : fittingFunction +
":" + paramName;
2373 auto cacheKey = std::make_pair(cacheParamKey, comp);
2374 auto cacheValue = std::make_shared<XMLInstrumentParameter>(
2375 logfileID,
value, interpolation, formula, formulaUnit, resultUnit, paramName, type, tie, constraint,
2376 penaltyFactor, fittingFunction, extractSingleValueAs, eq, comp,
m_angleConvertConst, description, visible);
2377 auto inserted = logfileCache.emplace(cacheKey, cacheValue);
2378 if (!inserted.second) {
2379 logfileCache[cacheKey] = cacheValue;
2398 const std::string &requestedDate) {
2401 std::map<std::string, std::string> &units = instrument->getLogfileUnit();
2402 std::map<std::string, std::string>::iterator unit_it;
2403 unit_it = units.find(
"angle");
2404 if (unit_it != units.end())
2405 if (unit_it->second ==
"radian")
2408 const std::string elemName =
"component-link";
2409 Poco::AutoPtr<NodeList> pNL_link = pRootElem->getElementsByTagName(elemName);
2410 unsigned long numberLinks = pNL_link->length();
2413 progress->
resetNumSteps(
static_cast<int64_t
>(numberLinks), 0.0, 0.95);
2415 Node *curNode = pRootElem->firstChild();
2417 if (curNode->nodeType() == Node::ELEMENT_NODE && curNode->nodeName() == elemName) {
2418 auto *curElem =
static_cast<Element *
>(curNode);
2423 progress->
report(
"Loading parameters");
2426 std::string
id = curElem->getAttribute(
"id");
2427 std::string
name = curElem->getAttribute(
"name");
2428 std::vector<std::shared_ptr<const Geometry::IComponent>> sharedIComp;
2431 if (
id.length() > 0) {
2433 std::stringstream(
id) >> detid;
2434 std::shared_ptr<const Geometry::IComponent> detector = instrument->getDetector(
static_cast<detid_t>(detid));
2439 g_log.
error() <<
"Error whilst loading parameters. No detector "
2442 g_log.
error() <<
"Please check that your detectors' ids are correct.\n";
2446 sharedIComp.emplace_back(detector);
2449 if (
name.length() > 0) {
2450 auto comp = std::dynamic_pointer_cast<const IComponent>(detector);
2452 bool consistent = (comp->getFullName() ==
name || comp->getName() ==
name);
2454 g_log.
warning() <<
"Error whilst loading parameters. Name '" <<
name <<
"' does not match id '" << detid
2456 g_log.
warning() <<
"Parameters have been applied to detector with id '" << detid
2457 <<
"'. Please check the name is correct.\n";
2463 if (
name.find(
'/', 0) == std::string::npos) {
2464 sharedIComp = instrument->getAllComponentsWithName(
name);
2466 std::shared_ptr<const Geometry::IComponent> shared = instrument->getComponentByName(
name);
2467 sharedIComp.emplace_back(shared);
2471 for (
auto &ptr : sharedIComp) {
2472 std::shared_ptr<const Geometry::Component> sharedComp =
2473 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 std::filesystem::path dir = usedCache->getParentDirectory();
2520 if (!dir.empty() && !std::filesystem::exists(dir)) {
2521 usedCache = std::move(fallBackCache);
2523 g_log.
information() <<
"Geometrycache directory does not exist, writing cache "
2524 "to system temp.\n";
2525 }
else if (!dir.empty() && (std::filesystem::status(dir).permissions() & std::filesystem::perms::owner_write) ==
2526 std::filesystem::perms::none) {
2527 usedCache = std::move(fallBackCache);
2529 g_log.
information() <<
"Geometrycache directory is read only, writing cache "
2530 "to system temp.\n";
2532 }
catch (std::filesystem::filesystem_error &) {
2533 g_log.
error() <<
"Unable to find instrument definition while attempting to "
2535 throw std::runtime_error(
"Unable to find instrument definition while "
2536 "attempting to write cache.\n");
2538 const std::string cacheFullPath = usedCache->getFileFullPathStr();
2539 g_log.
notice() <<
"Creating cache in " << cacheFullPath <<
"\n";
2541 std::map<std::string, std::shared_ptr<Geometry::IObject>>::iterator objItr;
2542 std::shared_ptr<Mantid::Geometry::vtkGeometryCacheWriter> writer(
2546 if (
auto csgObj = std::dynamic_pointer_cast<CSGObject>(((*objItr).second))) {
2547 csgObj->setVtkGeometryCacheWriter(writer);
2551 return cachingOption;
2562 std::filesystem::path fallBackPath =
2563 std::filesystem::path(ConfigService::Instance().getTempDir()) / (this->
getMangledName() +
".vtp");
2569 }
else if (fallBackCache->exists()) {
2575 return cachingOption;
2588 auto physical = std::make_unique<Instrument>(*
m_instrument);
2590 m_instrument->setPhysicalInstrument(std::move(physical));
2595 if (component.second) {
2601 if (component.second->hasAttribute(
"type") &&
dynamic_cast<ObjComponent *
>(component.first)) {
2602 const Poco::XML::XMLString shapeName = component.second->getAttribute(
"type");
2606 auto objCmpt =
dynamic_cast<ObjComponent *
>(component.first);
2608 objCmpt->
setShape(shapeIt->second);
2616 auto *det =
dynamic_cast<Detector *
>(component.first);
2641 std::map<std::string, Poco::XML::Element *> &getTypeElement) {
2644 if (pElem->tagName() !=
"type")
2646 "must be a pointer to an XML "
2647 "element with tag name type.");
2650 Poco::AutoPtr<NodeList> pNLccioh = pElem->getElementsByTagName(
"combine-components-into-one-shape");
2651 if (pNLccioh->length() == 0) {
2653 "element with tag name type,") +
2654 " which contain a <combine-components-into-one-shape> element.");
2658 Poco::AutoPtr<NodeList> pNLalg = pElem->getElementsByTagName(
"algebra");
2659 if (pNLalg->length() == 0) {
2661 " includes a <combine-components-into-one-shape> element. See "
2662 "docs.mantidproject.org/concepts/InstrumentDefinitionFile.");
2666 Poco::AutoPtr<NodeList> pNL = pElem->getElementsByTagName(
"location");
2667 unsigned long numLocation = pNL->length();
2668 if (numLocation == 0) {
2671 " includes a <combine-components-into-one-shape> element. See "
2672 "docs.mantidproject.org/concepts/InstrumentDefinitionFile.");
2676 Poco::AutoPtr<NodeList> pNL_TransRot = pElem->getElementsByTagName(
"translate-rotate-combined-shape-to");
2677 const Element *pTransRot =
nullptr;
2678 if (pNL_TransRot->length() == 1) {
2679 pTransRot =
static_cast<Element *
>(pNL_TransRot->item(0));
2686 std::unordered_set<Element *> allComponentInType;
2687 std::vector<std::string> allLocationName;
2688 for (
unsigned long i = 0; i < numLocation; i++) {
2689 auto *pLoc =
static_cast<Element *
>(pNL->item(i));
2698 std::string locationElementName = pLoc->getAttribute(
"name");
2699 if (std::find(allLocationName.begin(), allLocationName.end(), locationElementName) == allLocationName.end())
2700 allLocationName.emplace_back(locationElementName);
2703 std::string(
"Names in a <type> element containing ") +
2704 "a <combine-components-into-one-shape> element must be unique. " +
"Here error is that " +
2705 locationElementName +
2706 " appears at least twice. See docs.mantidproject.org/concepts/InstrumentDefinitionFile.");
2709 auto baseCoor = std::make_unique<CompAssembly>(
"base");
2724 baseCoor = std::make_unique<CompAssembly>(
"base");
2734 Poco::AutoPtr<Document> pDoc;
2736 pDoc = pParser.parseString(cuboidStr);
2741 Element *pCuboid = pDoc->documentElement();
2742 Poco::AutoPtr<Node> fisse = (pElem->ownerDocument())->importNode(pCuboid,
true);
2743 pElem->appendChild(fisse);
2745 allComponentInType.insert(pCompElem);
2749 for (
const auto &component : allComponentInType)
2750 pElem->removeChild(component);
2762 const Poco::XML::Element *cuboidEle,
2763 const std::string &cuboidName) {
2764 Element *pElem_lfb =
getShapeElement(cuboidEle,
"left-front-bottom-point");
2765 Element *pElem_lft =
getShapeElement(cuboidEle,
"left-front-top-point");
2766 Element *pElem_lbb =
getShapeElement(cuboidEle,
"left-back-bottom-point");
2767 Element *pElem_rfb =
getShapeElement(cuboidEle,
"right-front-bottom-point");
2781 std::ostringstream obj_str;
2783 obj_str <<
"<cuboid id=\"" << cuboidName <<
"\">";
2784 obj_str <<
"<left-front-bottom-point ";
2785 obj_str <<
"x=\"" << p_lfb.
X();
2786 obj_str <<
"\" y=\"" << p_lfb.
Y();
2787 obj_str <<
"\" z=\"" << p_lfb.
Z();
2789 obj_str <<
"<left-front-top-point ";
2790 obj_str <<
"x=\"" << p_lft.
X();
2791 obj_str <<
"\" y=\"" << p_lft.
Y();
2792 obj_str <<
"\" z=\"" << p_lft.
Z();
2794 obj_str <<
"<left-back-bottom-point ";
2795 obj_str <<
"x=\"" << p_lbb.
X();
2796 obj_str <<
"\" y=\"" << p_lbb.
Y();
2797 obj_str <<
"\" z=\"" << p_lbb.
Z();
2799 obj_str <<
"<right-front-bottom-point ";
2800 obj_str <<
"x=\"" << p_rfb.
X();
2801 obj_str <<
"\" y=\"" << p_rfb.
Y();
2802 obj_str <<
"\" z=\"" << p_rfb.
Z();
2804 obj_str <<
"</cuboid>";
2806 return obj_str.str();
2816 comp->
add(dummyComp);
2834 const std::string &cuboidName) {
2836 Poco::AutoPtr<Document> pDoc;
2838 pDoc = pParser.parseString(cuboidXML);
2843 Element *pCuboid = pDoc->documentElement();
2857Poco::AutoPtr<Poco::XML::Document>
2860 size_t nElements(0);
2861 if (pElem->hasAttribute(
"n-elements")) {
2862 auto n = boost::lexical_cast<int>(
Strings::strip(pElem->getAttribute(
"n-elements")));
2867 nElements =
static_cast<size_t>(
n);
2871 "docs.mantidproject.org/concepts/InstrumentDefinitionFile.");
2875 if (pElem->hasAttribute(
"name")) {
2876 name = pElem->getAttribute(
"name");
2879 int nameCountStart(0);
2880 if (pElem->hasAttribute(
"name-count-start")) {
2881 nameCountStart = boost::lexical_cast<int>(
Strings::strip(pElem->getAttribute(
"name-count-start")));
2884 int nameCountIncrement(1);
2885 if (pElem->hasAttribute(
"name-count-increment")) {
2886 nameCountIncrement = boost::lexical_cast<int>(
Strings::strip(pElem->getAttribute(
"name-count-increment")));
2888 if (nameCountIncrement <= 0)
2893 std::set<std::string> rangeAttrs = {
"x",
"y",
"z",
"r",
"t",
"p",
"rot"};
2898 std::set<std::string> rotAttrs = {
"axis-x",
"axis-y",
"axis-z"};
2901 std::set<std::string> allAttrs;
2902 allAttrs.insert(rangeAttrs.begin(), rangeAttrs.end());
2903 allAttrs.insert(rotAttrs.begin(), rotAttrs.end());
2909 std::map<std::string, double> attrValues;
2912 for (
const auto &attr : allAttrs) {
2913 if (pElem->hasAttribute(attr)) {
2914 attrValues[attr] = boost::lexical_cast<double>(
Strings::strip(pElem->getAttribute(attr)));
2919 std::map<std::string, double> rangeAttrSteps;
2922 for (
const auto &rangeAttr : rangeAttrs) {
2923 std::string endAttr = rangeAttr +
"-end";
2924 if (pElem->hasAttribute(endAttr)) {
2925 if (attrValues.find(rangeAttr) == attrValues.end()) {
2929 double from = attrValues[rangeAttr];
2930 auto to = boost::lexical_cast<double>(
Strings::strip(pElem->getAttribute(endAttr)));
2932 rangeAttrSteps[rangeAttr] = (to - from) / (
static_cast<double>(nElements) - 1);
2936 Poco::AutoPtr<Document> pDoc =
new Document;
2937 Poco::AutoPtr<Element> pRoot = pDoc->createElement(
"expansion-of-locations-element");
2938 pDoc->appendChild(pRoot);
2940 for (
size_t i = 0; i < nElements; ++i) {
2941 Poco::AutoPtr<Element> pLoc = pDoc->createElement(
"location");
2943 if (!
name.empty()) {
2945 pLoc->setAttribute(
"name",
name +
std::to_string(nameCountStart + (i * nameCountIncrement)));
2949 for (
auto &attrValue : attrValues) {
2950 pLoc->setAttribute(attrValue.first, boost::lexical_cast<std::string>(attrValue.second));
2953 if (rangeAttrSteps.find(attrValue.first) != rangeAttrSteps.end()) {
2954 attrValue.second += rangeAttrSteps[attrValue.first];
2958 pRoot->appendChild(pLoc);
2972 if (!filename.empty()) {
2973 std::filesystem::path path =
2974 std::filesystem::path(ConfigService::Instance().getVTPFileDirectory()) / (filename +
".vtp");
2975 retVal = path.string();
2991 const std::string &
name) {
2994 Poco::AutoPtr<NodeList> pNL = pElem->getElementsByTagName(
name);
2995 if (pNL->length() != 1) {
2996 throw std::invalid_argument(
"XML element: <" + pElem->tagName() +
2997 "> must contain exactly one sub-element with name: <" +
name +
">.");
2999 auto *retVal =
static_cast<Element *
>(pNL->item(0));
3011 if (pElem->hasAttribute(
"R") || pElem->hasAttribute(
"theta") || pElem->hasAttribute(
"phi")) {
3017 }
else if (pElem->hasAttribute(
"r") || pElem->hasAttribute(
"t") || pElem->hasAttribute(
"p"))
3058 const Poco::XML::Element *pLocElem,
3059 std::map<std::string, Poco::XML::Element *> &getTypeElement,
3075 Element *pType =
getTypeElement[pCompElem->getAttribute(
"type")];
3083 Poco::AutoPtr<NodeList> pNL = pType->getElementsByTagName(
"location");
3084 if (pNL->length() == 0) {
3085 return pType->getAttribute(
"name");
3086 }
else if (pNL->length() == 1) {
3087 const auto *pElem =
static_cast<Element *
>(pNL->item(0));
3091 std::string(
"When using <combine-components-into-one-shape> ") +
3092 " the containing component elements are not allowed to contain "
3093 "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
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...