25 : m_u0(0.0), m_v0(0.0), m_direction(
kvector_t(0.0, -1.0, 0.0)), m_distance(0.0),
26 m_dbeam_u0(0.0), m_dbeam_v0(0.0), m_detector_arrangement(GENERIC)
29 setName(
"RectangularDetector");
33 :
IDetector2D(other), m_normal_to_detector(other.m_normal_to_detector), m_u0(other.m_u0),
34 m_v0(other.m_v0), m_direction(other.m_direction), m_distance(other.m_distance),
35 m_dbeam_u0(other.m_dbeam_u0), m_dbeam_v0(other.m_dbeam_v0),
36 m_detector_arrangement(other.m_detector_arrangement), m_u_unit(other.m_u_unit),
37 m_v_unit(other.m_v_unit)
39 setName(
"RectangularDetector");
42 RectangularDetector::~RectangularDetector() =
default;
51 double alpha_i = beam.getAlpha();
53 initNormalVector(central_k);
57 void RectangularDetector::setPosition(
const kvector_t normal_to_detector,
double u0,
double v0,
60 m_detector_arrangement = GENERIC;
61 m_normal_to_detector = normal_to_detector;
62 m_distance = m_normal_to_detector.
mag();
65 m_direction = direction;
68 void RectangularDetector::setPerpendicularToSampleX(
double distance,
double u0,
double v0)
70 m_detector_arrangement = PERPENDICULAR_TO_SAMPLE;
71 setDistanceAndOffset(distance, u0, v0);
74 void RectangularDetector::setPerpendicularToDirectBeam(
double distance,
double u0,
double v0)
76 m_detector_arrangement = PERPENDICULAR_TO_DIRECT_BEAM;
77 setDistanceAndOffset(distance, u0, v0);
80 void RectangularDetector::setPerpendicularToReflectedBeam(
double distance,
double u0,
double v0)
82 m_detector_arrangement = PERPENDICULAR_TO_REFLECTED_BEAM;
83 setDistanceAndOffset(distance, u0, v0);
86 void RectangularDetector::setDirectBeamPosition(
double u0,
double v0)
88 m_detector_arrangement = PERPENDICULAR_TO_REFLECTED_BEAM_DPOS;
93 double RectangularDetector::getWidth()
const
95 const IAxis& axis = getAxis(0);
99 double RectangularDetector::getHeight()
const
101 const IAxis& axis = getAxis(1);
105 size_t RectangularDetector::getNbinsX()
const
107 return getAxis(0).
size();
110 size_t RectangularDetector::getNbinsY()
const
112 return getAxis(1).
size();
115 kvector_t RectangularDetector::getNormalVector()
const
117 return m_normal_to_detector;
120 double RectangularDetector::getU0()
const
125 double RectangularDetector::getV0()
const
130 kvector_t RectangularDetector::getDirectionVector()
const
135 double RectangularDetector::getDistance()
const
140 double RectangularDetector::getDirectBeamU0()
const
145 double RectangularDetector::getDirectBeamV0()
const
150 RectangularDetector::EDetectorArrangement RectangularDetector::getDetectorArrangment()
const
152 return m_detector_arrangement;
157 return Axes::Units::MM;
162 const IAxis& u_axis = getAxis(0);
163 const IAxis& v_axis = getAxis(1);
164 double u_min, v_min, width, height;
167 u_min = p_roi->getXlow();
168 v_min = p_roi->getYlow();
169 width = p_roi->getXup() - p_roi->getXlow();
170 height = p_roi->getYup() - p_roi->getYlow();
175 height = getHeight();
177 const kvector_t corner_position(m_normal_to_detector + (u_min - m_u0) * m_u_unit
178 + (v_min - m_v0) * m_v_unit);
179 const kvector_t uaxis_vector = width * m_u_unit;
180 const kvector_t vaxis_vector = height * m_v_unit;
186 const IAxis& u_axis = getAxis(0);
187 const IAxis& v_axis = getAxis(1);
193 const kvector_t corner_position(m_normal_to_detector + (u_bin.
m_lower - m_u0) * m_u_unit
194 + (v_bin.
m_lower - m_v0) * m_v_unit);
195 const kvector_t width = u_bin.getBinSize() * m_u_unit;
196 const kvector_t height = v_bin.getBinSize() * m_v_unit;
209 "RectangularDetector::getAxisName(size_t index) -> Error! index > 1");
217 const double alpha = beam.getAlpha();
218 const double phi = beam.getPhi();
221 const double kd = k_spec.
dot(normal_unit);
224 ASSERT(m_distance != 0);
225 const kvector_t rpix = k_spec * (m_distance / kd);
226 const double u = rpix.
dot(m_u_unit) + m_u0;
227 const double v = rpix.
dot(m_v_unit) + m_v0;
228 const IAxis& u_axis = getAxis(0);
229 const IAxis& v_axis = getAxis(1);
235 void RectangularDetector::setDistanceAndOffset(
double distance,
double u0,
double v0)
237 if (distance <= 0.0) {
238 std::ostringstream message;
239 message <<
"RectangularDetector::setPerpendicularToSample() -> Error. "
240 <<
"Distance to sample can't be negative or zero";
243 m_distance = distance;
248 void RectangularDetector::initNormalVector(
const kvector_t central_k)
252 if (m_detector_arrangement == GENERIC) {
256 else if (m_detector_arrangement == PERPENDICULAR_TO_SAMPLE) {
257 m_normal_to_detector =
kvector_t(m_distance, 0.0, 0.0);
260 else if (m_detector_arrangement == PERPENDICULAR_TO_DIRECT_BEAM) {
261 m_normal_to_detector = m_distance * central_k_unit;
264 else if (m_detector_arrangement == PERPENDICULAR_TO_REFLECTED_BEAM
265 || m_detector_arrangement == PERPENDICULAR_TO_REFLECTED_BEAM_DPOS) {
266 m_normal_to_detector = m_distance * central_k_unit;
267 m_normal_to_detector.
setZ(-m_normal_to_detector.
z());
272 "RectangularDetector::init() -> Unknown detector arrangement");
276 void RectangularDetector::initUandV(
double alpha_i)
278 double d2 = m_normal_to_detector.
dot(m_normal_to_detector);
280 d2 * m_direction - m_direction.
dot(m_normal_to_detector) * m_normal_to_detector;
281 m_u_unit = u_direction.
unit();
282 m_v_unit = m_u_unit.
cross(m_normal_to_detector).unit();
284 if (m_detector_arrangement == PERPENDICULAR_TO_REFLECTED_BEAM_DPOS) {
288 double uz = zp.
dot(m_u_unit) / zp.
mag();
289 double vz = zp.
dot(m_v_unit) / zp.
mag();
290 m_u0 = m_dbeam_u0 + m_distance * std::tan(2 * alpha_i) * uz;
291 m_v0 = m_dbeam_v0 + m_distance * std::tan(2 * alpha_i) * vz;
BasicVector3D< double > vecOfLambdaAlphaPhi(double _lambda, double _alpha, double _phi)
Creates a vector<double> as a wavevector with given wavelength and angles.
Defines class IDetectorResolution.
Defines M_PI and some more mathematical constants.
Defines class RectangularDetector.
Defines class RectangularPixel.
Defines class RegionOfInterest.
Defines class SimulationElement.
Defines some unit conversion factors and other constants in namespace Units.
auto dot(const BasicVector3D< U > &v) const
Returns dot product of vectors (antilinear in the first [=self] argument).
BasicVector3D< T > unit() const
Returns unit vector in direction of this. Throws for null vector.
double mag() const
Returns magnitude of the vector.
T z() const
Returns z-component in cartesian coordinate system.
void setZ(const T &a)
Sets z-component in cartesian coordinate system.
auto cross(const BasicVector3D< U > &v) const
Returns cross product of vectors (linear in both arguments).
Beam defined by wavelength, direction and intensity.
kvector_t getCentralK() const
Returns the wavevector.
Interface for one-dimensional axes.
virtual bool contains(double value) const
Returns true if axis contains given point.
virtual size_t findClosestIndex(double value) const =0
find bin index which is best match for given value
virtual Bin1D getBin(size_t index) const =0
retrieve a 1d bin for the given index
virtual double getMin() const =0
Returns value of first point of axis.
virtual size_t size() const =0
retrieve the number of bins
virtual double getMax() const =0
Returns value of last point of axis.
Abstract 2D detector interface.
const RegionOfInterest * regionOfInterest() const override
Returns region of interest if exists.
void setDetectorParameters(size_t n_x, double x_min, double x_max, size_t n_y, double y_min, double y_max)
Sets detector parameters using angle ranges.
size_t getGlobalIndex(size_t x, size_t y) const
Calculate global index from two axis indices.
size_t dimension() const
Returns actual dimensionality of the detector (number of defined axes)
size_t axisBinIndex(size_t index, size_t selected_axis) const
Calculate axis index for given global index.
size_t totalSize() const
Returns total number of pixels.
Interface for a function that maps [0,1]x[0,1] to the kvectors in a pixel.
A flat rectangular detector with axes and resolution function.
void init(const Beam &beam) override
Inits detector with the beam settings.
Axes::Units defaultAxesUnits() const override
return default axes units
size_t indexOfSpecular(const Beam &beam) const override
Returns index of pixel that contains the specular wavevector.
IPixel * createPixel(size_t index) const override
Creates an IPixel for the given OutputData object and index.
std::string axisName(size_t index) const override
Returns the name for the axis with given index.
RectangularDetector(size_t nxbins, double width, size_t nybins, double height)
Rectangular detector constructor.
A pixel in a RectangularDetector.
double m_lower
lower bound of the bin