27using namespace Kernel;
29using namespace Geometry;
30using namespace DataObjects;
33bool equals(
const double a,
const double b) {
34 return fabs(a - b) < std::numeric_limits<double>::min();
39 const auto wsValidator = std::make_shared<CompositeValidator>();
40 const auto positiveDouble = std::make_shared<BoundedValidator<double>>();
44 "If not empty, a table workspace of that "
45 "name will contain the center of mass position.");
47 declareProperty(
"CenterX", 0.0,
"Estimate for the beam center in X [m]. Default: 0");
48 declareProperty(
"CenterY", 0.0,
"Estimate for the beam center in Y [m]. Default: 0");
50 "Tolerance on the center of mass "
51 "position between each iteration [m]. "
55 "If true, a direct beam calculation will be performed. Otherwise, the "
57 "of the scattering data will be computed by excluding the beam area.");
59 positiveDouble->setLower(0);
61 "Radius of the beam area, in meters, used the exclude the "
62 "beam when calculating "
63 "the center of mass of the scattering pattern.");
68 const bool directBeam) {
69 double totalCount = 0;
70 for (
int i = 0; i < numSpec; i++) {
87 const int numSpec,
const double beamRadius,
const bool directBeam) {
88 double totalCount = 0;
89 const auto &spectrumInfo = boundingBox.
getWorkspace()->spectrumInfo();
90 for (
int i = 0; i < numSpec; i++) {
116 double ¢erY,
const int numSpec,
Progress &progress) {
119 const double beamRadius =
getProperty(
"BeamRadius");
130 previousBoundingBox.
setBounds(0., 0., 0., 0.);
133 double distance = -1;
134 double distanceCheck = 0;
135 double totalCount =
initBoundingBox(boundingBox, numSpec, beamRadius, directBeam);
137 int totalLocalMinima = 0;
138 int totalIterations = 0;
142 while (distance >
tolerance || distance < 0) {
151 if (!directBeam && (radiusX <= beamRadius || radiusY <= beamRadius)) {
152 g_log.
error() <<
"Center of mass falls within the beam center area: "
158 const auto oldCenterX = boundingBox.
getCenterX();
159 const auto oldCenterY = boundingBox.
getCenterY();
160 previousBoundingBox.
setBounds(oldCenterX - radiusX, oldCenterX + radiusX, oldCenterY - radiusY,
161 oldCenterY + radiusY);
165 if (
equals(distance, distanceCheck)) {
168 totalLocalMinima = 0;
172 if (totalLocalMinima > 5) {
173 g_log.
warning() <<
"Found the same or equivalent center of mass locations "
174 "more than 5 times in a row: stopping here\n";
184 distanceCheck = distance;
188 totalCount =
updateBoundingBox(boundingBox, previousBoundingBox, numSpec, beamRadius, directBeam);
190 progress.report(
"Find Beam Center");
208 if (!output.empty()) {
217 m_result->addColumn(
"str",
"Name");
218 m_result->addColumn(
"double",
"Value");
221 row <<
"X (m)" << centerX;
222 row = m_result->appendRow();
223 row <<
"Y (m)" << centerY;
231 std::vector<double> center_of_mass;
232 center_of_mass.emplace_back(centerX);
233 center_of_mass.emplace_back(centerY);
237 g_log.
information() <<
"Center of Mass found at x=" << centerX <<
" y=" << centerY <<
'\n';
250 childAlg->executeAsChildAlg();
251 inputWS = childAlg->getProperty(
"OutputWorkspace");
255 const auto numSpec =
static_cast<int>(inputWSWvl->getNumberHistograms());
#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.
bool existsProperty(const std::string &name) const override
Checks whether the named property is already in the list of managed property.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
void setPropertyValue(const std::string &name, const std::string &value) override
Set the value of a property by string N.B.
Helper class for reporting progress from algorithms.
TableRow represents a row in a TableWorkspace.
A property class for workspaces.
void exec() override
Execution code.
void findCenterOfMass(const API::MatrixWorkspace_sptr &inputWS, double ¢erX, double ¢erY, const int numSpec, API::Progress &progress)
Helper functions.
void storeOutputWorkspace(double centerX, double centerY)
Package the algorithm outputs one of two ways depending on whether or not it was given an input Event...
void init() override
Initialisation code.
bool isValidWs(int index) const
Performs checks on the spectrum located at index to determine if it is acceptable to be operated on.
double calculateDistance() const
double getCenterY() const
void setPosition(double x, double y)
double calculateRadiusY() const
void setCenter(double x, double y)
void updateMinMax(int index)
Compare current mins and maxs to the coordinates of the spectrum at index expnd mins and maxs to incl...
bool isOutOfBoundsOfNonDirectBeam(const double beamRadius, int index, const bool directBeam)
Checks to see if spectrum at index is within the diameter of the given beamRadius.
void setBounds(double xMin, double xMax, double yMin, double yMax)
void normalizePosition(double x, double y)
Perform normalization on x/y coords over given values.
double getCenterX() const
double updatePositionAndReturnCount(int index)
Sets member variables x/y to new x/y based on spectrum info and historgram data at the given index.
double calculateRadiusX() const
bool containsPoint(double x, double y)
Checks if a given x/y coord is within the bounding box.
API::MatrixWorkspace_const_sptr getWorkspace()
Support for a property that holds an array of values.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
bool MANTID_API_DLL equals(const MatrixWorkspace_sptr &lhs, const MatrixWorkspace_sptr &rhs, double tolerance=0.0)
Performs a comparison operation on two workspaces, using the CompareWorkspaces algorithm.
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
double updateBoundingBox(WorkspaceBoundingBox &boundingBox, WorkspaceBoundingBox &previousBoundingBox, const int numSpec, const double beamRadius, const bool directBeam)
double initBoundingBox(WorkspaceBoundingBox &boundingBox, const int numSpec, const double beamRadius, const bool directBeam)
@ Input
An input workspace.
@ Output
An output workspace.