Mantid
Loading...
Searching...
No Matches
SetupEQSANSReduction.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//----------------------------------------------------------------------
8// Includes
9//----------------------------------------------------------------------
21#include "Poco/NumberFormatter.h"
22
23#include <boost/algorithm/string/predicate.hpp>
24
26
27// Register the algorithm into the AlgorithmFactory
28DECLARE_ALGORITHM(SetupEQSANSReduction)
29
30using namespace Kernel;
31using namespace API;
32using namespace Geometry;
33
35 // Load options
36 std::string load_grp = "Load Options";
37 declareProperty("UseConfigTOFCuts", false,
38 "If true, the edges of the TOF distribution will be cut "
39 "according to the configuration file");
40 declareProperty("LowTOFCut", 0.0,
41 "TOF value below which events will not be "
42 "loaded into the workspace at load-time");
43 declareProperty("HighTOFCut", 0.0,
44 "TOF value above which events will not be "
45 "loaded into the workspace at load-time");
46 declareProperty("WavelengthStep", 0.1,
47 "Wavelength steps to be used when "
48 "rebinning the data before performing "
49 "the reduction");
50 declareProperty("UseConfigMask", false,
51 "If true, the masking information "
52 "found in the configuration file "
53 "will be used");
54 declareProperty("UseConfig", true, "If true, the best configuration file found will be used");
55 declareProperty("CorrectForFlightPath", false,
56 "If true, the TOF will be modified for the true flight path "
57 "from the sample to the detector pixel");
58
59 declareProperty("SkipTOFCorrection", false, "If true, the EQSANS TOF correction will be skipped");
60 declareProperty("PreserveEvents", false, "If true, the output workspace will be an event workspace");
61
62 declareProperty("SampleDetectorDistance", EMPTY_DBL(),
63 "Sample to detector distance to use (overrides meta data), in mm");
64
65 declareProperty("SampleDetectorDistanceOffset", EMPTY_DBL(),
66 "Offset to the sample to detector distance (use only when "
67 "using the detector distance found in the meta data), in mm");
68 declareProperty("SampleOffset", EMPTY_DBL(),
69 "Offset applies to the sample position (use only when "
70 "using the detector distance found in the meta data), in mm");
71 declareProperty("DetectorOffset", EMPTY_DBL(),
72 "Offset applies to the detector position (use only when "
73 "using the distance found in the meta data), in mm");
74
75 declareProperty("SolidAngleCorrection", true, "If true, the solid angle correction will be applied to the data");
76 declareProperty("DetectorTubes", false, "If true, the solid angle correction for tube detectors will be applied");
77
78 declareProperty("LoadNexusInstrumentXML", true,
79 "Reads the embedded Instrument XML from the NeXus file "
80 "(optional, default True). ");
81
82 // -- Define group --
83 setPropertyGroup("UseConfigTOFCuts", load_grp);
84 setPropertyGroup("LowTOFCut", load_grp);
85 setPropertyGroup("HighTOFCut", load_grp);
86
87 setPropertyGroup("WavelengthStep", load_grp);
88 setPropertyGroup("UseConfigMask", load_grp);
89 setPropertyGroup("UseConfig", load_grp);
90 setPropertyGroup("CorrectForFlightPath", load_grp);
91
92 setPropertyGroup("SkipTOFCorrection", load_grp);
93 setPropertyGroup("PreserveEvents", load_grp);
94
95 setPropertyGroup("SampleDetectorDistance", load_grp);
96 setPropertyGroup("SampleDetectorDistanceOffset", load_grp);
97
98 setPropertyGroup("SampleOffset", load_grp);
99 setPropertyGroup("DetectorOffset", load_grp);
100 setPropertyGroup("SolidAngleCorrection", load_grp);
101 setPropertyGroup("DetectorTubes", load_grp);
102 setPropertyGroup("LoadNexusInstrumentXML", load_grp);
103
104 // Beam center
105 std::string center_grp = "Beam Center";
106 std::vector<std::string> centerOptions{"None", "Value", "DirectBeam", "Scattering"};
107
108 declareProperty("BeamCenterMethod", "None", std::make_shared<StringListValidator>(centerOptions),
109 "Method for determining the data beam center");
110
111 // declareProperty("FindBeamCenter", false, "If True, the beam center will be
112 // calculated");
113 declareProperty("UseConfigBeam", false, "If True, the beam center will be taken from the config file");
114
115 // Option 1: Set beam center by hand
116 declareProperty("BeamCenterX", EMPTY_DBL(), "Position of the beam center, in pixel");
117 declareProperty("BeamCenterY", EMPTY_DBL(), "Position of the beam center, in pixel");
118 setPropertySettings("BeamCenterX", std::make_unique<VisibleWhenProperty>("BeamCenterMethod", IS_EQUAL_TO, "Value"));
119 setPropertySettings("BeamCenterY", std::make_unique<VisibleWhenProperty>("BeamCenterMethod", IS_EQUAL_TO, "Value"));
120
121 // Option 2: Find it (expose properties from FindCenterOfMass)
123 std::make_unique<API::FileProperty>("BeamCenterFile", "", API::FileProperty::OptionalLoad, "_event.nxs"),
124 "The name of the input event Nexus file to load");
125 setPropertySettings("BeamCenterFile",
126 std::make_unique<VisibleWhenProperty>("BeamCenterMethod", IS_NOT_EQUAL_TO, "None"));
127
128 // declareProperty("Tolerance", EMPTY_DBL(), "Tolerance on the center of mass
129 // position between each iteration [m]. Default: 0.00125");
130 auto positiveDouble = std::make_shared<BoundedValidator<double>>();
131 positiveDouble->setLower(0);
132 // declareProperty("UseDirectBeamMethod", true, "If true, the direct beam
133 // method will be used");
134 declareProperty("BeamRadius", EMPTY_DBL(),
135 "Radius of the beam area used the exclude the beam when calculating "
136 "the center of mass of the scattering pattern [pixels]. Default=3.0");
137 setPropertySettings("BeamRadius",
138 std::make_unique<VisibleWhenProperty>("BeamCenterMethod", IS_EQUAL_TO, "Scattering"));
139
140 // -- Define group --
141 setPropertyGroup("BeamCenterMethod", center_grp);
142 setPropertyGroup("UseConfigBeam", center_grp);
143 setPropertyGroup("BeamCenterX", center_grp);
144 setPropertyGroup("BeamCenterY", center_grp);
145 setPropertyGroup("BeamCenterFile", center_grp);
146 // setPropertyGroup("Tolerance", center_grp);
147 // setPropertyGroup("UseDirectBeamMethod", center_grp);
148 setPropertyGroup("BeamRadius", center_grp);
149
150 // Normalisation
151 std::string norm_grp = "Normalisation";
152 std::vector<std::string> incidentBeamNormOptions;
153 incidentBeamNormOptions.emplace_back("None");
154 // The data will be normalised to the monitor counts
155 incidentBeamNormOptions.emplace_back("Monitor");
156 // The data will be normalised to the total charge and divided by the beam
157 // profile
158 incidentBeamNormOptions.emplace_back("BeamProfileAndCharge");
159 // The data will be normalised to the total charge only (no beam profile)
160 incidentBeamNormOptions.emplace_back("Charge");
161 this->declareProperty("Normalisation", "BeamProfileAndCharge",
162 std::make_shared<StringListValidator>(incidentBeamNormOptions),
163 "Options for data normalisation");
164
165 declareProperty("LoadMonitors", false, "If true, the monitor workspace will be loaded");
166 // declareProperty("NormaliseToBeam", true, "If true, the data will be
167 // normalised to the total charge and divided by the beam profile");
168 // declareProperty("NormaliseToMonitor", false, "If true, the data will be
169 // normalised to the monitor, otherwise the total charge will be used");
171 std::make_unique<API::FileProperty>("MonitorReferenceFile", "", API::FileProperty::OptionalLoad, "_event.nxs"),
172 "The name of the beam monitor reference file used for normalisation");
173
174 setPropertyGroup("Normalisation", norm_grp);
175 setPropertyGroup("LoadMonitors", norm_grp);
176 setPropertyGroup("MonitorReferenceFile", norm_grp);
177
178 // Dark current
180 std::make_unique<API::FileProperty>("DarkCurrentFile", "", API::FileProperty::OptionalLoad, "_event.nxs"),
181 "The name of the input event Nexus file to load as dark current.");
182
183 // Sensitivity
184 std::string eff_grp = "Sensitivity";
186 std::make_unique<API::FileProperty>("SensitivityFile", "", API::FileProperty::OptionalLoad, "_event.nxs"),
187 "Flood field or sensitivity file.");
188 declareProperty("MinEfficiency", EMPTY_DBL(), positiveDouble,
189 "Minimum efficiency for a pixel to be considered (default: no minimum).");
190 declareProperty("MaxEfficiency", EMPTY_DBL(), positiveDouble,
191 "Maximum efficiency for a pixel to be considered (default: no maximum).");
192 declareProperty("UseDefaultDC", true,
193 "If true, the dark current subtracted "
194 "from the sample data will also be "
195 "subtracted from the flood field.");
196 declareProperty(std::make_unique<API::FileProperty>("SensitivityDarkCurrentFile", "", API::FileProperty::OptionalLoad,
197 "_event.nxs"),
198 "The name of the input file to load as dark current.");
199 // - sensitivity beam center
200 declareProperty("SensitivityBeamCenterMethod", "None", std::make_shared<StringListValidator>(centerOptions),
201 "Method for determining the sensitivity data beam center");
202
203 // Option 1: Set beam center by hand
204 declareProperty("SensitivityBeamCenterX", EMPTY_DBL(), "Sensitivity beam center location in X [pixels]");
205 setPropertySettings("SensitivityBeamCenterX",
206 std::make_unique<VisibleWhenProperty>("SensitivityBeamCenterMethod", IS_EQUAL_TO, "Value"));
207
208 declareProperty("SensitivityBeamCenterY", EMPTY_DBL(), "Sensitivity beam center location in Y [pixels]");
209 setPropertySettings("SensitivityBeamCenterY",
210 std::make_unique<VisibleWhenProperty>("SensitivityBeamCenterMethod", IS_EQUAL_TO, "Value"));
211
212 // Option 2: Find it (expose properties from FindCenterOfMass)
214 std::make_unique<API::FileProperty>("SensitivityBeamCenterFile", "", API::FileProperty::OptionalLoad, ".xml"),
215 "The name of the input data file to load");
216 setPropertySettings("SensitivityBeamCenterFile",
217 std::make_unique<VisibleWhenProperty>("SensitivityBeamCenterMethod", IS_NOT_EQUAL_TO, "None"));
218
219 declareProperty("SensitivityBeamCenterRadius", EMPTY_DBL(),
220 "Radius of the beam area used the exclude the beam when calculating "
221 "the center of mass of the scattering pattern [pixels]. Default=3.0");
222 setPropertySettings("SensitivityBeamCenterRadius",
223 std::make_unique<VisibleWhenProperty>("BeamCenterMethod", IS_EQUAL_TO, "Scattering"));
224
225 declareProperty("OutputSensitivityWorkspace", "", "Name to give the sensitivity workspace");
226
227 // -- Define group --
228 setPropertyGroup("SensitivityFile", eff_grp);
229 setPropertyGroup("MinEfficiency", eff_grp);
230 setPropertyGroup("MaxEfficiency", eff_grp);
231 setPropertyGroup("UseDefaultDC", eff_grp);
232 setPropertyGroup("SensitivityDarkCurrentFile", eff_grp);
233 setPropertyGroup("SensitivityBeamCenterMethod", eff_grp);
234 setPropertyGroup("SensitivityBeamCenterX", eff_grp);
235 setPropertyGroup("SensitivityBeamCenterY", eff_grp);
236 setPropertyGroup("SensitivityBeamCenterFile", eff_grp);
237 setPropertyGroup("SensitivityBeamCenterRadius", eff_grp);
238 setPropertyGroup("OutputSensitivityWorkspace", eff_grp);
239
240 // Transmission
241 std::string trans_grp = "Transmission";
242 std::vector<std::string> transOptions{"Value", "DirectBeam"};
243 declareProperty("TransmissionMethod", "Value", std::make_shared<StringListValidator>(transOptions),
244 "Transmission determination method");
245
246 // - Transmission value entered by hand
247 declareProperty("TransmissionValue", EMPTY_DBL(), positiveDouble, "Transmission value.");
248 setPropertySettings("TransmissionValue",
249 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "Value"));
250 declareProperty("TransmissionError", EMPTY_DBL(), positiveDouble, "Transmission error.");
251 setPropertySettings("TransmissionError",
252 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "Value"));
253
254 // - Direct beam method transmission calculation
255 declareProperty("TransmissionBeamRadius", 3.0, "Radius of the beam area used to compute the transmission [pixels]");
256 setPropertySettings("TransmissionBeamRadius",
257 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
259 std::make_unique<API::FileProperty>("TransmissionSampleDataFile", "", API::FileProperty::OptionalLoad, ".xml"),
260 "Sample data file for transmission calculation");
261 setPropertySettings("TransmissionSampleDataFile",
262 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
264 std::make_unique<API::FileProperty>("TransmissionEmptyDataFile", "", API::FileProperty::OptionalLoad, ".xml"),
265 "Empty data file for transmission calculation");
266 setPropertySettings("TransmissionEmptyDataFile",
267 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
268 declareProperty("FitFramesTogether", false, "If true, the two frames will be fit together");
269 setPropertySettings("FitFramesTogether",
270 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
271
272 // - transmission beam center
273 declareProperty("TransmissionBeamCenterMethod", "None", std::make_shared<StringListValidator>(centerOptions),
274 "Method for determining the transmission data beam center");
275 setPropertySettings("TransmissionBeamCenterMethod",
276 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
277
278 // Option 1: Set beam center by hand
279 declareProperty("TransmissionBeamCenterX", EMPTY_DBL(), "Transmission beam center location in X [pixels]");
280 setPropertySettings("TransmissionBeamCenterX",
281 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
282 declareProperty("TransmissionBeamCenterY", EMPTY_DBL(), "Transmission beam center location in Y [pixels]");
283 setPropertySettings("TransmissionBeamCenterY",
284 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
285
286 // Option 2: Find it (expose properties from FindCenterOfMass)
288 std::make_unique<API::FileProperty>("TransmissionBeamCenterFile", "", API::FileProperty::OptionalLoad, ".xml"),
289 "The name of the input data file to load");
290 setPropertySettings("TransmissionBeamCenterFile",
291 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
292
294 std::make_unique<API::FileProperty>("TransmissionDarkCurrentFile", "", API::FileProperty::OptionalLoad, ".xml"),
295 "The name of the input data file to load as transmission dark current.");
296 setPropertySettings("TransmissionDarkCurrentFile",
297 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_NOT_EQUAL_TO, "Value"));
298
299 declareProperty("TransmissionUseSampleDC", true,
300 "If true, the sample dark current will be used IF a dark current file is"
301 "not set.");
302 setPropertySettings("TransmissionUseSampleDC",
303 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_NOT_EQUAL_TO, "Value"));
304
305 declareProperty("ThetaDependentTransmission", true,
306 "If true, a theta-dependent transmission correction will be applied.");
307
308 // -- Define group --
309 setPropertyGroup("TransmissionMethod", trans_grp);
310 setPropertyGroup("TransmissionValue", trans_grp);
311 setPropertyGroup("TransmissionError", trans_grp);
312 setPropertyGroup("TransmissionBeamRadius", trans_grp);
313 setPropertyGroup("TransmissionSampleDataFile", trans_grp);
314 setPropertyGroup("TransmissionEmptyDataFile", trans_grp);
315 setPropertyGroup("FitFramesTogether", trans_grp);
316 setPropertyGroup("TransmissionBeamCenterMethod", trans_grp);
317 setPropertyGroup("TransmissionBeamCenterX", trans_grp);
318 setPropertyGroup("TransmissionBeamCenterY", trans_grp);
319 setPropertyGroup("TransmissionBeamCenterFile", trans_grp);
320
321 setPropertyGroup("TransmissionDarkCurrentFile", trans_grp);
322 setPropertyGroup("TransmissionUseSampleDC", trans_grp);
323 setPropertyGroup("ThetaDependentTransmission", trans_grp);
324
325 // Background options
326 std::string bck_grp = "Background";
327 declareProperty("BackgroundFiles", "", "Background data files");
328 declareProperty("BckTransmissionMethod", "Value", std::make_shared<StringListValidator>(transOptions),
329 "Transmission determination method");
330
331 // - Transmission value entered by hand
332 declareProperty("BckTransmissionValue", EMPTY_DBL(), positiveDouble, "Transmission value.");
333 setPropertySettings("BckTransmissionValue",
334 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "Value"));
335
336 declareProperty("BckTransmissionError", EMPTY_DBL(), positiveDouble, "Transmission error.");
337 setPropertySettings("BckTransmissionError",
338 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "Value"));
339
340 // - Direct beam method transmission calculation
341 declareProperty("BckTransmissionBeamRadius", 3.0,
342 "Radius of the beam area used to compute the transmission [pixels]");
343 setPropertySettings("BckTransmissionBeamRadius",
344 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
346 std::make_unique<API::FileProperty>("BckTransmissionSampleDataFile", "", API::FileProperty::OptionalLoad, ".xml"),
347 "Sample data file for transmission calculation");
348 setPropertySettings("BckTransmissionSampleDataFile",
349 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
351 std::make_unique<API::FileProperty>("BckTransmissionEmptyDataFile", "", API::FileProperty::OptionalLoad, ".xml"),
352 "Empty data file for transmission calculation");
353 setPropertySettings("BckTransmissionEmptyDataFile",
354 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
355 declareProperty("BckFitFramesTogether", false, "If true, the two frames will be fit together");
356 setPropertySettings("BckFitFramesTogether",
357 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
358
359 // - transmission beam center
360 declareProperty("BckTransmissionBeamCenterMethod", "None", std::make_shared<StringListValidator>(centerOptions),
361 "Method for determining the transmission data beam center");
362 setPropertySettings("BckTransmissionBeamCenterMethod",
363 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
364 // Option 1: Set beam center by hand
365 declareProperty("BckTransmissionBeamCenterX", EMPTY_DBL(), "Transmission beam center location in X [pixels]");
366 setPropertySettings("BckTransmissionBeamCenterX",
367 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
368 declareProperty("BckTransmissionBeamCenterY", EMPTY_DBL(), "Transmission beam center location in Y [pixels]");
369 // Option 2: Find it (expose properties from FindCenterOfMass)
370 setPropertySettings("BckTransmissionBeamCenterY",
371 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
373 std::make_unique<API::FileProperty>("BckTransmissionBeamCenterFile", "", API::FileProperty::OptionalLoad, ".xml"),
374 "The name of the input data file to load");
375 setPropertySettings("BckTransmissionBeamCenterFile",
376 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
377
378 declareProperty(std::make_unique<API::FileProperty>("BckTransmissionDarkCurrentFile", "",
380 "The name of the input data file to load as background "
381 "transmission dark current.");
382 setPropertySettings("BckTransmissionDarkCurrentFile",
383 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
384
385 declareProperty("BckThetaDependentTransmission", true,
386 "If true, a theta-dependent transmission correction will be applied.");
387
388 setPropertyGroup("BackgroundFiles", bck_grp);
389 setPropertyGroup("BckTransmissionMethod", bck_grp);
390 setPropertyGroup("BckTransmissionValue", bck_grp);
391 setPropertyGroup("BckTransmissionError", bck_grp);
392 setPropertyGroup("BckTransmissionBeamRadius", bck_grp);
393 setPropertyGroup("BckTransmissionSampleDataFile", bck_grp);
394 setPropertyGroup("BckTransmissionEmptyDataFile", bck_grp);
395 setPropertyGroup("BckTransmissionBeamCenterMethod", bck_grp);
396 setPropertyGroup("BckTransmissionBeamCenterX", bck_grp);
397 setPropertyGroup("BckTransmissionBeamCenterY", bck_grp);
398 setPropertyGroup("BckTransmissionBeamCenterFile", bck_grp);
399 setPropertyGroup("BckTransmissionDarkCurrentFile", bck_grp);
400 setPropertyGroup("BckThetaDependentTransmission", bck_grp);
401
402 // Geometry correction
403 declareProperty("SampleThickness", EMPTY_DBL(), "Sample thickness [cm]");
404
405 // Masking
406 std::string mask_grp = "Mask";
407 declareProperty(std::make_unique<ArrayProperty<int>>("MaskedDetectorList"), "List of detector IDs to be masked");
408 declareProperty(std::make_unique<ArrayProperty<int>>("MaskedEdges"),
409 "Number of pixels to mask on the edges: X-low, X-high, Y-low, Y-high");
410 std::vector<std::string> maskOptions{"None", "Front", "Back"};
411 declareProperty("MaskedSide", "None", std::make_shared<StringListValidator>(maskOptions),
412 "Mask one side of the detector");
413
414 setPropertyGroup("MaskedDetectorList", mask_grp);
415 setPropertyGroup("MaskedEdges", mask_grp);
416 setPropertyGroup("MaskedSide", mask_grp);
417
418 // Absolute scale
419 std::string abs_scale_grp = "Absolute Scale";
420 std::vector<std::string> scaleOptions;
421 scaleOptions.emplace_back("None");
422 scaleOptions.emplace_back("Value");
423 scaleOptions.emplace_back("ReferenceData");
424 declareProperty("AbsoluteScaleMethod", "None", std::make_shared<StringListValidator>(scaleOptions),
425 "Absolute scale correction method");
426 declareProperty("AbsoluteScalingFactor", 1.0, "Absolute scaling factor");
427 setPropertySettings("AbsoluteScalingFactor",
428 std::make_unique<VisibleWhenProperty>("AbsoluteScaleMethod", IS_EQUAL_TO, "Value"));
429
430 declareProperty(std::make_unique<API::FileProperty>("AbsoluteScalingReferenceFilename", "",
432 setPropertySettings("AbsoluteScalingReferenceFilename",
433 std::make_unique<VisibleWhenProperty>("AbsoluteScaleMethod", IS_EQUAL_TO, "ReferenceData"));
434 declareProperty("AbsoluteScalingBeamDiameter", 0.0,
435 "Beamstop diameter for computing the absolute scale factor [mm]. "
436 "Read from file if not supplied.");
437 setPropertySettings("AbsoluteScalingBeamDiameter",
438 std::make_unique<VisibleWhenProperty>("AbsoluteScaleMethod", IS_EQUAL_TO, "ReferenceData"));
439 declareProperty("AbsoluteScalingAttenuatorTrans", 1.0,
440 "Attenuator transmission value for computing the absolute scale factor");
441 setPropertySettings("AbsoluteScalingAttenuatorTrans",
442 std::make_unique<VisibleWhenProperty>("AbsoluteScaleMethod", IS_EQUAL_TO, "ReferenceData"));
443 declareProperty("AbsoluteScalingApplySensitivity", false,
444 "Apply sensitivity correction to the reference data "
445 "when computing the absolute scale factor");
446 setPropertySettings("AbsoluteScalingApplySensitivity",
447 std::make_unique<VisibleWhenProperty>("AbsoluteScaleMethod", IS_EQUAL_TO, "ReferenceData"));
448
449 setPropertyGroup("AbsoluteScaleMethod", abs_scale_grp);
450 setPropertyGroup("AbsoluteScalingFactor", abs_scale_grp);
451 setPropertyGroup("AbsoluteScalingReferenceFilename", abs_scale_grp);
452 setPropertyGroup("AbsoluteScalingBeamDiameter", abs_scale_grp);
453 setPropertyGroup("AbsoluteScalingAttenuatorTrans", abs_scale_grp);
454 setPropertyGroup("AbsoluteScalingApplySensitivity", abs_scale_grp);
455
456 // I(Q) calculation
457 std::string iq1d_grp = "I(q) Calculation";
458 declareProperty("DoAzimuthalAverage", true);
459 auto positiveInt = std::make_shared<BoundedValidator<int>>();
460 positiveInt->setLower(0);
461 declareProperty("IQNumberOfBins", 100, positiveInt, "Number of I(q) bins when binning is not specified");
462 declareProperty("IQLogBinning", false, "I(q) log binning when binning is not specified");
463 declareProperty("IQIndependentBinning", true,
464 "If true and frame skipping is "
465 "used, each frame will have "
466 "its own binning");
467 declareProperty("IQScaleResults", true, "If true and frame skipping is used, frame 1 will be scaled to frame 2");
468 declareProperty("ComputeResolution", false, "If true the Q resolution will be computed");
469 declareProperty("SampleApertureDiameter", 10.0, "Sample aperture diameter [mm]");
470
471 declareProperty("Do2DReduction", true);
472 declareProperty("IQ2DNumberOfBins", 100, positiveInt, "Number of I(qx,qy) bins.");
473
474 // -- Define group --
475 setPropertyGroup("DoAzimuthalAverage", iq1d_grp);
476 setPropertyGroup("IQNumberOfBins", iq1d_grp);
477 setPropertyGroup("IQLogBinning", iq1d_grp);
478 setPropertyGroup("IQIndependentBinning", iq1d_grp);
479 setPropertyGroup("IQScaleResults", iq1d_grp);
480 setPropertyGroup("ComputeResolution", iq1d_grp);
481 setPropertyGroup("SampleApertureDiameter", iq1d_grp);
482 setPropertyGroup("Do2DReduction", iq1d_grp);
483 setPropertyGroup("IQ2DNumberOfBins", iq1d_grp);
484
485 // Outputs
486 declareProperty("ProcessInfo", "", "Additional process information");
487 declareProperty("OutputDirectory", "", "Directory to put the output files in");
488 declareProperty("OutputMessage", "", Direction::Output);
489 declareProperty("ReductionProperties", "__sans_reduction_properties", Direction::Input);
490}
491
493 // Reduction property manager
494 const std::string reductionManagerName = getProperty("ReductionProperties");
495 if (reductionManagerName.empty()) {
496 g_log.error() << "ERROR: Reduction Property Manager name is empty\n";
497 return;
498 }
499 std::shared_ptr<PropertyManager> reductionManager = std::make_shared<PropertyManager>();
500 PropertyManagerDataService::Instance().addOrReplace(reductionManagerName, reductionManager);
501
502 // Store name of the instrument
503 reductionManager->declareProperty(std::make_unique<PropertyWithValue<std::string>>("InstrumentName", "EQSANS"));
504
505 // Store additional (and optional) process information
506 const std::string processInfo = getProperty("ProcessInfo");
507 reductionManager->declareProperty(std::make_unique<PropertyWithValue<std::string>>("ProcessInfo", processInfo));
508
509 // Store the output directory
510 const std::string outputDirectory = getProperty("OutputDirectory");
511 reductionManager->declareProperty(
512 std::make_unique<PropertyWithValue<std::string>>("OutputDirectory", outputDirectory));
513
514 // Store normalization algorithm
515 const std::string normalization = getProperty("Normalisation");
516 bool loadMonitors = getProperty("LoadMonitors");
517 const std::string monitorRefFile = getPropertyValue("MonitorReferenceFile");
518 // If we normalize to monitor, force the loading of monitor data
519 auto normAlg = createChildAlgorithm("EQSANSNormalise");
520
521 if (boost::contains(normalization, "BeamProfileAndCharge")) {
522 normAlg->setProperty("NormaliseToBeam", true);
523 normAlg->setProperty("BeamSpectrumFile", monitorRefFile);
524 } else if (boost::contains(normalization, "Charge")) {
525 normAlg->setProperty("NormaliseToBeam", false);
526 } else if (boost::contains(normalization, "Monitor")) {
527 if (monitorRefFile.empty()) {
528 g_log.error() << "ERROR: normalize-to-monitor was turned ON but no "
529 "reference data was selected\n";
530 } else {
531 loadMonitors = true;
532 }
533 normAlg->setProperty("NormaliseToMonitor", true);
534 normAlg->setProperty("BeamSpectrumFile", monitorRefFile);
535 }
536 normAlg->setPropertyValue("ReductionProperties", reductionManagerName);
537 auto normAlgProp = std::make_unique<AlgorithmProperty>("NormaliseAlgorithm");
538 normAlgProp->setValue(normAlg->toString());
539 reductionManager->declareProperty(std::move(normAlgProp));
540
541 // Load algorithm
542 auto loadAlg = createChildAlgorithm("EQSANSLoad");
543 const bool useConfigBeam = getProperty("UseConfigBeam");
544 loadAlg->setProperty("UseConfigBeam", useConfigBeam);
545 const bool useConfigTOFCuts = getProperty("UseConfigTOFCuts");
546 loadAlg->setProperty("UseConfigTOFCuts", useConfigTOFCuts);
547 if (!useConfigTOFCuts) {
548 const double lowTOFCut = getProperty("LowTOFCut");
549 const double highTOFCut = getProperty("HighTOFCut");
550 loadAlg->setProperty("LowTOFCut", lowTOFCut);
551 loadAlg->setProperty("HighTOFCut", highTOFCut);
552 }
553
554 const bool skipTOFCorrection = getProperty("SkipTOFCorrection");
555 loadAlg->setProperty("SkipTOFCorrection", skipTOFCorrection);
556
557 const bool correctForFlightPath = getProperty("CorrectForFlightPath");
558 loadAlg->setProperty("CorrectForFlightPath", correctForFlightPath);
559
560 const bool preserveEvents = getProperty("PreserveEvents");
561 loadAlg->setProperty("PreserveEvents", preserveEvents);
562 // load from nexus if they aren't in the reference file
563 loadAlg->setProperty("LoadMonitors", (loadMonitors && monitorRefFile.empty()));
564
565 const double sdd = getProperty("SampleDetectorDistance");
566 loadAlg->setProperty("SampleDetectorDistance", sdd);
567 const double sddOffset = getProperty("SampleDetectorDistanceOffset");
568 loadAlg->setProperty("SampleDetectorDistanceOffset", sddOffset);
569 const double dOffset = getProperty("DetectorOffset");
570 loadAlg->setProperty("DetectorOffset", dOffset);
571 const double sOffset = getProperty("SampleOffset");
572 loadAlg->setProperty("SampleOffset", sOffset);
573 const double wlStep = getProperty("WavelengthStep");
574 loadAlg->setProperty("WavelengthStep", wlStep);
575
576 const bool useConfig = getProperty("UseConfig");
577 loadAlg->setProperty("UseConfig", useConfig);
578 const bool useConfigMask = getProperty("UseConfigMask");
579 loadAlg->setProperty("UseConfigMask", useConfigMask);
580 const bool loadNexusInstrumentXML = getProperty("LoadNexusInstrumentXML");
581 loadAlg->setProperty("LoadNexusInstrumentXML", loadNexusInstrumentXML);
582 auto loadAlgProp = std::make_unique<AlgorithmProperty>("LoadAlgorithm");
583 loadAlgProp->setValue(loadAlg->toString());
584 reductionManager->declareProperty(std::move(loadAlgProp));
585
586 // Store dark current algorithm
587 const std::string darkCurrentFile = getPropertyValue("DarkCurrentFile");
588 if (!darkCurrentFile.empty()) {
589 auto darkAlg = createChildAlgorithm("EQSANSDarkCurrentSubtraction");
590 darkAlg->setProperty("Filename", darkCurrentFile);
591 darkAlg->setProperty("OutputDarkCurrentWorkspace", "");
592 darkAlg->setPropertyValue("ReductionProperties", reductionManagerName);
593 auto dcAlgProp = std::make_unique<AlgorithmProperty>("DarkCurrentAlgorithm");
594 dcAlgProp->setValue(darkAlg->toString());
595 reductionManager->declareProperty(std::move(dcAlgProp));
596 }
597
598 // Store default dark current algorithm
599 auto darkDefaultAlg = createChildAlgorithm("EQSANSDarkCurrentSubtraction");
600 darkDefaultAlg->setProperty("OutputDarkCurrentWorkspace", "");
601 darkDefaultAlg->setPropertyValue("ReductionProperties", reductionManagerName);
602 auto ddcAlgProp = std::make_unique<AlgorithmProperty>("DefaultDarkCurrentAlgorithm");
603 ddcAlgProp->setValue(darkDefaultAlg->toString());
604 reductionManager->declareProperty(std::move(ddcAlgProp));
605
606 // Solid angle correction
607 const bool solidAngleCorrection = getProperty("SolidAngleCorrection");
608 if (solidAngleCorrection) {
609 const bool detectorTubes = getProperty("DetectorTubes");
610 auto solidAlg = createChildAlgorithm("SANSSolidAngleCorrection");
611 solidAlg->setProperty("DetectorTubes", detectorTubes);
612 auto ssaAlgProp = std::make_unique<AlgorithmProperty>("SANSSolidAngleCorrection");
613 ssaAlgProp->setValue(solidAlg->toString());
614 reductionManager->declareProperty(std::move(ssaAlgProp));
615 }
616
617 // Beam center
618 const double beamCenterX = getProperty("BeamCenterX");
619 const double beamCenterY = getProperty("BeamCenterY");
620 const std::string centerMethod = getPropertyValue("BeamCenterMethod");
621
622 // Beam center option for transmission data
623 if (boost::iequals(centerMethod, "Value")) {
624 if (!isEmpty(beamCenterX) && !isEmpty(beamCenterY)) {
625 reductionManager->declareProperty(std::make_unique<PropertyWithValue<double>>("LatestBeamCenterX", beamCenterX));
626 reductionManager->declareProperty(std::make_unique<PropertyWithValue<double>>("LatestBeamCenterY", beamCenterY));
627 }
628 } else if (!boost::iequals(centerMethod, "None")) {
629 bool useDirectBeamMethod = true;
630 if (!boost::iequals(centerMethod, "DirectBeam"))
631 useDirectBeamMethod = false;
632 const std::string beamCenterFile = getProperty("BeamCenterFile");
633 if (!beamCenterFile.empty()) {
634 const double beamRadius = getProperty("BeamRadius");
635
636 auto ctrAlg = createChildAlgorithm("SANSBeamFinder");
637 ctrAlg->setProperty("Filename", beamCenterFile);
638 ctrAlg->setProperty("UseDirectBeamMethod", useDirectBeamMethod);
639 if (!isEmpty(beamRadius))
640 ctrAlg->setProperty("BeamRadius", beamRadius);
641 ctrAlg->setPropertyValue("ReductionProperties", reductionManagerName);
642
643 auto ctrAlgProp = std::make_unique<AlgorithmProperty>("SANSBeamFinderAlgorithm");
644 ctrAlgProp->setValue(ctrAlg->toString());
645 reductionManager->declareProperty(std::move(ctrAlgProp));
646 } else {
647 g_log.error() << "ERROR: Beam center determination was required"
648 " but no file was provided\n";
649 }
650 }
651
652 // Sensitivity correction, transmission and background
653 setupSensitivity(reductionManager);
654 setupTransmission(reductionManager);
655 setupBackground(reductionManager);
656
657 // Geometry correction
658 const double thickness = getProperty("SampleThickness");
659 if (!isEmpty(thickness)) {
660 auto thickAlg = createChildAlgorithm("NormaliseByThickness");
661 thickAlg->setProperty("SampleThickness", thickness);
662
663 auto geomAlgProp = std::make_unique<AlgorithmProperty>("GeometryAlgorithm");
664 geomAlgProp->setValue(thickAlg->toString());
665 reductionManager->declareProperty(std::move(geomAlgProp));
666 }
667
668 // Mask
669 const std::string maskDetList = getPropertyValue("MaskedDetectorList");
670 const std::string maskEdges = getPropertyValue("MaskedEdges");
671 const std::string maskSide = getProperty("MaskedSide");
672
673 auto maskAlg = createChildAlgorithm("SANSMask");
674 // The following is broken, try PropertyValue
675 maskAlg->setPropertyValue("Facility", "SNS");
676 maskAlg->setPropertyValue("MaskedDetectorList", maskDetList);
677 maskAlg->setPropertyValue("MaskedEdges", maskEdges);
678 maskAlg->setProperty("MaskedSide", maskSide);
679 auto maskAlgProp = std::make_unique<AlgorithmProperty>("MaskAlgorithm");
680 maskAlgProp->setValue(maskAlg->toString());
681 reductionManager->declareProperty(std::move(maskAlgProp));
682
683 // Absolute scaling
684 const std::string absScaleMethod = getProperty("AbsoluteScaleMethod");
685 if (boost::iequals(absScaleMethod, "Value")) {
686 const double absScaleFactor = getProperty("AbsoluteScalingFactor");
687
688 auto absAlg = createChildAlgorithm("SANSAbsoluteScale");
689 absAlg->setProperty("Method", absScaleMethod);
690 absAlg->setProperty("ScalingFactor", absScaleFactor);
691 absAlg->setPropertyValue("ReductionProperties", reductionManagerName);
692 auto absAlgProp = std::make_unique<AlgorithmProperty>("AbsoluteScaleAlgorithm");
693 absAlgProp->setValue(absAlg->toString());
694 reductionManager->declareProperty(std::move(absAlgProp));
695 } else if (boost::iequals(absScaleMethod, "ReferenceData")) {
696 const std::string absRefFile = getPropertyValue("AbsoluteScalingReferenceFilename");
697 const double beamDiam = getProperty("AbsoluteScalingBeamDiameter");
698 const double attTrans = getProperty("AbsoluteScalingAttenuatorTrans");
699 const bool applySensitivity = getProperty("AbsoluteScalingApplySensitivity");
700
701 auto absAlg = createChildAlgorithm("SANSAbsoluteScale");
702 absAlg->setProperty("Method", absScaleMethod);
703 absAlg->setProperty("ReferenceDataFilename", absRefFile);
704 absAlg->setProperty("BeamstopDiameter", beamDiam);
705 absAlg->setProperty("AttenuatorTransmission", attTrans);
706 absAlg->setProperty("ApplySensitivity", applySensitivity);
707 absAlg->setPropertyValue("ReductionProperties", reductionManagerName);
708 auto scaleAlgProp = std::make_unique<AlgorithmProperty>("AbsoluteScaleAlgorithm");
709 scaleAlgProp->setValue(absAlg->toString());
710 reductionManager->declareProperty(std::move(scaleAlgProp));
711 }
712
713 // Azimuthal averaging
714 const bool doAveraging = getProperty("DoAzimuthalAverage");
715 if (doAveraging) {
716 const std::string nBins = getPropertyValue("IQNumberOfBins");
717 const bool logBinning = getProperty("IQLogBinning");
718 const double sampleApert = getProperty("SampleApertureDiameter");
719 const bool computeResolution = getProperty("ComputeResolution");
720 const bool indepBinning = getProperty("IQIndependentBinning");
721 const bool scaleResults = getProperty("IQScaleResults");
722
723 auto iqAlg = createChildAlgorithm("EQSANSAzimuthalAverage1D");
724 iqAlg->setPropertyValue("NumberOfBins", nBins);
725 iqAlg->setProperty("LogBinning", logBinning);
726 iqAlg->setProperty("ScaleResults", scaleResults);
727 iqAlg->setProperty("ComputeResolution", computeResolution);
728 iqAlg->setProperty("IndependentBinning", indepBinning);
729 iqAlg->setProperty("SampleApertureDiameter", sampleApert);
730 iqAlg->setPropertyValue("ReductionProperties", reductionManagerName);
731
732 auto iqalgProp = std::make_unique<AlgorithmProperty>("IQAlgorithm");
733 iqalgProp->setValue(iqAlg->toString());
734 reductionManager->declareProperty(std::move(iqalgProp));
735 }
736
737 // 2D reduction
738 const bool do2DReduction = getProperty("Do2DReduction");
739 if (do2DReduction) {
740 const std::string n_bins = getPropertyValue("IQ2DNumberOfBins");
741 auto iqAlg = createChildAlgorithm("EQSANSQ2D");
742 iqAlg->setPropertyValue("NumberOfBins", n_bins);
743 auto xyalgProp = std::make_unique<AlgorithmProperty>("IQXYAlgorithm");
744 xyalgProp->setValue(iqAlg->toString());
745 reductionManager->declareProperty(std::move(xyalgProp));
746 }
747 setPropertyValue("OutputMessage", "EQSANS reduction options set");
748
749 // Save a string representation of this algorithm
750 auto setupAlgProp = std::make_unique<AlgorithmProperty>("SetupAlgorithm");
751 setupAlgProp->setValue(toString());
752 reductionManager->declareProperty(std::move(setupAlgProp));
753}
754
755void SetupEQSANSReduction::setupSensitivity(const std::shared_ptr<PropertyManager> &reductionManager) {
756 const std::string reductionManagerName = getProperty("ReductionProperties");
757
758 const std::string sensitivityFile = getPropertyValue("SensitivityFile");
759 if (!sensitivityFile.empty()) {
760 const bool useSampleDC = getProperty("UseDefaultDC");
761 const std::string sensitivityDarkCurrentFile = getPropertyValue("SensitivityDarkCurrentFile");
762 const std::string outputSensitivityWS = getPropertyValue("OutputSensitivityWorkspace");
763 const double minEff = getProperty("MinEfficiency");
764 const double maxEff = getProperty("MaxEfficiency");
765 const double sensitivityBeamCenterX = getProperty("SensitivityBeamCenterX");
766 const double sensitivityBeamCenterY = getProperty("SensitivityBeamCenterY");
767
768 auto effAlg = createChildAlgorithm("SANSSensitivityCorrection");
769 effAlg->setProperty("Filename", sensitivityFile);
770 effAlg->setProperty("UseSampleDC", useSampleDC);
771 effAlg->setProperty("DarkCurrentFile", sensitivityDarkCurrentFile);
772 effAlg->setProperty("MinEfficiency", minEff);
773 effAlg->setProperty("MaxEfficiency", maxEff);
774
775 // Beam center option for sensitivity data
776 const std::string centerMethod = getPropertyValue("SensitivityBeamCenterMethod");
777 if (boost::iequals(centerMethod, "Value")) {
778 if (!isEmpty(sensitivityBeamCenterX) && !isEmpty(sensitivityBeamCenterY)) {
779 effAlg->setProperty("BeamCenterX", sensitivityBeamCenterX);
780 effAlg->setProperty("BeamCenterY", sensitivityBeamCenterY);
781 }
782 } else if (boost::iequals(centerMethod, "DirectBeam") || boost::iequals(centerMethod, "Scattering")) {
783 const std::string beamCenterFile = getProperty("SensitivityBeamCenterFile");
784 const double sensitivityBeamRadius = getProperty("SensitivityBeamCenterRadius");
785 bool useDirectBeam = boost::iequals(centerMethod, "DirectBeam");
786 if (!beamCenterFile.empty()) {
787 auto ctrAlg = createChildAlgorithm("SANSBeamFinder");
788 ctrAlg->setProperty("Filename", beamCenterFile);
789 ctrAlg->setProperty("UseDirectBeamMethod", useDirectBeam);
790 ctrAlg->setProperty("PersistentCorrection", false);
791 if (!isEmpty(sensitivityBeamRadius))
792 ctrAlg->setProperty("BeamRadius", sensitivityBeamRadius);
793 ctrAlg->setPropertyValue("ReductionProperties", reductionManagerName);
794
795 auto sensAlgProp = std::make_unique<AlgorithmProperty>("SensitivityBeamCenterAlgorithm");
796 sensAlgProp->setValue(ctrAlg->toString());
797 reductionManager->declareProperty(std::move(sensAlgProp));
798 } else {
799 g_log.error() << "ERROR: Sensitivity beam center determination was required"
800 " but no file was provided\n";
801 }
802 }
803
804 effAlg->setPropertyValue("OutputSensitivityWorkspace", outputSensitivityWS);
805 effAlg->setPropertyValue("ReductionProperties", reductionManagerName);
806
807 auto algProp = std::make_unique<AlgorithmProperty>("SensitivityAlgorithm");
808 algProp->setValue(effAlg->toString());
809 reductionManager->declareProperty(std::move(algProp));
810 }
811}
812void SetupEQSANSReduction::setupTransmission(const std::shared_ptr<PropertyManager> &reductionManager) {
813 const std::string reductionManagerName = getProperty("ReductionProperties");
814 // Transmission options
815 const bool thetaDependentTrans = getProperty("ThetaDependentTransmission");
816 const std::string transMethod = getProperty("TransmissionMethod");
817 const std::string darkCurrent = getPropertyValue("TransmissionDarkCurrentFile");
818 const bool useSampleDC = getProperty("TransmissionUseSampleDC");
819
820 // Transmission is entered by hand
821 if (boost::iequals(transMethod, "Value")) {
822 const double transValue = getProperty("TransmissionValue");
823 const double transError = getProperty("TransmissionError");
824 if (!isEmpty(transValue) && !isEmpty(transError)) {
825 auto transAlg = createChildAlgorithm("ApplyTransmissionCorrection");
826 transAlg->setProperty("TransmissionValue", transValue);
827 transAlg->setProperty("TransmissionError", transError);
828 transAlg->setProperty("ThetaDependent", thetaDependentTrans);
829
830 auto algProp = std::make_unique<AlgorithmProperty>("TransmissionAlgorithm");
831 algProp->setValue(transAlg->toString());
832 reductionManager->declareProperty(std::move(algProp));
833 } else {
834 g_log.information("SetupEQSANSReduction [TransmissionAlgorithm]:"
835 "expected transmission/error values and got empty values");
836 }
837 }
838 // Direct beam method for transmission determination
839 else if (boost::iequals(transMethod, "DirectBeam")) {
840 const std::string sampleFilename = getPropertyValue("TransmissionSampleDataFile");
841 const std::string emptyFilename = getPropertyValue("TransmissionEmptyDataFile");
842 const double beamRadius = getProperty("TransmissionBeamRadius");
843 const bool fitFramesTogether = getProperty("FitFramesTogether");
844 const double beamX = getProperty("TransmissionBeamCenterX");
845 const double beamY = getProperty("TransmissionBeamCenterY");
846 const std::string centerMethod = getPropertyValue("TransmissionBeamCenterMethod");
847
848 auto transAlg = createChildAlgorithm("EQSANSDirectBeamTransmission");
849 transAlg->setProperty("FitFramesTogether", fitFramesTogether);
850 transAlg->setProperty("SampleDataFilename", sampleFilename);
851 transAlg->setProperty("EmptyDataFilename", emptyFilename);
852 transAlg->setProperty("BeamRadius", beamRadius);
853 transAlg->setProperty("DarkCurrentFilename", darkCurrent);
854 transAlg->setProperty("UseSampleDarkCurrent", useSampleDC);
855
856 // Beam center option for transmission data
857 if (boost::iequals(centerMethod, "Value") && !isEmpty(beamX) && !isEmpty(beamY)) {
858 transAlg->setProperty("BeamCenterX", beamX);
859 transAlg->setProperty("BeamCenterY", beamY);
860 } else if (boost::iequals(centerMethod, "DirectBeam")) {
861 const std::string beamCenterFile = getProperty("TransmissionBeamCenterFile");
862 if (!beamCenterFile.empty()) {
863 auto ctrAlg = createChildAlgorithm("SANSBeamFinder");
864 ctrAlg->setProperty("Filename", beamCenterFile);
865 ctrAlg->setProperty("UseDirectBeamMethod", true);
866 ctrAlg->setProperty("PersistentCorrection", false);
867 ctrAlg->setPropertyValue("ReductionProperties", reductionManagerName);
868
869 auto algProp = std::make_unique<AlgorithmProperty>("TransmissionBeamCenterAlgorithm");
870 algProp->setValue(ctrAlg->toString());
871 reductionManager->declareProperty(std::move(algProp));
872 } else {
873 g_log.error() << "ERROR: Transmission beam center determination was required"
874 " but no file was provided\n";
875 }
876 }
877 transAlg->setProperty("ThetaDependent", thetaDependentTrans);
878 auto algProp = std::make_unique<AlgorithmProperty>("TransmissionAlgorithm");
879 algProp->setValue(transAlg->toString());
880 reductionManager->declareProperty(std::move(algProp));
881 }
882}
883
884void SetupEQSANSReduction::setupBackground(const std::shared_ptr<PropertyManager> &reductionManager) {
885 const std::string reductionManagerName = getProperty("ReductionProperties");
886 // Background
887 const std::string backgroundFile = getPropertyValue("BackgroundFiles");
888 if (!backgroundFile.empty())
889 reductionManager->declareProperty(
890 std::make_unique<PropertyWithValue<std::string>>("BackgroundFiles", backgroundFile));
891 else
892 return;
893
894 const std::string darkCurrent = getPropertyValue("BckTransmissionDarkCurrentFile");
895 const bool bckThetaDependentTrans = getProperty("BckThetaDependentTransmission");
896 const std::string bckTransMethod = getProperty("BckTransmissionMethod");
897 if (boost::iequals(bckTransMethod, "Value")) {
898 const double transValue = getProperty("BckTransmissionValue");
899 const double transError = getProperty("BckTransmissionError");
900 if (!isEmpty(transValue) && !isEmpty(transError)) {
901 auto transAlg = createChildAlgorithm("ApplyTransmissionCorrection");
902 transAlg->setProperty("TransmissionValue", transValue);
903 transAlg->setProperty("TransmissionError", transError);
904 transAlg->setProperty("ThetaDependent", bckThetaDependentTrans);
905
906 auto algProp = std::make_unique<AlgorithmProperty>("BckTransmissionAlgorithm");
907 algProp->setValue(transAlg->toString());
908 reductionManager->declareProperty(std::move(algProp));
909 } else {
910 g_log.information("SetupEQSANSReduction [BckTransmissionAlgorithm]: "
911 "expected transmission/error values and got empty values");
912 }
913 } else if (boost::iequals(bckTransMethod, "DirectBeam")) {
914 const std::string sampleFilename = getPropertyValue("BckTransmissionSampleDataFile");
915 const std::string emptyFilename = getPropertyValue("BckTransmissionEmptyDataFile");
916 const double beamRadius = getProperty("BckTransmissionBeamRadius");
917 const double beamX = getProperty("BckTransmissionBeamCenterX");
918 const double beamY = getProperty("BckTransmissionBeamCenterY");
919 const bool thetaDependentTrans = getProperty("BckThetaDependentTransmission");
920 const bool useSampleDC = getProperty("TransmissionUseSampleDC");
921 const bool fitFramesTogether = getProperty("BckFitFramesTogether");
922
923 auto transAlg = createChildAlgorithm("EQSANSDirectBeamTransmission");
924 transAlg->setProperty("FitFramesTogether", fitFramesTogether);
925 transAlg->setProperty("SampleDataFilename", sampleFilename);
926 transAlg->setProperty("EmptyDataFilename", emptyFilename);
927 transAlg->setProperty("BeamRadius", beamRadius);
928 transAlg->setProperty("DarkCurrentFilename", darkCurrent);
929 transAlg->setProperty("UseSampleDarkCurrent", useSampleDC);
930
931 // Beam center option for transmission data
932 const std::string centerMethod = getPropertyValue("BckTransmissionBeamCenterMethod");
933 if (boost::iequals(centerMethod, "Value") && !isEmpty(beamX) && !isEmpty(beamY)) {
934 transAlg->setProperty("BeamCenterX", beamX);
935 transAlg->setProperty("BeamCenterY", beamY);
936 } else if (boost::iequals(centerMethod, "DirectBeam")) {
937 const std::string beamCenterFile = getProperty("BckTransmissionBeamCenterFile");
938 if (!beamCenterFile.empty()) {
939 auto ctrAlg = createChildAlgorithm("SANSBeamFinder");
940 ctrAlg->setProperty("Filename", beamCenterFile);
941 ctrAlg->setProperty("UseDirectBeamMethod", true);
942 ctrAlg->setProperty("PersistentCorrection", false);
943 ctrAlg->setPropertyValue("ReductionProperties", reductionManagerName);
944
945 auto algProp = std::make_unique<AlgorithmProperty>("BckTransmissionBeamCenterAlgorithm");
946 algProp->setValue(ctrAlg->toString());
947 reductionManager->declareProperty(std::move(algProp));
948 } else {
949 g_log.error() << "ERROR: Beam center determination was required"
950 " but no file was provided\n";
951 }
952 }
953 transAlg->setProperty("DarkCurrentFilename", darkCurrent);
954 transAlg->setProperty("ThetaDependent", thetaDependentTrans);
955 auto algProp = std::make_unique<AlgorithmProperty>("BckTransmissionAlgorithm");
956 algProp->setValue(transAlg->toString());
957 reductionManager->declareProperty(std::move(algProp));
958 }
959}
960} // namespace Mantid::WorkflowAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
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.
Kernel::Logger & g_log
Definition Algorithm.h:422
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
Support for a property that holds an array of values.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void setPropertyGroup(const std::string &name, const std::string &group)
Set the group for a given property.
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
The concrete, templated class for properties.
void setupSensitivity(const std::shared_ptr< Kernel::PropertyManager > &reductionManager)
void setupBackground(const std::shared_ptr< Kernel::PropertyManager > &reductionManager)
void setupTransmission(const std::shared_ptr< Kernel::PropertyManager > &reductionManager)
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54