24#include <boost/lexical_cast.hpp>
25#include <boost/regex.hpp>
28#include <Poco/DOM/DOMParser.h>
29#include <Poco/DOM/Document.h>
30#include <Poco/DOM/Element.h>
31#include <Poco/DOM/Node.h>
32#include <Poco/DOM/NodeList.h>
33#include <Poco/DOM/Text.h>
34#include <Poco/SAX/InputSource.h>
43using Poco::XML::Document;
44using Poco::XML::DOMParser;
45using Poco::XML::Element;
51using Types::Core::DateAndTime;
52using namespace Kernel;
54using namespace Geometry;
55using namespace DataObjects;
62 std::istringstream iss(s);
63 return !(iss >> f >> t).fail();
79 auto &
X = ws->mutableX(specID);
80 auto &
Y = ws->mutableY(specID);
81 auto &E = ws->mutableE(specID);
84 X[0] = wavelength - dwavelength / 2.0;
85 X[1] = wavelength + dwavelength / 2.0;
88 ws->getSpectrum(specID).setSpectrumNo(specID);
101 std::istream &is = descriptor.
data();
105 Poco::XML::InputSource src(is);
108 Poco::AutoPtr<Document> pDoc;
110 pDoc = pParser.parse(&src);
111 }
catch (Poco::Exception &e) {
117 Element *pRootElem = pDoc->documentElement();
119 if (pRootElem->tagName() ==
"SPICErack") {
131 "The name of the input xml file to load");
134 "The name of the Output workspace");
139 auto mustBePositive = std::make_shared<Kernel::BoundedValidator<double>>();
140 mustBePositive->setLower(0.0);
142 "Optional wavelength value to use when loading the data file "
143 "(Angstrom). This value will be used instead of the value "
144 "found in the data file.");
146 "Optional wavelength spread value to use when loading the "
147 "data file (Angstrom). This value will be used instead of "
148 "the value found in the data file.");
161 const std::vector<std::string> tags_to_ignore{
"Detector",
"DetectorWing"};
167 std::vector<int> data =
getData(
"//Data");
169 double monitorCounts = 0;
170 from_string<double>(monitorCounts, metadata[
"Counters/monitor"], std::dec);
171 double countingTime = 0;
172 from_string<double>(countingTime, metadata[
"Counters/time"], std::dec);
173 createWorkspace(data, metadata[
"Header/Scan_Title"], monitorCounts, countingTime);
181 std::string instrument = metadata[
"Header/Instrument"];
186 if (metadata.find(
"Motor_Positions/det_west_wing_rot") != metadata.end()) {
187 auto angle = boost::lexical_cast<double>(metadata[
"Motor_Positions/det_west_wing_rot"]);
205 std::pair<int, int> dims = std::make_pair(0, 0);
207 boost::regex b_re_sig(R
"(INT\d+\[(\d+),(\d+)\])");
208 if (boost::regex_match(dims_str, b_re_sig)) {
209 boost::match_results<std::string::const_iterator> match;
210 boost::regex_search(dims_str, match, b_re_sig);
215 if (dims.first == 0 || dims.second == 0)
216 g_log.
notice() <<
"Could not read in the number of pixels!" <<
'\n';
226 for (
const auto &keyValuePair : metadata) {
227 std::string key = keyValuePair.first;
228 std::replace(key.begin(), key.end(),
'/',
'_');
229 m_workspace->mutableRun().addProperty(key, keyValuePair.second,
true);
263 std::string s = metadata[
"Header/wavelength"];
265 s = metadata[
"Header/wavelength_spread"];
270 DateAndTime changingDate(
"2016-06-13 00:00:00");
272 g_log.
debug() <<
"Using wavelength spread as a ratio" <<
'\n';
290 std::vector<int> data;
291 unsigned int totalDataSize = 0;
295 g_log.
debug() <<
"Number the detectors found in Xpath " << dataXpath <<
" = " << detectors.size() <<
'\n';
298 for (
const auto &detector : detectors) {
299 std::string detectorXpath = std::string(dataXpath).append(
"/").append(detector);
307 if (detectorXpath.find(
"DetectorWing") != std::string::npos && dims.first * dims.second <= 4096)
310 totalDataSize += dims.first * dims.second;
311 g_log.
debug() <<
"Parsing detector XPath " << detectorXpath <<
" with dimensions: " << dims.first <<
" x "
312 << dims.second <<
" = " << dims.first * dims.second <<
'\n';
315 g_log.
debug() <<
"The size of detector contents (xpath = " << detectorXpath <<
") is " << data_str.size()
316 <<
" bytes." <<
'\n';
319 std::stringstream iss(data_str);
321 while (iss >> number) {
322 data.emplace_back(
static_cast<int>(number));
324 g_log.
debug() <<
"Detector XPath: " << detectorXpath
325 <<
" parsed. Total size of data processed up to now = " << data.size() <<
" from a total of "
326 << totalDataSize <<
'\n';
329 if (data.size() != totalDataSize) {
330 g_log.
error() <<
"Total data size = " << totalDataSize <<
". Parsed data size = " << data.size() <<
'\n';
332 "declared in the Spice XML meta-data.");
341 double monitor2_counts) {
345 m_workspace = std::dynamic_pointer_cast<DataObjects::Workspace2D>(
348 m_workspace->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create(
"Wavelength");
358 for (
auto count : data) {
362 double error = sqrt(0.5 +
fabs(
static_cast<double>(
count) - 0.5));
372 const std::string &newName,
const std::string &units) {
374 std::string value_str = metadata[oldName];
376 from_string<T>(
value, value_str, std::dec);
402 std::vector<double> trapDiameters = {76.2, 50.8, 76.2, 101.6};
404 double trapDiameterInUse = trapDiameters[1];
406 std::vector<double> trapMotorPositions;
407 trapMotorPositions.emplace_back(boost::lexical_cast<double>(metadata[
"Motor_Positions/trap_y_25mm"]));
408 trapMotorPositions.emplace_back(boost::lexical_cast<double>(metadata[
"Motor_Positions/trap_y_50mm"]));
409 trapMotorPositions.emplace_back(boost::lexical_cast<double>(metadata[
"Motor_Positions/trap_y_76mm"]));
410 trapMotorPositions.emplace_back(boost::lexical_cast<double>(metadata[
"Motor_Positions/trap_y_101mm"]));
413 std::vector<size_t> trapIndexInUse;
414 for (
size_t i = 0; i < trapMotorPositions.size(); i++) {
415 if (trapMotorPositions[i] > 26.0) {
417 trapIndexInUse.emplace_back(i);
421 g_log.
debug() <<
"trapIndexInUse length:" << trapIndexInUse.size() <<
"\n";
424 std::vector<double> trapDiametersInUse;
425 trapDiametersInUse.reserve(trapIndexInUse.size());
426 std::transform(trapIndexInUse.cbegin(), trapIndexInUse.cend(), std::back_inserter(trapDiametersInUse),
427 [&trapDiameters](
const auto index) { return trapDiameters[index]; });
429 g_log.
debug() <<
"trapDiametersInUse length:" << trapDiametersInUse.size() <<
"\n";
432 auto trapDiameterInUseIt = std::max_element(trapDiametersInUse.begin(), trapDiametersInUse.end());
433 if (trapDiameterInUseIt != trapDiametersInUse.end())
434 trapDiameterInUse = *trapDiameterInUseIt;
436 g_log.
debug() <<
"trapDiameterInUse:" << trapDiameterInUse <<
"\n";
438 addRunProperty<double>(
"beam-trap-diameter", trapDiameterInUse,
"mm");
445 m_startTime = DateAndTime(attributes[
"start_time"]);
446 m_endTime = DateAndTime(attributes[
"end_time"]);
453 addRunProperty<std::string>(
"start_time",
m_startTime.toISO8601String(),
"");
454 addRunProperty<std::string>(
"run_start",
m_startTime.toISO8601String(),
"");
460 double sample_thickness;
461 from_string<double>(sample_thickness, metadata[
"Header/Sample_Thickness"], std::dec);
463 g_log.
debug() <<
"sans_spice_xml_format_version >= 1.03 :: sample_thickness "
464 "in mm. Converting to cm...";
465 sample_thickness *= 0.1;
467 addRunProperty<double>(
"sample-thickness", sample_thickness,
"cm");
469 addRunProperty<double>(metadata,
"Header/Sample_Thickness",
"sample-thickness",
"mm");
471 addRunProperty<double>(metadata,
"Header/source_aperture_size",
"source-aperture-diameter",
"mm");
472 addRunProperty<double>(metadata,
"Header/sample_aperture_size",
"sample-aperture-diameter",
"mm");
475 double source_distance;
476 from_string<double>(source_distance, metadata[
"Header/source_distance"], std::dec);
478 g_log.
debug() <<
"sans_spice_xml_format_version >= 1.03 :: source_distance "
479 "in meters. Converting to mm...";
480 source_distance *= 1000.0;
482 addRunProperty<double>(
"source-sample-distance", source_distance,
"mm");
484 addRunProperty<int>(metadata,
"Motor_Positions/nguides",
"number-of-guides",
"");
486 addRunProperty<double>(
"wavelength",
m_wavelength,
"Angstrom");
487 addRunProperty<double>(
"wavelength-spread",
m_dwavelength,
"Angstrom");
490 addRunProperty<double>(metadata,
"Counters/monitor",
"monitor",
"");
491 addRunProperty<double>(metadata,
"Counters/time",
"timer",
"sec");
516 double sample_detector_distance = 0, sample_detector_distance_offset = 0, sample_si_window_distance = 0;
519 if (metadata.find(
"Motor_Positions/sample_det_dist") != metadata.end()) {
521 from_string<double>(sample_detector_distance, metadata[
"Motor_Positions/sample_det_dist"], std::dec);
522 sample_detector_distance *= 1000.0;
523 addRunProperty<double>(
"sample-detector-distance", sample_detector_distance,
"mm");
524 sample_detector_distance_offset =
525 addRunProperty<double>(metadata,
"Header/tank_internal_offset",
"sample-detector-distance-offset",
"mm");
526 sample_si_window_distance =
527 addRunProperty<double>(metadata,
"Header/sample_to_flange",
"sample-si-window-distance",
"mm");
531 from_string<double>(sample_detector_distance, metadata[
"Motor_Positions/flange_det_dist"], std::dec);
532 sample_detector_distance *= 1000.0;
533 addRunProperty<double>(
"sample-detector-distance-offset", 0,
"mm");
534 addRunProperty<double>(
"sample-detector-distance", sample_detector_distance,
"mm");
535 sample_si_window_distance =
536 addRunProperty<double>(metadata,
"Header/sample_to_flange",
"sample-si-window-distance",
"mm");
539 double total_sample_detector_distance;
540 if (metadata.find(
"Motor_Positions/sdd") != metadata.end()) {
543 from_string<double>(total_sample_detector_distance, metadata[
"Motor_Positions/sdd"], std::dec);
544 total_sample_detector_distance *= 1000.0;
545 sample_detector_distance = total_sample_detector_distance;
547 addRunProperty<double>(
"sample-detector-distance-offset", 0,
"mm");
548 addRunProperty<double>(
"sample-detector-distance", sample_detector_distance,
"mm");
549 addRunProperty<double>(
"sample-si-window-distance", 0,
"mm");
551 g_log.
debug() <<
"Sample-Detector-Distance from SDD tag = " << total_sample_detector_distance <<
'\n';
554 total_sample_detector_distance =
555 sample_detector_distance + sample_detector_distance_offset + sample_si_window_distance;
557 addRunProperty<double>(
"total-sample-detector-distance", total_sample_detector_distance,
"mm");
561 auto p = std::make_unique<Mantid::Kernel::TimeSeriesProperty<double>>(
"sdd");
562 p->addValue(DateAndTime::getCurrentTime(), total_sample_detector_distance);
575 from_string<double>(
detectorTranslation, metadata[
"Motor_Positions/detector_trans"], std::dec);
578 auto p = std::make_unique<Mantid::Kernel::TimeSeriesProperty<double>>(
"detector-translation");
595 loadInst->setPropertyValue(
"InstrumentName", inst_name);
599 }
catch (std::invalid_argument &) {
601 }
catch (std::runtime_error &) {
602 g_log.
information(
"Unable to successfully run LoadInstrument Child Algorithm");
626 g_log.
notice() <<
"Rotating Wing Detector " << angle <<
" degrees." <<
'\n';
629 auto p = std::make_unique<Mantid::Kernel::TimeSeriesProperty<double>>(
"rotangle");
631 p->addValue(DateAndTime::getCurrentTime(), angle);
643 if (metadata.find(
"Header/sans_spice_xml_format_version") != metadata.end()) {
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
#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.
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.
This class stores information regarding an experimental run as a series of log entries.
A property class for workspaces.
void setBeamTrapRunProperty(std::map< std::string, std::string > &metadata)
Sets the beam trap as Run Property There's several beamstrap position.
const std::string name() const override
Algorithm's name for identification overriding a virtual method.
int confidence(Kernel::FileDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
static const int nMonitors
Number of monitors.
DataObjects::Workspace2D_sptr m_workspace
void setWavelength(std::map< std::string, std::string > &metadata)
Gets the wavelength and wavelength spread from the metadata and sets them as class attributes.
Mantid::Types::Core::DateAndTime m_endTime
std::pair< int, int > parseDetectorDimensions(const std::string &)
Parse the 2 integers of the form: INT32[192,256].
void runLoadInstrument(const std::string &inst_name, const DataObjects::Workspace2D_sptr &localWorkspace)
Run LoadInstrument Child Algorithm.
double m_wavelength_input
Mantid::Types::Core::DateAndTime m_startTime
void addMetadataAsRunProperties(const std::map< std::string, std::string > &)
Adds map of the form key:value as Workspace run properties.
void detectorTranslation(std::map< std::string, std::string > &metadata)
Puts a numeric series in the log with the value of detector translation.
void detectorDistance(std::map< std::string, std::string > &metadata)
Calculates the detector distances and sets them as Run properties Here fog starts: GPSANS: distance =...
double m_sansSpiceXmlFormatVersion
void throwException(Poco::XML::Element const *elem, const std::string &name, const std::string &fileName)
This method throws not found error if a element is not found in the xml file.
std::vector< int > getData(const std::string &)
Parses the data dimensions and stores them as member variables Reads the data and returns a vector.
void init() override
Overwrites Algorithm method.
T addRunProperty(std::map< std::string, std::string > &metadata, const std::string &oldName, const std::string &newName, const std::string &units="")
Inserts a property in the run with a new name!
void setSansSpiceXmlFormatVersion(std::map< std::string, std::string > &metadata)
void setMetadataAsRunProperties(std::map< std::string, std::string > &metadata)
void rotateDetector(const double &)
This will rotate the detector named componentName around z-axis.
Mantid::DataHandling::XmlHandler m_xmlHandler
void exec() override
Overwrites Algorithm method.
double m_wavelength_spread_input
void setInputPropertiesAsMemberProperties()
Get the input algorithm properties and sets them as class attributes.
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.
Exception for when an item is not found in a collection.
Marks code as not implemented yet.
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.
void notice(const std::string &msg)
Logs at notice level.
void error(const std::string &msg)
Logs at error level.
void information(const std::string &msg)
Logs at information level.
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...
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
bool from_string(T &t, const std::string &s, std::ios_base &(*f)(std::ios_base &))
void store_value(const DataObjects::Workspace2D_sptr &ws, int specID, double value, double error, double wavelength, double dwavelength)
Convenience function to store a detector value into a given spectrum.
std::shared_ptr< Workspace2D > Workspace2D_sptr
shared pointer to Mantid::DataObjects::Workspace2D
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.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Describes the direction (within an algorithm) of a Property.
@ Output
An output workspace.