10#include "Poco/DOM/AutoPtr.h"
11#include "Poco/DOM/DOMParser.h"
12#include "Poco/DOM/Document.h"
13#include "Poco/DOM/NamedNodeMap.h"
14#include "Poco/DOM/NodeFilter.h"
15#include "Poco/DOM/NodeIterator.h"
16#include "Poco/SAX/InputSource.h"
17#include "Poco/SAX/SAXException.h"
19#include <boost/lexical_cast.hpp>
23#include <unordered_map>
44const char *ID_ATT =
"id";
45const char *FORMULA_ATT =
"formula";
46const char *ATOMNUM_ATT =
"atomicnumber";
47const char *MASSNUM_ATT =
"massnumber";
48const char *NDENSITY_ATT =
"numberdensity";
49const char *ZPARAM_ATT =
"zparameter";
50const char *CELLVOL_ATT =
"unitcellvol";
51const char *MASSDENS_ATT =
"massdensity";
52const char *TOTSC_ATT =
"totalscatterxsec";
53const char *COHSC_ATT =
"cohscatterxsec";
54const char *INCOHSC_ATT =
"incohscatterxsec";
55const char *ABSORB_ATT =
"absorptionxsec";
56const char *ATTENPROF_ATT =
"attenuationprofile";
57const char *ATTENPROFX_ATT =
"xrayattenuationprofile";
61 virtual ~BuilderHandle() =
default;
62 virtual void operator()(MaterialBuilder &builder,
const std::string &
value)
const = 0;
64using BuilderHandle_uptr = std::unique_ptr<BuilderHandle>;
67template <
typename ArgType>
using BuilderMethod = MaterialBuilder &(MaterialBuilder::*)(ArgType);
71template <
typename ArgType>
struct TypedBuilderHandle final :
public BuilderHandle {
73 using ValueType =
typename std::remove_const<typename std::remove_reference<ArgType>::type>::type;
75 explicit TypedBuilderHandle(BuilderMethod<ArgType>
m) : BuilderHandle(),
m_method(
m) {}
77 void operator()(MaterialBuilder &builder,
const std::string &
value)
const override {
78 auto typedVal = boost::lexical_cast<ValueType>(
value);
86using Handlers = std::unordered_map<std::string, BuilderHandle_uptr>;
89template <
typename ArgType>
void insertHandle(Handlers *hash,
const std::string &name, BuilderMethod<ArgType>
m) {
90 hash->insert(std::make_pair(name, BuilderHandle_uptr(
new TypedBuilderHandle<ArgType>(
m))));
94const BuilderHandle &findHandle(
const std::string &name) {
95 static Handlers handles;
96 if (handles.empty()) {
112 auto iter = handles.find(name);
113 if (iter != handles.end())
114 return *(iter->second);
116 throw std::runtime_error(
"Unknown material attribute '" + name +
"'");
126void addToBuilder(MaterialBuilder *builder,
const std::string &attr,
const std::string &
value) {
130 const auto &setter = findHandle(attr);
131 setter(*builder,
value);
149 using DocumentPtr = AutoPtr<Document>;
151 InputSource src(istr);
157 doc = parser.parse(&src);
158 }
catch (SAXParseException &exc) {
159 std::ostringstream os;
160 os <<
"MaterialXMLReader::read() - Error parsing stream as XML: " << exc.what();
161 throw std::invalid_argument(os.str());
164 Element *rootElement = doc->documentElement();
167 NodeIterator nodeIter(rootElement, NodeFilter::SHOW_ELEMENT);
168 Node *node = nodeIter.nextNode();
173 matr =
parse(
static_cast<Element *
>(node));
177 node = nodeIter.nextNode();
180 throw std::invalid_argument(
"MaterialXMLReader::read() - No material tags found.");
196 using NamedNodeMapPtr = AutoPtr<NamedNodeMap>;
197 NamedNodeMapPtr attrs = element->attributes();
198 const auto id = attrs->getNamedItem(ID_ATT);
199 if (!
id || id->nodeValue().empty()) {
200 throw std::invalid_argument(
"MaterialXMLReader::read() - No 'id' tag found "
201 "or emptry string provided.");
203 attrs->removeNamedItem(ID_ATT);
206 builder.
setName(id->nodeValue());
208 const auto nattrs = attrs->length();
209 for (
unsigned long i = 0; i < nattrs; ++i) {
210 Node *node = attrs->item(i);
211 addToBuilder(&builder, node->nodeName(), node->nodeValue());
213 return builder.
build();
double value
The value of the point.
BuilderMethod< ArgType > m_method
Create a material from a set of user defined options.
MaterialBuilder & setMassDensity(double massDensity)
Set the mass density of the sample in g / cc.
MaterialBuilder & setAttenuationProfileFilename(std::string filename)
Set a value for the attenuation profile filename.
Material build() const
Build the new Material object from the current set of options.
MaterialBuilder & setName(const std::string &name)
Set the string name given to the material.
MaterialBuilder & setMassNumber(int massNumber)
Set the isotope by mass number.
MaterialBuilder & setFormula(const std::string &formula)
Set the chemical formula of the material.
MaterialBuilder & setZParameter(double zparam)
Set the number of formula units in the unit cell.
MaterialBuilder & setTotalScatterXSection(double xsec)
Set a value for the total scattering cross section.
MaterialBuilder & setUnitCellVolume(double cellVolume)
Set the volume of unit cell.
MaterialBuilder & setAbsorptionXSection(double xsec)
Set a value for the absorption cross section.
void setAttenuationSearchPath(std::string path)
Set a value for the attenuation profile search path.
MaterialBuilder & setCoherentXSection(double xsec)
Set a value for the coherent scattering cross section.
MaterialBuilder & setIncoherentXSection(double xsec)
Set a value for the incoherent scattering cross section.
MaterialBuilder & setNumberDensity(double rho)
Set the number density of the sample in atoms or formula units / Angstrom^3.
MaterialBuilder & setAtomicNumber(int atomicNumber)
Set the type of atom by its atomic number.
MaterialBuilder & setXRayAttenuationProfileFilename(std::string filename)
Set a value for the attenuation profile filename.
Material parse(std::istream &istr) const
Takes a stream that is assumed to contain a single complete material definition, reads the definition...
static constexpr const char * MATERIAL_TAG
A material is defined as being composed of a given element, defined as a PhysicalConstants::NeutronAt...