19#include "Poco/NumberFormatter.h"
20#include "Poco/String.h"
29using namespace Kernel;
31using namespace Geometry;
32using namespace DataObjects;
35 const std::vector<std::string> fileExts{
"_event.nxs",
".xml"};
37 "Data filed used to find beam center");
42 declareProperty(
"UseDirectBeamMethod",
true,
"If true, the direct beam method will be used");
43 declareProperty(
"BeamRadius", 3.0,
"Beam radius in pixels, used with the scattered beam method");
49 "If true, the algorithm will be persistent and re-used when "
50 "other data sets are processed");
56 std::filesystem::path path(beamCenterFile);
57 const std::string entryName =
"SANSBeamFinder" + path.stem().string();
58 const std::string reductionManagerName =
getProperty(
"ReductionProperties");
64 m_output_message +=
" |Using existing workspace: " + finderWS->getName() +
'\n';
67 std::string finderWSName =
"__beam_finder_" + path.stem().string();
71 loadAlg->setProperty(
"Filename", beamCenterFile);
72 loadAlg->setProperty(
"NoBeamCenter",
true);
73 loadAlg->setProperty(
"BeamCenterX",
EMPTY_DBL());
74 loadAlg->setProperty(
"BeamCenterY",
EMPTY_DBL());
75 loadAlg->setProperty(
"ReductionProperties", reductionManagerName);
76 loadAlg->executeAsChildAlg();
77 finderWS = loadAlg->getProperty(
"OutputWorkspace");
79 std::string msg = loadAlg->getPropertyValue(
"OutputMessage");
85 const std::string loadString = loadAlg0->toString();
88 loadAlg->setProperty(
"Filename", beamCenterFile);
89 if (loadAlg->existsProperty(
"NoBeamCenter"))
90 loadAlg->setProperty(
"NoBeamCenter",
true);
91 if (loadAlg->existsProperty(
"BeamCenterX"))
92 loadAlg->setProperty(
"BeamCenterX",
EMPTY_DBL());
93 if (loadAlg->existsProperty(
"BeamCenterY"))
94 loadAlg->setProperty(
"BeamCenterY",
EMPTY_DBL());
95 if (loadAlg->existsProperty(
"ReductionProperties"))
96 loadAlg->setProperty(
"ReductionProperties", reductionManagerName);
97 loadAlg->setPropertyValue(
"OutputWorkspace", finderWSName);
99 std::shared_ptr<Workspace> wks = AnalysisDataService::Instance().retrieve(finderWSName);
100 finderWS = std::dynamic_pointer_cast<MatrixWorkspace>(wks);
103 if (loadAlg->existsProperty(
"OutputMessage")) {
104 std::string msg = loadAlg->getPropertyValue(
"OutputMessage");
117 const std::string reductionManagerName =
getProperty(
"ReductionProperties");
118 if (PropertyManagerDataService::Instance().doesExist(reductionManagerName)) {
119 m_reductionManager = PropertyManagerDataService::Instance().retrieve(reductionManagerName);
122 PropertyManagerDataService::Instance().addOrReplace(reductionManagerName,
m_reductionManager);
125 const bool persistent =
getProperty(
"PersistentCorrection");
127 auto algProp = std::make_unique<AlgorithmProperty>(
"SANSBeamFinderAlgorithm");
135 bool specialMapping =
false;
137 const std::string instrumentName =
m_reductionManager->getPropertyValue(
"InstrumentName");
138 specialMapping = instrumentName ==
"HFIRSANS";
146 const std::string beamCenterFile =
getProperty(
"Filename");
147 std::filesystem::path path(beamCenterFile);
148 const std::string entryNameX =
"SANSBeamFinder_X_" + path.stem().string();
149 const std::string entryNameY =
"SANSBeamFinder_Y_" + path.stem().string();
168 ctrAlg->setProperty(
"InputWorkspace", beamCenterWS);
170 const bool directBeam =
getProperty(
"UseDirectBeamMethod");
171 ctrAlg->setProperty(
"DirectBeam", directBeam);
174 if (!directBeam && !
isEmpty(beamRadius)) {
175 std::vector<double> pars = beamCenterWS->getInstrument()->getNumberParameter(
"x-pixel-size");
177 g_log.
error() <<
"Could not read pixel size from instrument "
178 "parameters: using default\n";
180 ctrAlg->setProperty(
"BeamRadius", beamRadius * pars[0] / 1000.0);
184 std::vector<double> centerOfMass = ctrAlg->getProperty(
"CenterOfMass");
186 if (specialMapping) {
207 "[" + Poco::NumberFormatter::format(center_x, 3) +
", " + Poco::NumberFormatter::format(center_y, 3) +
"]\n";
226 const std::string &componentName) {
228 auto instrument = beamCenterWS->getInstrument();
230 std::shared_ptr<Mantid::Geometry::RectangularDetector> component;
232 component = std::const_pointer_cast<Mantid::Geometry::RectangularDetector>(
233 std::dynamic_pointer_cast<const Mantid::Geometry::RectangularDetector>(
234 instrument->getComponentByName(componentName)));
235 }
catch (std::exception &) {
236 g_log.
warning(
"Expecting the component " + componentName +
" to be a RectangularDetector. maskEdges not executed.");
241 g_log.
warning(
"Expecting the component " + componentName +
" to be a RectangularDetector. maskEdges not executed.");
245 std::vector<int> IDs;
248 for (
int i = 0; i <
right * component->idstep(); i++) {
249 IDs.emplace_back(component->idstart() + i);
252 for (
int i = component->maxDetectorID(); i > (component->maxDetectorID() -
left * component->idstep()); i--) {
257 for (
int row = 0; row < low; row++) {
258 for (
int i = row + component->idstart();
259 i < component->nelements() * component->idstep() - component->idstep() + low + component->idstart();
260 i += component->idstep()) {
266 for (
int row = 0; row < high; row++) {
267 for (
int i = component->idstep() + component->idstart() - row - 1;
268 i < component->nelements() * component->idstep() + component->idstart(); i += component->idstep()) {
273 g_log.
debug() <<
"SANSBeamFinder::maskEdges Detector Ids to Mask:" << std::endl;
274 for (
auto id : IDs) {
280 maskAlg->setChild(
true);
281 maskAlg->setProperty(
"Workspace", beamCenterWS);
282 maskAlg->setProperty(
"DetectorList", IDs);
286 if (instrument->getComponentByName(
"wing_detector")) {
288 maskAlg->setProperty(
"Workspace", beamCenterWS);
289 maskAlg->setPropertyValue(
"Facility",
"HFIR");
290 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.
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.