/
CalculateSlits.cpp
126 lines (101 loc) · 4.46 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
126
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidReflectometry/CalculateSlits.h"
#include <cmath>
#include <memory>
namespace Mantid::Reflectometry {
using namespace Mantid::API;
using namespace Mantid::Kernel;
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(CalculateSlits)
//----------------------------------------------------------------------------------------------
/** Constructor
*/
CalculateSlits::CalculateSlits() = default;
//----------------------------------------------------------------------------------------------
/** Destructor
*/
CalculateSlits::~CalculateSlits() = default;
//----------------------------------------------------------------------------------------------
/// 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", Direction::Output);
declareProperty("Slit2", Mantid::EMPTY_DBL(), "Calculated 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 Mantid::Reflectometry