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:576
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.
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
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
@ Load
allowed here which will be passed to the algorithm
Definition: FileProperty.h:52
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 the spectrum number of this spectrum.
Definition: ISpectrum.cpp:127
void addProperty(Kernel::Property *prop, bool overwrite=false)
Add data to the object in the form of a property.
Definition: LogManager.h:79
This class stores information regarding an experimental run as a series of log entries.
Definition: Run.h:38
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)
Definition: LoadSwans.cpp:232
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...
Definition: LoadSwans.cpp:263
std::map< uint32_t, std::vector< uint32_t > > loadData()
Load the data into a map.
Definition: LoadSwans.cpp:151
void placeDetectorInSpace()
Place the detector in space according to the distance and angle Needs in the IDF Parameters file the ...
Definition: LoadSwans.cpp:123
int version() const override
Algorithm's version for identification.
Definition: LoadSwans.cpp:41
void setMetaDataAsWorkspaceProperties(const std::vector< double > &metadata)
Definition: LoadSwans.cpp:222
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 ...
Definition: LoadSwans.cpp:186
void loadInstrument()
Run the Child Algorithm LoadInstrument.
Definition: LoadSwans.cpp:102
void setTimeAxis()
Get shortest and longest tof from the Parameters file and sets the time axis Properties must be prese...
Definition: LoadSwans.cpp:249
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:56
void addEventQuickly(const Types::Event::TofEvent &event)
Append an event to the histogram, without clearing the cache, to make it faster.
Definition: EventList.h:104
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:114
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
OptionalBool : Tri-state bool.
Definition: OptionalBool.h:25
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:233
Kernel::Logger g_log("ExperimentInfo")
static logger object
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.
Definition: LoadHelper.cpp:472
void moveComponent(const API::MatrixWorkspace_sptr &ws, const std::string &componentName, const Kernel::V3D &newPos)
LoadHelper::moveComponent.
Definition: LoadHelper.cpp:454
Kernel::V3D getComponentPosition(const API::MatrixWorkspace_sptr &ws, const std::string &componentName)
LoadHelper::getComponentPosition.
Definition: LoadHelper.cpp:489
constexpr double deg2rad
Defines units/enum for Crystal work.
Definition: AngleUnits.h:20
@ Output
An output workspace.
Definition: Property.h:54