28using namespace Kernel;
30using namespace Geometry;
31using namespace DataObjects;
34 const auto wsValidator = std::make_shared<CompositeValidator>();
35 const auto positiveDouble = std::make_shared<BoundedValidator<double>>();
39 "TableWorkspace will contain the center of mass position. "
40 "When empty, a CenterOfMass output parameter with two elements (x,y) is created.");
42 declareProperty(
"CenterX", 0.0,
"Initial estimate for the beam center in X in meters");
43 declareProperty(
"CenterY", 0.0,
"Initial estimate for the beam center in Y in meters");
45 "Tolerance on the center of mass position between each iteration in meters. "
46 "Suggested value is the size of a quarter of a pixel.");
49 "When true, the calculation will include the pixels within BeamRadius from the beam center. "
50 "Since the process is iterative, the pixels masked by DirectBeam=False will move.");
52 positiveDouble->setLower(0);
54 "Radius of the direct beam area, in meters, used the exclude the beam when calculating "
55 "the center of mass of the scattering pattern. "
56 "This is ignored when DirectBeam=True");
58 "Integration radius, in meters, used to include when calculating "
59 "the center of mass of the scattering pattern.");
71 double ¢erY,
Progress &progress) {
73 const bool includeDirectBeam =
getProperty(
"DirectBeam");
74 const double beamRadius =
getProperty(
"BeamRadius");
76 const double integrationRadius =
isDefault(
"IntegrationRadius") ? 100. :
getProperty(
"IntegrationRadius");
82 WorkspaceBoundingBox boundingBox(inputWS, integrationRadius, beamRadius, !includeDirectBeam, centerX, centerY);
86 double distanceFromPrevious = std::numeric_limits<double>::max();
88 double distanceFromPreviousPrevious = std::numeric_limits<double>::max();
90 int totalLocalMinima = 0;
91 int totalIterations = 0;
92 constexpr int LOCAL_MINIMA_MAX{5};
96 while (distanceFromPrevious >
tolerance) {
103 g_log.
error(
"Center of mass falls within the beam center area: stopping here");
112 if (
Kernel::equals(distanceFromPrevious, distanceFromPreviousPrevious)) {
115 totalLocalMinima = 0;
119 if (totalLocalMinima > LOCAL_MINIMA_MAX) {
120 g_log.
warning() <<
"Found the same or equivalent center of mass locations more than " << LOCAL_MINIMA_MAX
121 <<
" times in a row: stopping here\n";
131 distanceFromPreviousPrevious = distanceFromPrevious;
136 progress.report(
"Find Beam Center");
156 if (!output.empty()) {
165 m_result->addColumn(
"str",
"Name");
166 m_result->addColumn(
"double",
"Value");
169 row <<
"X (m)" << centerX;
170 row = m_result->appendRow();
171 row <<
"Y (m)" << centerY;
179 std::vector<double> center_of_mass;
180 center_of_mass.emplace_back(centerX);
181 center_of_mass.emplace_back(centerY);
185 g_log.
information() <<
"Center of Mass found at x=" << centerX <<
" y=" << centerY <<
'\n';
198 childAlg->executeAsChildAlg();
199 inputWS = childAlg->getProperty(
"OutputWorkspace");
#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.
bool isDefault(const std::string &name) const
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, 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 centerOfMassWithinBeamCenter()
This only has effect if the integral is ignoring the beam center as a whole.
void prepareCenterCalculation()
Copy the current center to the previous and update the x/y range for overall integration.
double getCenterY() const
double distanceFromPrevious() const
double getCenterX() const
void findNewCenterPosition()
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
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
MANTID_KERNEL_DLL bool equals(T const x, T const y)
Test for equality of doubles using compiler-defined precision.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Input
An input workspace.
@ Output
An output workspace.