Mantid
Loading...
Searching...
No Matches
IMDDimensionFactory.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10
11#include <Poco/AutoPtr.h>
12#include <Poco/DOM/DOMParser.h>
13#include <Poco/DOM/Document.h>
14#include <Poco/DOM/Element.h>
15#include <Poco/DOM/NamedNodeMap.h>
16#include <Poco/NumberParser.h>
17#include <Poco/XML/XMLException.h>
18#include <memory>
19
20namespace Mantid::Geometry {
21
27IMDDimension_sptr createDimension(const std::string &dimensionXMLString) {
28 Poco::XML::DOMParser pParser;
29 Poco::AutoPtr<Poco::XML::Document> pDoc;
30 try {
31 pDoc = pParser.parseString(dimensionXMLString);
32
33 } catch (Poco::XML::XMLException &ex) {
34 // Transform into std::invalid_argument
35 throw std::invalid_argument(std::string("Invalid string passed to createDimension: ") + ex.what());
36 }
37 return createDimension(*pDoc->documentElement());
38}
39
41IMDDimension_sptr createDimension(const Poco::XML::Element &dimensionXML) {
42 Poco::AutoPtr<Poco::XML::NamedNodeMap> attributes = dimensionXML.attributes();
43
44 // First and only attribute is the dimension id.
45 // Poco::XML::Node* dimensionId = attributes->item(0);
46 const std::string id = dimensionXML.getAttribute("ID"); // dimensionId->innerText();
47 if (id.empty()) {
48 throw std::invalid_argument("Invalid string passed to createDimension: No ID attribute");
49 }
50
51 Poco::XML::Element *nameElement = dimensionXML.getChildElement("Name");
52 if (nullptr == nameElement) {
53 throw std::invalid_argument("Invalid string passed to createDimension: No Name element");
54 }
55 const std::string name = nameElement->innerText();
56
57 Poco::XML::Element *unitsElement = dimensionXML.getChildElement("Units");
58 std::string units = "None";
59 if (nullptr != unitsElement) {
60 // Set units if they exist.
61 units = unitsElement->innerText();
62 }
63
64 Poco::XML::Element *frameElement = dimensionXML.getChildElement("Frame");
65 std::string frame = "Unknown frame";
66 if (nullptr != frameElement) {
67 // Set the frame if it exists
68 frame = frameElement->innerText();
69 }
70
71 Poco::XML::Element *upperBoundsElement = dimensionXML.getChildElement("UpperBounds");
72 if (nullptr == upperBoundsElement) {
73 throw std::invalid_argument("Invalid string passed to createDimension: No UpperBounds element");
74 }
75 Poco::XML::Element *lowerBoundsElement = dimensionXML.getChildElement("LowerBounds");
76 if (nullptr == lowerBoundsElement) {
77 throw std::invalid_argument("Invalid string passed to createDimension: No LowerBounds element");
78 }
79
80 double upperBounds, lowerBounds;
81 try {
82 upperBounds = Poco::NumberParser::parseFloat(upperBoundsElement->innerText());
83 lowerBounds = Poco::NumberParser::parseFloat(lowerBoundsElement->innerText());
84 } catch (Poco::SyntaxException &ex) {
85 throw std::invalid_argument(std::string("Invalid string passed to createDimension: ") + ex.what());
86 }
87
88 Poco::XML::Element *numBinsElement = dimensionXML.getChildElement("NumberOfBins");
89 if (nullptr == numBinsElement) {
90 throw std::invalid_argument("Invalid string passed to createDimension: No NumberOfBins element");
91 }
92 unsigned int nBins;
93 try {
94 nBins = Poco::NumberParser::parseUnsigned(numBinsElement->innerText());
95 } catch (Poco::SyntaxException &ex) {
96 throw std::invalid_argument(std::string("Invalid string passed to createDimension: ") + ex.what());
97 }
98
99 Poco::XML::Element *integrationXML = dimensionXML.getChildElement("Integrated");
100 if (nullptr != integrationXML) {
101 double upperLimit = std::stod(integrationXML->getChildElement("UpperLimit")->innerText());
102 double lowerLimit = std::stod(integrationXML->getChildElement("LowerLimit")->innerText());
103
104 // As it is not currently possible to set integration ranges on a
105 // MDDimension or MDGeometryDescription, boundaries become integration
106 // ranges.
107 upperBounds = upperLimit;
108 lowerBounds = lowerLimit;
109 }
110
111 // Select the unit.
112 MDFrame_const_uptr mdframe = makeMDFrameFactoryChain()->create(MDFrameArgument(frame, units));
113
114 return std::make_shared<MDHistoDimension>(name, id, *mdframe, static_cast<coord_t>(lowerBounds),
115 static_cast<coord_t>(upperBounds), nBins);
116}
117
127IMDDimension_sptr createDimension(const std::string &dimensionXMLString, int nBins, coord_t min, coord_t max) {
128 auto dimension = createDimension(dimensionXMLString);
129 dimension->setRange(nBins, min, max);
130 return dimension;
131}
132
133} // namespace Mantid::Geometry
Input argument type for MDFrameFactory chainable factory.
MANTID_GEOMETRY_DLL IMDDimension_sptr createDimension(const std::string &dimensionXMLString)
Creates IMDDimension objects based on input XML.
std::shared_ptr< IMDDimension > IMDDimension_sptr
Shared Pointer for IMDDimension. Frequently used type in framework.
Definition: IMDDimension.h:98
std::unique_ptr< const MDFrame > MDFrame_const_uptr
Definition: MDFrame.h:37
MDFrameFactory_uptr MANTID_GEOMETRY_DLL makeMDFrameFactoryChain()
Make a complete factory chain.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition: MDTypes.h:27