27#include <boost/format.hpp>
50 return "Calculates bin-by-bin correction factors for attenuation due to "
52 "in a cylindrical sample in the wall of a hollow can";
61 auto wsValidator = std::make_shared<CompositeValidator>();
65 "The input workspace in units of wavelength.");
68 "The name to use for the output workspace.");
71 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
72 mustBePositive->setLower(0.0);
73 declareProperty(
"CanOuterRadius", -1.0, mustBePositive,
"The outer radius of the can in centimetres");
74 declareProperty(
"CanInnerRadius", -1.0, mustBePositive,
"The inner radius of the can in centimetres");
77 declareProperty(
"SampleHeight", -1.0, mustBePositive,
"The height of the sample in centimetres");
78 declareProperty(
"SampleThickness", -1.0, mustBePositive,
"The thickness of the sample in centimetres");
79 auto nonEmptyString = std::make_shared<MandatoryValidator<std::string>>();
80 declareProperty(
"SampleChemicalFormula",
"",
"Chemical composition of the sample material", nonEmptyString);
82 "The number density of the sample in number of formulas per "
86 auto positiveInt = std::make_shared<Kernel::BoundedValidator<int>>();
87 positiveInt->setLower(1);
89 "The number of wavelength points for which a simulation is "
90 "atttempted (default: all points)");
92 "The number of \"neutron\" events to generate per simulated point");
93 declareProperty(
"SeedValue", 123456789, positiveInt,
"Seed the random number generator with this value");
125 auto refFrame = inst->getReferenceFrame();
127 bool childLog =
g_log.
is(Logger::Priority::PRIO_DEBUG);
129 alg->setProperty(
"InputWorkspace",
workspace);
132 alg->executeAsChildAlg();
133 }
catch (
const std::exception &exc) {
134 throw std::invalid_argument(std::string(
"Unable to create sample shape: '") + exc.what() +
"'");
153 const double canLowRadiusCM =
getProperty(
"CanInnerRadius");
154 const double canUppRadiusCM =
getProperty(
"CanOuterRadius");
155 const double sampleHeightCM =
getProperty(
"SampleHeight");
156 const double sampleThickCM =
getProperty(
"SampleThickness");
158 const double wallMidPtCM = canLowRadiusCM + 0.5 * (canUppRadiusCM - canLowRadiusCM);
159 const double lowRadiusMtr = (wallMidPtCM - 0.5 * sampleThickCM) / 100.;
160 const double uppRadiusMtr = (wallMidPtCM + 0.5 * sampleThickCM) / 100.;
164 const V3D bottomCentre{0.0, -sampleHeightCM / 2.0 / 100.0, 0.0};
165 const std::string innerCylID = std::string(
"inner-cyl");
166 const std::string innerCyl =
cylinderXML(innerCylID, bottomCentre, lowRadiusMtr, upAxis, sampleHeightCM / 100.0);
167 const std::string outerCylID = std::string(
"outer-cyl");
168 const std::string outerCyl =
cylinderXML(outerCylID, bottomCentre, uppRadiusMtr, upAxis, sampleHeightCM / 100.0);
171 boost::format algebra(
"<algebra val=\"(%1% (# %2%))\" />");
172 algebra % outerCylID % innerCylID;
173 auto xml = outerCyl +
"\n" + innerCyl +
"\n" + algebra.str();
174 g_log.
debug() <<
"Sample shape XML:\n" << xml <<
"\n";
187 const double radius,
const V3D &axis,
const double height)
const {
190 static const char *CYL_TEMPLATE =
"<cylinder id=\"%1%\">\n"
191 "<centre-of-bottom-base x=\"%2%\" y=\"%3%\" z=\"%4%\" />\n"
192 " <axis x=\"%5%\" y=\"%6%\" z=\"%7%\" />\n"
193 " <radius val=\"%8%\" />\n"
194 " <height val=\"%9%\" />\n"
197 boost::format xml(CYL_TEMPLATE);
198 xml %
id % bottomCentre.
X() % bottomCentre.
Y() % bottomCentre.
Z() % axis.
X() % axis.
Y() % axis.
Z() % radius %
height;
207 bool childLog =
g_log.
is(Logger::Priority::PRIO_DEBUG);
209 alg->setProperty(
"InputWorkspace",
workspace);
210 alg->setProperty(
"ChemicalFormula",
getPropertyValue(
"SampleChemicalFormula"));
211 alg->setProperty<
double>(
"SampleNumberDensity",
getProperty(
"SampleNumberDensity"));
213 alg->executeAsChildAlg();
214 }
catch (std::exception &exc) {
215 throw std::invalid_argument(std::string(
"Unable to set sample material: '") + exc.what() +
"'");
226 bool childLog =
g_log.
is(Logger::Priority::PRIO_DEBUG);
228 alg->setProperty(
"InputWorkspace",
workspace);
229 alg->setProperty<
int>(
"NumberOfWavelengthPoints",
getProperty(
"NumberOfWavelengthPoints"));
230 alg->setProperty<
int>(
"EventsPerPoint",
getProperty(
"EventsPerPoint"));
231 alg->setProperty<
int>(
"SeedValue",
getProperty(
"SeedValue"));
233 alg->executeAsChildAlg();
234 }
catch (std::exception &exc) {
235 throw std::invalid_argument(std::string(
"Error running absorption correction: '") + exc.what() +
"'");
238 return alg->getProperty(
"OutputWorkspace");
#define DECLARE_ALGORITHM(classname)
IPeaksWorkspace_sptr workspace
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
A validator which checks that a workspace has a valid instrument.
A property class for workspaces.
A validator which checks that the unit of the workspace referred to by a WorkspaceProperty is the exp...
Constructs a hollow sample shape, defines material for the sample and runs the MonteCarloAbsorption a...
const std::string cylinderXML(const std::string &id, const Kernel::V3D &bottomCentre, const double radius, const Kernel::V3D &axis, const double height) const
void runSetSampleMaterial(const API::MatrixWorkspace_sptr &workspace)
Attaches a new Material object to the sample.
void init() override
Initialize the algorithm's properties.
const std::string category() const override
Algorithm's category for identification.
void attachSample(const API::MatrixWorkspace_sptr &workspace)
API::MatrixWorkspace_sptr runMonteCarloAbsorptionCorrection(const API::MatrixWorkspace_sptr &workspace)
Run the MonteCarloAbsorption algorithm on the given workspace and return the calculated factors.
void exec() override
Execute the algorithm.
void runCreateSampleShape(const API::MatrixWorkspace_sptr &workspace)
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
std::string createSampleShapeXML(const Kernel::V3D &upAxis) const
Create the XML that defines a hollow cylinder with dimensions provided by the user The shape is a hol...
int version() const override
Algorithm's version for identification.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
bool is(int level) const
Returns true if at least the given log level is set.
constexpr double X() const noexcept
Get x.
constexpr double Y() const noexcept
Get y.
constexpr double Z() const noexcept
Get z.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
@ Input
An input workspace.
@ Output
An output workspace.