24#include "Poco/NumberFormatter.h"
26#include "Poco/String.h"
32using namespace Kernel;
34using namespace Geometry;
35using namespace DataObjects;
40 const std::vector<std::string> fileExts{
"_event.nxs",
".xml"};
42 "Flood field or sensitivity file.");
44 "If true, the dark current subtracted "
45 "from the sample data will also be "
46 "subtracted from the flood field.");
48 "The name of the input file to load as dark current.");
50 auto positiveDouble = std::make_shared<BoundedValidator<double>>();
51 positiveDouble->setLower(0);
53 "Minimum efficiency for a pixel to be considered (default: no minimum).");
55 "Maximum efficiency for a pixel to be considered (default: no maximum).");
58 "Transmission value for the flood field material "
59 "(default: no transmission).");
61 "Transmission error for the flood field material "
62 "(default: no transmission).");
65 "Beam position in X pixel coordinates (optional: otherwise "
66 "sample beam center is used)");
68 "Beam position in Y pixel coordinates (optional: otherwise "
69 "sample beam center is used)");
70 declareProperty(
"MaskedFullComponent",
"",
"Component Name to fully mask according to the IDF file.");
72 "Number of pixels to mask on the edges: X-low, X-high, Y-low, Y-high");
73 declareProperty(
"MaskedComponent",
"",
"Component Name to mask the edges according to the IDF file.");
89 Poco::Path path(filePath);
90 const std::string extn = path.getExtension();
91 const std::string nxs(
"nxs");
92 const std::string nx5(
"nx5");
93 if (!(Poco::icompare(nxs, extn) == 0 || Poco::icompare(nx5, extn) == 0))
97 std::vector<std::string> entryName, definition;
100 g_log.
error(
"Error reading file " + filePath);
102 }
else if (
count == 0) {
103 g_log.
error(
"Error no entries found in " + filePath);
107 return entryName[0] ==
"mantid_workspace_1";
117 const std::string reductionManagerName =
getProperty(
"ReductionProperties");
118 std::shared_ptr<PropertyManager> reductionManager;
122 reductionManager = std::make_shared<PropertyManager>();
126 if (!reductionManager->existsProperty(
"SensitivityAlgorithm")) {
127 auto algProp = std::make_unique<AlgorithmProperty>(
"SensitivityAlgorithm");
129 reductionManager->declareProperty(std::move(algProp));
132 progress.report(
"Loading sensitivity file");
136 Poco::Path path(fileName);
137 const std::string entryName =
"Sensitivity" + path.getBaseName();
139 std::string floodWSName =
"__sensitivity_" + path.getBaseName();
141 if (reductionManager->existsProperty(entryName)) {
142 std::string wsName = reductionManager->getPropertyValue(entryName);
146 g_log.
debug() <<
"SANSSensitivityCorrection :: Using sensitivity workspace: " << wsName <<
"\n";
152 g_log.
debug() <<
"SANSSensitivityCorrection :: Loading sensitivity file: " << fileName <<
"\n";
154 loadAlg->setProperty(
"Filename", fileName);
155 loadAlg->executeAsChildAlg();
156 Workspace_sptr floodWS_ws = loadAlg->getProperty(
"OutputWorkspace");
157 floodWS = std::dynamic_pointer_cast<MatrixWorkspace>(floodWS_ws);
160 if (!floodWS->run().hasProperty(
"is_sensitivity")) {
163 g_log.
error() <<
"A processed Mantid workspace was loaded but it "
164 "wasn't a sensitivity file!\n";
174 if (reductionManager->existsProperty(
"LatestBeamCenterX") &&
175 reductionManager->existsProperty(
"LatestBeamCenterY")) {
176 center_x = reductionManager->getProperty(
"LatestBeamCenterX");
177 center_y = reductionManager->getProperty(
"LatestBeamCenterY");
178 m_output_message +=
" |Setting beam center to [" + Poco::NumberFormatter::format(center_x, 1) +
", " +
179 Poco::NumberFormatter::format(center_y, 1) +
"]\n";
184 const std::string rawFloodWSName =
"__flood_data_" + path.getBaseName();
186 if (!reductionManager->existsProperty(
"LoadAlgorithm")) {
188 loadAlg->setProperty(
"Filename", fileName);
189 if (!
isEmpty(center_x) && loadAlg->existsProperty(
"BeamCenterX"))
190 loadAlg->setProperty(
"BeamCenterX", center_x);
191 if (!
isEmpty(center_y) && loadAlg->existsProperty(
"BeamCenterY"))
192 loadAlg->setProperty(
"BeamCenterY", center_y);
193 loadAlg->setPropertyValue(
"OutputWorkspace", rawFloodWSName);
194 loadAlg->executeAsChildAlg();
196 rawFloodWS = std::dynamic_pointer_cast<MatrixWorkspace>(tmpWS);
201 IAlgorithm_sptr loadAlg0 = reductionManager->getProperty(
"LoadAlgorithm");
202 const std::string loadString = loadAlg0->toString();
204 loadAlg->setChild(
true);
205 loadAlg->setProperty(
"Filename", fileName);
206 loadAlg->setPropertyValue(
"OutputWorkspace", rawFloodWSName);
207 if (!
isEmpty(center_x) && loadAlg->existsProperty(
"BeamCenterX"))
208 loadAlg->setProperty(
"BeamCenterX", center_x);
209 if (!
isEmpty(center_y) && loadAlg->existsProperty(
"BeamCenterY"))
210 loadAlg->setProperty(
"BeamCenterY", center_y);
212 rawFloodWS = loadAlg->getProperty(
"OutputWorkspace");
214 if (loadAlg->existsProperty(
"OutputMessage")) {
215 std::string msg = loadAlg->getPropertyValue(
"OutputMessage");
222 if (!rawFloodWS->run().hasProperty(
"is_sensitivity")) {
226 std::string dark_result;
227 if (reductionManager->existsProperty(
"DarkCurrentAlgorithm")) {
228 IAlgorithm_sptr darkAlg = reductionManager->getProperty(
"DarkCurrentAlgorithm");
229 darkAlg->setChild(
true);
230 darkAlg->setProperty(
"InputWorkspace", rawFloodWS);
231 darkAlg->setProperty(
"OutputWorkspace", rawFloodWS);
238 if (darkAlg->existsProperty(
"OutputMessage"))
239 dark_result = darkAlg->getPropertyValue(
"OutputMessage");
240 }
else if (!darkCurrentFile.empty()) {
241 darkAlg->setProperty(
"Filename", darkCurrentFile);
242 darkAlg->setProperty(
"PersistentCorrection",
false);
244 if (darkAlg->existsProperty(
"OutputMessage"))
245 dark_result = darkAlg->getPropertyValue(
"OutputMessage");
247 dark_result =
" Dark current subtracted\n";
249 }
else if (!darkCurrentFile.empty()) {
254 if (reductionManager->existsProperty(
"DefaultDarkCurrentAlgorithm")) {
255 IAlgorithm_sptr darkAlg = reductionManager->getProperty(
"DefaultDarkCurrentAlgorithm");
256 darkAlg->setChild(
true);
257 darkAlg->setProperty(
"InputWorkspace", rawFloodWS);
258 darkAlg->setProperty(
"OutputWorkspace", rawFloodWS);
259 darkAlg->setProperty(
"Filename", darkCurrentFile);
260 darkAlg->setProperty(
"PersistentCorrection",
false);
262 if (darkAlg->existsProperty(
"OutputMessage"))
263 dark_result = darkAlg->getPropertyValue(
"OutputMessage");
268 dark_result =
" No dark current algorithm provided: skipped\n";
274 if (reductionManager->existsProperty(
"SANSSolidAngleCorrection")) {
275 IAlgorithm_sptr solidAlg = reductionManager->getProperty(
"SANSSolidAngleCorrection");
276 solidAlg->setChild(
true);
277 solidAlg->setProperty(
"InputWorkspace", rawFloodWS);
278 solidAlg->setProperty(
"OutputWorkspace", rawFloodWS);
280 std::string msg =
"Solid angle correction applied\n";
281 if (solidAlg->existsProperty(
"OutputMessage"))
282 msg = solidAlg->getPropertyValue(
"OutputMessage");
287 double floodTransmissionValue =
getProperty(
"FloodTransmissionValue");
288 double floodTransmissionError =
getProperty(
"FloodTransmissionError");
290 if (!
isEmpty(floodTransmissionValue)) {
291 g_log.
debug() <<
"SANSSensitivityCorrection :: Applying transmission "
294 transAlg->setProperty(
"InputWorkspace", rawFloodWS);
295 transAlg->setProperty(
"OutputWorkspace", rawFloodWS);
296 transAlg->setProperty(
"TransmissionValue", floodTransmissionValue);
297 transAlg->setProperty(
"TransmissionError", floodTransmissionError);
298 transAlg->setProperty(
"ThetaDependent",
true);
300 rawFloodWS = transAlg->getProperty(
"OutputWorkspace");
306 effAlg->setProperty(
"InputWorkspace", rawFloodWS);
308 const double minEff =
getProperty(
"MinEfficiency");
309 const double maxEff =
getProperty(
"MaxEfficiency");
310 const std::string maskFullComponent =
getPropertyValue(
"MaskedFullComponent");
314 effAlg->setProperty(
"MinEfficiency", minEff);
315 effAlg->setProperty(
"MaxEfficiency", maxEff);
316 effAlg->setProperty(
"MaskedFullComponent", maskFullComponent);
317 effAlg->setProperty(
"MaskedEdges", maskEdges);
318 effAlg->setProperty(
"MaskedComponent", maskComponent);
320 floodWS = effAlg->getProperty(
"OutputWorkspace");
322 floodWS = rawFloodWS;
325 if (reductionManager->existsProperty(
"SensitivityPatchAlgorithm")) {
326 IAlgorithm_sptr patchAlg = reductionManager->getProperty(
"SensitivityPatchAlgorithm");
327 patchAlg->setChild(
true);
328 patchAlg->setProperty(
"Workspace", floodWS);
333 floodWS->mutableRun().addProperty(
"is_sensitivity", 1,
"",
true);
335 std::string floodWSOutputName =
getPropertyValue(
"OutputSensitivityWorkspace");
336 if (floodWSOutputName.empty()) {
339 reductionManager->declareProperty(
341 reductionManager->setPropertyValue(entryName, floodWSName);
342 reductionManager->setProperty(entryName, floodWS);
344 setProperty(
"OutputSensitivityWorkspace", floodWS);
347 progress.report(3,
"Loaded flood field");
354 divideAlg->setProperty(
"LHSWorkspace", inputWS);
355 divideAlg->setProperty(
"RHSWorkspace", floodWS);
356 divideAlg->executeAsChildAlg();
361 maskAlg->setProperty(
"Workspace", outputWS);
362 maskAlg->setProperty(
"MaskedWorkspace", floodWS);
363 maskAlg->executeAsChildAlg();
369 progress.report(
"Performed sensitivity correction");
#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.
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.
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.
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
@ Load
allowed here which will be passed to the algorithm
Helper class for reporting progress from algorithms.
A property class for workspaces.
Support for a property that holds an array of values.
Records the filename and the description of failure.
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.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::string m_output_message
void init() override
Initialisation code.
bool fileCheck(const std::string &filePath)
Check whether we have a processed file of not.
void exec() override
Execution code.
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
MANTID_NEXUS_DLL int getNexusEntryTypes(const std::string &fileName, std::vector< std::string > &entryName, std::vector< std::string > &definition)
Get all the Nexus entry types for a file.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ InOut
Both an input & output workspace.
@ Input
An input workspace.
@ Output
An output workspace.