Mantid
Loading...
Searching...
No Matches
HFIRInstrument.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8#include "MantidAPI/Run.h"
13#include "MantidKernel/Logger.h"
17#include "Poco/NumberParser.h"
18
19#include <boost/lexical_cast.hpp>
20#include <boost/regex.hpp>
21#include <memory>
22#include <utility>
23
30/*
31 * Read a parameter from the instrument description
32 */
33double readInstrumentParameter(const std::string &parameter, const API::MatrixWorkspace_sptr &dataWS) {
34 std::vector<double> pars = dataWS->getInstrument()->getNumberParameter(parameter);
35 if (pars.empty())
36 throw Kernel::Exception::InstrumentDefinitionError("Unable to find [" + parameter + "] instrument parameter");
37 return pars[0];
38}
39
40/*
41 * Return the detector ID corresponding to the [x,y] pixel coordinates.
42 */
43int getDetectorFromPixel(const int &pixel_x, const int &pixel_y, const API::MatrixWorkspace_sptr &dataWS) {
44 UNUSED_ARG(dataWS);
45 return 1000000 + 1000 * pixel_x + pixel_y;
46}
47
48/*
49 * Returns the real-space coordinates corresponding to the
50 * given pixel coordinates [m].
51 */
52void getCoordinateFromPixel(const double &pixel_x, const double &pixel_y, const API::MatrixWorkspace_sptr &dataWS,
53 double &x, double &y) {
54 const int nx_pixels = static_cast<int>(readInstrumentParameter("number-of-x-pixels", dataWS));
55 const int ny_pixels = static_cast<int>(readInstrumentParameter("number-of-y-pixels", dataWS));
56 const double pixel_size_x = readInstrumentParameter("x-pixel-size", dataWS);
57 const double pixel_size_y = readInstrumentParameter("y-pixel-size", dataWS);
58 x = (pixel_x - nx_pixels / 2.0 + 0.5) * pixel_size_x / 1000.0;
59 y = (pixel_y - ny_pixels / 2.0 + 0.5) * pixel_size_y / 1000.0;
60}
61
62/*
63 * Returns the pixel coordinates corresponding to the given real-space position.
64 * This assumes that the center of the detector is aligned
65 * with the beam. An additional offset may need to be applied
66 * @param x: real-space x coordinate [m]
67 * @param y: real-space y coordinate [m]
68 *
69 */
70void getPixelFromCoordinate(const double &x, const double &y, const API::MatrixWorkspace_sptr &dataWS, double &pixel_x,
71 double &pixel_y) {
72 const int nx_pixels = static_cast<int>(readInstrumentParameter("number-of-x-pixels", dataWS));
73 const int ny_pixels = static_cast<int>(readInstrumentParameter("number-of-y-pixels", dataWS));
74 const double pixel_size_x = readInstrumentParameter("x-pixel-size", dataWS);
75 const double pixel_size_y = readInstrumentParameter("y-pixel-size", dataWS);
76 pixel_x = x / pixel_size_x * 1000.0 + nx_pixels / 2.0 - 0.5;
77 pixel_y = y / pixel_size_y * 1000.0 + ny_pixels / 2.0 - 0.5;
78}
79
80/*
81 * Returns the default beam center position, or the pixel location
82 * of real-space coordinates (0,0).
83 */
84void getDefaultBeamCenter(const API::MatrixWorkspace_sptr &dataWS, double &pixel_x, double &pixel_y) {
85 getPixelFromCoordinate(0.0, 0.0, dataWS, pixel_x, pixel_y);
86}
87
88/*
89 * Get the source to sample distance (ssd)
90 * If "Header/source_distance exists", ssd is this
91 * otherwise get the guides distance (based on the number of guides used),
92 * defined in instrument parameters file as "aperture-distances"
93 * and sums "Header/sample_aperture_to_flange"
94 */
96
97 double sourceToSampleDistance;
98
99 std::vector<double> parsDouble = dataWS->getInstrument()->getNumberParameter("Header_source_distance");
100 if (!parsDouble.empty()) {
101 // First let's try to get source_distance first:
102 sourceToSampleDistance = parsDouble[0] *= 1000; // convert to mm
103 } else {
104 const auto nGuides = dataWS->run().getPropertyValueAsType<int>("Motor_Positions_nguides");
105 // aperture-distances: array from the instrument parameters
106 std::vector<std::string> parsString = dataWS->getInstrument()->getStringParameter("aperture-distances");
107 if (parsString.empty())
108 throw Kernel::Exception::InstrumentDefinitionError("Unable to find [aperture-distances] instrument parameter");
109 std::string guidesDistances = parsString[0];
110
111 std::vector<std::string> guidesDistancesSplit;
112 boost::split(guidesDistancesSplit, guidesDistances, boost::is_any_of("\t ,"), boost::token_compress_on);
113 sourceToSampleDistance = boost::lexical_cast<double>(guidesDistancesSplit[nGuides]);
114
115 auto sourceToSampleDistanceOffset =
116 dataWS->run().getPropertyValueAsType<double>("Header_sample_aperture_to_flange");
117
118 sourceToSampleDistance -= sourceToSampleDistanceOffset;
119 }
120 return sourceToSampleDistance;
121}
122
123} // namespace Mantid::WorkflowAlgorithms::HFIRInstrument
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition: System.h:64
Exception for errors associated with the instrument definition.
Definition: Exception.h:220
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
void getDefaultBeamCenter(const API::MatrixWorkspace_sptr &dataWS, double &pixel_x, double &pixel_y)
double getSourceToSampleDistance(const API::MatrixWorkspace_sptr &dataWS)
double readInstrumentParameter(const std::string &parameter, const API::MatrixWorkspace_sptr &dataWS)
File change history is stored at: https://github.com/mantidproject/mantid Code Documentation is avail...
int getDetectorFromPixel(const int &pixel_x, const int &pixel_y, const API::MatrixWorkspace_sptr &dataWS)
void getCoordinateFromPixel(const double &pixel_x, const double &pixel_y, const API::MatrixWorkspace_sptr &dataWS, double &x, double &y)
void getPixelFromCoordinate(const double &x, const double &y, const API::MatrixWorkspace_sptr &dataWS, double &pixel_x, double &pixel_y)