Mantid
Loading...
Searching...
No Matches
MDLeanEvent.h
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#pragma once
8
9#include "MantidDataObjects/DllConfig.h"
13#include <algorithm>
14#include <cmath>
15#include <cstring>
16#include <numeric>
17#include <stdexcept>
18#include <string>
19#include <vector>
20
21namespace Mantid {
22namespace DataObjects {
23
44template <size_t nd> class MDLeanEvent;
45
46template <size_t nd> void swap(MDLeanEvent<nd> &first, MDLeanEvent<nd> &second);
47
58struct EventAccessor {};
59
60template <size_t nd> class MANTID_DATAOBJECTS_DLL MDLeanEvent {
61public:
67
68 template <class Accessor>
74 struct AccessFor {
75 static std::enable_if_t<std::is_same<EventAccessor, typename Accessor::EventAccessType>::value>
77 event.convertToCoordinates(space);
78 }
79 static std::enable_if_t<std::is_same<EventAccessor, typename Accessor::EventAccessType>::value>
81 event.convertToIndex(space);
82 }
83 static
84 typename std::enable_if<std::is_same<EventAccessor, typename Accessor::EventAccessType>::value, MortonT>::type
85 getIndex(const MDLeanEvent<nd> &event) {
86 return event.index;
87 }
88 };
89 template <class Accessor> friend struct AccessFor;
90
91protected:
95 float signal;
96
102
108#pragma pack(push, 1)
109 union {
110 coord_t center[nd];
112 };
113#pragma pack(pop)
114
115private:
123 index = morton_index::coordinatesToIndex<nd, IntT, MortonT>(center, space);
124 }
125
133 auto coords = morton_index::indexToCoordinates<nd, IntT, MortonT>(index, space);
134 for (unsigned i = 0; i < nd; ++i)
135 center[i] = coords[i];
136 }
137
138public:
139 /* Will be keeping functions inline for (possible?) performance improvements
140 */
141
142 // Enum to flag this templated type as NOT a full md event type.
143 enum { is_full_mdevent = false };
144
145 //---------------------------------------------------------------------------------------------
147 MDLeanEvent() : signal(1.0), errorSquared(1.0) {}
148
149 //---------------------------------------------------------------------------------------------
155 MDLeanEvent(const double signal, const double errorSquared)
156 : signal(float(signal)), errorSquared(float(errorSquared)) {}
157
158 //---------------------------------------------------------------------------------------------
164 MDLeanEvent(const float signal, const float errorSquared) : signal(signal), errorSquared(errorSquared) {}
165
166 //---------------------------------------------------------------------------------------------
174 MDLeanEvent(const float signal, const float errorSquared, const coord_t *centers)
175 : signal(signal), errorSquared(errorSquared) {
176 for (size_t i = 0; i < nd; i++)
177 center[i] = centers[i];
178 }
179 //---------------------------------------------------------------------------------------------
187 MDLeanEvent(const double signal, const double errorSquared, const coord_t *centers)
188 : signal(float(signal)), errorSquared(float(errorSquared)) {
189 for (size_t i = 0; i < nd; i++)
190 center[i] = centers[i];
191 }
192
193#ifdef COORDT_IS_FLOAT
194 //---------------------------------------------------------------------------------------------
202 MDLeanEvent(const float signal, const float errorSquared, const double *centers)
203 : signal(signal), errorSquared(errorSquared) {
204 for (size_t i = 0; i < nd; i++)
205 center[i] = static_cast<coord_t>(centers[i]);
206 }
207#endif
208 //---------------------------------------------------------------------------------------------
212 MDLeanEvent(const MDLeanEvent &rhs) : signal(rhs.signal), errorSquared(rhs.errorSquared) {
213 for (size_t i = 0; i < nd; i++)
214 center[i] = rhs.center[i];
215 }
216
217 //---------------------------------------------------------------------------------------------
218 friend void swap<nd>(MDLeanEvent &first, MDLeanEvent &second);
219
221 swap(*this, other);
222 return *this;
223 }
224
228 coord_t getCenter(const size_t n) const { return center[n]; }
229
230 //---------------------------------------------------------------------------------------------
234 const coord_t *getCenter() const { return center; }
235
236 //---------------------------------------------------------------------------------------------
241 coord_t *getCenterNonConst() { return center; }
242
243 //---------------------------------------------------------------------------------------------
248 void setCenter(const size_t n, const coord_t value) { center[n] = value; }
249
250#ifdef COORDT_IS_FLOAT
251 //---------------------------------------------------------------------------------------------
256 void setCenter(const size_t n, const double value) { center[n] = static_cast<coord_t>(value); }
257#endif
258
259 //---------------------------------------------------------------------------------------------
264 void setCoords(const coord_t *centers) {
265 for (size_t i = 0; i < nd; i++)
266 center[i] = centers[i];
267 }
268
269 //---------------------------------------------------------------------------------------------
272 size_t getNumDims() const { return nd; }
273
274 //---------------------------------------------------------------------------------------------
277 float getSignal() const { return signal; }
278
279 //---------------------------------------------------------------------------------------------
282 float getErrorSquared() const { return errorSquared; }
283
284 //---------------------------------------------------------------------------------------------
291 float getError() const { return float(sqrt(errorSquared)); }
292
293 //---------------------------------------------------------------------------------------------
296 void setSignal(const float newSignal) { signal = newSignal; }
297
298 //---------------------------------------------------------------------------------------------
301 void setErrorSquared(const float newerrorSquared) { errorSquared = newerrorSquared; }
302
303 //---------------------------------------------------------------------------------------------
305 static std::string getTypeName() { return "MDLeanEvent"; }
306
307 //---------------------------------------------------------------------------------------------
310 uint16_t getExpInfoIndex() const { return 0; }
311
312 //---------------------------------------------------------------------------------------------
316 uint16_t getGoniometerIndex() const { return 0; }
317
318 //---------------------------------------------------------------------------------------------
321 int32_t getDetectorID() const { return 0; }
322
323 /* static method used to convert vector of lean events into vector of their
324 coordinates & signal and error
325 @param events -- vector of events
326 @return data -- vector of events coordinates, their signal and error
327 casted to coord_t type
328 @return ncols -- the number of colunts in the data (it is nd+2 here but
329 may be different for other data types)
330 @return totalSignal -- total signal in the vector of events
331 @return totalErr -- total error corresponting to the vector of events
332 */
333 static inline void eventsToData(const std::vector<MDLeanEvent<nd>> &mdLeanEvents, std::vector<coord_t> &data,
334 size_t &ncols, double &totalSignal, double &totalErrSq) {
335 ncols = nd + 2;
336 size_t nEvents = mdLeanEvents.size();
337 data.resize(nEvents * ncols);
338
339 totalSignal = 0;
340 totalErrSq = 0;
341
342 size_t dataIndex(0);
343 for (const MDLeanEvent<nd> &mdLeanEvent : mdLeanEvents) {
344 data[dataIndex++] = static_cast<coord_t>(mdLeanEvent.signal);
345 data[dataIndex++] = static_cast<coord_t>(mdLeanEvent.errorSquared);
346 for (size_t d = 0; d < nd; d++)
347 data[dataIndex++] = mdLeanEvent.center[d];
348 // Track the total signal
349 totalSignal += signal_t(mdLeanEvent.signal);
350 totalErrSq += signal_t(mdLeanEvent.errorSquared);
351 }
352 }
353
354 /* static method used to convert vector of data into vector of lean events
355 @return coord -- vector of events coordinates, their signal and error
356 casted to coord_t type
357 @param events -- vector of events
358 @param reserveMemory -- reserve memory for events copying. Set to false if
359 one wants to add new events to the existing one.
360 */
361 static inline void dataToEvents(const std::vector<coord_t> &coord, std::vector<MDLeanEvent<nd>> &events,
362 bool reserveMemory = true) {
363 // Number of columns = number of dimensions + 2 (signal/error)
364 size_t numColumns = (nd + 2);
365 size_t numEvents = coord.size() / numColumns;
366 if (numEvents * numColumns != coord.size())
367 throw(std::invalid_argument("wrong input array of data to convert to "
368 "lean events, suspected column data for "
369 "different dimensions/(type of) events "));
370
371 if (reserveMemory) // Reserve the amount of space needed. Significant speed
372 // up (~30% thanks to this)
373 {
374 events.clear();
375 events.reserve(numEvents);
376 }
377 for (size_t i = 0; i < numEvents; i++) {
378 // Index into the data array
379 size_t ii = i * numColumns;
380
381 // Point directly into the data block for the centers.
382 const coord_t *centers = &(coord[ii + 2]);
383
384 // Create the event with signal, error squared, and the centers
385 events.emplace_back(static_cast<signal_t>(coord[ii]), static_cast<signal_t>(coord[ii + 1]), centers);
386 }
387 }
388};
389
390template <size_t ND> void swap(MDLeanEvent<ND> &first, MDLeanEvent<ND> &second) {
391 std::swap(first.signal, second.signal);
392 std::swap(first.errorSquared, second.errorSquared);
393 // Index always of the same size as center
394 std::swap(first.index, second.index);
395}
396
397} // namespace DataObjects
398} // namespace Mantid
const std::vector< double > & rhs
double value
The value of the point.
Definition: FitMW.cpp:51
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
Templated class holding data about a neutron detection event in N-dimensions (for example,...
Definition: MDLeanEvent.h:60
MDLeanEvent(const float signal, const float errorSquared, const coord_t *centers)
Constructor with signal and error and an array of centers.
Definition: MDLeanEvent.h:174
uint16_t getExpInfoIndex() const
Definition: MDLeanEvent.h:310
size_t getNumDims() const
Returns the number of dimensions in the event.
Definition: MDLeanEvent.h:272
MDLeanEvent()
Empty constructor.
Definition: MDLeanEvent.h:147
void convertToIndex(const morton_index::MDSpaceBounds< nd > &space)
Calculate Morton index for center coordinates for given space and ovveride the memory used for storin...
Definition: MDLeanEvent.h:122
MDLeanEvent & operator=(MDLeanEvent other)
Definition: MDLeanEvent.h:220
static void eventsToData(const std::vector< MDLeanEvent< nd > > &mdLeanEvents, std::vector< coord_t > &data, size_t &ncols, double &totalSignal, double &totalErrSq)
Definition: MDLeanEvent.h:333
const coord_t * getCenter() const
Returns the array of coordinates.
Definition: MDLeanEvent.h:234
void setCoords(const coord_t *centers)
Sets all the coordinates.
Definition: MDLeanEvent.h:264
float getSignal() const
Returns the signal (weight) of this event.
Definition: MDLeanEvent.h:277
coord_t * getCenterNonConst()
Returns the array of coordinates, as a pointer to a non-const array.
Definition: MDLeanEvent.h:241
float errorSquared
The square of the error carried in this event.
Definition: MDLeanEvent.h:101
MDLeanEvent(const double signal, const double errorSquared)
Constructor with signal and error.
Definition: MDLeanEvent.h:155
typename morton_index::IndexTypes< nd, coord_t >::IntType IntT
Additional index type defenitions.
Definition: MDLeanEvent.h:65
void setSignal(const float newSignal)
Set the signal of the event.
Definition: MDLeanEvent.h:296
MDLeanEvent(const float signal, const float errorSquared)
Constructor with signal and error.
Definition: MDLeanEvent.h:164
float getError() const
Returns the error (not squared) of this event.
Definition: MDLeanEvent.h:291
float getErrorSquared() const
Returns the error (squared) of this event.
Definition: MDLeanEvent.h:282
uint16_t getGoniometerIndex() const
Definition: MDLeanEvent.h:316
MDLeanEvent(const double signal, const double errorSquared, const coord_t *centers)
Constructor with signal and error and an array of centers.
Definition: MDLeanEvent.h:187
static std::string getTypeName()
Definition: MDLeanEvent.h:305
static void dataToEvents(const std::vector< coord_t > &coord, std::vector< MDLeanEvent< nd > > &events, bool reserveMemory=true)
Definition: MDLeanEvent.h:361
void setCenter(const size_t n, const coord_t value)
Sets the n-th coordinate axis value.
Definition: MDLeanEvent.h:248
typename morton_index::IndexTypes< nd, coord_t >::MortonType MortonT
Definition: MDLeanEvent.h:66
void setErrorSquared(const float newerrorSquared)
Set the squared error of the event.
Definition: MDLeanEvent.h:301
void convertToCoordinates(const morton_index::MDSpaceBounds< nd > &space)
Calculate coordinates of the center of event from it Morton index in known space and oveerride index ...
Definition: MDLeanEvent.h:132
float signal
The signal (aka weight) from the neutron event.
Definition: MDLeanEvent.h:95
MDLeanEvent(const MDLeanEvent &rhs)
Copy constructor.
Definition: MDLeanEvent.h:212
coord_t getCenter(const size_t n) const
Definition: MDLeanEvent.h:228
std::size_t numEvents(::NeXus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames, const std::string &prefix, const NexusHDF5Descriptor &descriptor)
Get the number of events in the currently opened group.
void swap(MDLeanEvent< nd > &first, MDLeanEvent< nd > &second)
Helper class which provides the Collimation Length for SANS instruments.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition: MDTypes.h:27
double signal_t
Typedef for the signal recorded in a MDBox, etc.
Definition: MDTypes.h:36
Eigen::Array< float, static_cast< int >(ND), 2 > MDSpaceBounds
Definition: Types.h:31
Structure to mark the classes, which can switch the "physical" meaning of the union used in MDLeanEve...
Definition: MDLeanEvent.h:58
Internal structure to avoid the direct exposing of API functions, which change the state of event (sw...
Definition: MDLeanEvent.h:74
static std::enable_if_t< std::is_same< EventAccessor, typename Accessor::EventAccessType >::value > convertToCoordinates(MDLeanEvent< nd > &event, const morton_index::MDSpaceBounds< nd > &space)
Definition: MDLeanEvent.h:76
static std::enable_if_t< std::is_same< EventAccessor, typename Accessor::EventAccessType >::value > convertToIndex(MDLeanEvent< nd > &event, const morton_index::MDSpaceBounds< nd > &space)
Definition: MDLeanEvent.h:80
static std::enable_if< std::is_same< EventAccessor, typenameAccessor::EventAccessType >::value, MortonT >::type getIndex(const MDLeanEvent< nd > &event)
Definition: MDLeanEvent.h:85
typename UnderlyingInt< FP >::type IntType
Definition: Types.h:85
typename MortonIndex< ND *sizeof(FP)>::type MortonType
Definition: Types.h:84