-
Notifications
You must be signed in to change notification settings - Fork 122
/
CalculateSlits.cpp
125 lines (99 loc) · 3.77 KB
/
CalculateSlits.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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
116
117
118
119
120
121
122
123
124
125
#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.";
};
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void CalculateSlits::init() {
declareProperty("Slit1Slit2", Mantid::EMPTY_DBL(),
"Distance between slit 1 and slit 2 in mm");
declareProperty("Slit2SA", Mantid::EMPTY_DBL(), "Unknown distance in mm");
declareProperty("Resolution", Mantid::EMPTY_DBL(), "Resolution");
declareProperty("Footprint", Mantid::EMPTY_DBL(), "Footprint in mm");
declareProperty("Angle", Mantid::EMPTY_DBL(), "Angle in degrees");
declareProperty("Slit1", Mantid::EMPTY_DBL(), "Slit 1 width in mm",
Direction::Output);
declareProperty("Slit2", Mantid::EMPTY_DBL(), "Slit 2 width in mm",
Direction::Output);
}
//----------------------------------------------------------------------------------------------
/** 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