25constexpr double DEFAULT_ANGLE = 45.0;
27constexpr double DEFAULT_DETECTOR_DISTANCE = 10.0;
28constexpr double ConversionFrom_cm_to_m = 0.01;
41 auto wsValidator = std::make_shared<CompositeValidator>();
44 "The name of the input workspace.");
47 "The name of the Muon Implantation Profile.");
50 "The name to use for the output workspace.");
52 auto positiveDouble = std::make_shared<Kernel::BoundedValidator<double>>();
53 positiveDouble->setLower(0);
54 declareProperty(
"DetectorAngle", DEFAULT_ANGLE, positiveDouble,
55 "Angle in degrees between beam and Detector."
56 "Range of normal values for detectors are : "
57 "Ge1 : 90-180 , Ge2 : 270-360 , Ge3 : 0 - 90 , Ge4 "
61 declareProperty(
"DetectorDistance", DEFAULT_DETECTOR_DISTANCE, positiveDouble,
68 std::map<std::string, std::string> issues;
70 issues[
"InputWorkspace"] =
"The InputWorkspace must be a MatrixWorkspace.";
73 issues[
"MuonImplantationProfile"] =
"The MuonImplantationProfile must be a MatrixWorkspace.";
75 if (!issues.empty()) {
78 if (!inputWS->sample().getShape().hasValidShape()) {
79 issues[
"InputWorkspace"] =
"Input workspace does not have a Sample";
81 auto material = inputWS->sample().getShape().material();
82 if (!material.hasValidXRayAttenuationProfile()) {
83 issues[
"InputWorkspace"] =
"Input workspace does not have a Xray Attenuation profile";
85 if (muonProfile->getNumberHistograms() != 1) {
86 issues[
"MuonImplantationProfile"] =
"Muon Implantation profile must have only one spectrum";
105 detectorDistance = detectorDistance * ConversionFrom_cm_to_m;
107 if (detectorAngle > 180.0) {
108 detectorDistance = -detectorDistance;
122 double sum_of_elems = std::accumulate(muonIntensity.begin(), muonIntensity.end(), 0.0);
124 std::transform(muonIntensity.begin(), muonIntensity.end(), muonIntensity.begin(),
125 [sum_of_elems](
double d) { return d / sum_of_elems; });
126 return muonIntensity;
139 double detectorDistance) {
140 const MantidVec muonDepth = muonProfile->readX(0);
141 Kernel::V3D const muonPoint = {0.0, 0.0, detectorDistance};
146 if (muonPath.
count() == 0) {
147 throw std::runtime_error(
"No valid solution, check shape parameters, Muon "
148 "depth profile and detector distance");
152 std::vector<Kernel::V3D> muonPos;
153 for (
auto depth : muonDepth) {
156 Kernel::V3D pos = {0.0, 0.0, sampleDepth - (depth * ConversionFrom_cm_to_m)};
157 muonPos.push_back(pos);
169 convtoPoints->setProperty(
"InputWorkspace", inputWS);
170 convtoPoints->execute();
174 MantidVec muonIntensity = muonProfile->readY(0);
176 double detectorAngle =
getProperty(
"DetectorAngle");
177 double detectorDistance =
getProperty(
"DetectorDistance");
179 std::vector<Kernel::V3D> muonPos =
calculateMuonPos(muonProfile, inputWS, detectorDistance);
181 for (
size_t j = 0; j < inputWS->getNumberHistograms(); j++) {
182 auto &yData = outputWS->mutableY(j);
184 for (
size_t i = 0; i < xData.size(); i++) {
185 double totalFactor{0};
186 for (
size_t k = 0; k < normalisedMuonIntensity.size(); k++) {
193 if (xrayPath.
count() == 0) {
194 throw std::runtime_error(
"No valid solution, check shape parameters "
195 ", detector disatance and angle");
197 for (
auto &link : xrayPath) {
198 double distInObject = link.distInsideObject;
199 factor = factor * link.object->material().xRayAttenuation(distInObject, xData[i]);
201 totalFactor += (normalisedMuonIntensity[k] * factor);
203 yData[i] = totalFactor;
#define DECLARE_ALGORITHM(classname)
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 property class for workspaces.
Calculates attenuation of xrays due to absorption in a sample.
void exec() override
Execution.
double degreesToRadians(double degrees)
Converts angles in degrees to angles in radians.
std::vector< double > normaliseMuonIntensity(MantidVec muonIntensity)
normalise moun intensity to 1.
std::vector< Kernel::V3D > calculateMuonPos(API::MatrixWorkspace_sptr &muonProfile, const API::MatrixWorkspace_sptr &inputWS, double detectorDistance)
Calculate the muon implantation position in the sample.
Kernel::V3D calculateDetectorPos(double const detectorAngle, double detectorDistance)
Calculates the position of the detector.
std::map< std::string, std::string > validateInputs() override
Method checking errors on ALL the inputs, before execution.
Concrete workspace implementation.
IObject : Interface for geometry objects.
virtual int interceptSurface(Geometry::Track &) const =0
Defines a track as a start point and a direction.
int count() const
Returns the number of links.
LType::const_iterator cbegin() const
Returns an interator to the start of the set of links (const version)
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
bool MANTID_GEOMETRY_DLL intersection(const ConvexPolygon &P, const ConvexPolygon &Q, ConvexPolygon &out)
Compute the instersection of two convex polygons.
MANTID_KERNEL_DLL V3D normalize(V3D v)
Normalizes a V3D.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
@ Input
An input workspace.
@ Output
An output workspace.