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