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
60// Apply visibility attribute for non-MSVC builds (needed for clang/OSX).
61#if defined(_MSC_VER)
62template <size_t nd> class MDLeanEvent {
63#else
64template <size_t nd> class MANTID_DATAOBJECTS_DLL MDLeanEvent {
65#endif
66public:
72
73 template <class Accessor>
79 struct AccessFor {
80 static std::enable_if_t<std::is_same<EventAccessor, typename Accessor::EventAccessType>::value>
82 event.convertToCoordinates(space);
83 }
84 static std::enable_if_t<std::is_same<EventAccessor, typename Accessor::EventAccessType>::value>
86 event.convertToIndex(space);
87 }
88 static
89 typename std::enable_if<std::is_same<EventAccessor, typename Accessor::EventAccessType>::value, MortonT>::type
90 getIndex(const MDLeanEvent<nd> &event) {
91 return event.index;
92 }
93 };
94 template <class Accessor> friend struct AccessFor;
95
96protected:
100 float signal;
101
107
113#pragma pack(push, 1)
114 union {
115 coord_t center[nd];
117 };
118#pragma pack(pop)
119
120private:
128 index = morton_index::coordinatesToIndex<nd, IntT, MortonT>(center, space);
129 }
130
138 auto coords = morton_index::indexToCoordinates<nd, IntT, MortonT>(index, space);
139 for (unsigned i = 0; i < nd; ++i)
140 center[i] = coords[i];
141 }
142
143public:
144 /* Will be keeping functions inline for (possible?) performance improvements
145 */
146
147 // Enum to flag this templated type as NOT a full md event type.
148 enum { is_full_mdevent = false };
149
150 //---------------------------------------------------------------------------------------------
152 MDLeanEvent() : signal(1.0), errorSquared(1.0) {}
153
154 //---------------------------------------------------------------------------------------------
160 MDLeanEvent(const double signal, const double errorSquared)
161 : signal(float(signal)), errorSquared(float(errorSquared)) {}
162
163 //---------------------------------------------------------------------------------------------
169 MDLeanEvent(const float signal, const float errorSquared) : signal(signal), errorSquared(errorSquared) {}
170
171 //---------------------------------------------------------------------------------------------
179 MDLeanEvent(const float signal, const float errorSquared, const coord_t *centers)
180 : signal(signal), errorSquared(errorSquared) {
181 for (size_t i = 0; i < nd; i++)
182 center[i] = centers[i];
183 }
184 //---------------------------------------------------------------------------------------------
192 MDLeanEvent(const double signal, const double errorSquared, const coord_t *centers)
193 : signal(float(signal)), errorSquared(float(errorSquared)) {
194 for (size_t i = 0; i < nd; i++)
195 center[i] = centers[i];
196 }
197
198#ifdef COORDT_IS_FLOAT
199 //---------------------------------------------------------------------------------------------
207 MDLeanEvent(const float signal, const float errorSquared, const double *centers)
208 : signal(signal), errorSquared(errorSquared) {
209 for (size_t i = 0; i < nd; i++)
210 center[i] = static_cast<coord_t>(centers[i]);
211 }
212#endif
213 //---------------------------------------------------------------------------------------------
217 MDLeanEvent(const MDLeanEvent &rhs) : signal(rhs.signal), errorSquared(rhs.errorSquared) {
218 for (size_t i = 0; i < nd; i++)
219 center[i] = rhs.center[i];
220 }
221
222 //---------------------------------------------------------------------------------------------
223 friend void swap<nd>(MDLeanEvent &first, MDLeanEvent &second);
224
226 swap(*this, other);
227 return *this;
228 }
229
233 coord_t getCenter(const size_t n) const { return center[n]; }
234
235 //---------------------------------------------------------------------------------------------
239 const coord_t *getCenter() const { return center; }
240
241 //---------------------------------------------------------------------------------------------
246 coord_t *getCenterNonConst() { return center; }
247
248 //---------------------------------------------------------------------------------------------
253 void setCenter(const size_t n, const coord_t value) { center[n] = value; }
254
255#ifdef COORDT_IS_FLOAT
256 //---------------------------------------------------------------------------------------------
261 void setCenter(const size_t n, const double value) { center[n] = static_cast<coord_t>(value); }
262#endif
263
264 //---------------------------------------------------------------------------------------------
269 void setCoords(const coord_t *centers) {
270 for (size_t i = 0; i < nd; i++)
271 center[i] = centers[i];
272 }
273
274 //---------------------------------------------------------------------------------------------
277 size_t getNumDims() const { return nd; }
278
279 //---------------------------------------------------------------------------------------------
282 float getSignal() const { return signal; }
283
284 //---------------------------------------------------------------------------------------------
287 float getErrorSquared() const { return errorSquared; }
288
289 //---------------------------------------------------------------------------------------------
296 float getError() const { return float(sqrt(errorSquared)); }
297
298 //---------------------------------------------------------------------------------------------
301 void setSignal(const float newSignal) { signal = newSignal; }
302
303 //---------------------------------------------------------------------------------------------
306 void setErrorSquared(const float newerrorSquared) { errorSquared = newerrorSquared; }
307
308 //---------------------------------------------------------------------------------------------
310 static std::string getTypeName() { return "MDLeanEvent"; }
311
312 //---------------------------------------------------------------------------------------------
315 uint16_t getExpInfoIndex() const { return 0; }
316
317 //---------------------------------------------------------------------------------------------
321 uint16_t getGoniometerIndex() const { return 0; }
322
323 //---------------------------------------------------------------------------------------------
326 int32_t getDetectorID() const { return 0; }
327
328 /* static method used to convert vector of lean events into vector of their
329 coordinates & signal and error
330 @param events -- vector of events
331 @return data -- vector of events coordinates, their signal and error
332 casted to coord_t type
333 @return ncols -- the number of colunts in the data (it is nd+2 here but
334 may be different for other data types)
335 @return totalSignal -- total signal in the vector of events
336 @return totalErr -- total error corresponting to the vector of events
337 */
338 static inline void eventsToData(const std::vector<MDLeanEvent<nd>> &mdLeanEvents, std::vector<coord_t> &data,
339 size_t &ncols, double &totalSignal, double &totalErrSq) {
340 ncols = nd + 2;
341 size_t nEvents = mdLeanEvents.size();
342 data.resize(nEvents * ncols);
343
344 totalSignal = 0;
345 totalErrSq = 0;
346
347 size_t dataIndex(0);
348 for (const MDLeanEvent<nd> &mdLeanEvent : mdLeanEvents) {
349 data[dataIndex++] = static_cast<coord_t>(mdLeanEvent.signal);
350 data[dataIndex++] = static_cast<coord_t>(mdLeanEvent.errorSquared);
351 for (size_t d = 0; d < nd; d++)
352 data[dataIndex++] = mdLeanEvent.center[d];
353 // Track the total signal
354 totalSignal += signal_t(mdLeanEvent.signal);
355 totalErrSq += signal_t(mdLeanEvent.errorSquared);
356 }
357 }
358
359 /* static method used to convert vector of data into vector of lean events
360 @return coord -- vector of events coordinates, their signal and error
361 casted to coord_t type
362 @param events -- vector of events
363 @param reserveMemory -- reserve memory for events copying. Set to false if
364 one wants to add new events to the existing one.
365 */
366 static inline void dataToEvents(const std::vector<coord_t> &coord, std::vector<MDLeanEvent<nd>> &events,
367 bool reserveMemory = true) {
368 // Number of columns = number of dimensions + 2 (signal/error)
369 size_t numColumns = (nd + 2);
370 size_t numEvents = coord.size() / numColumns;
371 if (numEvents * numColumns != coord.size())
372 throw(std::invalid_argument("wrong input array of data to convert to "
373 "lean events, suspected column data for "
374 "different dimensions/(type of) events "));
375
376 if (reserveMemory) // Reserve the amount of space needed. Significant speed
377 // up (~30% thanks to this)
378 {
379 events.clear();
380 events.reserve(numEvents);
381 }
382 for (size_t i = 0; i < numEvents; i++) {
383 // Index into the data array
384 size_t ii = i * numColumns;
385
386 // Point directly into the data block for the centers.
387 const coord_t *centers = &(coord[ii + 2]);
388
389 // Create the event with signal, error squared, and the centers
390 events.emplace_back(static_cast<signal_t>(coord[ii]), static_cast<signal_t>(coord[ii + 1]), centers);
391 }
392 }
393};
394
395template <size_t ND> void swap(MDLeanEvent<ND> &first, MDLeanEvent<ND> &second) {
396 std::swap(first.signal, second.signal);
397 std::swap(first.errorSquared, second.errorSquared);
398 // Index always of the same size as center
399 std::swap(first.index, second.index);
400}
401
402} // namespace DataObjects
403} // 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
Templated class holding data about a neutron detection event in N-dimensions (for example,...
Definition MDLeanEvent.h:64
MDLeanEvent(const float signal, const float errorSquared, const coord_t *centers)
Constructor with signal and error and an array of centers.
size_t getNumDims() const
Returns the number of dimensions in the event.
MDLeanEvent()
Empty constructor.
void convertToIndex(const morton_index::MDSpaceBounds< nd > &space)
Calculate Morton index for center coordinates for given space and ovveride the memory used for storin...
MDLeanEvent & operator=(MDLeanEvent other)
static void eventsToData(const std::vector< MDLeanEvent< nd > > &mdLeanEvents, std::vector< coord_t > &data, size_t &ncols, double &totalSignal, double &totalErrSq)
const coord_t * getCenter() const
Returns the array of coordinates.
void setCoords(const coord_t *centers)
Sets all the coordinates.
float getSignal() const
Returns the signal (weight) of this event.
coord_t * getCenterNonConst()
Returns the array of coordinates, as a pointer to a non-const array.
float errorSquared
The square of the error carried in this event.
MDLeanEvent(const double signal, const double errorSquared)
Constructor with signal and error.
typename morton_index::IndexTypes< nd, coord_t >::IntType IntT
Additional index type defenitions.
Definition MDLeanEvent.h:70
void setSignal(const float newSignal)
Set the signal of the event.
MDLeanEvent(const float signal, const float errorSquared)
Constructor with signal and error.
float getError() const
Returns the error (not squared) of this event.
float getErrorSquared() const
Returns the error (squared) of this event.
uint16_t getGoniometerIndex() const
MDLeanEvent(const double signal, const double errorSquared, const coord_t *centers)
Constructor with signal and error and an array of centers.
static std::string getTypeName()
static void dataToEvents(const std::vector< coord_t > &coord, std::vector< MDLeanEvent< nd > > &events, bool reserveMemory=true)
void setCenter(const size_t n, const coord_t value)
Sets the n-th coordinate axis value.
typename morton_index::IndexTypes< nd, coord_t >::MortonType MortonT
Definition MDLeanEvent.h:71
void setErrorSquared(const float newerrorSquared)
Set the squared error of the event.
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 ...
friend void swap(MDLeanEvent &first, MDLeanEvent &second)
float signal
The signal (aka weight) from the neutron event.
MDLeanEvent(const MDLeanEvent &rhs)
Copy constructor.
coord_t getCenter(const size_t n) const
std::size_t numEvents(Nexus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames, const std::string &prefix)
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:79
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:81
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:85
static std::enable_if< std::is_same< EventAccessor, typenameAccessor::EventAccessType >::value, MortonT >::type getIndex(const MDLeanEvent< nd > &event)
Definition MDLeanEvent.h:90
typename UnderlyingInt< FP >::type IntType
Definition Types.h:103
typename MortonIndex< ND *sizeof(FP)>::type MortonType
Definition Types.h:102