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
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.
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:65
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:66
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 ...
float signal
The signal (aka weight) from the neutron event.
Definition MDLeanEvent.h:95
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, const Nexus::NexusDescriptor &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:103
typename MortonIndex< ND *sizeof(FP)>::type MortonType
Definition Types.h:102