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 <memory>
20#include <utility>
21
22#include <boost/algorithm/string/classification.hpp>
23#include <boost/algorithm/string/split.hpp>
24#include <boost/lexical_cast.hpp>
25#include <boost/regex.hpp>
26
33/*
34 * Read a parameter from the instrument description
35 */
36double readInstrumentParameter(const std::string &parameter, const API::MatrixWorkspace_sptr &dataWS) {
37 std::vector<double> pars = dataWS->getInstrument()->getNumberParameter(parameter);
38 if (pars.empty())
39 throw Kernel::Exception::InstrumentDefinitionError("Unable to find [" + parameter + "] instrument parameter");
40 return pars[0];
41}
42
43/*
44 * Return the detector ID corresponding to the [x,y] pixel coordinates.
45 */
46int getDetectorFromPixel(const int &pixel_x, const int &pixel_y, const API::MatrixWorkspace_sptr &dataWS) {
47 UNUSED_ARG(dataWS);
48 return 1000000 + 1000 * pixel_x + pixel_y;
49}
50
51/*
52 * Returns the real-space coordinates corresponding to the
53 * given pixel coordinates [m].
54 */
55void getCoordinateFromPixel(const double &pixel_x, const double &pixel_y, const API::MatrixWorkspace_sptr &dataWS,
56 double &x, double &y) {
57 const int nx_pixels = static_cast<int>(readInstrumentParameter("number-of-x-pixels", dataWS));
58 const int ny_pixels = static_cast<int>(readInstrumentParameter("number-of-y-pixels", dataWS));
59 const double pixel_size_x = readInstrumentParameter("x-pixel-size", dataWS);
60 const double pixel_size_y = readInstrumentParameter("y-pixel-size", dataWS);
61 x = (pixel_x - nx_pixels / 2.0 + 0.5) * pixel_size_x / 1000.0;
62 y = (pixel_y - ny_pixels / 2.0 + 0.5) * pixel_size_y / 1000.0;
63}
64
65/*
66 * Returns the pixel coordinates corresponding to the given real-space position.
67 * This assumes that the center of the detector is aligned
68 * with the beam. An additional offset may need to be applied
69 * @param x: real-space x coordinate [m]
70 * @param y: real-space y coordinate [m]
71 *
72 */
73void getPixelFromCoordinate(const double &x, const double &y, const API::MatrixWorkspace_sptr &dataWS, double &pixel_x,
74 double &pixel_y) {
75 const int nx_pixels = static_cast<int>(readInstrumentParameter("number-of-x-pixels", dataWS));
76 const int ny_pixels = static_cast<int>(readInstrumentParameter("number-of-y-pixels", dataWS));
77 const double pixel_size_x = readInstrumentParameter("x-pixel-size", dataWS);
78 const double pixel_size_y = readInstrumentParameter("y-pixel-size", dataWS);
79 pixel_x = x / pixel_size_x * 1000.0 + nx_pixels / 2.0 - 0.5;
80 pixel_y = y / pixel_size_y * 1000.0 + ny_pixels / 2.0 - 0.5;
81}
82
83/*
84 * Returns the default beam center position, or the pixel location
85 * of real-space coordinates (0,0).
86 */
87void getDefaultBeamCenter(const API::MatrixWorkspace_sptr &dataWS, double &pixel_x, double &pixel_y) {
88 getPixelFromCoordinate(0.0, 0.0, dataWS, pixel_x, pixel_y);
89}
90
91/*
92 * Get the source to sample distance (ssd)
93 * If "Header/source_distance exists", ssd is this
94 * otherwise get the guides distance (based on the number of guides used),
95 * defined in instrument parameters file as "aperture-distances"
96 * and sums "Header/sample_aperture_to_flange"
97 */
99
100 double sourceToSampleDistance;
101
102 std::vector<double> parsDouble = dataWS->getInstrument()->getNumberParameter("Header_source_distance");
103 if (!parsDouble.empty()) {
104 // First let's try to get source_distance first:
105 sourceToSampleDistance = parsDouble[0] * 1000; // convert to mm
106 } else {
107 const auto nGuides = dataWS->run().getPropertyValueAsType<int>("Motor_Positions_nguides");
108 // aperture-distances: array from the instrument parameters
109 std::vector<std::string> parsString = dataWS->getInstrument()->getStringParameter("aperture-distances");
110 if (parsString.empty())
111 throw Kernel::Exception::InstrumentDefinitionError("Unable to find [aperture-distances] instrument parameter");
112 std::string guidesDistances = parsString[0];
113
114 std::vector<std::string> guidesDistancesSplit;
115 boost::split(guidesDistancesSplit, guidesDistances, boost::is_any_of("\t ,"), boost::token_compress_on);
116 sourceToSampleDistance = boost::lexical_cast<double>(guidesDistancesSplit[nGuides]);
117
118 auto sourceToSampleDistanceOffset =
119 dataWS->run().getPropertyValueAsType<double>("Header_sample_aperture_to_flange");
120
121 sourceToSampleDistance -= sourceToSampleDistanceOffset;
122 }
123 return sourceToSampleDistance;
124}
125
126} // namespace Mantid::WorkflowAlgorithms::HFIRInstrument
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition System.h:48
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)