30 : min_radius(-1.), max_radius(-1), start_angle(-1), clockwise(false), num_bins(-1), centre_x(-1.), centre_y(-1.),
31 centre_z(-1), bin_size(-1) {}
48 "An input workspace.");
50 "An output workspace.");
52 auto twoOrThree = std::make_shared<Kernel::ArrayLengthValidator<double>>(2, 3);
53 std::vector<double> myInput(3, 0);
55 "Coordinate of the centre of the ring");
56 auto nonNegative = std::make_shared<Kernel::BoundedValidator<double>>();
57 nonNegative->setLower(0);
59 declareProperty<double>(
"MinRadius", 0, nonNegative->clone(),
"Radius of the inner ring(m)");
61 std::move(nonNegative)),
62 "Radius of the outer ring(m)");
63 auto nonNegativeInt = std::make_shared<Kernel::BoundedValidator<int>>();
64 nonNegativeInt->setLower(1);
65 declareProperty<int>(
"NumBins", 100, std::move(nonNegativeInt),
"Number of slice bins for the output");
66 auto degreesLimits = std::make_shared<Kernel::BoundedValidator<double>>();
67 degreesLimits->setLower(-360);
68 degreesLimits->setUpper(360);
69 declareProperty<double>(
"StartAngle", 0, degreesLimits,
"The angle to start from.");
71 std::vector<std::string> op(2);
73 op[1] =
"Anti-ClockWise";
74 declareProperty(
"Sense",
"Anti-ClockWise", std::make_shared<Kernel::StringListValidator>(op),
75 "The direction of the integration around the ring");
106 auto checkEvent = std::dynamic_pointer_cast<API::IEventWorkspace>(inputWS);
108 throw std::invalid_argument(
"RingProfile is not defined for EventWorkspaces.");
110 g_log.
debug() <<
"Get the input parameters \n";
112 std::vector<double> centre =
getProperty(
"Centre");
115 if (centre.size() == 3)
124 g_log.
debug() <<
"Check the inputs of the algorithm\n";
126 if (inputWS->getAxis(1)->isSpectra()) {
132 m_progress = std::shared_ptr<API::Progress>(
new API::Progress(
this, 0.0, 1.0, inputWS->getNumberHistograms() + 1));
135 std::vector<double> output_bins(
num_bins, 0);
137 g_log.
debug() <<
"Execute the ring profile calculation\n";
139 if (inputWS->getAxis(1)->isSpectra()) {
154 for (
size_t j = 0; j < output_bins.size(); j++)
155 refY[j] = output_bins[output_bins.size() - j - 1];
157 for (
size_t j = 0; j < output_bins.size(); j++)
158 refY[j] = output_bins[j];
165 std::vector<double> angles(output_bins.size() + 1);
168 for (
int j = 0; j < static_cast<int>(angles.size()); j++)
174 auto horizontal = std::make_unique<API::NumericAxis>(refX.size());
175 horizontal->unit() = std::make_shared<Kernel::Units::Phi>();
176 horizontal->title() =
"Ring Angle";
177 for (
size_t j = 0; j < refX.size(); j++)
178 horizontal->setValue(j, refX[j]);
179 outputWS->replaceAxis(0, std::move(horizontal));
183 auto verticalAxis = std::make_unique<API::TextAxis>(1);
184 verticalAxis->unit() = inputWS->getAxis(1)->unit();
185 verticalAxis->title() = inputWS->getAxis(1)->title();
186 outputWS->replaceAxis(1, std::move(verticalAxis));
208 const auto &spectrumInfo = inputWS->spectrumInfo();
209 double first_x, first_y, first_z;
213 if (i >= inputWS->getNumberHistograms())
214 throw std::invalid_argument(
"Did not find any non monitor detector position");
216 if (spectrumInfo.isMonitor(i))
218 const auto pos = spectrumInfo.position(i);
225 double last_x, last_y, last_z;
226 i = inputWS->getNumberHistograms() - 1;
230 throw std::invalid_argument(
"There is no region defined for the instrument of this workspace");
232 if (spectrumInfo.isMonitor(i))
234 const auto pos = spectrumInfo.position(i);
241 double xMax, yMax, zMax;
242 double xMin, yMin, zMin;
243 xMax = std::max(first_x, last_x);
244 yMax = std::max(first_y, last_y);
245 zMax = std::max(first_z, last_z);
246 xMin = std::min(first_x, last_x);
247 yMin = std::min(first_y, last_y);
248 zMin = std::min(first_z, last_z);
250 std::stringstream limits_s;
251 limits_s <<
"([" << xMin <<
", " << xMax <<
"], [" << yMin <<
", " << yMax <<
"], [" << zMin <<
", " << zMax
253 g_log.
debug() <<
"The limits for the instrument is : " << limits_s.str() <<
'\n';
254 int xOutside = 0, yOutside = 0, zOutside = 0;
255 if (centre_x < xMin || centre_x > xMax)
257 if (centre_y < yMin || centre_y > yMax)
259 if (centre_z < zMin || centre_z > zMax)
261 int summed = xOutside + yOutside + zOutside;
266 <<
") is outside the limits of the detectors inside this instrument: " << limits_s.str();
267 throw std::invalid_argument(s.str());
270 xOutside = yOutside = zOutside = 0;
278 summed = xOutside + yOutside + zOutside;
282 s <<
"The defined minRadius make the inner ring outside the limits of "
283 "the detectors inside this instrument: "
285 throw std::invalid_argument(s.str());
289 throw std::invalid_argument(
"Invalid input workspace. This workspace does "
290 "not has detectors to get the positions "
310 g_log.
notice() <<
"CheckingInputs For Numeric Workspace\n";
319 const MantidVec &refX = inputWS->readX(inputWS->getNumberHistograms() / 2);
321 double min_v_x, max_v_x;
322 min_v_x = std::min(refX[0], refX.back());
323 max_v_x = std::max(refX[0], refX.back());
324 g_log.
notice() <<
"Limits X = " << min_v_x <<
" " << max_v_x <<
'\n';
326 if (centre_x < min_v_x || centre_x > max_v_x) {
328 s <<
"The input value for centre (X=" <<
centre_x <<
") is outside the limits of the instrument [" << min_v_x
329 <<
", " << max_v_x <<
"]";
330 throw std::invalid_argument(s.str());
341 throw std::invalid_argument(
"Vertical axis is not a numeric axis. If it is "
342 "a spectra axis try running "
343 "ConvertSpectrumAxis first.");
344 double min_v_y = std::min(oldAxis2->
getMin(), oldAxis2->
getMax());
345 double max_v_y = std::max(oldAxis2->
getMin(), oldAxis2->
getMax());
346 g_log.
notice() <<
"Limits Y = " << min_v_y <<
" " << max_v_y <<
'\n';
348 if (centre_y < min_v_y || centre_y > max_v_y) {
350 s <<
"The input value for centre (Y=" <<
centre_y <<
") is outside the limits of the instrument [" << min_v_y
351 <<
", " << max_v_y <<
"]";
352 throw std::invalid_argument(s.str());
358 throw std::invalid_argument(
"The minimun radius is outside the region of the instrument");
376 std::vector<double> &output_bins) {
378 const auto &spectrumInfo = inputWS->spectrumInfo();
379 for (
int i = 0; i < static_cast<int>(inputWS->getNumberHistograms()); i++) {
380 m_progress->report(
"Computing ring bins positions for detectors");
383 if (!spectrumInfo.hasDetectors(i)) {
388 if (spectrumInfo.isMonitor(i))
400 g_log.
debug() <<
"Bin for the index " << i <<
" = " << bin_n <<
" Pos = " << spectrumInfo.position(i) <<
'\n';
402 const MantidVec &refY = inputWS->getSpectrum(i).dataY();
404 for (
double sp_ind : refY)
405 output_bins[bin_n] += sp_ind;
431 double radio, theta, phi;
437 double effect_distance = radio * sin(theta * M_PI / 180);
442 if (effect_distance < min_radius || effect_distance >
max_radius || effect_distance == 0)
463 std::vector<double> &output_bins) {
465 std::vector<int> bin_n(inputWS->dataY(0).size(), -1);
468 for (
int i = 0; i < static_cast<int>(inputWS->getNumberHistograms()); i++) {
469 m_progress->report(
"Computing ring bins positions for pixels");
476 const MantidVec &refY = inputWS->dataY(i);
477 for (
size_t j = 0; j < bin_n.size(); j++) {
484 output_bins[bin_n[j]] += refY[j];
518 if (bins_pos.size() != ws->dataY(spectrum_index).size())
519 throw std::runtime_error(
"Invalid bin positions vector");
524 throw std::logic_error(
"Failed to cast workspace axis to NumericAxis");
529 double ypos = (*oldAxis2)(spectrum_index);
531 double diffy_quad = pow(diffy, 2.0);
535 auto xvec = ws->dataX(spectrum_index);
538 for (
size_t i = 0; i < xvec.size() - 1; i++) {
540 double xpos = (xvec[i] + xvec[i + 1]) / 2.0;
543 double distance = sqrt(pow(diffx, 2.0) + diffy_quad);
546 if (distance < min_radius || distance >
max_radius || distance == 0) {
551 double angle = atan2(diffy, diffx);
581 angle *= (180 / M_PI);
591 return static_cast<int>(angle);
#define DECLARE_ALGORITHM(classname)
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Class to represent a numeric axis of a workspace.
double getMax() const override
returns max value defined on axis
double getMin() const override
returns min value defined on axis
Helper class for reporting progress from algorithms.
A property class for workspaces.
Calculates the sum of the counts against a circular ring.
double centre_x
copy of centre for axis(0)
bool clockwise
flag that indicate if Sense input was configure to clockwise
void exec() override
Execute the algorithm.
double centre_y
copy of centre for axis(1)
void init() override
Initialize the algorithm's properties.
void checkInputsForNumericWorkspace(const API::MatrixWorkspace_sptr &)
validate the inputs of the algorithm for 2d matrix based instrument
void checkInputsForSpectraWorkspace(const API::MatrixWorkspace_sptr &)
validate the inputs of the algorithm for instrument based workspace
void processInstrumentRingProfile(const API::MatrixWorkspace_sptr &inputWS, std::vector< double > &output_bins)
process ring profile for instrument based workspace
double min_radius
copy of the minRadius input
double bin_size
The size of the bins in angle that is equal to 360 / NumBins.
double max_radius
copy of the maxRadius input
int fromAngleToBin(double angle, bool degree=true)
get the bin position for the given angle
void getBinForPixel(const API::MatrixWorkspace_sptr &, int, std::vector< int > &)
identify the bin position for the given pixel in the image based workspace
double start_angle
copy of the StartAngle input
std::shared_ptr< API::Progress > m_progress
double centre_z
copy of centre for axis(2)
void processNumericImageRingProfile(const API::MatrixWorkspace_sptr &inputWS, std::vector< double > &output_bins)
process ring profile for image based workspace
int num_bins
copy of NumBins input
Support for a property that holds an array of values.
Exception for when an item is not found in a collection.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
void notice(const std::string &msg)
Logs at notice level.
void information(const std::string &msg)
Logs at information level.
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
void getSpherical(double &R, double &theta, double &phi) const noexcept
Return the vector's position in spherical coordinates.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
@ Input
An input workspace.
@ Output
An output workspace.