21#include <unordered_map>
26using namespace Geometry;
27using namespace Kernel;
30const std::string UNIT_M =
"m";
31const std::string UNIT_CM =
"cm";
32const std::string UNIT_MM =
"mm";
33static const std::unordered_map<std::string, double> unitToMeters{{UNIT_M, 1.0}, {UNIT_CM, 0.01}, {UNIT_MM, 0.001}};
45 std::make_shared<InstrumentValidator>()),
48 "Estimated centre of mass of illuminated sample volume");
50 auto moreThanZero = std::make_shared<BoundedValidator<double>>();
51 moreThanZero->setLower(1e-6);
53 "The size of one side of an integration element cube in {ElementUnits}");
56 std::make_shared<StringListValidator>(std::vector<std::string>{UNIT_M, UNIT_CM, UNIT_MM}),
57 "The units which ElementSize has been provided in");
64 const V3D beamDirection =
m_inputWS->getInstrument()->getBeamDirection();
67 const std::string elementUnits =
getProperty(
"ElementUnits");
69 auto it = unitToMeters.find(elementUnits);
70 if (it == unitToMeters.end()) {
71 throw std::invalid_argument(
"Supported units for ElementUnits are (m, cm, mm), not: " + elementUnits);
92 V3D averagePosInLabFrame;
93 if (
m_inputWS->run().hasProperty(
"GaugeVolume")) {
96 const V3D averagePosInShapeFrame =
98 averagePosInLabFrame = gonioR * averagePosInShapeFrame;
100 setProperty(
"CentreOfMass", std::vector<double>(averagePosInLabFrame));
109 if (raster.l1.size() == 0) {
111 const std::string mess(
"Failed to find any points in the rasterized illumination volume within the sample shape - "
112 "Check sample shape and gauge volume are defined correctly or try reducing the ElementSize");
114 throw std::runtime_error(mess);
125 const std::string mess(
"No shape has been defined for the sample in the input workspace");
127 throw std::invalid_argument(mess);
136 g_log.
information(
"Calculating scattering within the gauge volume defined on the input workspace");
137 const std::string xml =
m_inputWS->run().getProperty(
"GaugeVolume")->value();
144 const auto bbox = gauge->getBoundingBox();
145 const double xLength = bbox.xMax() - bbox.xMin();
146 const double yLength = bbox.yMax() - bbox.yMin();
147 const double zLength = bbox.zMax() - bbox.zMin();
148 const auto numXSlices =
static_cast<size_t>(xLength /
m_cubeSide);
149 const auto numYSlices =
static_cast<size_t>(yLength /
m_cubeSide);
150 const auto numZSlices =
static_cast<size_t>(zLength /
m_cubeSide);
151 if (numXSlices == 0 || numYSlices == 0 || numZSlices == 0) {
152 const std::string mess(
"Gauge volume is too small for the chosen ElementSize - "
153 "try reducing the ElementSize");
155 throw std::runtime_error(mess);
157 const double dx = xLength /
static_cast<double>(numXSlices);
158 const double dy = yLength /
static_cast<double>(numYSlices);
159 const double dz = zLength /
static_cast<double>(numZSlices);
161 V3D sum(0.0, 0.0, 0.0);
163 for (
size_t i = 0; i < numZSlices; ++i) {
164 const double z = (
static_cast<double>(i) + 0.5) * dz + bbox.zMin();
165 for (
size_t j = 0; j < numYSlices; ++j) {
166 const double y = (
static_cast<double>(j) + 0.5) * dy + bbox.yMin();
167 for (
size_t k = 0; k < numXSlices; ++k) {
168 const double x = (
static_cast<double>(k) + 0.5) * dx + bbox.xMin();
173 if (!gauge->isValid(pLab)) {
177 const V3D pShape = gonioIsIdentity ? pLab : gonioRInv * pLab;
178 if (!sampleObject.
isValid(pShape)) {
187 const std::string mess(
"Failed to find any voxels inside both the gauge volume and the sample "
188 "shape - check sample shape and gauge volume are defined correctly or "
189 "try reducing the ElementSize");
191 throw std::runtime_error(mess);
193 sum /=
static_cast<double>(
count);
199 V3D sum = std::accumulate(pos.begin(), pos.end(),
V3D(0.0, 0.0, 0.0));
200 sum /=
static_cast<double>(pos.size());
204 const std::string mess(
"No intersection points found between illumination volume and sample shape - "
205 "Check sample shape and gauge volume are defined correctly or try reducing the ElementSize");
207 throw std::runtime_error(mess);
#define DECLARE_ALGORITHM(classname)
Base class from which all concrete algorithm classes should be derived.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
This class stores information about the sample used in particular run.
const Geometry::IObject & getShape() const
Return the sample shape.
const Geometry::IObject_sptr getShapePtr() const
Return a pointer to the sample shape.
A property class for workspaces.
void init() override
Initialisation code.
const Kernel::V3D rasterizeLabGaugeAndCalculateMeanElementPosition(const Geometry::IObject &sampleObject, const Kernel::Matrix< double > &gonioR)
Rasterise the workspace's lab-frame GaugeVolume directly, transforming each candidate voxel into the ...
const Geometry::IObject_sptr extractValidSampleObject(const API::Sample &sample)
Create the sample object using the Geometry classes, or use the existing one.
const Kernel::V3D rasterizeGaugeVolumeAndCalculateMeanElementPosition(const Kernel::V3D beamDirection, const Geometry::IObject_sptr integrationVolume, const Geometry::IObject_sptr sampleObject)
Calculate as raster of the illumination volume, evaluating which points are within the sample geometr...
void exec() override
Execution code.
double m_cubeSide
Element size of raster.
const Kernel::V3D calcAveragePosition(const std::vector< Kernel::V3D > &pos)
API::MatrixWorkspace_sptr m_inputWS
A pointer to the input workspace.
IObject : Interface for geometry objects.
virtual bool isValid(const Kernel::V3D &) const =0
virtual bool hasValidShape() const =0
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...
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void error(const std::string &msg)
Logs at error level.
void information(const std::string &msg)
Logs at information level.
T Invert()
LU inversion routine.
The concrete, templated class for properties.
MANTID_GEOMETRY_DLL Raster calculate(const Kernel::V3D &beamDirection, const IObject &integShape, const IObject &sampleShape, const double cubeSizeInMetre)
std::shared_ptr< IObject > IObject_sptr
Typdef for a shared pointer.
@ Input
An input workspace.
@ Output
An output workspace.