Mantid
Loading...
Searching...
No Matches
LoadHFIRSANS.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 +
9#include "MantidAPI/Axis.h"
12#include "MantidAPI/Run.h"
23
24#include <boost/algorithm/string/split.hpp>
25#include <boost/algorithm/string/trim.hpp>
26#include <boost/lexical_cast.hpp>
27#include <boost/regex.hpp>
28#include <memory>
29
31#include <Poco/DOM/DOMParser.h>
32#include <Poco/DOM/Document.h>
33#include <Poco/DOM/Element.h>
34#include <Poco/DOM/Node.h>
35#include <Poco/DOM/NodeList.h>
36#include <Poco/DOM/Text.h>
37#include <Poco/SAX/InputSource.h>
38
39#include <algorithm>
40#include <cmath>
41#include <iostream>
42#include <limits>
43#include <memory>
44#include <sstream>
45#include <string>
46#include <utility>
47#include <vector>
48
49namespace Mantid::DataHandling {
50
53using Types::Core::DateAndTime;
54using namespace Kernel;
55using namespace API;
56using namespace Geometry;
57using namespace DataObjects;
58
59// Register the algorithm into the AlgorithmFactory
61
63 : m_sansSpiceXmlFormatVersion(0.0), m_wavelength(0.0), m_dwavelength(0.0), m_sampleDetectorDistance(0.0) {}
64
72 if (descriptor.extension() != ".xml")
73 return 0;
74
75 std::istream &is = descriptor.data();
76 int confidence(0);
77
78 { // start of inner scope
79 Poco::XML::InputSource src(is);
80 // Set up the DOM parser and parse xml file
81 Poco::XML::DOMParser pParser;
82 Poco::AutoPtr<Poco::XML::Document> pDoc;
83 try {
84 pDoc = pParser.parse(&src);
85 } catch (Poco::Exception &e) {
86 throw Kernel::Exception::FileError("Unable to parse File (" + descriptor.filename() + ")", e.displayText());
87 } catch (...) {
88 throw Kernel::Exception::FileError("Unable to parse File:", descriptor.filename());
89 }
90 // Get pointer to root element
91 Poco::XML::Element *pRootElem = pDoc->documentElement();
92 if (pRootElem) {
93 if (pRootElem->tagName() == "SPICErack") {
94 confidence = 80;
95 }
96 }
97 } // end of inner scope
98
99 return confidence;
100}
101
104 declareProperty(std::make_unique<API::FileProperty>("Filename", "", API::FileProperty::Load, ".xml"),
105 "The name of the input xml file to load");
107 std::make_unique<API::WorkspaceProperty<API::Workspace>>("OutputWorkspace", "", Kernel::Direction::Output),
108 "The name of the Output workspace");
109
110 // Optionally, we can specify the wavelength and wavelength spread and
111 // overwrite the value in the data file (used when the data file is not
112 // populated)
113 auto mustBePositive = std::make_shared<Kernel::BoundedValidator<double>>();
114 mustBePositive->setLower(0.0);
115 declareProperty("Wavelength", EMPTY_DBL(), mustBePositive,
116 "Optional wavelength value to use when loading the data file "
117 "(Angstrom). This value will be used instead of the value "
118 "found in the data file.");
119 declareProperty("WavelengthSpread", EMPTY_DBL(), mustBePositive,
120 "Optional wavelength spread value to use when loading the "
121 "data file (Angstrom). This value will be used instead of "
122 "the value found in the data file.");
123 declareProperty("SampleDetectorDistance", EMPTY_DBL(),
124 "Sample to detector distance to use (overrides meta data), in mm");
125}
126
127/*******************************************************************************
128 * Main method.
129 */
131
132 // Parse the XML metadata
134 setTimes();
138 // ugly hack for Biosans wing detector:
139 // it tests if there is metadata tagged with the wing detector
140 // if so, puts the detector in the right angle
141 if (m_metadata.find("Motor_Positions/det_west_wing_rot") != m_metadata.end()) {
143 }
144 moveDetector();
146 // This needs parameters from IDF! Run load instrument before!
148 setProperty("OutputWorkspace", m_workspace);
149}
150
158 // Set up the XmlHandler handler and parse xml file
159 std::string fileName = getPropertyValue("Filename");
160 try {
161 m_xmlHandler = XmlHandler(fileName);
162 } catch (...) {
163 throw Kernel::Exception::FileError("Unable to parse File:", std::move(fileName));
164 }
167}
168
169/***
170 * 2016/11/09 : There is a new tag sans_spice_xml_format_version in the XML
171 * It identifies changes in the XML format.
172 * Useful to test tags rather than using the date.
173 * @param metadata
174 */
176
177 if (m_metadata.find("Header/sans_spice_xml_format_version") != m_metadata.end()) {
178 m_sansSpiceXmlFormatVersion = boost::lexical_cast<double>(m_metadata["Header/sans_spice_xml_format_version"]);
179 }
180 g_log.debug() << "Sans_spice_xml_format_version == " << m_sansSpiceXmlFormatVersion << "\n";
181}
182
184 // start_time
185 std::map<std::string, std::string> attributes = m_xmlHandler.get_attributes_from_tag("/");
186
187 m_startTime = DateAndTime(attributes["start_time"]);
188 m_endTime = DateAndTime(attributes["end_time"]);
189}
190
195
196 double wavelength_input = getProperty("Wavelength");
197 double wavelength_spread_input = getProperty("WavelengthSpread");
198
199 if (isEmpty(wavelength_input)) {
200 m_wavelength = boost::lexical_cast<double>(m_metadata["Header/wavelength"]);
201 } else {
202 m_wavelength = wavelength_input;
203 }
204
205 if (isEmpty(wavelength_spread_input)) {
206 m_dwavelength = boost::lexical_cast<double>(m_metadata["Header/wavelength_spread"]);
207 // 20160720: New wavelength will be a ratio
208 // UGLY HACK! Comparing dates...
209 DateAndTime changingDate("2016-06-13 00:00:00");
210 if (m_startTime >= changingDate) {
211 g_log.debug() << "Using wavelength spread as a ratio..." << '\n';
213 }
214 } else {
215 m_dwavelength = wavelength_spread_input;
216 }
217
218 g_log.debug() << "Final Wavelength: " << m_wavelength << " :: Wavelength Spread: " << m_dwavelength << '\n';
219}
220
225std::pair<int, int> LoadHFIRSANS::parseDetectorDimensions(const std::string &dims_str) {
226
227 // Read in the detector dimensions from the Detector tag
228
229 std::pair<int, int> dims = std::make_pair(0, 0);
230
231 boost::regex b_re_sig(R"(INT\d+\[(\d+),(\d+)\])");
232 if (boost::regex_match(dims_str, b_re_sig)) {
233 boost::match_results<std::string::const_iterator> match;
234 boost::regex_search(dims_str, match, b_re_sig);
235 // match[0] is the full string
236 Kernel::Strings::convert(match[1], dims.first);
237 Kernel::Strings::convert(match[2], dims.second);
238 }
239 if (dims.first == 0 || dims.second == 0)
240 g_log.notice() << "Could not read in the number of pixels!" << '\n';
241 return dims;
242}
243
248std::vector<int> LoadHFIRSANS::readData(const std::string &dataXpath) {
249
250 // data container
251 std::vector<int> data;
252 unsigned int totalDataSize = 0;
253
254 // let's see how many detectors we have
255 std::vector<std::string> detectors = m_xmlHandler.get_subnodes(dataXpath);
256 g_log.debug() << "Number the detectors found in Xpath " << dataXpath << " = " << detectors.size() << '\n';
257
258 // iterate every detector in the xml file
259 for (const auto &detector : detectors) {
260 std::string detectorXpath = std::string(dataXpath).append("/").append(detector);
261 // type : INT32[192,256]
262 std::map<std::string, std::string> attributes = m_xmlHandler.get_attributes_from_tag(detectorXpath);
263 std::pair<int, int> dims = parseDetectorDimensions(attributes["type"]);
264
265 // Horrible hack:
266 // Some old files had a: //Data/DetectorWing with dimensions:
267 // 16 x 256 = 4096. This must be ignored as it is not in the IDF
268 // The real wing detector is larger than that
269 if (detectorXpath.find("DetectorWing") != std::string::npos && dims.first * dims.second <= 4096)
270 break;
271
272 totalDataSize += dims.first * dims.second;
273 g_log.debug() << "Parsing detector XPath " << detectorXpath << " with dimensions: " << dims.first << " x "
274 << dims.second << " = " << dims.first * dims.second << '\n';
275
276 std::string data_str = m_xmlHandler.get_text_from_tag(detectorXpath);
277 g_log.debug() << "The size of detector contents (xpath = " << detectorXpath << ") is " << data_str.size()
278 << " bytes." << '\n';
279
280 // convert string data into a vector<int>
281 std::stringstream iss(data_str);
282 double number;
283 while (iss >> number) {
284 data.emplace_back(static_cast<int>(number));
285 }
286 g_log.debug() << "Detector XPath: " << detectorXpath
287 << " parsed. Total size of data processed up to now = " << data.size() << " from a total of "
288 << totalDataSize << '\n';
289 }
290
291 if (data.size() != totalDataSize) {
292 g_log.error() << "Total data size = " << totalDataSize << ". Parsed data size = " << data.size() << '\n';
293 throw Kernel::Exception::NotImplementedError("Inconsistent data set: There were more data pixels found than "
294 "declared in the Spice XML meta-data.");
295 }
296 return data;
297}
298
304void LoadHFIRSANS::permuteTubes(std::vector<int> &data) {
305 const std::string &instrumentName = m_metadata["Header/Instrument"];
306
307 if (instrumentName.compare("CG2") == 0 || instrumentName.compare("GPSANS") == 0) {
308 std::vector<int> temp(data.size());
309 size_t nTubes(std::stoul(m_metadata["Header/Number_of_X_Pixels"]));
310 size_t nEightPacks = nTubes / 8;
311 size_t nPixelPerTube(std::stoul(m_metadata["Header/Number_of_Y_Pixels"]));
312 // permutation that takes us from a tube ID in the IDF to a tube ID in the
313 // XML file
314 std::vector<size_t> perm{0, 2, 4, 6, 1, 3, 5, 7};
315 size_t newStartPixelID, oldStartPixelID;
316 for (size_t e = 0; e < nEightPacks; ++e) { // iterate over all eightpacks
317 for (size_t t = 0; t < 8; t++) { // iterate over each tube in an eightpack
318 newStartPixelID = (t + 8 * e) * nPixelPerTube; // t+8*e is the new tube ID
319 oldStartPixelID = (perm[t] + 8 * e) * nPixelPerTube; // perm[t]+8*e is the old tube ID
320 for (size_t p = 0; p < nPixelPerTube; p++) { // copy the "contents of the tube"
321 temp[p + newStartPixelID] = data[p + oldStartPixelID];
322 }
323 }
324 }
325 for (size_t i = 0; i < data.size(); i++) {
326 data[i] = temp[i];
327 }
328 }
329}
330
341void LoadHFIRSANS::storeValue(int specID, double value, double error, double wavelength, double dwavelength) {
342 auto &X = m_workspace->mutableX(specID);
343 auto &Y = m_workspace->mutableY(specID);
344 auto &E = m_workspace->mutableE(specID);
345 // The following is mostly to make Mantid happy by defining a histogram with
346 // a single bin around the neutron wavelength
347 X[0] = wavelength - dwavelength / 2.0;
348 X[1] = wavelength + dwavelength / 2.0;
349 Y[0] = value;
350 E[0] = error;
351 m_workspace->getSpectrum(specID).setSpectrumNo(specID);
352}
353
355
356 std::vector<int> data = readData("//Data");
357 permuteTubes(data);
358
359 int numSpectra = static_cast<int>(data.size()) + m_nMonitors;
360
361 m_workspace = std::dynamic_pointer_cast<DataObjects::Workspace2D>(
362 API::WorkspaceFactory::Instance().create("Workspace2D", numSpectra, 2, 1));
363 m_workspace->setTitle(m_metadata["Header/Scan_Title"]);
364 m_workspace->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("Wavelength");
365 m_workspace->setYUnit("Counts");
366
367 auto monitorCounts = boost::lexical_cast<double>(m_metadata["Counters/monitor"]);
368 auto countingTime = boost::lexical_cast<double>(m_metadata["Counters/time"]);
369
370 int specID = 0;
371 // Store monitor counts in the beggining
372 storeValue(specID++, monitorCounts, monitorCounts > 0 ? sqrt(monitorCounts) : 0.0, m_wavelength, m_dwavelength);
373
374 storeValue(specID++, countingTime, 0.0, m_wavelength, m_dwavelength);
375
376 // Store detector pixels
377 for (auto count : data) {
378 // Data uncertainties, computed according to the HFIR/IGOR reduction code
379 // The following is what I would suggest instead...
380 // error = count > 0 ? sqrt((double)count) : 0.0;
381 double error = sqrt(0.5 + fabs(static_cast<double>(count) - 0.5));
383 }
384}
385
386template <class T>
387void LoadHFIRSANS::addRunProperty(const std::string &name, const T &value, const std::string &units) {
388 g_log.debug() << "Adding Property to the Run: " << name << " -> " << value << "\n";
389 m_workspace->mutableRun().addProperty(name, value, units, true);
390}
391
392template <class T> void LoadHFIRSANS::addRunTimeSeriesProperty(const std::string &name, const T &value) {
393 g_log.debug() << "Adding Time Series Property to the Run: " << name << " -> " << value << "\n";
394 API::Run &runDetails = m_workspace->mutableRun();
396 p->addValue(DateAndTime::getCurrentTime(), value);
397 runDetails.addLogData(p);
398}
399
416
417 std::vector<double> trapDiameters = {76.2, 50.8, 76.2, 101.6};
418 // default use the shortest trap
419 double trapDiameterInUse = trapDiameters[1];
420
421 std::vector<double> trapMotorPositions;
422 trapMotorPositions.emplace_back(boost::lexical_cast<double>(m_metadata["Motor_Positions/trap_y_25mm"]));
423 trapMotorPositions.emplace_back(boost::lexical_cast<double>(m_metadata["Motor_Positions/trap_y_50mm"]));
424 trapMotorPositions.emplace_back(boost::lexical_cast<double>(m_metadata["Motor_Positions/trap_y_76mm"]));
425 trapMotorPositions.emplace_back(boost::lexical_cast<double>(m_metadata["Motor_Positions/trap_y_101mm"]));
426
427 // store diameters for traps that are in use (resting positions are below 25mm)
428 std::vector<double> trapDiametersInUse;
429 auto posIt = trapMotorPositions.cbegin();
430 std::copy_if(trapDiameters.cbegin(), trapDiameters.cend(), std::back_inserter(trapDiametersInUse),
431 [&posIt](double) { return *posIt++ > 26.0; });
432
433 g_log.debug() << "trapDiametersInUse length:" << trapDiametersInUse.size() << "\n";
434
435 // The maximum value for the trapDiametersInUse is the trap in use
436 auto trapDiameterInUseIt = std::max_element(trapDiametersInUse.begin(), trapDiametersInUse.end());
437 if (trapDiameterInUseIt != trapDiametersInUse.end())
438 trapDiameterInUse = *trapDiameterInUseIt;
439
440 g_log.debug() << "trapDiameterInUse:" << trapDiameterInUse << "\n";
441
442 addRunProperty<double>("beam-trap-diameter", trapDiameterInUse, "mm");
443}
444
450
451 for (const auto &keyValuePair : m_metadata) {
452 std::string key = keyValuePair.first;
453 std::replace(key.begin(), key.end(), '/', '_');
454 m_workspace->mutableRun().addProperty(key, keyValuePair.second, true);
455 }
456
457 addRunProperty<std::string>("start_time", m_startTime.toISO8601String(), "");
458 addRunProperty<std::string>("run_start", m_startTime.toISO8601String(), "");
459 m_workspace->mutableRun().setStartAndEndTime(m_startTime, m_endTime);
460
462
463 addRunProperty<double>("wavelength", m_wavelength, "Angstrom");
464 addRunProperty<double>("wavelength-spread", m_dwavelength, "Angstrom");
465 addRunProperty<double>("wavelength-spread-ratio", m_dwavelength / m_wavelength);
466
467 addRunProperty<double>("monitor", boost::lexical_cast<double>(m_metadata["Counters/monitor"]));
468 addRunProperty<double>("timer", boost::lexical_cast<double>(m_metadata["Counters/time"]), "sec");
469
470 // XML 1.03: sample thickness is now in meters
471 auto sample_thickness = boost::lexical_cast<double>(m_metadata["Header/Sample_Thickness"]);
472 if (m_sansSpiceXmlFormatVersion >= 1.03) {
473 g_log.debug() << "sans_spice_xml_format_version >= 1.03 :: "
474 "sample_thickness in mm. Converting to cm...";
475 sample_thickness *= 0.1;
476 }
477 addRunProperty<double>("sample-thickness", sample_thickness, "cm");
478
479 addRunProperty<double>("source-aperture-diameter",
480 boost::lexical_cast<double>(m_metadata["Header/source_aperture_size"]), "mm");
481 addRunProperty<double>("source_aperture_diameter",
482 boost::lexical_cast<double>(m_metadata["Header/source_aperture_size"]), "mm");
483
484 addRunProperty<double>("sample-aperture-diameter",
485 boost::lexical_cast<double>(m_metadata["Header/sample_aperture_size"]), "mm");
486 addRunProperty<double>("sample_aperture_diameter",
487 boost::lexical_cast<double>(m_metadata["Header/sample_aperture_size"]), "mm");
488
489 addRunProperty<double>("number-of-guides", boost::lexical_cast<double>(m_metadata["Motor_Positions/nguides"]));
490}
491
496
497 const std::string &instrumentName = m_metadata["Header/Instrument"];
498
499 auto loadInstrumentAlgorithm = createChildAlgorithm("LoadInstrument");
500
501 // Now execute the Child Algorithm. Catch and log any error, but don't stop.
502 try {
503 loadInstrumentAlgorithm->setPropertyValue("InstrumentName", instrumentName);
504 loadInstrumentAlgorithm->setProperty<API::MatrixWorkspace_sptr>("Workspace", m_workspace);
505 loadInstrumentAlgorithm->setProperty("RewriteSpectraMap", Mantid::Kernel::OptionalBool(true));
506 loadInstrumentAlgorithm->execute();
507 } catch (std::invalid_argument &) {
508 g_log.information("Invalid argument to LoadInstrument Child Algorithm");
509 } catch (std::runtime_error &) {
510 g_log.information("Unable to successfully run LoadInstrument Child Algorithm");
511 }
512}
513
518
519 // The angle is negative!
520 double angle = -boost::lexical_cast<double>(m_metadata["Motor_Positions/det_west_wing_rot"]);
521 g_log.notice() << "Rotating Wing Detector " << angle << " degrees." << '\n';
522 addRunTimeSeriesProperty<double>("rotangle", angle);
523}
524
529
530 m_sampleDetectorDistance = getProperty("SampleDetectorDistance");
531
533 // SDD is as input
534 g_log.debug() << "Getting the SampleDetectorDistance = " << m_sampleDetectorDistance
535 << " from the Algorithm input property.\n";
536 } else if (m_metadata.find("Motor_Positions/sdd") != m_metadata.end()) {
537 // Newest version: SDD as a specific tag
538 m_sampleDetectorDistance = boost::lexical_cast<double>(m_metadata["Motor_Positions/sdd"]);
539 m_sampleDetectorDistance *= 1000.0;
540 } else if (m_metadata.find("Motor_Positions/sample_det_dist") != m_metadata.end()) {
541 // Old Format
542 auto sampleDetectorDistancePartial = boost::lexical_cast<double>(m_metadata["Motor_Positions/sample_det_dist"]);
543 sampleDetectorDistancePartial *= 1000.0;
544
545 auto sampleDetectorDistanceOffset = boost::lexical_cast<double>(m_metadata["Header/tank_internal_offset"]);
546
547 auto sampleDetectorDistanceWindow = boost::lexical_cast<double>(m_metadata["Header/sample_to_flange"]);
548
550 sampleDetectorDistancePartial + sampleDetectorDistanceOffset + sampleDetectorDistanceWindow;
551 } else {
552 // New format:
553 m_sampleDetectorDistance = boost::lexical_cast<double>(m_metadata["Motor_Positions/sample_det_dist"]);
554 m_sampleDetectorDistance *= 1000.0;
555 }
556 g_log.debug() << "Sample Detector Distance = " << m_sampleDetectorDistance << " mm." << '\n';
557 addRunProperty<double>("sample-detector-distance", m_sampleDetectorDistance, "mm");
558 addRunProperty<double>("sample_detector_distance", m_sampleDetectorDistance, "mm");
559
560 addRunTimeSeriesProperty<double>("sdd", m_sampleDetectorDistance);
561}
562
567
569 auto translationDistance = boost::lexical_cast<double>(m_metadata["Motor_Positions/detector_trans"]);
570 g_log.debug() << "Detector Translation = " << translationDistance << " mm." << '\n';
571 addRunTimeSeriesProperty<double>("detector-translation", translationDistance);
572}
573
577std::string LoadHFIRSANS::getInstrumentStringParameter(const std::string &parameter) {
578 std::vector<std::string> pars = m_workspace->getInstrument()->getStringParameter(parameter);
579 if (pars.empty()) {
580 g_log.warning() << "Parameter not found: " << parameter << " in the instrument parameter file.\n";
581 return std::string();
582 } else {
583 g_log.debug() << "Found the parameter: " << parameter << " = " << pars[0] << " in the instrument parameter file.\n";
584 return pars[0];
585 }
586}
587
591double LoadHFIRSANS::getInstrumentDoubleParameter(const std::string &parameter) {
592 std::vector<double> pars = m_workspace->getInstrument()->getNumberParameter(parameter);
593 if (pars.empty()) {
594 g_log.warning() << "Parameter not found in the instrument parameter file: " << parameter << "\n";
595 return std::numeric_limits<double>::quiet_NaN();
596 } else {
597 g_log.debug() << "Found the parameter in the instrument parameter file: " << parameter << " = " << pars[0] << "\n";
598 return pars[0];
599 }
600}
613 // First let's try to get source_distance first:
614 auto sourceToSampleDistance = boost::lexical_cast<double>(m_metadata["Header/source_distance"]);
615 // XML 1.03: source distance is now in meters
616 if (m_sansSpiceXmlFormatVersion >= 1.03) {
617 sourceToSampleDistance *= 1000; // convert to mm
618 }
619 if (sourceToSampleDistance <= 0) {
620 g_log.warning() << "Source To Sample Distance: Header/source_distance = " << sourceToSampleDistance
621 << ". Trying to calculate it from the number of guides used and offset." << '\n';
622 const int nGuides = static_cast<int>(boost::lexical_cast<double>(m_metadata["Motor_Positions/nguides"]));
623 // aperture-distances: array from the instrument parameters
624 std::string guidesDistances = getInstrumentStringParameter("aperture-distances");
625 std::vector<std::string> guidesDistancesSplit;
626 boost::split(guidesDistancesSplit, guidesDistances, boost::is_any_of("\t ,"), boost::token_compress_on);
627 sourceToSampleDistance = boost::lexical_cast<double>(guidesDistancesSplit[nGuides]);
628 g_log.debug() << "Number of guides used = " << nGuides << " --> Raw SSD = " << sourceToSampleDistance << "mm.\n";
629 auto sourceToSampleDistanceOffset = boost::lexical_cast<double>(m_metadata["Header/sample_aperture_to_flange"]);
630 g_log.debug() << "SSD offset = " << sourceToSampleDistanceOffset << "mm.\n";
631 sourceToSampleDistance -= sourceToSampleDistanceOffset;
632 }
633 g_log.information() << "Source To Sample Distance = " << sourceToSampleDistance << "mm.\n";
634 return sourceToSampleDistance;
635}
636
641
642 double sourceToSampleDistance = getSourceToSampleDistance();
643 addRunProperty<double>("source-sample-distance", sourceToSampleDistance, "mm");
644 addRunProperty<double>("source_sample_distance", sourceToSampleDistance, "mm");
645
646 const auto sampleAperture = boost::lexical_cast<double>(m_metadata["Header/sample_aperture_size"]);
647 const auto sourceAperture = boost::lexical_cast<double>(m_metadata["Header/source_aperture_size"]);
648 g_log.debug() << "Computing beam diameter. m_sampleDetectorDistance=" << m_sampleDetectorDistance
649 << " SourceToSampleDistance=" << sourceToSampleDistance << " sourceAperture= " << sourceAperture
650 << " sampleAperture=" << sampleAperture << "\n";
651
652 const double beamDiameter =
653 m_sampleDetectorDistance / sourceToSampleDistance * (sourceAperture + sampleAperture) + sampleAperture;
654 addRunProperty<double>("beam-diameter", beamDiameter, "mm");
655}
656
657} // namespace Mantid::DataHandling
std::string name
Definition Run.cpp:60
double value
The value of the point.
Definition FitMW.cpp:51
double error
#define fabs(x)
Definition Matrix.cpp:22
int count
counter
Definition Matrix.cpp:37
#define DECLARE_FILELOADER_ALGORITHM(classname)
DECLARE_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro when wri...
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
Kernel::Logger & g_log
Definition Algorithm.h:423
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
@ Load
allowed here which will be passed to the algorithm
void addLogData(Kernel::Property *p)
Add a log entry.
Definition LogManager.h:126
This class stores information regarding an experimental run as a series of log entries.
Definition Run.h:35
A property class for workspaces.
This algorithm loads a SPICE2D file for HFIR SANS into a workspace.
void permuteTubes(std::vector< int > &data)
Reorder data to take into account that the sequence of tubes in the XML file is different than the se...
void storeMetaDataIntoWS()
Add all metadata parsed values as log entries Add any other metadata needed.
std::pair< int, int > parseDetectorDimensions(const std::string &dims_str)
Parse the 2 integers of the form: INT32[192,256].
void addRunProperty(const std::string &name, const T &value, const std::string &units="")
static const int m_nMonitors
Number of monitors.
void runLoadInstrument()
Run the Child Algorithm LoadInstrument.
Mantid::Types::Core::DateAndTime m_startTime
DataObjects::Workspace2D_sptr m_workspace
const std::vector< std::string > m_tags_to_ignore
void setBeamTrapRunProperty()
Sets the beam trap as Run Property There's several beamstrap position.
void rotateDetector()
This will rotate the detector named componentName around z-axis.
double getSourceToSampleDistance()
Source to Detector Distance is already calculated in the metadata tag source_distance (if source_dist...
void setWavelength()
Sets the wavelength as class atributes.
std::vector< int > readData(const std::string &dataXpath="//Data")
Loads the data from the XML file.
void init() override
Overwrites Algorithm method.
double getInstrumentDoubleParameter(const std::string &parameter)
From the parameters file get a double parameter.
Mantid::DataHandling::XmlHandler m_xmlHandler
void moveDetector()
Places the detector at the right sample_detector_distance.
void exec() override
Overwrites Algorithm method.
void setDetectorDistance()
Calculates the detector distances and sets them as Run properties.
std::string getInstrumentStringParameter(const std::string &parameter)
From the parameters file get a string parameter.
std::map< std::string, std::string > m_metadata
int confidence(Kernel::FileDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
const std::string name() const override
Algorithm's name for identification overriding a virtual method.
void addRunTimeSeriesProperty(const std::string &name, const T &value)
void storeValue(int specID, double value, double error, double wavelength, double dwavelength)
Convenience function to store a detector value into a given spectrum.
void setBeamDiameter()
Compute beam diameter at the detector.
Mantid::Types::Core::DateAndTime m_endTime
std::string get_text_from_tag(const std::string &)
std::map< std::string, std::string > get_metadata(const std::vector< std::string > &tags_to_ignore)
Build dictionary {string : string } of all tags in the dictionary Composed tags: / replaced by _.
std::map< std::string, std::string > get_attributes_from_tag(const std::string &)
std::vector< std::string > get_subnodes(const std::string &)
Returns list of sub-nodes for a xpath node For: xpath = //Data/ Returns: Detector ,...
Records the filename and the description of failure.
Definition Exception.h:98
Marks code as not implemented yet.
Definition Exception.h:138
Defines a wrapper around an open file.
const std::string & filename() const
Access the filename.
std::istream & data()
Access the open file stream.
const std::string & extension() const
Access the file extension.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
void notice(const std::string &msg)
Logs at notice level.
Definition Logger.cpp:126
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
OptionalBool : Tri-state bool.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
A specialised Property class for holding a series of time-value pairs.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
int convert(const std::string &A, T &out)
Convert a string into a number.
Definition Strings.cpp:696
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
Describes the direction (within an algorithm) of a Property.
Definition Property.h:50
@ Output
An output workspace.
Definition Property.h:54