Mantid
Loading...
Searching...
No Matches
SetupHFIRReduction.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//----------------------------------------------------------------------
20#include <boost/algorithm/string/predicate.hpp>
22
23// Register the algorithm into the AlgorithmFactory
24DECLARE_ALGORITHM(SetupHFIRReduction)
25
26using namespace Kernel;
27using namespace API;
28using namespace Geometry;
29using namespace DataObjects;
30
32 // Load options
33 std::string load_grp = "Load Options";
34
35 declareProperty("SampleDetectorDistance", EMPTY_DBL(),
36 "Sample to detector distance to use (overrides meta data), in mm");
37 declareProperty("SampleDetectorDistanceOffset", EMPTY_DBL(),
38 "Offset to the sample to detector distance (use only when "
39 "using the distance found in the meta data), in mm");
40 declareProperty("SolidAngleCorrection", true, "If true, the solid angle correction will be applied to the data");
41 declareProperty("DetectorTubes", false, "If true, the solid angle correction for tube detectors will be applied");
42 declareProperty("DetectorWing", false,
43 "If true, the solid angle "
44 "correction for the Wing Detector (curved detector) "
45 "will be applied");
46
47 // Optionally, we can specify the wavelength and wavelength spread and
48 // overwrite
49 // the value in the data file (used when the data file is not populated)
50 auto mustBePositive = std::make_shared<Kernel::BoundedValidator<double>>();
51 mustBePositive->setLower(0.0);
52 declareProperty("Wavelength", EMPTY_DBL(), mustBePositive,
53 "Wavelength value to use when loading the data file (Angstrom).");
54 declareProperty("WavelengthSpread", 0.1, mustBePositive,
55 "Wavelength spread to use when loading the data file (default 0.0)");
56
57 setPropertyGroup("SampleDetectorDistance", load_grp);
58 setPropertyGroup("SampleDetectorDistanceOffset", load_grp);
59 setPropertyGroup("SolidAngleCorrection", load_grp);
60 setPropertyGroup("DetectorTubes", load_grp);
61 setPropertyGroup("DetectorWing", load_grp);
62 setPropertyGroup("Wavelength", load_grp);
63 setPropertyGroup("WavelengthSpread", load_grp);
64
65 // Beam center
66 std::string center_grp = "Beam Center";
67 std::vector<std::string> centerOptions{"None", "Value", "DirectBeam", "Scattering"};
68
69 declareProperty("BeamCenterMethod", "None", std::make_shared<StringListValidator>(centerOptions),
70 "Method for determining the data beam center");
71
72 // Option 1: Set beam center by hand
73 declareProperty("BeamCenterX", EMPTY_DBL(), "Position of the beam center, in pixel");
74 declareProperty("BeamCenterY", EMPTY_DBL(), "Position of the beam center, in pixel");
75 setPropertySettings("BeamCenterX", std::make_unique<VisibleWhenProperty>("BeamCenterMethod", IS_EQUAL_TO, "Value"));
76 setPropertySettings("BeamCenterY", std::make_unique<VisibleWhenProperty>("BeamCenterMethod", IS_EQUAL_TO, "Value"));
77
78 // Option 2: Find it (expose properties from FindCenterOfMass)
79 declareProperty(std::make_unique<API::FileProperty>("BeamCenterFile", "", API::FileProperty::OptionalLoad, ".xml"),
80 "The name of the input data file to load");
81 setPropertySettings("BeamCenterFile",
82 std::make_unique<VisibleWhenProperty>("BeamCenterMethod", IS_NOT_EQUAL_TO, "None"));
83
84 // declareProperty("Tolerance", EMPTY_DBL(), "Tolerance on the center of mass
85 // position between each iteration [m]. Default: 0.00125");
86 auto positiveDouble = std::make_shared<BoundedValidator<double>>();
87 positiveDouble->setLower(0);
88 declareProperty("BeamRadius", EMPTY_DBL(),
89 "Radius of the beam area used the exclude the beam when calculating "
90 "the center of mass of the scattering pattern [pixels]. Default=3.0");
91 setPropertySettings("BeamRadius",
92 std::make_unique<VisibleWhenProperty>("BeamCenterMethod", IS_EQUAL_TO, "Scattering"));
93
94 setPropertyGroup("BeamCenterMethod", center_grp);
95 setPropertyGroup("BeamCenterX", center_grp);
96 setPropertyGroup("BeamCenterY", center_grp);
97 setPropertyGroup("BeamCenterFile", center_grp);
98 // setPropertyGroup("Tolerance", center_grp);
99 setPropertyGroup("BeamRadius", center_grp);
100
101 // Normalisation
102 std::vector<std::string> incidentBeamNormOptions;
103 incidentBeamNormOptions.emplace_back("None");
104 incidentBeamNormOptions.emplace_back("Monitor");
105 incidentBeamNormOptions.emplace_back("Timer");
106 this->declareProperty("Normalisation", "Monitor", std::make_shared<StringListValidator>(incidentBeamNormOptions),
107 "Options for data normalisation");
108
109 // Dark current
110 declareProperty(std::make_unique<API::FileProperty>("DarkCurrentFile", "", API::FileProperty::OptionalLoad, ".xml"),
111 "The name of the input data file to load as dark current.");
112
113 // Sensitivity
114 std::string eff_grp = "Sensitivity";
115 declareProperty(std::make_unique<API::FileProperty>("SensitivityFile", "", API::FileProperty::OptionalLoad, ".xml"),
116 "Flood field or sensitivity file.");
117 declareProperty("MinEfficiency", EMPTY_DBL(), positiveDouble,
118 "Minimum efficiency for a pixel to be considered (default: no minimum).");
119 declareProperty("MaxEfficiency", EMPTY_DBL(), positiveDouble,
120 "Maximum efficiency for a pixel to be considered (default: no maximum).");
121 declareProperty("UseDefaultDC", true,
122 "If true, the dark current subtracted "
123 "from the sample data will also be "
124 "subtracted from the flood field.");
126 std::make_unique<API::FileProperty>("SensitivityDarkCurrentFile", "", API::FileProperty::OptionalLoad, ".xml"),
127 "The name of the input file to load as dark current.");
128 setPropertySettings("SensitivityDarkCurrentFile",
129 std::make_unique<VisibleWhenProperty>("UseDefaultDC", IS_EQUAL_TO, "0"));
130
131 // - sensitivity beam center
132 declareProperty("SensitivityBeamCenterMethod", "None", std::make_shared<StringListValidator>(centerOptions),
133 "Method for determining the sensitivity data beam center");
134
135 // Option 1: Set beam center by hand
136 declareProperty("SensitivityBeamCenterX", EMPTY_DBL(), "Sensitivity beam center location in X [pixels]");
137 setPropertySettings("SensitivityBeamCenterX",
138 std::make_unique<VisibleWhenProperty>("SensitivityBeamCenterMethod", IS_EQUAL_TO, "Value"));
139
140 declareProperty("SensitivityBeamCenterY", EMPTY_DBL(), "Sensitivity beam center location in Y [pixels]");
141 setPropertySettings("SensitivityBeamCenterY",
142 std::make_unique<VisibleWhenProperty>("SensitivityBeamCenterMethod", IS_EQUAL_TO, "Value"));
143
144 // Option 2: Find it (expose properties from FindCenterOfMass)
146 std::make_unique<API::FileProperty>("SensitivityBeamCenterFile", "", API::FileProperty::OptionalLoad, ".xml"),
147 "The name of the input data file to load");
148 setPropertySettings("SensitivityBeamCenterFile",
149 std::make_unique<VisibleWhenProperty>("SensitivityBeamCenterMethod", IS_NOT_EQUAL_TO, "None"));
150
151 declareProperty("SensitivityBeamCenterRadius", EMPTY_DBL(),
152 "Radius of the beam area used the exclude the beam when calculating "
153 "the center of mass of the scattering pattern [pixels]. Default=3.0");
154 setPropertySettings("SensitivityBeamCenterRadius",
155 std::make_unique<VisibleWhenProperty>("BeamCenterMethod", IS_EQUAL_TO, "Scattering"));
156
157 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("OutputSensitivityWorkspace", "",
159
160 setPropertyGroup("SensitivityFile", eff_grp);
161 setPropertyGroup("MinEfficiency", eff_grp);
162 setPropertyGroup("MaxEfficiency", eff_grp);
163 setPropertyGroup("UseDefaultDC", eff_grp);
164 setPropertyGroup("SensitivityDarkCurrentFile", eff_grp);
165 setPropertyGroup("SensitivityBeamCenterMethod", eff_grp);
166 setPropertyGroup("SensitivityBeamCenterX", eff_grp);
167 setPropertyGroup("SensitivityBeamCenterY", eff_grp);
168 setPropertyGroup("SensitivityBeamCenterFile", eff_grp);
169 setPropertyGroup("SensitivityBeamCenterRadius", eff_grp);
170 setPropertyGroup("OutputSensitivityWorkspace", eff_grp);
171
172 // Transmission
173 std::string trans_grp = "Transmission";
174 std::vector<std::string> transOptions{"Value", "DirectBeam", "BeamSpreader"};
175 declareProperty("TransmissionMethod", "Value", std::make_shared<StringListValidator>(transOptions),
176 "Transmission determination method");
177
178 // - Transmission value entered by hand
179 declareProperty("TransmissionValue", EMPTY_DBL(), positiveDouble, "Transmission value.");
180 setPropertySettings("TransmissionValue",
181 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "Value"));
182 declareProperty("TransmissionError", EMPTY_DBL(), positiveDouble, "Transmission error.");
183 setPropertySettings("TransmissionError",
184 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "Value"));
185
186 // - Direct beam method transmission calculation
187 declareProperty("TransmissionBeamRadius", 3.0, "Radius of the beam area used to compute the transmission [pixels]");
188 setPropertySettings("TransmissionBeamRadius",
189 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
191 std::make_unique<API::FileProperty>("TransmissionSampleDataFile", "", API::FileProperty::OptionalLoad, ".xml"),
192 "Sample data file for transmission calculation");
193 setPropertySettings("TransmissionSampleDataFile",
194 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
196 std::make_unique<API::FileProperty>("TransmissionEmptyDataFile", "", API::FileProperty::OptionalLoad, ".xml"),
197 "Empty data file for transmission calculation");
198 setPropertySettings("TransmissionEmptyDataFile",
199 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
200
201 // - transmission beam center
202 declareProperty("TransmissionBeamCenterMethod", "None", std::make_shared<StringListValidator>(centerOptions),
203 "Method for determining the transmission data beam center");
204 setPropertySettings("TransmissionBeamCenterMethod",
205 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
206
207 // Option 1: Set beam center by hand
208 declareProperty("TransmissionBeamCenterX", EMPTY_DBL(), "Transmission beam center location in X [pixels]");
209 setPropertySettings("TransmissionBeamCenterX",
210 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
211 declareProperty("TransmissionBeamCenterY", EMPTY_DBL(), "Transmission beam center location in Y [pixels]");
212 setPropertySettings("TransmissionBeamCenterY",
213 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
214
215 // Option 2: Find it (expose properties from FindCenterOfMass)
217 std::make_unique<API::FileProperty>("TransmissionBeamCenterFile", "", API::FileProperty::OptionalLoad, ".xml"),
218 "The name of the input data file to load");
219 setPropertySettings("TransmissionBeamCenterFile",
220 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
221
222 // - Beam spreader transmission method
224 std::make_unique<API::FileProperty>("TransSampleSpreaderFilename", "", API::FileProperty::OptionalLoad, ".xml"));
225 setPropertySettings("TransSampleSpreaderFilename",
226 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
228 std::make_unique<API::FileProperty>("TransDirectSpreaderFilename", "", API::FileProperty::OptionalLoad, ".xml"));
229 setPropertySettings("TransDirectSpreaderFilename",
230 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
231 declareProperty(std::make_unique<API::FileProperty>("TransSampleScatteringFilename", "",
233 setPropertySettings("TransSampleScatteringFilename",
234 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
235 declareProperty(std::make_unique<API::FileProperty>("TransDirectScatteringFilename", "",
237 setPropertySettings("TransDirectScatteringFilename",
238 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
239 declareProperty("SpreaderTransmissionValue", 1.0, "Beam spreader transmission value");
240 setPropertySettings("SpreaderTransmissionValue",
241 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
242 declareProperty("SpreaderTransmissionError", 0.0, "Beam spreader transmission error");
243 setPropertySettings("SpreaderTransmissionError",
244 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
245
247 std::make_unique<API::FileProperty>("TransmissionDarkCurrentFile", "", API::FileProperty::OptionalLoad, ".xml"),
248 "The name of the input data file to load as transmission dark current.");
249 setPropertySettings("TransmissionDarkCurrentFile",
250 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_NOT_EQUAL_TO, "Value"));
251
252 declareProperty("TransmissionUseSampleDC", true,
253 "If true, the sample dark current will be used IF a dark current file is"
254 "not set.");
255 setPropertySettings("TransmissionUseSampleDC",
256 std::make_unique<VisibleWhenProperty>("TransmissionMethod", IS_NOT_EQUAL_TO, "Value"));
257
258 declareProperty("ThetaDependentTransmission", true,
259 "If true, a theta-dependent transmission correction will be applied.");
260
261 setPropertyGroup("TransmissionMethod", trans_grp);
262 setPropertyGroup("TransmissionValue", trans_grp);
263 setPropertyGroup("TransmissionError", trans_grp);
264 setPropertyGroup("TransmissionBeamRadius", trans_grp);
265 setPropertyGroup("TransmissionSampleDataFile", trans_grp);
266 setPropertyGroup("TransmissionEmptyDataFile", trans_grp);
267 setPropertyGroup("TransmissionBeamCenterMethod", trans_grp);
268 setPropertyGroup("TransmissionBeamCenterX", trans_grp);
269 setPropertyGroup("TransmissionBeamCenterY", trans_grp);
270 setPropertyGroup("TransmissionBeamCenterFile", trans_grp);
271
272 setPropertyGroup("TransSampleSpreaderFilename", trans_grp);
273 setPropertyGroup("TransDirectSpreaderFilename", trans_grp);
274 setPropertyGroup("TransSampleScatteringFilename", trans_grp);
275 setPropertyGroup("TransDirectScatteringFilename", trans_grp);
276 setPropertyGroup("SpreaderTransmissionValue", trans_grp);
277 setPropertyGroup("SpreaderTransmissionError", trans_grp);
278 setPropertyGroup("TransmissionDarkCurrentFile", trans_grp);
279 setPropertyGroup("TransmissionUseSampleDC", trans_grp);
280 setPropertyGroup("ThetaDependentTransmission", trans_grp);
281
282 // Background options
283 std::string bck_grp = "Background";
284 declareProperty("BackgroundFiles", "", "Background data files");
285 declareProperty("BckTransmissionMethod", "Value", std::make_shared<StringListValidator>(transOptions),
286 "Transmission determination method");
287
288 // - Transmission value entered by hand
289 declareProperty("BckTransmissionValue", EMPTY_DBL(), positiveDouble, "Transmission value.");
290 setPropertySettings("BckTransmissionValue",
291 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "Value"));
292
293 declareProperty("BckTransmissionError", EMPTY_DBL(), positiveDouble, "Transmission error.");
294 setPropertySettings("BckTransmissionError",
295 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "Value"));
296
297 // - Direct beam method transmission calculation
298 declareProperty("BckTransmissionBeamRadius", 3.0,
299 "Radius of the beam area used to compute the transmission [pixels]");
300 setPropertySettings("BckTransmissionBeamRadius",
301 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
303 std::make_unique<API::FileProperty>("BckTransmissionSampleDataFile", "", API::FileProperty::OptionalLoad, ".xml"),
304 "Sample data file for transmission calculation");
305 setPropertySettings("BckTransmissionSampleDataFile",
306 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
308 std::make_unique<API::FileProperty>("BckTransmissionEmptyDataFile", "", API::FileProperty::OptionalLoad, ".xml"),
309 "Empty data file for transmission calculation");
310 setPropertySettings("BckTransmissionEmptyDataFile",
311 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
312
313 // - transmission beam center
314 declareProperty("BckTransmissionBeamCenterMethod", "None", std::make_shared<StringListValidator>(centerOptions),
315 "Method for determining the transmission data beam center");
316 setPropertySettings("BckTransmissionBeamCenterMethod",
317 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
318 // Option 1: Set beam center by hand
319 declareProperty("BckTransmissionBeamCenterX", EMPTY_DBL(), "Transmission beam center location in X [pixels]");
320 setPropertySettings("BckTransmissionBeamCenterX",
321 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
322 declareProperty("BckTransmissionBeamCenterY", EMPTY_DBL(), "Transmission beam center location in Y [pixels]");
323 // Option 2: Find it (expose properties from FindCenterOfMass)
324 setPropertySettings("BckTransmissionBeamCenterY",
325 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
327 std::make_unique<API::FileProperty>("BckTransmissionBeamCenterFile", "", API::FileProperty::OptionalLoad, ".xml"),
328 "The name of the input data file to load");
329 setPropertySettings("BckTransmissionBeamCenterFile",
330 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "DirectBeam"));
331
332 // - Beam spreader transmission method
333 declareProperty(std::make_unique<API::FileProperty>("BckTransSampleSpreaderFilename", "",
335 setPropertySettings("BckTransSampleSpreaderFilename",
336 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
337 declareProperty(std::make_unique<API::FileProperty>("BckTransDirectSpreaderFilename", "",
339 setPropertySettings("BckTransDirectSpreaderFilename",
340 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
341 declareProperty(std::make_unique<API::FileProperty>("BckTransSampleScatteringFilename", "",
343 setPropertySettings("BckTransSampleScatteringFilename",
344 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
345 declareProperty(std::make_unique<API::FileProperty>("BckTransDirectScatteringFilename", "",
347 setPropertySettings("BckTransDirectScatteringFilename",
348 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
349 declareProperty("BckSpreaderTransmissionValue", 1.0, "Beam spreader transmission value");
350 setPropertySettings("BckSpreaderTransmissionValue",
351 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
352 declareProperty("BckSpreaderTransmissionError", 0.0, "Beam spreader transmission error");
353 setPropertySettings("BckSpreaderTransmissionError",
354 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
355
356 declareProperty(std::make_unique<API::FileProperty>("BckTransmissionDarkCurrentFile", "",
358 "The name of the input data file to load as background "
359 "transmission dark current.");
360 setPropertySettings("BckTransmissionDarkCurrentFile",
361 std::make_unique<VisibleWhenProperty>("BckTransmissionMethod", IS_EQUAL_TO, "BeamSpreader"));
362
363 declareProperty("BckThetaDependentTransmission", true,
364 "If true, a theta-dependent transmission correction will be applied.");
365
366 setPropertyGroup("BackgroundFiles", bck_grp);
367 setPropertyGroup("BckTransmissionMethod", bck_grp);
368 setPropertyGroup("BckTransmissionValue", bck_grp);
369 setPropertyGroup("BckTransmissionError", bck_grp);
370 setPropertyGroup("BckTransmissionBeamRadius", bck_grp);
371 setPropertyGroup("BckTransmissionSampleDataFile", bck_grp);
372 setPropertyGroup("BckTransmissionEmptyDataFile", bck_grp);
373 setPropertyGroup("BckTransmissionBeamCenterMethod", bck_grp);
374 setPropertyGroup("BckTransmissionBeamCenterX", bck_grp);
375 setPropertyGroup("BckTransmissionBeamCenterY", bck_grp);
376 setPropertyGroup("BckTransmissionBeamCenterFile", bck_grp);
377 setPropertyGroup("BckTransSampleSpreaderFilename", bck_grp);
378 setPropertyGroup("BckTransDirectSpreaderFilename", bck_grp);
379 setPropertyGroup("BckTransSampleScatteringFilename", bck_grp);
380 setPropertyGroup("BckTransDirectScatteringFilename", bck_grp);
381 setPropertyGroup("BckSpreaderTransmissionValue", bck_grp);
382 setPropertyGroup("BckSpreaderTransmissionError", bck_grp);
383 setPropertyGroup("BckTransmissionDarkCurrentFile", bck_grp);
384 setPropertyGroup("BckThetaDependentTransmission", bck_grp);
385
386 // Geometry correction
387 declareProperty("SampleThickness", EMPTY_DBL(), "Sample thickness [cm]");
388
389 // Masking
390 std::string mask_grp = "Mask";
391 declareProperty(std::make_unique<ArrayProperty<int>>("MaskedDetectorList"), "List of detector IDs to be masked");
392 declareProperty(std::make_unique<ArrayProperty<int>>("MaskedEdges"),
393 "Number of pixels to mask on the edges: X-low, X-high, Y-low, Y-high");
394 declareProperty("MaskedComponent", "", "Component Name to mask the edges according to the IDF file.");
395 std::vector<std::string> maskOptions;
396 maskOptions.emplace_back("None");
397 maskOptions.emplace_back("Front");
398 maskOptions.emplace_back("Back");
399 declareProperty("MaskedSide", "None", std::make_shared<StringListValidator>(maskOptions),
400 "Mask one side of the detector");
401 declareProperty("MaskedFullComponent", "", "Component Name to mask the edges according to the IDF file.");
402
403 setPropertyGroup("MaskedDetectorList", mask_grp);
404 setPropertyGroup("MaskedEdges", mask_grp);
405 setPropertyGroup("MaskedComponent", mask_grp);
406 setPropertyGroup("MaskedSide", mask_grp);
407 setPropertyGroup("MaskedFullComponent", mask_grp);
408
409 // Absolute scale
410 std::string abs_scale_grp = "Absolute Scale";
411 std::vector<std::string> scaleOptions;
412 scaleOptions.emplace_back("None");
413 scaleOptions.emplace_back("Value");
414 scaleOptions.emplace_back("ReferenceData");
415 declareProperty("AbsoluteScaleMethod", "None", std::make_shared<StringListValidator>(scaleOptions),
416 "Absolute scale correction method");
417 declareProperty("AbsoluteScalingFactor", 1.0, "Absolute scaling factor");
418 setPropertySettings("AbsoluteScalingFactor",
419 std::make_unique<VisibleWhenProperty>("AbsoluteScaleMethod", IS_EQUAL_TO, "Value"));
420
421 declareProperty(std::make_unique<API::FileProperty>("AbsoluteScalingReferenceFilename", "",
423 setPropertySettings("AbsoluteScalingReferenceFilename",
424 std::make_unique<VisibleWhenProperty>("AbsoluteScaleMethod", IS_EQUAL_TO, "ReferenceData"));
425 declareProperty("AbsoluteScalingBeamDiameter", 0.0,
426 "Beamstop diameter for computing the absolute scale factor [mm]. "
427 "Read from file if not supplied.");
428 setPropertySettings("AbsoluteScalingBeamDiameter",
429 std::make_unique<VisibleWhenProperty>("AbsoluteScaleMethod", IS_EQUAL_TO, "ReferenceData"));
430 declareProperty("AbsoluteScalingAttenuatorTrans", 1.0,
431 "Attenuator transmission value for computing the absolute scale factor");
432 setPropertySettings("AbsoluteScalingAttenuatorTrans",
433 std::make_unique<VisibleWhenProperty>("AbsoluteScaleMethod", IS_EQUAL_TO, "ReferenceData"));
434 declareProperty("AbsoluteScalingApplySensitivity", false,
435 "Apply sensitivity correction to the reference data "
436 "when computing the absolute scale factor");
437 setPropertySettings("AbsoluteScalingApplySensitivity",
438 std::make_unique<VisibleWhenProperty>("AbsoluteScaleMethod", IS_EQUAL_TO, "ReferenceData"));
439
440 setPropertyGroup("AbsoluteScaleMethod", abs_scale_grp);
441 setPropertyGroup("AbsoluteScalingFactor", abs_scale_grp);
442 setPropertyGroup("AbsoluteScalingReferenceFilename", abs_scale_grp);
443 setPropertyGroup("AbsoluteScalingBeamDiameter", abs_scale_grp);
444 setPropertyGroup("AbsoluteScalingAttenuatorTrans", abs_scale_grp);
445 setPropertyGroup("AbsoluteScalingApplySensitivity", abs_scale_grp);
446
447 // I(Q) calculation
448 std::string iq1d_grp = "I(q) Calculation";
449 declareProperty("DoAzimuthalAverage", true);
450 declareProperty(std::make_unique<ArrayProperty<double>>("IQBinning", std::make_shared<RebinParamsValidator>(true)));
451
452 auto positiveInt = std::make_shared<BoundedValidator<int>>();
453 positiveInt->setLower(0);
454 declareProperty("IQNumberOfBins", 100, positiveInt, "Number of I(q) bins when binning is not specified.");
455 declareProperty("IQLogBinning", false, "I(q) log binning when binning is not specified.");
456 declareProperty("IQAlignLogWithDecades", false,
457 "If true and log binning was selected, the bins will be aligned to log "
458 "decades "
459 "and the number of bins will be used as the number of bins per decade.");
460
461 declareProperty("NumberOfSubpixels", 1, positiveInt,
462 "Number of sub-pixels used for each detector pixel in each direction."
463 "The total number of sub-pixels will be NPixelDivision*NPixelDivision.");
464 declareProperty("ErrorWeighting", false, "Choose whether each pixel contribution will be weighted by 1/error^2.");
465
466 // Wedge options
467 declareProperty("NumberOfWedges", 2, positiveInt, "Number of wedges to calculate.");
468 declareProperty("WedgeAngle", 30.0, "Opening angle of each wedge, in degrees.");
469 declareProperty("WedgeOffset", 0.0, "Angular offset for the wedges, in degrees.");
470
471 declareProperty("Do2DReduction", true);
472 declareProperty("IQ2DNumberOfBins", 100, positiveInt, "Number of I(qx,qy) bins.");
473 declareProperty("IQxQyLogBinning", false, "I(qx,qy) log binning when binning is not specified.");
474
475 setPropertyGroup("DoAzimuthalAverage", iq1d_grp);
476 setPropertyGroup("IQBinning", iq1d_grp);
477 setPropertyGroup("IQNumberOfBins", iq1d_grp);
478 setPropertyGroup("IQLogBinning", iq1d_grp);
479 setPropertyGroup("NumberOfSubpixels", iq1d_grp);
480 setPropertyGroup("ErrorWeighting", iq1d_grp);
481
482 declareProperty("ProcessInfo", "", "Additional process information");
483 declareProperty("OutputDirectory", "", "Directory to put the output files in");
484 declareProperty("OutputMessage", "", Direction::Output);
485 declareProperty("ReductionProperties", "__sans_reduction_properties", Direction::Input);
486}
487
489 // Reduction property manager
490 const std::string reductionManagerName = getProperty("ReductionProperties");
491 if (reductionManagerName.empty()) {
492 g_log.error() << "ERROR: Reduction Property Manager name is empty\n";
493 return;
494 }
495 std::shared_ptr<PropertyManager> reductionManager = std::make_shared<PropertyManager>();
496 PropertyManagerDataService::Instance().addOrReplace(reductionManagerName, reductionManager);
497
498 // Store name of the instrument
499 reductionManager->declareProperty(std::make_unique<PropertyWithValue<std::string>>("InstrumentName", "HFIRSANS"));
500
501 // Store additional (and optional) process information
502 const std::string processInfo = getProperty("ProcessInfo");
503 reductionManager->declareProperty(std::make_unique<PropertyWithValue<std::string>>("ProcessInfo", processInfo));
504
505 // Store the output directory
506 const std::string outputDirectory = getProperty("OutputDirectory");
507 reductionManager->declareProperty(
508 std::make_unique<PropertyWithValue<std::string>>("OutputDirectory", outputDirectory));
509
510 // Load algorithm
511 const double sdd = getProperty("SampleDetectorDistance");
512 const double sddOffset = getProperty("SampleDetectorDistanceOffset");
513 const double wavelength = getProperty("Wavelength");
514 const double wavelengthSpread = getProperty("WavelengthSpread");
515
516 auto loadAlg = createChildAlgorithm("HFIRLoad");
517 if (!isEmpty(sdd))
518 loadAlg->setProperty("SampleDetectorDistance", sdd);
519 if (!isEmpty(sddOffset))
520 loadAlg->setProperty("SampleDetectorDistanceOffset", sddOffset);
521 if (!isEmpty(wavelength)) {
522 loadAlg->setProperty("Wavelength", wavelength);
523 loadAlg->setProperty("WavelengthSpread", wavelengthSpread);
524 }
525 auto loadAlgProp = std::make_unique<AlgorithmProperty>("LoadAlgorithm");
526 loadAlgProp->setValue(loadAlg->toString());
527 reductionManager->declareProperty(std::move(loadAlgProp));
528
529 // Beam center
530 const double beamCenterX = getProperty("BeamCenterX");
531 const double beamCenterY = getProperty("BeamCenterY");
532 const std::string centerMethod = getPropertyValue("BeamCenterMethod");
533
534 // Beam center option for transmission data
535 if (boost::iequals(centerMethod, "Value")) {
536 if (!isEmpty(beamCenterX) && !isEmpty(beamCenterY)) {
537 reductionManager->declareProperty(std::make_unique<PropertyWithValue<double>>("LatestBeamCenterX", beamCenterX));
538 reductionManager->declareProperty(std::make_unique<PropertyWithValue<double>>("LatestBeamCenterY", beamCenterY));
539 }
540 } else if (!boost::iequals(centerMethod, "None")) {
541 bool useDirectBeamMethod = true;
542 if (!boost::iequals(centerMethod, "DirectBeam"))
543 useDirectBeamMethod = false;
544 const std::string beamCenterFile = getProperty("BeamCenterFile");
545 if (!beamCenterFile.empty()) {
546 const double beamRadius = getProperty("BeamRadius");
547
548 auto ctrAlg = createChildAlgorithm("SANSBeamFinder");
549 ctrAlg->setProperty("Filename", beamCenterFile);
550 ctrAlg->setProperty("UseDirectBeamMethod", useDirectBeamMethod);
551 if (!isEmpty(beamRadius))
552 ctrAlg->setProperty("BeamRadius", beamRadius);
553 ctrAlg->setPropertyValue("ReductionProperties", reductionManagerName);
554
555 auto beamFinderAlgProp = std::make_unique<AlgorithmProperty>("SANSBeamFinderAlgorithm");
556 beamFinderAlgProp->setValue(ctrAlg->toString());
557 reductionManager->declareProperty(std::move(beamFinderAlgProp));
558 } else {
559 g_log.error() << "ERROR: Beam center determination was required"
560 " but no file was provided\n";
561 }
562 }
563
564 // Store dark current algorithm
565 const std::string darkCurrentFile = getPropertyValue("DarkCurrentFile");
566 if (!darkCurrentFile.empty()) {
567 auto darkAlg = createChildAlgorithm("HFIRDarkCurrentSubtraction");
568 darkAlg->setProperty("Filename", darkCurrentFile);
569 darkAlg->setProperty("OutputDarkCurrentWorkspace", "");
570 darkAlg->setPropertyValue("ReductionProperties", reductionManagerName);
571 auto dcAlgProp = std::make_unique<AlgorithmProperty>("DarkCurrentAlgorithm");
572 dcAlgProp->setValue(darkAlg->toString());
573 reductionManager->declareProperty(std::move(dcAlgProp));
574 }
575
576 // Store default dark current algorithm
577 auto darkDefaultAlg = createChildAlgorithm("HFIRDarkCurrentSubtraction");
578 darkDefaultAlg->setProperty("OutputDarkCurrentWorkspace", "");
579 darkDefaultAlg->setPropertyValue("ReductionProperties", reductionManagerName);
580 auto ddcAlgProp = std::make_unique<AlgorithmProperty>("DefaultDarkCurrentAlgorithm");
581 ddcAlgProp->setValue(darkDefaultAlg->toString());
582 reductionManager->declareProperty(std::move(ddcAlgProp));
583
584 // Solid angle correction
585 const bool solidAngleCorrection = getProperty("SolidAngleCorrection");
586 const bool isTubeDetector = getProperty("DetectorTubes");
587 const bool isCurvedDetector = getProperty("DetectorWing");
588 if (solidAngleCorrection) {
589 auto solidAlg = createChildAlgorithm("SANSSolidAngleCorrection");
590 solidAlg->setProperty("DetectorTubes", isTubeDetector);
591 solidAlg->setProperty("DetectorWing", isCurvedDetector);
592 auto ssaAlgProp = std::make_unique<AlgorithmProperty>("SANSSolidAngleCorrection");
593 ssaAlgProp->setValue(solidAlg->toString());
594 reductionManager->declareProperty(std::move(ssaAlgProp));
595 }
596
597 // Normalization
598 const std::string normalization = getProperty("Normalisation");
599 if (!boost::contains(normalization, "None")) {
600 auto normAlg = createChildAlgorithm("HFIRSANSNormalise");
601 normAlg->setProperty("NormalisationType", normalization);
602 auto normAlgProp = std::make_unique<AlgorithmProperty>("NormaliseAlgorithm");
603 normAlgProp->setValue(normAlg->toString());
604 reductionManager->declareProperty(std::move(normAlgProp));
605 reductionManager->declareProperty(
606 std::make_unique<PropertyWithValue<std::string>>("TransmissionNormalisation", normalization));
607 } else
608 reductionManager->declareProperty(
609 std::make_unique<PropertyWithValue<std::string>>("TransmissionNormalisation", "Timer"));
610
611 // Sensitivity correction, transmission and background
612 setupSensitivity(reductionManager);
613 setupTransmission(reductionManager);
614 setupBackground(reductionManager);
615
616 // Geometry correction
617 const double thickness = getProperty("SampleThickness");
618 if (!isEmpty(thickness)) {
619 auto thickAlg = createChildAlgorithm("NormaliseByThickness");
620 thickAlg->setProperty("SampleThickness", thickness);
621
622 auto thickAlgProp = std::make_unique<AlgorithmProperty>("GeometryAlgorithm");
623 thickAlgProp->setValue(thickAlg->toString());
624 reductionManager->declareProperty(std::move(thickAlgProp));
625 }
626
627 // Mask
628 const std::string maskDetList = getPropertyValue("MaskedDetectorList");
629 const std::string maskEdges = getPropertyValue("MaskedEdges");
630 const std::string maskSide = getProperty("MaskedSide");
631 const std::string maskComponent = getPropertyValue("MaskedComponent");
632 const std::string maskFullComponent = getPropertyValue("MaskedFullComponent");
633
634 auto maskAlg = createChildAlgorithm("SANSMask");
635 // The following is broken, try PropertyValue
636 maskAlg->setPropertyValue("Facility", "HFIR");
637 maskAlg->setPropertyValue("MaskedDetectorList", maskDetList);
638 maskAlg->setPropertyValue("MaskedEdges", maskEdges);
639 maskAlg->setProperty("MaskedSide", maskSide);
640 maskAlg->setProperty("MaskedComponent", maskComponent);
641 maskAlg->setProperty("MaskedFullComponent", maskFullComponent);
642
643 auto maskAlgProp = std::make_unique<AlgorithmProperty>("MaskAlgorithm");
644 maskAlgProp->setValue(maskAlg->toString());
645 reductionManager->declareProperty(std::move(maskAlgProp));
646
647 // Absolute scaling
648 const std::string absScaleMethod = getProperty("AbsoluteScaleMethod");
649 if (boost::iequals(absScaleMethod, "Value")) {
650 const double absScaleFactor = getProperty("AbsoluteScalingFactor");
651
652 auto absAlg = createChildAlgorithm("SANSAbsoluteScale");
653 absAlg->setProperty("Method", absScaleMethod);
654 absAlg->setProperty("ScalingFactor", absScaleFactor);
655 absAlg->setPropertyValue("ReductionProperties", reductionManagerName);
656 auto absScaleAlgProp = std::make_unique<AlgorithmProperty>("AbsoluteScaleAlgorithm");
657 absScaleAlgProp->setValue(absAlg->toString());
658 reductionManager->declareProperty(std::move(absScaleAlgProp));
659 } else if (boost::iequals(absScaleMethod, "ReferenceData")) {
660 const std::string absRefFile = getPropertyValue("AbsoluteScalingReferenceFilename");
661 const double beamDiam = getProperty("AbsoluteScalingBeamDiameter");
662 const double attTrans = getProperty("AbsoluteScalingAttenuatorTrans");
663 const bool applySensitivity = getProperty("AbsoluteScalingApplySensitivity");
664
665 auto absAlg = createChildAlgorithm("SANSAbsoluteScale");
666 absAlg->setProperty("Method", absScaleMethod);
667 absAlg->setProperty("ReferenceDataFilename", absRefFile);
668 absAlg->setProperty("BeamstopDiameter", beamDiam);
669 absAlg->setProperty("AttenuatorTransmission", attTrans);
670 absAlg->setProperty("ApplySensitivity", applySensitivity);
671 absAlg->setPropertyValue("ReductionProperties", reductionManagerName);
672 auto refScaleAlgProp = std::make_unique<AlgorithmProperty>("AbsoluteScaleAlgorithm");
673 refScaleAlgProp->setValue(absAlg->toString());
674 reductionManager->declareProperty(std::move(refScaleAlgProp));
675 }
676
677 // Azimuthal averaging
678 const bool doAveraging = getProperty("DoAzimuthalAverage");
679 if (doAveraging) {
680 const std::string binning = getPropertyValue("IQBinning");
681 const std::string n_bins = getPropertyValue("IQNumberOfBins");
682 const bool log_binning = getProperty("IQLogBinning");
683 const std::string n_subpix = getPropertyValue("NumberOfSubpixels");
684 const bool err_weighting = getProperty("ErrorWeighting");
685
686 const std::string n_wedges = getPropertyValue("NumberOfWedges");
687 const double wedge_angle = getProperty("WedgeAngle");
688 const double wedge_offset = getProperty("WedgeOffset");
689 const bool align = getProperty("IQAlignLogWithDecades");
690
691 auto iqAlg = createChildAlgorithm("SANSAzimuthalAverage1D");
692 iqAlg->setPropertyValue("Binning", binning);
693 iqAlg->setPropertyValue("NumberOfBins", n_bins);
694 iqAlg->setProperty("LogBinning", log_binning);
695 iqAlg->setPropertyValue("NumberOfSubpixels", n_subpix);
696 iqAlg->setProperty("ErrorWeighting", err_weighting);
697 iqAlg->setProperty("ComputeResolution", true);
698 iqAlg->setProperty("NumberOfWedges", n_wedges);
699 iqAlg->setProperty("WedgeAngle", wedge_angle);
700 iqAlg->setProperty("WedgeOffset", wedge_offset);
701 iqAlg->setProperty("AlignWithDecades", align);
702 iqAlg->setPropertyValue("ReductionProperties", reductionManagerName);
703
704 auto iqAlgProp = std::make_unique<AlgorithmProperty>("IQAlgorithm");
705 iqAlgProp->setValue(iqAlg->toString());
706 reductionManager->declareProperty(std::move(iqAlgProp));
707 }
708
709 // 2D reduction
710 const bool do2DReduction = getProperty("Do2DReduction");
711 if (do2DReduction) {
712 const std::string n_bins = getPropertyValue("IQ2DNumberOfBins");
713 const bool log_binning = getProperty("IQxQyLogBinning");
714 auto iqAlg = createChildAlgorithm("EQSANSQ2D");
715 iqAlg->setPropertyValue("NumberOfBins", n_bins);
716 iqAlg->setProperty("IQxQyLogBinning", log_binning);
717 auto xyAlgProp = std::make_unique<AlgorithmProperty>("IQXYAlgorithm");
718 xyAlgProp->setValue(iqAlg->toString());
719 reductionManager->declareProperty(std::move(xyAlgProp));
720 }
721
722 setPropertyValue("OutputMessage", "HFIR reduction options set");
723
724 // Save a string representation of this algorithm
725 auto setupAlgProp = std::make_unique<AlgorithmProperty>("SetupAlgorithm");
726 setupAlgProp->setValue(toString());
727 reductionManager->declareProperty(std::move(setupAlgProp));
728}
729
730void SetupHFIRReduction::setupSensitivity(const std::shared_ptr<PropertyManager> &reductionManager) {
731 const std::string reductionManagerName = getProperty("ReductionProperties");
732
733 const std::string sensitivityFile = getPropertyValue("SensitivityFile");
734 if (!sensitivityFile.empty()) {
735 const bool useSampleDC = getProperty("UseDefaultDC");
736 const std::string sensitivityDarkCurrentFile = getPropertyValue("SensitivityDarkCurrentFile");
737 const std::string outputSensitivityWS = getPropertyValue("OutputSensitivityWorkspace");
738 const double minEff = getProperty("MinEfficiency");
739 const double maxEff = getProperty("MaxEfficiency");
740 const double sensitivityBeamCenterX = getProperty("SensitivityBeamCenterX");
741 const double sensitivityBeamCenterY = getProperty("SensitivityBeamCenterY");
742 const std::string maskFullComponent = getPropertyValue("MaskedFullComponent");
743 const std::string maskComponent = getPropertyValue("MaskedComponent");
744
745 // nx_low=0, nx_high=0, ny_low=0, ny_high=0
746 std::vector<int> maskEdges = getProperty("MaskedEdges");
747 // it only make sense masking edges for sensitivity if there are a lot of
748 // pixels masked
749 // Let'a assume more than 10:
750 std::stringstream maskEdgesStringStream;
751 for (size_t i = 0; i < maskEdges.size(); i++) {
752 if (i != 0)
753 maskEdgesStringStream << ",";
754 if (maskEdges[i] <= 10)
755 maskEdgesStringStream << 0;
756 else
757 maskEdgesStringStream << maskEdges[i];
758 }
759
760 auto effAlg = createChildAlgorithm("SANSSensitivityCorrection");
761 effAlg->setProperty("Filename", sensitivityFile);
762 effAlg->setProperty("UseSampleDC", useSampleDC);
763 effAlg->setProperty("DarkCurrentFile", sensitivityDarkCurrentFile);
764 effAlg->setProperty("MinEfficiency", minEff);
765 effAlg->setProperty("MaxEfficiency", maxEff);
766 effAlg->setProperty("MaskedFullComponent", maskFullComponent);
767 effAlg->setProperty("MaskedComponent", maskComponent);
768 effAlg->setPropertyValue("MaskedEdges", maskEdgesStringStream.str());
769
770 // Beam center option for sensitivity data
771 const std::string centerMethod = getPropertyValue("SensitivityBeamCenterMethod");
772 if (boost::iequals(centerMethod, "Value")) {
773 if (!isEmpty(sensitivityBeamCenterX) && !isEmpty(sensitivityBeamCenterY)) {
774 effAlg->setProperty("BeamCenterX", sensitivityBeamCenterX);
775 effAlg->setProperty("BeamCenterY", sensitivityBeamCenterY);
776 }
777 } else if (boost::iequals(centerMethod, "DirectBeam") || boost::iequals(centerMethod, "Scattering")) {
778 const std::string beamCenterFile = getProperty("SensitivityBeamCenterFile");
779 const double sensitivityBeamRadius = getProperty("SensitivityBeamCenterRadius");
780 bool useDirectBeam = boost::iequals(centerMethod, "DirectBeam");
781 if (!beamCenterFile.empty()) {
782 auto ctrAlg = createChildAlgorithm("SANSBeamFinder");
783 ctrAlg->setProperty("Filename", beamCenterFile);
784 ctrAlg->setProperty("UseDirectBeamMethod", useDirectBeam);
785 ctrAlg->setProperty("PersistentCorrection", false);
786 if (useDirectBeam && !isEmpty(sensitivityBeamRadius))
787 ctrAlg->setProperty("BeamRadius", sensitivityBeamRadius);
788 ctrAlg->setPropertyValue("ReductionProperties", reductionManagerName);
789
790 auto beamCentreAlgProp = std::make_unique<AlgorithmProperty>("SensitivityBeamCenterAlgorithm");
791 beamCentreAlgProp->setValue(ctrAlg->toString());
792 reductionManager->declareProperty(std::move(beamCentreAlgProp));
793 } else {
794 g_log.error() << "ERROR: Sensitivity beam center determination was required"
795 " but no file was provided\n";
796 }
797 }
798
799 effAlg->setProperty("OutputSensitivityWorkspace", outputSensitivityWS);
800 effAlg->setPropertyValue("ReductionProperties", reductionManagerName);
801
802 auto effAlgProp = std::make_unique<AlgorithmProperty>("SensitivityAlgorithm");
803 effAlgProp->setValue(effAlg->toString());
804 reductionManager->declareProperty(std::move(effAlgProp));
805 }
806}
807
808void SetupHFIRReduction::setupBackground(const std::shared_ptr<PropertyManager> &reductionManager) {
809 const std::string reductionManagerName = getProperty("ReductionProperties");
810 // Background
811 const std::string backgroundFile = getPropertyValue("BackgroundFiles");
812 if (!backgroundFile.empty())
813 reductionManager->declareProperty(
814 std::make_unique<PropertyWithValue<std::string>>("BackgroundFiles", backgroundFile));
815 else
816 return;
817
818 const std::string darkCurrent = getPropertyValue("BckTransmissionDarkCurrentFile");
819 const bool bckThetaDependentTrans = getProperty("BckThetaDependentTransmission");
820 const std::string bckTransMethod = getProperty("BckTransmissionMethod");
821 if (boost::iequals(bckTransMethod, "Value")) {
822 const double transValue = getProperty("BckTransmissionValue");
823 const double transError = getProperty("BckTransmissionError");
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", bckThetaDependentTrans);
829
830 auto backTransAlgProp = std::make_unique<AlgorithmProperty>("BckTransmissionAlgorithm");
831 backTransAlgProp->setValue(transAlg->toString());
832 reductionManager->declareProperty(std::move(backTransAlgProp));
833 } else {
834 g_log.information("SetupHFIRReduction [BckTransmissionAlgorithm]: "
835 "expected transmission/error values and got empty values");
836 }
837 } else if (boost::iequals(bckTransMethod, "DirectBeam")) {
838 const std::string sampleFilename = getPropertyValue("BckTransmissionSampleDataFile");
839 const std::string emptyFilename = getPropertyValue("BckTransmissionEmptyDataFile");
840 const double beamRadius = getProperty("BckTransmissionBeamRadius");
841 const double beamX = getProperty("BckTransmissionBeamCenterX");
842 const double beamY = getProperty("BckTransmissionBeamCenterY");
843 const bool thetaDependentTrans = getProperty("BckThetaDependentTransmission");
844
845 auto transAlg = createChildAlgorithm("SANSDirectBeamTransmission");
846 transAlg->setProperty("SampleDataFilename", sampleFilename);
847 transAlg->setProperty("EmptyDataFilename", emptyFilename);
848 transAlg->setProperty("BeamRadius", beamRadius);
849
850 // Beam center option for transmission data
851 const std::string centerMethod = getPropertyValue("BckTransmissionBeamCenterMethod");
852 if (boost::iequals(centerMethod, "Value") && !isEmpty(beamX) && !isEmpty(beamY)) {
853 transAlg->setProperty("BeamCenterX", beamX);
854 transAlg->setProperty("BeamCenterY", beamY);
855 } else if (boost::iequals(centerMethod, "DirectBeam")) {
856 const std::string beamCenterFile = getProperty("BckTransmissionBeamCenterFile");
857 if (!beamCenterFile.empty()) {
858 auto ctrAlg = createChildAlgorithm("SANSBeamFinder");
859 ctrAlg->setProperty("Filename", beamCenterFile);
860 ctrAlg->setProperty("UseDirectBeamMethod", true);
861 ctrAlg->setProperty("PersistentCorrection", false);
862 ctrAlg->setPropertyValue("ReductionProperties", reductionManagerName);
863
864 auto backBeamCentreAlgProp = std::make_unique<AlgorithmProperty>("BckTransmissionBeamCenterAlgorithm");
865 backBeamCentreAlgProp->setValue(ctrAlg->toString());
866 reductionManager->declareProperty(std::move(backBeamCentreAlgProp));
867 } else {
868 g_log.error() << "ERROR: Beam center determination was required"
869 " but no file was provided\n";
870 }
871 }
872 transAlg->setProperty("DarkCurrentFilename", darkCurrent);
873 transAlg->setProperty("ThetaDependent", thetaDependentTrans);
874 auto btAlgProp = std::make_unique<AlgorithmProperty>("BckTransmissionAlgorithm");
875 btAlgProp->setValue(transAlg->toString());
876 reductionManager->declareProperty(std::move(btAlgProp));
877 }
878 // Beam spreader method for transmission determination
879 else if (boost::iequals(bckTransMethod, "BeamSpreader")) {
880 const std::string sampleSpread = getPropertyValue("BckTransSampleSpreaderFilename");
881 const std::string directSpread = getPropertyValue("BckTransDirectSpreaderFilename");
882 const std::string sampleScatt = getPropertyValue("BckTransSampleScatteringFilename");
883 const std::string directScatt = getPropertyValue("BckTransDirectScatteringFilename");
884 const double spreaderTrValue = getProperty("BckSpreaderTransmissionValue");
885 const double spreaderTrError = getProperty("BckSpreaderTransmissionError");
886 const bool thetaDependentTrans = getProperty("BckThetaDependentTransmission");
887
888 auto transAlg = createChildAlgorithm("SANSBeamSpreaderTransmission");
889 transAlg->setProperty("SampleSpreaderFilename", sampleSpread);
890 transAlg->setProperty("DirectSpreaderFilename", directSpread);
891 transAlg->setProperty("SampleScatteringFilename", sampleScatt);
892 transAlg->setProperty("DirectScatteringFilename", directScatt);
893 transAlg->setProperty("SpreaderTransmissionValue", spreaderTrValue);
894 transAlg->setProperty("SpreaderTransmissionError", spreaderTrError);
895 transAlg->setProperty("DarkCurrentFilename", darkCurrent);
896 transAlg->setProperty("ThetaDependent", thetaDependentTrans);
897 auto btSpreaderAlgProp = std::make_unique<AlgorithmProperty>("BckTransmissionAlgorithm");
898 btSpreaderAlgProp->setValue(transAlg->toString());
899 reductionManager->declareProperty(std::move(btSpreaderAlgProp));
900 }
901}
902
903void SetupHFIRReduction::setupTransmission(const std::shared_ptr<PropertyManager> &reductionManager) {
904 const std::string reductionManagerName = getProperty("ReductionProperties");
905 // Transmission options
906 const bool thetaDependentTrans = getProperty("ThetaDependentTransmission");
907 const std::string transMethod = getProperty("TransmissionMethod");
908 const std::string darkCurrent = getPropertyValue("TransmissionDarkCurrentFile");
909 const bool useSampleDC = getProperty("TransmissionUseSampleDC");
910
911 // Transmission is entered by hand
912 if (boost::iequals(transMethod, "Value")) {
913 const double transValue = getProperty("TransmissionValue");
914 const double transError = getProperty("TransmissionError");
915 if (!isEmpty(transValue) && !isEmpty(transError)) {
916 auto transAlg = createChildAlgorithm("ApplyTransmissionCorrection");
917 transAlg->setProperty("TransmissionValue", transValue);
918 transAlg->setProperty("TransmissionError", transError);
919 transAlg->setProperty("ThetaDependent", thetaDependentTrans);
920
921 auto transAlgProp = std::make_unique<AlgorithmProperty>("TransmissionAlgorithm");
922 transAlgProp->setValue(transAlg->toString());
923 reductionManager->declareProperty(std::move(transAlgProp));
924 } else {
925 g_log.information("SetupHFIRReduction [TransmissionAlgorithm]:"
926 "expected transmission/error values and got empty values");
927 }
928 }
929 // Direct beam method for transmission determination
930 else if (boost::iequals(transMethod, "DirectBeam")) {
931 const std::string sampleFilename = getPropertyValue("TransmissionSampleDataFile");
932 const std::string emptyFilename = getPropertyValue("TransmissionEmptyDataFile");
933 const double beamRadius = getProperty("TransmissionBeamRadius");
934 const double beamX = getProperty("TransmissionBeamCenterX");
935 const double beamY = getProperty("TransmissionBeamCenterY");
936 const std::string centerMethod = getPropertyValue("TransmissionBeamCenterMethod");
937
938 auto transAlg = createChildAlgorithm("SANSDirectBeamTransmission");
939 transAlg->setProperty("SampleDataFilename", sampleFilename);
940 transAlg->setProperty("EmptyDataFilename", emptyFilename);
941 transAlg->setProperty("BeamRadius", beamRadius);
942 transAlg->setProperty("DarkCurrentFilename", darkCurrent);
943 transAlg->setProperty("UseSampleDarkCurrent", useSampleDC);
944
945 // Beam center option for transmission data
946 if (boost::iequals(centerMethod, "Value") && !isEmpty(beamX) && !isEmpty(beamY)) {
947 transAlg->setProperty("BeamCenterX", beamX);
948 transAlg->setProperty("BeamCenterY", beamY);
949 } else if (boost::iequals(centerMethod, "DirectBeam")) {
950 const std::string beamCenterFile = getProperty("TransmissionBeamCenterFile");
951 if (!beamCenterFile.empty()) {
952 auto ctrAlg = createChildAlgorithm("SANSBeamFinder");
953 ctrAlg->setProperty("Filename", beamCenterFile);
954 ctrAlg->setProperty("UseDirectBeamMethod", true);
955 ctrAlg->setProperty("PersistentCorrection", false);
956 ctrAlg->setPropertyValue("ReductionProperties", reductionManagerName);
957
958 auto tbcAlgProp = std::make_unique<AlgorithmProperty>("TransmissionBeamCenterAlgorithm");
959 tbcAlgProp->setValue(ctrAlg->toString());
960 reductionManager->declareProperty(std::move(tbcAlgProp));
961 } else {
962 g_log.error() << "ERROR: Transmission beam center determination was required"
963 " but no file was provided\n";
964 }
965 }
966 transAlg->setProperty("ThetaDependent", thetaDependentTrans);
967 auto thetaTransAlgProp = std::make_unique<AlgorithmProperty>("TransmissionAlgorithm");
968 thetaTransAlgProp->setValue(transAlg->toString());
969 reductionManager->declareProperty(std::move(thetaTransAlgProp));
970 }
971 // Direct beam method for transmission determination
972 else if (boost::iequals(transMethod, "BeamSpreader")) {
973 const std::string sampleSpread = getPropertyValue("TransSampleSpreaderFilename");
974 const std::string directSpread = getPropertyValue("TransDirectSpreaderFilename");
975 const std::string sampleScatt = getPropertyValue("TransSampleScatteringFilename");
976 const std::string directScatt = getPropertyValue("TransDirectScatteringFilename");
977 const double spreaderTrValue = getProperty("SpreaderTransmissionValue");
978 const double spreaderTrError = getProperty("SpreaderTransmissionError");
979
980 auto transAlg = createChildAlgorithm("SANSBeamSpreaderTransmission");
981 transAlg->setProperty("SampleSpreaderFilename", sampleSpread);
982 transAlg->setProperty("DirectSpreaderFilename", directSpread);
983 transAlg->setProperty("SampleScatteringFilename", sampleScatt);
984 transAlg->setProperty("DirectScatteringFilename", directScatt);
985 transAlg->setProperty("SpreaderTransmissionValue", spreaderTrValue);
986 transAlg->setProperty("SpreaderTransmissionError", spreaderTrError);
987 transAlg->setProperty("DarkCurrentFilename", darkCurrent);
988 transAlg->setProperty("ThetaDependent", thetaDependentTrans);
989 auto directTransAlgProp = std::make_unique<AlgorithmProperty>("TransmissionAlgorithm");
990 directTransAlgProp->setValue(transAlg->toString());
991 reductionManager->declareProperty(std::move(directTransAlgProp));
992 }
993}
994
995} // 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
A property class for workspaces.
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 setupBackground(const std::shared_ptr< Kernel::PropertyManager > &reductionManager)
void setupSensitivity(const std::shared_ptr< Kernel::PropertyManager > &reductionManager)
void setupTransmission(const std::shared_ptr< Kernel::PropertyManager > &reductionManager)
void init() override
Initialisation code.
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