Newer
Older
#include "MantidAlgorithms/CalculateSlits.h"
#include <boost/shared_ptr.hpp>
#include <math.h>
namespace Mantid {
namespace Algorithms {
using namespace Mantid::API;
using namespace Mantid::Geometry;
using namespace Mantid::Kernel;
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(CalculateSlits)
//----------------------------------------------------------------------------------------------
/** Constructor
*/
CalculateSlits::CalculateSlits() {}
//----------------------------------------------------------------------------------------------
/** Destructor
*/
CalculateSlits::~CalculateSlits() {}
//----------------------------------------------------------------------------------------------
/// Algorithm's name for identification. @see Algorithm::name
const std::string CalculateSlits::name() const { return "CalculateSlits"; }
/// Algorithm's version for identification. @see Algorithm::version
int CalculateSlits::version() const { return 1; }
/// Algorithm's category for identification. @see Algorithm::category
const std::string CalculateSlits::category() const {
return "Reflectometry\\ISIS";
}
/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
const std::string CalculateSlits::summary() const {
return "Calculates appropriate slit widths for reflectometry instruments "
"based on the instrument setup, desired resolution, and desired footprint of the experiment.";
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void CalculateSlits::init() {
declareProperty("Slit1Slit2", Mantid::EMPTY_DBL(),
"Distance between Slit 1 and Slit 2 in mm. Where Slit 1 and "
"Slit 2 are the two slits before the sample holder.");
declareProperty("Slit2SA", Mantid::EMPTY_DBL(),
"Offset in the beam direction in mm. (Due to Slit 2 being "
"translatable in the vertical axis)");
declareProperty("Resolution", Mantid::EMPTY_DBL(),
"The Resolution that you desire to obtain in the experiment");
declareProperty("Footprint", Mantid::EMPTY_DBL(), "The Footprint you wish to achieve for the experiment, in mm");
declareProperty("Angle", Mantid::EMPTY_DBL(), "Incident angle in degrees.");
declareProperty("Slit1", Mantid::EMPTY_DBL(), "Calculated Slit 1 width in mm",
declareProperty("Slit2", Mantid::EMPTY_DBL(), "Calculated Slit 2 width in mm",
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void CalculateSlits::exec() {
const double res = getProperty("Resolution");
const double fp = getProperty("Footprint");
const double angleDeg = getProperty("Angle");
const double s1s2 = getProperty("Slit1Slit2");
const double s2sa = getProperty("Slit2SA");
/*
|←----d-----→|
_ _
_ _ _-¯ | ↑
↑ | ¯-_ _-¯ | |
S₂ | (Θ_X_Θ) | S₁ ←---beam---
↓ |_-¯ ¯-_ | |
¯ ¯-_| ↓
¯
_ _
_-¯ | ↑
_-¯ | |
_-¯ _| | ½S₀
_-¯α) | | ↓
¯¯¯¯¯¯¯¯¯¯¯¯ ¯
|←----d-----→|
For the purposes of these diagrams, Θ has
already been multiplied by the resolution.
α = ½Θ
t = tan(α)
r = resolution
f = footprint (???)
u = unknown dimension
S₀ = S₁ + S₂
= 2•d•t
S₁ = 2•d•t - S₂
= 2•d•t - f•sin(α/r) + 2•u•t
= 2•(d+u)•t - f•sin(α/r)
S₂ = f•sin(α/r) - 2•u•t
sin(α/r) is opp/hyp of the full angle, without the resolution coefficient
if f is the hypotenuse of a triangle constructed from the full angle
then f•sin(α/r) is the length of the side opposite the angle
*/
// Convert angle to radians for our calculations
const double a = angleDeg * M_PI / 180.0;
const double s2 = (fp * sin(a)) - (2 * s2sa * tan(res * a));
const double s1 = (2 * s1s2 * tan(res * a)) - s2;
setProperty("Slit1", s1);
setProperty("Slit2", s2);
}
} // namespace Algorithms
} // namespace Mantid