Mantid
Loading...
Searching...
No Matches
SaveIsawQvector.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 +
8
16
17#include <algorithm>
18#include <fstream>
19
20using namespace Mantid::API;
21using namespace Mantid::Kernel;
22using namespace Mantid::DataObjects;
23using Mantid::Types::Event::TofEvent;
24
25namespace Mantid::MDAlgorithms {
26
27// Register the algorithm into the AlgorithmFactory
28DECLARE_ALGORITHM(SaveIsawQvector)
29
30
31const std::string ELASTIC("Elastic");
33const std::string Q3D("Q3D");
35const std::size_t DIMS(3);
37const std::size_t BUFF_SIZE(DIMS * sizeof(float));
38
39//----------------------------------------------------------------------------------------------
41const std::string SaveIsawQvector::name() const { return "SaveIsawQvector"; }
42
44int SaveIsawQvector::version() const { return 1; }
45
47const std::string SaveIsawQvector::category() const { return "DataHandling\\Isaw"; }
48
49//----------------------------------------------------------------------------------------------
53 auto ws_valid = std::make_shared<CompositeValidator>();
54 //
55 ws_valid->add<InstrumentValidator>();
56 // the validator which checks if the workspace has axis and any units
57 ws_valid->add<WorkspaceUnitValidator>("TOF");
58
59 declareProperty(std::make_unique<WorkspaceProperty<EventWorkspace>>("InputWorkspace", "", Direction::Input, ws_valid),
60 "An input EventWorkspace with units along X-axis and defined "
61 "instrument with defined sample");
62 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::OptionalSave, ".bin"),
63 "Optional path to an hkl file to save. Vectors returned if no file "
64 "requested.");
65 declareProperty("RightHanded", true, "Save the Q-vector as k_f - k_i");
66 declareProperty("ISAWcoords", true, "Save the Q-vector with y gravitationally up and x pointing downstream");
67 std::vector<double> Qx_save, Qy_save, Qz_save;
68 declareProperty("Qx_vector", Qx_save, "The name of the vector in which to store the list of Qx", Direction::Output);
69 declareProperty("Qy_vector", Qy_save, "The name of the vector in which to store the list of Qy", Direction::Output);
70 declareProperty("Qz_vector", Qz_save, "The name of the vector in which to store the list of Qz", Direction::Output);
71}
72
73//----------------------------------------------------------------------------------------------
77 // get the input workspace
78 EventWorkspace_sptr wksp = getProperty("InputWorkspace");
79
80 // this only works for unweighted events
81 if (wksp->getEventType() != API::TOF) {
82 throw std::runtime_error("SaveIsawQvector only works for raw events");
83 }
84 // error out if there are not events
85 if (wksp->getNumberEvents() <= 0) {
86 throw std::runtime_error("SaveIsawQvector does not work for empty event lists");
87 }
88
89 // open the output file
90 std::string filename = getPropertyValue("Filename");
91 std::ofstream handle;
92 if (!filename.empty()) {
93 handle.open(filename.c_str(), std::ios::out | std::ios::binary);
94 if (!handle.is_open())
95 throw std::runtime_error("Failed to open file for writing");
96 }
97 // set up a descripter of where we are going
98 this->initTargetWSDescr(wksp);
99
100 size_t coord_map[DIMS] = {0, 1, 2}; // x->x, y->y, z->z
101 double coord_signs[DIMS] = {1., 1., 1.}; // signs are unchanged
102 if (this->getProperty("ISAWcoords")) {
103 // x -> z
104 coord_map[0] = 2;
105
106 // y -> x
107 coord_map[1] = 0;
108
109 // z -> y
110 coord_map[2] = 1;
111 }
112 if (this->getProperty("RightHanded")) {
113 // everything changes sign
114 std::transform(std::cbegin(coord_signs), std::cend(coord_signs), std::begin(coord_signs),
115 [](const auto value) { return -value; });
116 }
117
118 // units conersion helper
119 UnitsConversionHelper unitConv;
120 unitConv.initialize(m_targWSDescr, "Momentum");
121
122 // initialize the MD coordinates conversion class
124 q_converter->initialize(m_targWSDescr);
125
126 // set up the progress bar
127 const size_t numSpectra = wksp->getNumberHistograms();
128 Progress prog(this, 0.5, 1.0, numSpectra);
129
130 // loop through the eventlists
131 float buffer[DIMS];
132 std::vector<double> Qx_save, Qy_save, Qz_save;
133 for (std::size_t i = 0; i < numSpectra; ++i) {
134 // get a reference to the event list
135 const EventList &events = wksp->getSpectrum(i);
136
137 // check to see if the event list is empty
138 if (events.empty()) {
139 prog.report();
140 continue; // nothing to do
141 }
142
143 // update which pixel is being converted
144 std::vector<coord_t> locCoord(DIMS, 0.);
145 unitConv.updateConversion(i);
146 q_converter->calcYDepCoordinates(locCoord, i);
147
148 // loop over the events
149 double signal(1.); // ignorable garbage
150 double errorSq(1.); // ignorable garbage
151 const std::vector<TofEvent> &raw_events = events.getEvents();
152 for (const auto &raw_event : raw_events) {
153 double val = unitConv.convertUnits(raw_event.tof());
154 q_converter->calcMatrixCoord(val, locCoord, signal, errorSq);
155 for (size_t dim = 0; dim < DIMS; ++dim) {
156 buffer[dim] = static_cast<float>(coord_signs[dim] * locCoord[coord_map[dim]]);
157 }
158 if (filename.empty()) {
159 Qx_save.emplace_back(static_cast<double>(buffer[0]));
160 Qy_save.emplace_back(static_cast<double>(buffer[1]));
161 Qz_save.emplace_back(static_cast<double>(buffer[2]));
162 } else
163 handle.write(reinterpret_cast<char *>(buffer), BUFF_SIZE);
164 } // end of loop over events in list
165
166 prog.report();
167 } // end of loop over spectra
168 if (filename.empty()) {
169 setProperty("Qx_vector", Qx_save);
170 setProperty("Qy_vector", Qy_save);
171 setProperty("Qz_vector", Qz_save);
172 } else
173 handle.close(); // cleanup
174}
175
183 m_targWSDescr.setMinMax(std::vector<double>(3, -2000.), std::vector<double>(3, 2000.));
186
187 // generate the detectors table
188 Mantid::API::Algorithm_sptr childAlg = createChildAlgorithm("PreprocessDetectorsToMD", 0., .5);
189 childAlg->setProperty("InputWorkspace", wksp);
190 childAlg->executeAsChildAlg();
191
192 DataObjects::TableWorkspace_sptr table = childAlg->getProperty("OutputWorkspace");
193 if (!table)
194 throw(std::runtime_error("Can not retrieve results of \"PreprocessDetectorsToMD\""));
195 else
197}
198
199} // namespace Mantid::MDAlgorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
double value
The value of the point.
Definition: FitMW.cpp:51
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
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
@ OptionalSave
to specify a file to write to but an empty string is
Definition: FileProperty.h:50
A validator which checks that a workspace has a valid instrument.
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A property class for workspaces.
A validator which checks that the unit of the workspace referred to by a WorkspaceProperty is the exp...
A class for holding :
Definition: EventList.h:56
std::vector< Types::Event::TofEvent > & getEvents()
Return the list of TofEvents contained.
Definition: EventList.cpp:780
bool empty() const
Much like stl containers, returns true if there is nothing in the event list.
Definition: EventList.cpp:1158
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
Definition: ProgressBase.h:51
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
void setMinMax(const std::vector< double > &minVal, const std::vector< double > &maxVal)
function sets up min-max values to the dimensions, described by the class
std::string AlgID
the string which describes ChildAlgorithm, used to convert source ws to target MD ws.
void buildFromMatrixWS(const API::MatrixWorkspace_sptr &pWS, const std::string &QMode, const std::string &dEMode, const std::vector< std::string > &dimPropertyNames=std::vector< std::string >())
method builds MD Event ws description from a matrix workspace and the transformations,...
DataObjects::TableWorkspace_const_sptr m_PreprDetTable
void setLorentsCorr(bool On=false)
do we need to perform Lorentz corrections
void init() override
Initialize the algorithm's properties.
void initTargetWSDescr(const DataObjects::EventWorkspace_sptr &wksp)
SaveIsawQvector::initTargetWSDescr Initialize the output information for the MD conversion framework.
const std::string category() const override
Algorithm's category for identification.
const std::string name() const override
Algorithm's name for identification.
int version() const override
Algorithm's version for identification.
void exec() override
Execute the algorithm.
void updateConversion(size_t i)
Method updates unit conversion given the index of detector parameters in the array of detectors.
void initialize(const MDWSDescription &targetWSDescr, const std::string &unitsTo, bool forceViaTOF=false)
Initialize unit conversion helper This method is interface to internal initialize method,...
double convertUnits(double val) const
do actual unit conversion from input to oputput data
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
Definition: Algorithm.h:61
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
const std::string Q3D("Q3D")
Only convert to Q-vector.
const std::size_t DIMS(3)
Q-vector is always three dimensional.
std::shared_ptr< MDTransfInterface > MDTransf_sptr
const std::size_t BUFF_SIZE(DIMS *sizeof(float))
Constant for the size of the buffer to write to disk.
const std::string ELASTIC("Elastic")
This only works for diffraction.
@ Input
An input workspace.
Definition: Property.h:53
@ Output
An output workspace.
Definition: Property.h:54