Mantid
Loading...
Searching...
No Matches
LoadSwans.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 +
13
14#include <algorithm>
15#include <boost/tokenizer.hpp>
16#include <fstream>
17#include <map>
18
19namespace Mantid::DataHandling {
20
21using namespace Mantid::Kernel;
22using namespace Mantid::Geometry;
23using namespace Mantid::API;
24using namespace Mantid::DataObjects;
25using Mantid::Types::Event::TofEvent;
26
27// Register the algorithm into the AlgorithmFactory
29
30//----------------------------------------------------------------------------------------------
33LoadSwans::LoadSwans() = default;
34
35//----------------------------------------------------------------------------------------------
36
38const std::string LoadSwans::name() const { return "LoadSwans"; }
39
41int LoadSwans::version() const { return 1; }
42
44const std::string LoadSwans::category() const { return "DataHandling\\Text;SANS\\DataHandling"; }
45
47const std::string LoadSwans::summary() const { return "Loads SNS SWANS Data"; }
48
56 // since this is a test loader, the confidence will always be 0!
57 // I don't want the Load algorithm to pick this one!
58 if (descriptor.extension() != ".dat")
59 return 1;
60 else
61 return 0;
62}
63
64//----------------------------------------------------------------------------------------------
68 declareProperty(std::make_unique<FileProperty>("FilenameData", "", FileProperty::Load, ".dat"),
69 "The name of the text file to read, including its full or "
70 "relative path. The file extension must be .dat.");
71
72 declareProperty(std::make_unique<FileProperty>("FilenameMetaData", "", FileProperty::Load, "meta.dat"),
73 "The name of the text file to read, including its full or "
74 "relative path. The file extension must be meta.dat.");
75
76 declareProperty(std::make_unique<WorkspaceProperty<EventWorkspace>>("OutputWorkspace", "", Direction::Output),
77 "The name to use for the output workspace");
78}
79
80//----------------------------------------------------------------------------------------------
84 m_ws = std::make_shared<Mantid::DataObjects::EventWorkspace>();
85 // Load instrument here to get the necessary Parameters from the XML file
88 std::map<uint32_t, std::vector<uint32_t>> eventMap = loadData();
89 std::vector<double> metadata = loadMetaData();
95 setProperty("OutputWorkspace", m_ws);
96}
97
103
104 auto loadInst = createChildAlgorithm("LoadInstrument");
105
106 // Now execute the Child Algorithm. Catch and log any error, but don't stop.
107 try {
108 loadInst->setPropertyValue("InstrumentName", m_instrumentName);
109 loadInst->setProperty<MatrixWorkspace_sptr>("Workspace", m_ws);
110 loadInst->setProperty("RewriteSpectraMap", Mantid::Kernel::OptionalBool(true));
111 loadInst->execute();
112 } catch (...) {
113 g_log.information("Cannot load the instrument definition.");
114 }
115}
116
124
125 std::string componentName = m_ws->getInstrument()->getStringParameter("detector-name")[0];
126 const double distance = static_cast<double>(m_ws->getInstrument()->getNumberParameter("detector-sample-distance")[0]);
127 // Make the angle negative to accommodate the sense of rotation.
128 const double angle = -m_ws->run().getPropertyValueAsType<double>("angle");
129
130 g_log.information() << "Moving detector " << componentName << " " << distance << " meters and " << angle
131 << " degrees.\n";
132
133 constexpr double deg2rad = M_PI / 180.0;
134 V3D pos = LoadHelper::getComponentPosition(m_ws, componentName);
135 double angle_rad = angle * deg2rad;
136 V3D newpos(distance * sin(angle_rad), pos.Y(), distance * cos(angle_rad));
137 LoadHelper::moveComponent(m_ws, componentName, newpos);
138
139 // Apply a local rotation to stay perpendicular to the beam
140 constexpr V3D axis(0.0, 1.0, 0.0);
141 Quat rotation(angle, axis);
143}
144
151std::map<uint32_t, std::vector<uint32_t>> LoadSwans::loadData() {
152
153 std::string filename = getPropertyValue("FilenameData");
154 std::ifstream input(filename, std::ifstream::binary | std::ios::ate);
155 input.seekg(0);
156
157 m_ws->initialize(m_detector_size, 1, 1);
158
159 std::map<uint32_t, std::vector<uint32_t>> eventMap;
160
161 while (input.is_open()) {
162 if (input.eof())
163 break;
164 uint32_t tof = 0;
165 input.read(reinterpret_cast<char *>(&tof), sizeof(tof));
166 tof -= static_cast<uint32_t>(1e9);
167 tof = static_cast<uint32_t>(tof * 0.1);
168
169 uint32_t pos = 0;
170 input.read(reinterpret_cast<char *>(&pos), sizeof(pos));
171 if (pos < 400000) {
172 g_log.warning() << "Detector index invalid: " << pos << '\n';
173 continue;
174 }
175 pos -= 400000;
176 eventMap[pos].emplace_back(tof);
177 }
178 return eventMap;
179}
180
186std::vector<double> LoadSwans::loadMetaData() {
187 std::vector<double> metadata;
188 std::string filename = getPropertyValue("FilenameMetaData");
189 std::ifstream infile(filename);
190 if (infile.fail()) {
191 g_log.error("Error reading file " + filename);
192 throw Exception::FileError("Unable to read data in File:", filename);
193 }
194 std::string line;
195 while (getline(infile, line)) {
196 // line with data, need to be parsed by white spaces
197 if (!line.empty() && line[0] != '#') {
198 g_log.debug() << "Metadata parsed line: " << line << '\n';
201 metadata.reserve(tokenizer.size());
202 std::transform(tokenizer.cbegin(), tokenizer.cend(), std::back_inserter(metadata),
203 [](const auto &token) { return boost::lexical_cast<double>(token); });
204 }
205 }
206 if (metadata.size() < 6) {
207 g_log.error("Expecting length >=6 for metadata arguments!");
208 throw Exception::NotFoundError("Number of arguments for metadata must be at least 6. Found: ", metadata.size());
209 }
210 return metadata;
211}
212
213/*
214 * Known metadata positions to date:
215 * 0 - run number
216 * 1 - wavelength
217 * 2 - chopper frequency
218 * 3 - time offset
219 * 4 - ??
220 * 5 - angle
221 */
222void LoadSwans::setMetaDataAsWorkspaceProperties(const std::vector<double> &metadata) {
223 API::Run &runDetails = m_ws->mutableRun();
224 runDetails.addProperty<double>("wavelength", metadata[1]);
225 runDetails.addProperty<double>("angle", metadata[5]);
226}
227
228/*
229 * Puts all events from the map into the WS
230 *
231 */
232void LoadSwans::loadDataIntoTheWorkspace(const std::map<uint32_t, std::vector<uint32_t>> &eventMap) {
233 for (const auto &position : eventMap) {
234 EventList &el = m_ws->getSpectrum(position.first);
235 el.setSpectrumNo(position.first);
236 el.setDetectorID(position.first);
237 for (const auto &event : position.second) {
238 el.addEventQuickly(TofEvent(event));
239 }
240 }
241}
242
250 const unsigned int shortest_tof =
251 static_cast<unsigned int>(m_ws->getInstrument()->getNumberParameter("shortest-tof")[0]);
252 const unsigned int longest_tof =
253 static_cast<unsigned int>(m_ws->getInstrument()->getNumberParameter("longest-tof")[0]);
254 // Now, create a default X-vector for histogramming, with just 2 bins.
255 auto axis = HistogramData::BinEdges{static_cast<double>(shortest_tof), static_cast<double>(longest_tof)};
256 m_ws->setAllX(axis);
257}
258
264 const unsigned int x_size =
265 static_cast<unsigned int>(m_ws->getInstrument()->getNumberParameter("number-of-x-pixels")[0]);
266 const unsigned int y_size =
267 static_cast<unsigned int>(m_ws->getInstrument()->getNumberParameter("number-of-y-pixels")[0]);
268 return x_size * y_size;
269}
270
271} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
double position
Definition GetAllEi.cpp:154
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
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.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
Kernel::Logger & g_log
Definition Algorithm.h:422
@ Load
allowed here which will be passed to the algorithm
void setDetectorID(const detid_t detID)
Clear the list of detector IDs, then add one.
Definition ISpectrum.cpp:84
void setSpectrumNo(specnum_t num)
Sets the spectrum number of this spectrum.
void addProperty(Kernel::Property *prop, bool overwrite=false)
Add data to the object in the form of a property.
Definition LogManager.h:91
This class stores information regarding an experimental run as a series of log entries.
Definition Run.h:35
A property class for workspaces.
LoadSwans : Test Loader to read data from the LDRD new SWANS detector.
Definition LoadSwans.h:21
void exec() override
Execute the algorithm.
Definition LoadSwans.cpp:83
const std::string m_instrumentName
Definition LoadSwans.h:49
void init() override
Initialize the algorithm's properties.
Definition LoadSwans.cpp:67
const std::string category() const override
Algorithm's category for identification.
Definition LoadSwans.cpp:44
const std::string name() const override
Algorithms name for identification.
Definition LoadSwans.cpp:38
void loadDataIntoTheWorkspace(const std::map< uint32_t, std::vector< uint32_t > > &eventMap)
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
Definition LoadSwans.cpp:47
unsigned int getDetectorSize()
From the Parameters XML file gets number-of-x-pixels and number-of-y-pixels and calculates the detect...
std::map< uint32_t, std::vector< uint32_t > > loadData()
Load the data into a map.
void placeDetectorInSpace()
Place the detector in space according to the distance and angle Needs in the IDF Parameters file the ...
int version() const override
Algorithm's version for identification.
Definition LoadSwans.cpp:41
void setMetaDataAsWorkspaceProperties(const std::vector< double > &metadata)
DataObjects::EventWorkspace_sptr m_ws
Definition LoadSwans.h:44
std::vector< double > loadMetaData()
Load metadata file witch to date is just a line of of double values Parses this file and put it into ...
void loadInstrument()
Run the Child Algorithm LoadInstrument.
void setTimeAxis()
Get shortest and longest tof from the Parameters file and sets the time axis Properties must be prese...
int confidence(Kernel::FileDescriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
Definition LoadSwans.cpp:55
A class for holding :
Definition EventList.h:57
void addEventQuickly(const Types::Event::TofEvent &event)
Append an event to the histogram, without clearing the cache, to make it faster.
Definition EventList.h:105
Records the filename and the description of failure.
Definition Exception.h:98
Exception for when an item is not found in a collection.
Definition Exception.h:145
Defines a wrapper around an open file.
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 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.
Class for quaternions.
Definition Quat.h:39
@ TOK_IGNORE_EMPTY
ignore empty tokens
@ TOK_TRIM
remove leading and trailing whitespace from tokens
std::size_t size() const noexcept
Get the total number of tokens.
ConstIterator cend() const
Const iterator referring to the past-the-end element in the container.
ConstIterator cbegin() const
Const iterator referring to first element in the container.
Class for 3D vectors.
Definition V3D.h:34
constexpr double Y() const noexcept
Get y.
Definition V3D.h:239
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
void rotateComponent(const API::MatrixWorkspace_sptr &ws, const std::string &componentName, const Kernel::Quat &rot)
LoadHelper::rotateComponent.
void moveComponent(const API::MatrixWorkspace_sptr &ws, const std::string &componentName, const Kernel::V3D &newPos)
LoadHelper::moveComponent.
Kernel::V3D getComponentPosition(const API::MatrixWorkspace_sptr &ws, const std::string &componentName)
LoadHelper::getComponentPosition.
constexpr double deg2rad
Defines units/enum for Crystal work.
Definition AngleUnits.h:20
@ Output
An output workspace.
Definition Property.h:54