19#include "Poco/NumberFormatter.h"
21#include "Poco/String.h"
28using namespace Kernel;
30using namespace Geometry;
31using namespace DataObjects;
34 const std::vector<std::string> fileExts{
"_event.nxs",
".xml"};
36 "Data filed used to find beam center");
41 declareProperty(
"UseDirectBeamMethod",
true,
"If true, the direct beam method will be used");
42 declareProperty(
"BeamRadius", 3.0,
"Beam radius in pixels, used with the scattered beam method");
48 "If true, the algorithm will be persistent and re-used when "
49 "other data sets are processed");
55 Poco::Path path(beamCenterFile);
56 const std::string entryName =
"SANSBeamFinder" + path.getBaseName();
57 const std::string reductionManagerName =
getProperty(
"ReductionProperties");
63 m_output_message +=
" |Using existing workspace: " + finderWS->getName() +
'\n';
66 std::string finderWSName =
"__beam_finder_" + path.getBaseName();
70 loadAlg->setProperty(
"Filename", beamCenterFile);
71 loadAlg->setProperty(
"NoBeamCenter",
true);
72 loadAlg->setProperty(
"BeamCenterX",
EMPTY_DBL());
73 loadAlg->setProperty(
"BeamCenterY",
EMPTY_DBL());
74 loadAlg->setProperty(
"ReductionProperties", reductionManagerName);
75 loadAlg->executeAsChildAlg();
76 finderWS = loadAlg->getProperty(
"OutputWorkspace");
78 std::string msg = loadAlg->getPropertyValue(
"OutputMessage");
84 const std::string loadString = loadAlg0->toString();
87 loadAlg->setProperty(
"Filename", beamCenterFile);
88 if (loadAlg->existsProperty(
"NoBeamCenter"))
89 loadAlg->setProperty(
"NoBeamCenter",
true);
90 if (loadAlg->existsProperty(
"BeamCenterX"))
91 loadAlg->setProperty(
"BeamCenterX",
EMPTY_DBL());
92 if (loadAlg->existsProperty(
"BeamCenterY"))
93 loadAlg->setProperty(
"BeamCenterY",
EMPTY_DBL());
94 if (loadAlg->existsProperty(
"ReductionProperties"))
95 loadAlg->setProperty(
"ReductionProperties", reductionManagerName);
96 loadAlg->setPropertyValue(
"OutputWorkspace", finderWSName);
99 finderWS = std::dynamic_pointer_cast<MatrixWorkspace>(wks);
102 if (loadAlg->existsProperty(
"OutputMessage")) {
103 std::string msg = loadAlg->getPropertyValue(
"OutputMessage");
116 const std::string reductionManagerName =
getProperty(
"ReductionProperties");
124 const bool persistent =
getProperty(
"PersistentCorrection");
126 auto algProp = std::make_unique<AlgorithmProperty>(
"SANSBeamFinderAlgorithm");
134 bool specialMapping =
false;
136 const std::string instrumentName =
m_reductionManager->getPropertyValue(
"InstrumentName");
137 specialMapping = instrumentName ==
"HFIRSANS";
145 const std::string beamCenterFile =
getProperty(
"Filename");
146 Poco::Path path(beamCenterFile);
147 const std::string entryNameX =
"SANSBeamFinder_X_" + path.getBaseName();
148 const std::string entryNameY =
"SANSBeamFinder_Y_" + path.getBaseName();
167 ctrAlg->setProperty(
"InputWorkspace", beamCenterWS);
169 const bool directBeam =
getProperty(
"UseDirectBeamMethod");
170 ctrAlg->setProperty(
"DirectBeam", directBeam);
173 if (!directBeam && !
isEmpty(beamRadius)) {
174 std::vector<double> pars = beamCenterWS->getInstrument()->getNumberParameter(
"x-pixel-size");
176 g_log.
error() <<
"Could not read pixel size from instrument "
177 "parameters: using default\n";
179 ctrAlg->setProperty(
"BeamRadius", beamRadius * pars[0] / 1000.0);
183 std::vector<double> centerOfMass = ctrAlg->getProperty(
"CenterOfMass");
185 if (specialMapping) {
206 "[" + Poco::NumberFormatter::format(center_x, 3) +
", " + Poco::NumberFormatter::format(center_y, 3) +
"]\n";
225 const std::string &componentName) {
227 auto instrument = beamCenterWS->getInstrument();
229 std::shared_ptr<Mantid::Geometry::RectangularDetector> component;
231 component = std::const_pointer_cast<Mantid::Geometry::RectangularDetector>(
232 std::dynamic_pointer_cast<const Mantid::Geometry::RectangularDetector>(
233 instrument->getComponentByName(componentName)));
234 }
catch (std::exception &) {
235 g_log.
warning(
"Expecting the component " + componentName +
" to be a RectangularDetector. maskEdges not executed.");
240 g_log.
warning(
"Expecting the component " + componentName +
" to be a RectangularDetector. maskEdges not executed.");
244 std::vector<int> IDs;
247 for (
int i = 0; i <
right * component->idstep(); i++) {
248 IDs.emplace_back(component->idstart() + i);
251 for (
int i = component->maxDetectorID(); i > (component->maxDetectorID() -
left * component->idstep()); i--) {
256 for (
int row = 0; row < low; row++) {
257 for (
int i = row + component->idstart();
258 i < component->nelements() * component->idstep() - component->idstep() + low + component->idstart();
259 i += component->idstep()) {
265 for (
int row = 0; row < high; row++) {
266 for (
int i = component->idstep() + component->idstart() - row - 1;
267 i < component->nelements() * component->idstep() + component->idstart(); i += component->idstep()) {
272 g_log.
debug() <<
"SANSBeamFinder::maskEdges Detector Ids to Mask:" << std::endl;
273 for (
auto id : IDs) {
279 maskAlg->setChild(
true);
280 maskAlg->setProperty(
"Workspace", beamCenterWS);
281 maskAlg->setProperty(
"DetectorList", IDs);
285 if (instrument->getComponentByName(
"wing_detector")) {
287 maskAlg->setProperty(
"Workspace", beamCenterWS);
288 maskAlg->setPropertyValue(
"Facility",
"HFIR");
289 maskAlg->setProperty(
"MaskedFullComponent",
"wing_detector");
#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.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
std::string toString() const override
Serialize an object to a string.
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.
static IAlgorithm_sptr fromString(const std::string &input)
De-serialize an object from a string.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
@ Load
allowed here which will be passed to the algorithm
A property class for workspaces.
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 error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning 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 exec() override
Execution code.
std::shared_ptr< Kernel::PropertyManager > m_reductionManager
API::MatrixWorkspace_sptr loadBeamFinderFile(const std::string &beamCenterFile)
void maskEdges(const API::MatrixWorkspace_sptr &beamCenterWS, int high, int low, int left, int right, const std::string &componentName="detector1")
std::string m_output_message
void init() override
Initialisation code.
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
void getPixelFromCoordinate(const double &x, const double &y, const API::MatrixWorkspace_sptr &dataWS, double &pixel_x, double &pixel_y)
void getPixelFromCoordinate(const double &x, const double &y, const API::MatrixWorkspace_sptr &dataWS, double &pixel_x, double &pixel_y)
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Input
An input workspace.
@ Output
An output workspace.