Mantid
Loading...
Searching...
No Matches
MDEventWSWrapper.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 +
7#include <utility>
8
11
12namespace Mantid::MDAlgorithms {
13
21template <size_t nd> void MDEventWSWrapper::createEmptyEventWS(const MDWSDescription &description) {
22
23 std::shared_ptr<DataObjects::MDEventWorkspace<DataObjects::MDEvent<nd>, nd>> ws =
24 std::shared_ptr<DataObjects::MDEventWorkspace<DataObjects::MDEvent<nd>, nd>>(
26
27 auto numBins = description.getNBins();
28 size_t nBins(10); // HACK. this means we have 10 bins artificially. This can't
29 // be right.
30 // Give all the dimensions
31 for (size_t d = 0; d < nd; d++) {
32 if (!numBins.empty())
33 nBins = numBins[d];
34
35 Geometry::MDHistoDimension *dim = nullptr;
36 if (d < 3 && description.isQ3DMode()) {
37 // We should have frame and scale information that we can use correctly
38 // for our Q dimensions.
39 auto mdFrame = description.getFrame(d);
40
41 dim = new Geometry::MDHistoDimension(description.getDimNames()[d], description.getDimIDs()[d], *mdFrame,
42 Mantid::coord_t(description.getDimMin()[d]),
43 Mantid::coord_t(description.getDimMax()[d]), nBins);
44
45 } else {
46 Mantid::Geometry::GeneralFrame frame(description.getDimNames()[d], description.getDimUnits()[d]);
47 dim = new Geometry::MDHistoDimension(description.getDimNames()[d], description.getDimIDs()[d], frame,
48 Mantid::coord_t(description.getDimMin()[d]),
49 Mantid::coord_t(description.getDimMax()[d]), nBins);
50 }
51
52 ws->addDimension(Geometry::MDHistoDimension_sptr(dim));
53 }
54 ws->initialize();
55
56 m_Workspace = ws;
57}
59template <> void MDEventWSWrapper::createEmptyEventWS<0>(const MDWSDescription & /*unused*/) {
60 throw(std::invalid_argument("MDEventWSWrapper:createEmptyEventWS can not be "
61 "initiated with 0 dimensions"));
62}
63
84template <size_t nd>
85void MDEventWSWrapper::addMDDataND(const float *sigErr, const uint16_t *expInfoIndex, const uint16_t *goniometerIndex,
86 const uint32_t *detId, const coord_t *Coord, size_t dataSize) const {
87
88 auto *const pWs = dynamic_cast<DataObjects::MDEventWorkspace<DataObjects::MDEvent<nd>, nd> *>(m_Workspace.get());
89 if (pWs) {
90 for (size_t i = 0; i < dataSize; i++) {
91 pWs->addEvent(DataObjects::MDEvent<nd>(*(sigErr + 2 * i), *(sigErr + 2 * i + 1), *(expInfoIndex + i),
92 *(goniometerIndex + i), *(detId + i), (Coord + i * nd)));
93 }
94 } else {
95 auto *const pLWs =
97
98 if (!pLWs)
99 throw std::runtime_error("Bad Cast: Target MD workspace to add events "
100 "does not correspond to type of events you try "
101 "to add to it");
102
103 for (size_t i = 0; i < dataSize; i++) {
104 pLWs->addEvent(DataObjects::MDLeanEvent<nd>(*(sigErr + 2 * i), *(sigErr + 2 * i + 1), (Coord + i * nd)));
105 }
106 }
107}
108
111template <>
112void MDEventWSWrapper::addMDDataND<0>(const float * /*unused*/, const uint16_t * /*unused*/,
113 const uint16_t * /*unused*/, const uint32_t * /*unused*/,
114 const coord_t * /*unused*/, size_t /*unused*/) const {
115 throw(std::invalid_argument(" class has not been initiated, can not add data "
116 "to 0-dimensional workspace"));
117}
118
119template <size_t nd> void MDEventWSWrapper::splitBoxList() {
120 auto *const pWs = dynamic_cast<DataObjects::MDEventWorkspace<DataObjects::MDEvent<nd>, nd> *>(m_Workspace.get());
121 if (!pWs)
122 throw(std::bad_cast());
123
124 m_needSplitting = false;
125}
126
127template <> void MDEventWSWrapper::splitBoxList<0>() {
128 throw(std::invalid_argument(" class has not been initiated, can not split "
129 "0-dimensional workspace boxes"));
130}
131
133template <size_t nd> void MDEventWSWrapper::calcCentroidND() {
134
135 auto *const pWs =
137 if (!pWs)
138 throw(std::bad_cast());
139
140 // pWs->getBox()->refreshCentroid(NULL);
141}
144template <> void MDEventWSWrapper::calcCentroidND<0>() {
145 throw(std::invalid_argument(" class has not been initiated"));
146}
147
151 if (m_NDimensions == 0)
152 throw(std::invalid_argument("The workspace has not been initiated yet"));
153 return size_t(m_NDimensions);
154}
155
166
167 if (WSD.nDimensions() < 1 || WSD.nDimensions() > MAX_N_DIM) {
168 std::string ERR = " Number of requested MD dimensions: " + std::to_string(WSD.nDimensions()) +
169 " exceeds maximal number of MD dimensions: " + std::to_string(static_cast<int>(MAX_N_DIM)) +
170 " instantiated during compilation\n";
171 throw(std::invalid_argument(ERR));
172 }
173
174 m_NDimensions = static_cast<int>(WSD.nDimensions());
175 // call the particular function, which creates the workspace with n_dimensions
176 (this->*(wsCreator[m_NDimensions]))(WSD);
177
178 // set up the matrix, which convert momentums from Q in orthogonal crystal
179 // coordinate system and units of Angstrom^-1 to hkl or orthogonal hkl or
180 // whatever
181 m_Workspace->setWTransf(WSD.m_Wtransf);
182 return m_Workspace;
183}
184
188 m_Workspace = std::move(spWS);
189 m_NDimensions = m_Workspace->getNumDims();
190}
191
204void MDEventWSWrapper::addMDData(std::vector<float> &sigErr, std::vector<uint16_t> &expInfoIndex,
205 std::vector<uint16_t> &goniometerIndex, std::vector<uint32_t> &detId,
206 std::vector<coord_t> &Coord, size_t dataSize) const {
207
208 if (dataSize == 0)
209 return;
210 // perform the actual dimension-dependent addition
211 (this->*(mdEvAddAndForget[m_NDimensions]))(&sigErr[0], &expInfoIndex[0], &goniometerIndex[0], &detId[0], &Coord[0],
212 dataSize);
213}
214
221 // decrease the sp count by one
222 m_Workspace.reset();
223 // mark the number of dimensions invalid;
224 m_NDimensions = 0;
225}
226
227// the class instantiated by compiler at compilation time and generates the map,
228// between the number of dimensions and the function, which process this number
229// of dimensions
230template <size_t i> class LOOP {
231public:
232 static inline void EXEC(MDEventWSWrapper *pH) {
234 pH->wsCreator[i] = &MDEventWSWrapper::createEmptyEventWS<i>;
235 pH->mdEvAddAndForget[i] = &MDEventWSWrapper::addMDDataND<i>;
236 pH->mdCalCentroid[i] = &MDEventWSWrapper::calcCentroidND<i>;
237 pH->mdBoxListSplitter[i] = &MDEventWSWrapper::splitBoxList<i>;
238 }
239};
240// the class terminates the compitlation-time metaloop and sets up functions
241// which process 0-dimension workspace operations
242template <> class LOOP<0> {
243public:
244 static inline void EXEC(MDEventWSWrapper *pH) {
245 pH->wsCreator[0] = &MDEventWSWrapper::createEmptyEventWS<0>;
246 pH->mdEvAddAndForget[0] = &MDEventWSWrapper::addMDDataND<0>;
247 pH->mdCalCentroid[0] = &MDEventWSWrapper::calcCentroidND<0>;
248 pH->mdBoxListSplitter[0] = &MDEventWSWrapper::splitBoxList<0>;
249 }
250};
251
253MDEventWSWrapper::MDEventWSWrapper() : m_NDimensions(0), m_needSplitting(false) {
254 wsCreator.resize(MAX_N_DIM + 1);
255 mdEvAddAndForget.resize(MAX_N_DIM + 1);
256 mdCalCentroid.resize(MAX_N_DIM + 1);
257 mdBoxListSplitter.resize(MAX_N_DIM + 1);
259}
260
261} // namespace Mantid::MDAlgorithms
MDEventFactory : collection of methods to create MDLeanEvent* instances, by specifying the number of ...
Templated class for the multi-dimensional event workspace.
size_t addEvent(const MDE &event)
Templated class holding data about a neutron detection event in N-dimensions (for example,...
Definition: MDEvent.h:36
Templated class holding data about a neutron detection event in N-dimensions (for example,...
Definition: MDLeanEvent.h:60
GeneralFrame : Any MDFrame that isn't related to momemtum transfer.
Definition: GeneralFrame.h:21
static void EXEC(MDEventWSWrapper *pH)
static void EXEC(MDEventWSWrapper *pH)
void releaseWorkspace()
releases the shared pointer to the MD workspace, stored by the class and makes the class instance und...
std::vector< fpCreateWS > wsCreator
VECTORS OF FUNCTION POINTERS to different number of dimensions methdods vector holding function point...
void addMDDataND(const float *sigErr, const uint16_t *expInfoIndex, const uint16_t *goniometerIndex, const uint32_t *detId, const coord_t *Coord, size_t dataSize) const
templated by number of dimensions function to add multidimensional data to the workspace it is expect...
void addMDData(std::vector< float > &sigErr, std::vector< uint16_t > &expInfoIndex, std::vector< uint16_t > &goniometerIndex, std::vector< uint32_t > &detId, std::vector< coord_t > &Coord, size_t dataSize) const
add the data to the internal workspace.
size_t m_NDimensions
actual number of dimensions, initiated in current MD workspace; 0 if not initated;
size_t nDimensions() const
get number of dimensions, for the workspace, currently accessed by the algorithm.
API::IMDEventWorkspace_sptr m_Workspace
pointer to taret MD workspace:
void setMDWS(API::IMDEventWorkspace_sptr spWS)
initiate the class with pointer to existing MD workspace
std::vector< fpVoidMethod > mdBoxListSplitter
vector holding function pointers to the code, which split list of boxes need splitting
std::vector< fpVoidMethod > mdCalCentroid
vector holding function pointers to the code, which refreshes centroid (could it be moved to IMD?...
API::IMDEventWorkspace_sptr createEmptyMDWS(const MDWSDescription &WSD)
function creates empty MD event workspace with given parameters (workspace factory) and stores intern...
void createEmptyEventWS(const MDWSDescription &description)
internal helper function to create empty MDEventWorkspace with nd dimensions and set up internal poin...
void calcCentroidND()
helper function to refresh centroid on MDEventWorkspace with nd dimensions
std::vector< fpAddData > mdEvAddAndForget
vector holding function pointers to the code, which adds diffrent dimension number events to the work...
helper class describes the properties of target MD workspace, which should be obtained as the result ...
bool isQ3DMode() const
Is the algorithm running in Q3D mode?
std::vector< std::string > getDimIDs() const
Geometry::MDFrame_uptr getFrame(size_t d) const
Retrieve the md frame.
std::vector< std::string > getDimNames() const
std::vector< size_t > getNBins() const
std::vector< std::string > getDimUnits() const
std::vector< double > getDimMin() const
std::vector< double > getDimMax() const
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
std::shared_ptr< MDHistoDimension > MDHistoDimension_sptr
Shared pointer to a MDHistoDimension.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition: MDTypes.h:27
std::string to_string(const wide_integer< Bits, Signed > &n)