Skip to content
Snippets Groups Projects
Commit e072007d authored by Janik Zikovsky's avatar Janik Zikovsky
Browse files

Refs #2016: MDEvents namespace added (instead of MDEvent)

parent c634d888
No related merge requests found
Showing
with 1776 additions and 0 deletions
# Source files
set (SRC_FILES
# src/MDEventWorkspace.cpp
src/MDBox.cpp
)
# Header files
set (INC_FILES
inc/MantidMDEvents/MDEvent.h
inc/MantidMDEvents/IMDBox.h
inc/MantidMDEvents/MDBox.h
# inc/MantidMDEvents/MDEventWorkspace.h
inc/MantidMDEvents/MDDimensionExtents.h
)
# Test files. Other source files required.
set (TEST_FILES
)
set ( GMOCK_TEST_FILES
test/MDEventTest.h
test/MDBoxTest.h
)
# Add the target for this directory
add_library ( MDEvents ${SRC_FILES} ${INC_FILES})
# Set the name of the generated library
set_target_properties ( MDEvents PROPERTIES OUTPUT_NAME MantidMDEventss
COMPILE_DEFINITIONS IN_MANTID_MDEVENT )
# Add to the 'Framework' group in VS
set_property ( TARGET MDEvents PROPERTY FOLDER "Framework" )
# Find hdf5 libraries
if( WIN32 )
#Exact libraries will need to be refined for windows 64/32 bit as they are different in third_party.
# this allows studio using dll-s for hdf5
add_definitions ( -D_HDF5USEDLL_ )
set ( HDF5_INCLUDE_DIRS ${CMAKE_INCLUDE_PATH}/hdf5 )
# separate configuration files h5config.h for hdf5 in 32 and 64 bit versions
if ( CMAKE_CL_64 )
set ( HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS}/win64 )
else()
set ( HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS}/win32 )
endif()
# release hdf5dll.lib relates to hdf5.1.6 which does not have debug version when hdf5_18dll is release version for hdf5.1.8 and debug
# version for hdf5.1.8 is hdf5ddll.lib
set ( HDF5_LIBRARIES ${CMAKE_LIBRARY_PATH}/hdf5_18dll.lib )
else()
# unix build currently works wirh hdf1.6 linked against Nexus.
# Some preprocessor command should already be defined to distinguish between 5.1.6 and 5.1.8
find_package (HDF5 REQUIRED)
add_definitions ( -DHDF_1_6 )
endif()
include_directories(${HDF5_INCLUDE_DIRS} inc)
target_link_libraries ( MDEvents ${MANTIDLIBS} ${HDF5_LIBRARIES})
# Create test file projects
if ( CXXTEST_FOUND )
include_directories(${HDF5_INCLUDE_DIRS} inc)
if ( GMOCK_FOUND AND GTEST_FOUND )
cxxtest_add_test ( MDEventsTest ${TEST_FILES} ${GMOCK_TEST_FILES} )
target_link_libraries( MDEventsTest MDEvents ${MANTIDLIBS} ${HDF5_LIBRARIES} ${GMOCK_LIBRARIES} )
else ()
cxxtest_add_test ( MDEventsTest ${TEST_FILES} )
target_link_libraries( MDEventsTest MDEvents ${MANTIDLIBS} ${HDF5_LIBRARIES} )
endif ()
add_dependencies ( FrameworkTests MDEventsTest )
# Add to the 'FrameworkTests' group in VS
set_property ( TARGET MDEventsTest PROPERTY FOLDER "FrameworkTests" )
endif ()
#ifndef IMDBOX_H_
#define IMDBOX_H_
#include "MantidKernel/System.h"
#include "MantidMDEvents/MDPoint.h"
#include "MantidMDEvents/MDDimensionExtents.h"
#include "MantidAPI/IMDWorkspace.h"
namespace Mantid
{
namespace MDEvents
{
//===============================================================================================
/** Abstract Interface for a multi-dimensional event "box".
* To be subclassed by MDBox and MDGridBox
*
* A box is a container of MDPoint's within a certain range of values
* within the nd dimensions. This range defines a n-dimensional "box"
* or rectangular prism.
*
* @tparam nd :: the number of dimensions that each MDEvent will be tracking.
* an int > 0.
*
* @author Janik Zikovsky, SNS
* @date Dec 7, 2010
*
* */
template <size_t nd, size_t nv = 0, typename TE = char>
class DLLExport IMDBox
{
public:
IMDBox();
virtual void addPoint( const MDPoint<nd,nv,TE> & point) = 0;
virtual void clear() = 0;
virtual size_t getNPoints() const = 0;
virtual size_t getNumDims() const = 0;
virtual std::vector< MDPoint<nd,nv,TE> > * getPointsCopy();
virtual double getSignal() const;
virtual double getErrorSquared() const;
private:
/** Array of MDDimensionStats giving the extents and
* other stats on the box dimensions.
*/
MDDimensionExtents dimExtents[nd];
public:
/// Convenience typedef for a shared pointer to a this type of class
typedef boost::shared_ptr< IMDBox<nd,nv,TE> > sptr;
};
//===============================================================================================
/** Simple class which holds the extents (min/max)
* of a given dimension in a MD workspace or MDBox
*/
DLLExport class MDDimensionExtents
{
public:
/** Empty constructor - reset everything */
MDDimensionExtents() :
min( std::numeric_limits<CoordType>::max() ),
max( -std::numeric_limits<CoordType>::max() )
{ }
// ---- Public members ----------
/// Extent: minimum value in that dimension
CoordType min;
/// Extent: maximum value in that dimension
CoordType max;
};
//===============================================================================================
/** Simple class which holds statistics
* about a given dimension in a MD workspace or MDBox
*/
DLLExport class MDDimensionStats : public MDDimensionExtents
{
public:
/** Empty constructor - reset everything */
MDDimensionStats() :
MDDimensionExtents(),
total( 0 ),
approxVariance( 0 )
{ }
// ---- Public members ----------
/** Sum of the coordinate value of all points contained.
* Divide by the number of points to get the mean!
*/
CoordType total;
/** Approximate variance - used for quick std.deviation estimates.
*
* A running sum of (X - mean(X))^2, where mean(X) is calculated at the
* time of adding the point. This approximation gets better as the number of
* points increases.
*
* Divide by the number of points to get the square of the standard deviation!
*/
CoordType approxVariance;
};
}//namespace MDEvents
}//namespace Mantid
#endif /* MDBOX_H_ */
#ifndef IMDEVENTWORKSPACE_H_
#define IMDEVENTWORKSPACE_H_
#include "MantidKernel/System.h"
#include "MantidMDEvents/MDEvent.h"
#include "MantidAPI/IMDWorkspace.h"
namespace Mantid
{
namespace MDEvents
{
/** Abstract base class for multi-dimension event workspaces (MDEventWorkspace).
* This class will handle as much of the common operations as possible;
* but since MDEventWorkspace is a templated class, that makes some aspects
* impossible.
*
* @author Janik Zikovsky, SNS
* @date Dec 3, 2010
*
* */
DLLExport class IMDEventWorkspace // : public API::IMDWorkspace
{
public:
/** Returns the number of dimensions in this workspace */
virtual int getNumDims() const = 0;
/** Returns the total number of points (events) in this workspace */
virtual size_t getNPoints() const = 0;
/** Returns the number of bytes of memory
* used by the workspace. */
virtual size_t getMemoryUsed() const = 0;
};
}//namespace MDEvents
}//namespace Mantid
#endif /* IMDEVENTWORKSPACE_H_ */
#ifndef MDBOX_H_
#define MDBOX_H_
#include "MantidKernel/System.h"
#include "MantidMDEvents/MDEvent.h"
#include "MantidMDEvents/MDDimensionExtents.h"
#include "MantidAPI/IMDWorkspace.h"
namespace Mantid
{
namespace MDEvents
{
//===============================================================================================
/** Templated class for a multi-dimensional event "box".
*
* A box is a container of MDPoint's within a certain range of values
* within the nd dimensions. This range defines a n-dimensional "box"
* or rectangular prism.
*
* This class is a simple list of points with no more internal structure.
*
* @tparam nd :: the number of dimensions that each MDEvent will be tracking.
* an int > 0.
*
* @author Janik Zikovsky, SNS
* @date Dec 7, 2010
*
* */
template <size_t nd>
class DLLExport MDBox
{
public:
MDBox();
void addEvent( const MDEvent<nd> & point);
void clear();
size_t getNPoints() const;
size_t getNumDims() const;
std::vector< MDEvent<nd> > & getPoints();
double getSignal() const;
double getErrorSquared() const;
private:
/** Vector of MDEvent's, in no particular order.
* */
std::vector< MDEvent<nd> > data;
/** Array of MDDimensionExtents giving the extents and
* in each dimension.
*/
MDDimensionExtents dims[nd];
/** Total signal from all points within */
double signal;
/** Total error (squared) from all points within */
double errorSquared;
public:
/// Typedef for a shared pointer to a MDBox
typedef boost::shared_ptr<MDBox<nd> > sptr;
};
//===============================================================================================
/** Simple class which holds statistics
* about a given dimension in a MD workspace or MDBox
*/
DLLExport class MDDimensionStats : public MDDimensionExtents
{
public:
/** Empty constructor - reset everything */
MDDimensionStats() :
MDDimensionExtents(),
total( 0 ),
approxVariance( 0 )
{ }
// ---- Public members ----------
/** Sum of the coordinate value of all points contained.
* Divide by the number of points to get the mean!
*/
CoordType total;
/** Approximate variance - used for quick std.deviation estimates.
*
* A running sum of (X - mean(X))^2, where mean(X) is calculated at the
* time of adding the point. This approximation gets better as the number of
* points increases.
*
* Divide by the number of points to get the square of the standard deviation!
*/
CoordType approxVariance;
};
}//namespace MDEvents
}//namespace Mantid
#endif /* MDBOX_H_ */
#ifndef MDDIMENSIONEXTENTS_H_
#define MDDIMENSIONEXTENTS_H_
/*
* MDDimensionExtents.h
*
* Created on: Jan 14, 2011
* Author: Janik Zikovsky
*/
#include "MantidKernel/System.h"
#include "MantidMDEvents/MDPoint.h"
#include <limits>
namespace Mantid
{
namespace MDEvents
{
//===============================================================================================
/** Simple class that holds the extents (min/max)
* of a given dimension in a MD workspace or MDBox
*/
DLLExport class MDDimensionExtents
{
public:
/** Empty constructor - reset everything.
* */
MDDimensionExtents() :
min( std::numeric_limits<CoordType>::max() ),
max( -std::numeric_limits<CoordType>::max() )
{ }
// ---- Public members ----------
/// Extent: minimum value in that dimension
CoordType min;
/// Extent: maximum value in that dimension
CoordType max;
};
}//namespace MDEvents
}//namespace Mantid
#endif /* MDDIMENSIONEXTENTS_H_ */
#ifndef MDEVENT_H_
#define MDEVENT_H_
#include "MantidKernel/System.h"
#include <numeric>
#include <math.h>
namespace Mantid
{
namespace MDEvents
{
/** Typedef for the data type to use for coordinate axes.
* This could be a float or a double, depending on requirements.
* We can change this in order to compare
* performance/memory/accuracy requirements.
*/
typedef double CoordType;
/** Macro TMDE to make declaring template functions
* faster. Put this macro before function declarations.
*/
#define TMDE template <size_t nd>
/** Templated class holding data about a neutron detection event
* in N-dimensions (for example, Qx, Qy, Qz, E).
*
* Each neutron has a signal (a float, can be != 1) and an error. This
* is the same principle as the WeightedEvent in EventWorkspace's
*
* This class is meant to be as small in memory as possible, since there
* will be (many) billions of it.
* No virtual methods! This adds a vtable which uses lots of memory.
*
* @tparam nd :: the number of dimensions that each MDEvent will be tracking.
* an int > 0.
* @tparam ne :: the number of extra (non-float) ints of information to store.
* These could be detector ids, run numbers, etc. and will consist
* of signed 32-bit ints
*
* @author Janik Zikovsky, SNS
* @date Dec 3, 2010
*
* */
template <size_t nd>
class DLLExport MDEvent
{
private:
/** The signal (aka weight) from the neutron event.
* Will be exactly 1.0 unless modified at some point.
*/
float signal;
/** The square of the error carried in this event.
* Will be 1.0 unless modified by arithmetic.
* The square is used for more efficient calculations.
*/
float errorSquared;
/** The N-dimensional coordinates. A simple
* fixed-sized array of (floats or doubles).
*/
CoordType coord[nd];
public:
/* Will be keeping functions inline for (possible?) performance improvements */
//---------------------------------------------------------------------------------------------
/** Empty constructor */
MDEvent() :
signal(1.0), errorSquared(1.0)
{
}
//---------------------------------------------------------------------------------------------
/** Constructor with signal and error
*
* @param signal :: signal
* @param errorSquared :: errorSquared
* */
MDEvent(const float signal, const float errorSquared) :
signal(signal), errorSquared(errorSquared)
{
}
//---------------------------------------------------------------------------------------------
/** Constructor with signal and error and an array of coords
*
* @param signal :: signal
* @param errorSquared :: errorSquared
* @param coords :: pointer to a nd-sized array of values to set for all coordinates.
* */
MDEvent(const float signal, const float errorSquared, const CoordType * coords) :
signal(signal), errorSquared(errorSquared)
{
for (size_t i=0; i<nd; i++)
coord[i] = coords[i];
}
//---------------------------------------------------------------------------------------------
/** Copy constructor
*
* @param rhs :: mdevent to copy
* @param errorSquared :: errorSquared
* */
MDEvent(const MDEvent &rhs) :
signal(rhs.signal), errorSquared(rhs.errorSquared)
{
for (size_t i=0; i<nd; i++)
coord[i] = rhs.coord[i];
}
//---------------------------------------------------------------------------------------------
/** Returns the n-th coordinate axis value.
* @param n :: index (0-based) of the dimension you want.
* */
CoordType getCoord(const size_t n) const
{
return coord[n];
}
//---------------------------------------------------------------------------------------------
/** Sets the n-th coordinate axis value.
* @param n :: index (0-based) of the dimension you want to set
* @param value :: value to set.
* */
void setCoord(const size_t n, const CoordType value)
{
coord[n] = value;
}
//---------------------------------------------------------------------------------------------
/** Sets all the coordinates.
*
* @param coords :: pointer to a nd-sized array of the values to set.
* */
void setCoords(const CoordType * coords)
{
for (size_t i=0; i<nd; i++)
coord[i] = coords[i];
}
//---------------------------------------------------------------------------------------------
/** Returns the number of dimensions in the event.
* */
size_t getNumDims() const
{
return nd;
}
//---------------------------------------------------------------------------------------------
/** Returns the signal (weight) of this event.
* */
float getSignal() const
{
return signal;
}
//---------------------------------------------------------------------------------------------
/** Returns the error (squared) of this event.
* */
float getErrorSquared() const
{
return errorSquared;
}
//---------------------------------------------------------------------------------------------
/** Returns the error (not squared) of this event.
* */
float getError() const
{
return sqrt(errorSquared);
}
};
}//namespace MDEvents
}//namespace Mantid
#endif /* MDEVENT_H_ */
#ifndef MDEVENTWORKSPACE_H_
#define MDEVENTWORKSPACE_H_
#include "MantidKernel/System.h"
#include "MantidMDEvents/MDEvent.h"
#include "MantidMDEvents/MDPoint.h"
#include "MantidMDEvents/IMDEventWorkspace.h"
#include "MantidAPI/IMDWorkspace.h"
namespace Mantid
{
namespace MDEvents
{
/** Templated class for the multi-dimensional event workspace.
*
* Template parameters are the same as the MDPoint<> template params, and
* determine the basic MDPoint type used.
*
* @tparam nd :: the number of dimensions that each MDPoint will be tracking.
* an usigned int > 0.
*
* @tparam nv :: number of corner vertices per dimension. If only the
* center of the point is required, this == 0.
* If all corners are needed, this == nd.
* Default value == 0; meaning only the center coordinates are used.
*
* @tparam TE :: Type for a bit of extra data that can be carried around in each point.
* For example, this could be a single uint32 representing a detector ID.
* Or, if more complex things are required, this could be a struct with
* a few fields (should not be dynamically allocated like a pointer, in general).
* Default value == char[0] (occupying no memory).
*
* @author Janik Zikovsky, SNS
* @date Dec 3, 2010
*
* */
template <size_t nd, size_t nv=0, typename TE=char>
class DLLExport MDEventWorkspace : public IMDEventWorkspace
{
public:
/** Typedef of the basic MDPoint data type used in this MDEventWorkspace.
* This is for convenience; an algorithm can declare
* MyWorkspace::Point somePoint;
* without having to look up template parameters...
*/
typedef MDPoint<nd,nv,TE> Point;
/** Returns the number of dimensions in this workspace */
virtual int getNumDims() const;
/** Returns the total number of points (events) in this workspace */
virtual size_t getNPoints() const;
/** Returns the number of bytes of memory
* used by the workspace. */
virtual size_t getMemoryUsed() const;
/** Sample function returning the n-th point in the workspace.
* This may not be needed.
* */
Point getPoint(int n);
protected:
};
}//namespace MDEvents
}//namespace Mantid
#endif /* MDEVENTWORKSPACE_H_ */
#ifndef MDGRIDBOX_H_
#define MDGRIDBOX_H_
#include "MantidKernel/System.h"
#include "MantidMDEvents/MDPoint.h"
#include "MantidMDEvents/IMDEventWorkspace.h"
#include "MantidAPI/IMDWorkspace.h"
namespace Mantid
{
namespace MDEvents
{
// Forward declaration
class MDDimensionStats;
//===============================================================================================
/** Class for a gridded box that contains other boxes.
*
* A box is a container of MDPoint's within a certain range of values
* within the nd dimensions. This range defines a n-dimensional "box"
* or rectangular prism.
*
* This class is a simple list of points with no more internal structure.
*
* @tparam nd :: the number of dimensions that each MDEvent will be tracking.
* an int > 0.
*
* @author Janik Zikovsky, SNS
* @date Dec 7, 2010
*
* */
template <size_t nd, size_t nv = 0, typename TE = char>
class DLLExport MDGridBox
{
public:
MDGridBox();
virtual void addPoint( const MDPoint<nd,nv,TE> & point);
virtual void clear();
virtual MDDimensionStats getStats(const size_t dim) const;
virtual size_t getNPoints() const;
size_t getNumDims() const;
std::vector< MDPoint<nd,nv,TE> > & getPoints();
double getSignal() const;
double getErrorSquared() const;
private:
/** Vector of MDEvent's, in no particular order.
* */
std::vector< MDPoint<nd,nv,TE> > data;
/** Array of MDDimensionStats giving the extents and
* other stats on the box dimensions.
*/
MDDimensionStats dimStats[nd];
/** Total signal from all points within */
double signal;
/** Total error (squared) from all points within */
double errorSquared;
public:
/// Typedef for a shared pointer to a MDBox
typedef boost::shared_ptr<MDBox<nd> > sptr;
};
//===============================================================================================
/** Simple class which holds the extents (min/max)
* of a given dimension in a MD workspace or MDBox
*/
DLLExport class MDDimensionExtents
{
public:
/** Empty constructor - reset everything */
MDDimensionExtents() :
min( std::numeric_limits<CoordType>::max() ),
max( -std::numeric_limits<CoordType>::max() )
{ }
// ---- Public members ----------
/// Extent: minimum value in that dimension
CoordType min;
/// Extent: maximum value in that dimension
CoordType max;
};
//===============================================================================================
/** Simple class which holds statistics
* about a given dimension in a MD workspace or MDBox
*/
DLLExport class MDDimensionStats : public MDDimensionExtents
{
public:
/** Empty constructor - reset everything */
MDDimensionStats() :
MDDimensionExtents(),
total( 0 ),
approxVariance( 0 )
{ }
// ---- Public members ----------
/** Sum of the coordinate value of all points contained.
* Divide by the number of points to get the mean!
*/
CoordType total;
/** Approximate variance - used for quick std.deviation estimates.
*
* A running sum of (X - mean(X))^2, where mean(X) is calculated at the
* time of adding the point. This approximation gets better as the number of
* points increases.
*
* Divide by the number of points to get the square of the standard deviation!
*/
CoordType approxVariance;
};
}//namespace MDEvents
}//namespace Mantid
#endif /* MDBOX_H_ */
#ifndef MDPOINT_H_
#define MDPOINT_H_
#include "MantidKernel/System.h"
#include <numeric>
#include <math.h>
namespace Mantid
{
namespace MDEvents
{
/** Typedef for the data type to use for coordinate axes.
* This could be a float or a double, depending on requirements.
* We can change this in order to compare
* performance/memory/accuracy requirements.
*/
typedef double CoordType;
/** Macro TMDP to make declaring template functions
* faster. Put this macro before function declarations.
*
*/
#define TMDP template <size_t nd, size_t nv, typename TE>
/** Templated class holding data about a signal from neutron(s) at a given point
* in N-dimensions (for example, Qx, Qy, Qz, E).
*
* To be more general, the MDPoint class can hold a number of vertices
* that define the corners of the volume occupied.
*
* If MDPoint represents a single neutron event, in which case the corner
* vertices are not needed.
*
* Each point has a signal (a float, can be != 1.0) and an error. This
* is the same principle as the WeightedEvent in EventWorkspace's
*
* This class is meant to be as small in memory as possible, since there
* will be (many) billions of it.
* No virtual methods! This adds a vtable which uses lots of memory.
*
* @tparam nd :: the number of dimensions that each MDPoint will be tracking.
* an usigned int > 0.
*
* @tparam nv :: number of corner vertices per dimension. If only the
* center of the point is required, this == 0.
* If all corners are needed, this == nd.
* Default value == 0; meaning only the center coordinates are used.
*
* @tparam TE :: Type for a bit of extra data that can be carried around in each point.
* For example, this could be a single uint32 representing a detector ID.
* Or, if more complex things are required, this could be a struct with
* a few fields (should not be dynamically allocated like a pointer, in general).
* Default value == char[0] (occupying no memory).
*
* @author Janik Zikovsky, SNS
* @date Dec 3, 2010
*
* */
template <size_t nd, size_t nv=1, typename TE = char>
class DLLExport MDPoint
{
private:
/** The signal (aka weight) from the point.
* For a single neutron event, this will be exactly 1.0 unless modified at some point.
*/
float signal;
/** The square of the error carried in this point.
* For events, this will be 1.0 unless modified by arithmetic.
* N.B. The square is used for more efficient calculations.
*/
float errorSquared;
/** The N-dimensional coordinates of the center.
* A simple fixed-sized array of (floats or doubles).
*/
CoordType center[nd];
/** The vertices of each corner of the data point, describing
* a n-dimensional parallepiped.
*
* The vertices are stored as a nv*nd array of coordinate. There are
* nv vertices, each with nd dimensions.
*/
CoordType corners[nv*nd];
/** Template-specified bit of extra data that can be carried around
* in each point. For example, this could be a single uint32 representing
* a detector ID.
* Or, if more complex things are required, this could be a struct with
* a few fields (should not be dynamically allocated like a pointer, in general).
*/
TE extra;
public:
/* Will be keeping functions inline for (possible?) performance improvements */
//---------------------------------------------------------------------------------------------
/** Empty constructor */
MDPoint() :
signal(1.0), errorSquared(1.0)
{
}
//---------------------------------------------------------------------------------------------
/** Constructor with signal and error
*
* @param signal :: signal
* @param errorSquared :: errorSquared
* */
MDPoint(const float signal, const float errorSquared) :
signal(signal), errorSquared(errorSquared)
{
}
//---------------------------------------------------------------------------------------------
/** Constructor with signal and error and an array of coords
*
* @param signal :: signal
* @param errorSquared :: errorSquared
* @param centers :: pointer to a nd-sized array of values to set for all coordinates.
* */
MDPoint(const float signal, const float errorSquared, const CoordType * centers) :
signal(signal), errorSquared(errorSquared)
{
for (size_t i=0; i<nd; i++)
center[i] = centers[i];
}
//---------------------------------------------------------------------------------------------
/** Copy constructor
*
* @param rhs :: MDPoint to copy
* @param errorSquared :: errorSquared
* */
MDPoint(const MDPoint &rhs) :
signal(rhs.signal), errorSquared(rhs.errorSquared)
{
for (size_t i=0; i<nd; i++)
center[i] = rhs.center[i];
}
//---------------------------------------------------------------------------------------------
/** Returns the n-th center coordinate axis value.
* @param n :: index (0-based) of the dimension you want.
* */
CoordType getCenter(const size_t n) const
{
return center[n];
}
//---------------------------------------------------------------------------------------------
/** Returns a direct pointer to the center coordinates of this point,
* which is a [nd]-sized array.
* */
CoordType * getCenters()
{
return &center;
}
//---------------------------------------------------------------------------------------------
/** Returns the n-th corner coordinate axis value, one dimension at a time
*
* @param nvert :: index (0-based) of the corner to set
* @param ndim :: index (0-based) of the dimension you want to set. Must be 0 <= ndim <= nd
* */
CoordType getCorner(const size_t nvert, const size_t ndim) const
{
return corners[nvert*nd + ndim];
}
//---------------------------------------------------------------------------------------------
/** Returns a pointer to the n-th corner coordinate.
*
* @param nvert :: index (0-based) of the corner to set
* */
CoordType * getCorner(const size_t nvert)
{
return &corners[nvert*nd];
}
//---------------------------------------------------------------------------------------------
/** Returns a pointer to the corner vertices of this point,
* which is a [nd][nv] array.
* */
CoordType * getCorners()
{
return &corners;
}
//---------------------------------------------------------------------------------------------
/** Sets the n-th center coordinate axis value.
* @param n :: index (0-based) of the dimension you want to set
* @param value :: value to set.
* */
void setCenter(const size_t n, const CoordType value)
{
center[n] = value;
}
//---------------------------------------------------------------------------------------------
/** Sets all the center coordinates.
*
* @param coords :: pointer to a nd-sized array of the values to set.
* */
void setCenters(const CoordType * coords)
{
for (size_t i=0; i<nd; i++)
center[i] = coords[i];
}
//---------------------------------------------------------------------------------------------
/** Returns the n-th center coordinate axis value, one dimension at a time
*
* @param nvert :: index (0-based) of the corner to set
* @param ndim :: index (0-based) of the dimension you want to set. Must be 0 <= ndim <= nd
* @param value :: value to set.
* */
CoordType setCorner(const size_t nvert, const size_t ndim, const CoordType value)
{
corners[nvert*nd + ndim] = value;
}
//---------------------------------------------------------------------------------------------
/** Returns the n-th center coordinate axis value, one vertex at a time
*
* @param nvert :: index (0-based) of the corner to set
* @param coords :: an array, sized (nd), of coordinates to set.
* */
CoordType setCorner(const size_t nvert, const CoordType * coords)
{
for (size_t i=0; i<nd; i++)
corners[nvert*nd + i] = coords[i];
}
//---------------------------------------------------------------------------------------------
/** Sets all the center coordinates.
*
* @param coords :: pointer to a [nv*nd]-sized array of the values to set.
* */
void setCorners(const CoordType * coords)
{
for (size_t i=0; i<nv*nd; i++)
corners[i] = coords[i];
}
//---------------------------------------------------------------------------------------------
/** Returns the number of dimensions in the point (nd template parameter).
* */
size_t getNumDims() const
{
return nd;
}
//---------------------------------------------------------------------------------------------
/** Returns the signal (weight) of this point.
* */
float getSignal() const
{
return signal;
}
//---------------------------------------------------------------------------------------------
/** Returns the error (squared) of this point.
* */
float getErrorSquared() const
{
return errorSquared;
}
//---------------------------------------------------------------------------------------------
/** Returns the error (not squared) of this point.
* */
float getError() const
{
return sqrt(errorSquared);
}
//---------------------------------------------------------------------------------------------
/** Returns a reference to the extra type.
* */
TE & getExtra()
{
return extra;
}
//---------------------------------------------------------------------------------------------
/** Returns a const reference to the extra type.
* NOTE: For friend classes, you may access the .extra field directly. This will be faster.
*
* */
TE & getExtra() const
{
return extra;
}
//---------------------------------------------------------------------------------------------
/** Sets the extra data. The extra data is copied into this MDPoint.
* Note: It may be advantageous to use getExtra() and modify the
* extra field directly, since that function returns a reference.
*
* @param _extra :: reference to an instance of type TE.
* */
void setExtra(TE & _extra)
{
extra = _extra;
}
};
}//namespace MDEvents
}//namespace Mantid
#endif /* MDPOINT_H_ */
#include "MantidMDEvents/MDBox.h"
#include "MantidMDEvents/MDEvent.h"
namespace Mantid
{
namespace MDEvents
{
//-----------------------------------------------------------------------------------------------
/** Empty constructor */
TMDE
MDBox<nd>::MDBox() :
signal(0.0), errorSquared(0.0)
{
}
//-----------------------------------------------------------------------------------------------
/** Clear any points contained. */
TMDE
void MDBox<nd>::clear()
{
signal = 0.0;
errorSquared = 0.0;
data.clear();
}
//-----------------------------------------------------------------------------------------------
/** Returns the number of dimensions in this box */
TMDE
size_t MDBox<nd>::getNumDims() const
{
return nd;
}
//-----------------------------------------------------------------------------------------------
/** Returns the total number of points (events) in this box */
TMDE
size_t MDBox<nd>::getNPoints() const
{
return data.size();
}
//-----------------------------------------------------------------------------------------------
/** Returns a reference to the points vector contained within.
*/
TMDE
std::vector< MDEvent<nd> > & MDBox<nd>::getPoints()
{
return data;
}
//-----------------------------------------------------------------------------------------------
/** Returns the integrated signal from all points within.
*/
TMDE
double MDBox<nd>::getSignal() const
{
return signal;
}
//-----------------------------------------------------------------------------------------------
/** Returns the integrated error squared from all points within.
*/
TMDE
double MDBox<nd>::getErrorSquared() const
{
return errorSquared;
}
//-----------------------------------------------------------------------------------------------
/** Add a MDEvent to the box.
* @param point :: reference to a MDEvent to add.
* */
TMDE
void MDBox<nd>::addEvent( const MDEvent<nd> & point)
{
this->data.push_back(point);
// Keep the running total of signal and error
signal += point.getSignal();
errorSquared += point.getErrorSquared();
}
// Here we export a bunch of version of MDBox with various dimension sizes.
// We need to define one for every possibility.
template DLLExport class MDBox<1>;
template DLLExport class MDBox<2>;
template DLLExport class MDBox<3>;
template DLLExport class MDBox<4>;
}//namespace MDEvents
}//namespace Mantid
#include "MantidMDEvents/MDEventWorkspace.h"
#include "MantidMDEvents/MDEvent.h"
namespace Mantid
{
namespace MDEvents
{
//-----------------------------------------------------------------------------------------------
/** Returns the number of dimensions in this workspace */
template <size_t nd, size_t nv, typename TE>
int MDEventWorkspace<nd,nv,TE>::getNumDims() const
{
return nd;
}
/** Returns the total number of points (events) in this workspace */
template <size_t nd, size_t nv, typename TE>
size_t MDEventWorkspace<nd,nv,TE>::getNPoints() const
{
//return data.size();
return 0;
}
/** Returns the number of bytes of memory
* used by the workspace. */
template <size_t nd, size_t nv, typename TE>
size_t MDEventWorkspace<nd,nv,TE>::getMemoryUsed() const
{
return this->getNPoints() * sizeof(MDEvent<nd>);
}
//-----------------------------------------------------------------------------------------------
// We export a bunch of version of MDEventWorkspace with various dimension sizes.
template DLLExport class MDEventWorkspace<1,0,char>;
template DLLExport class MDEventWorkspace<2,0,char>;
template DLLExport class MDEventWorkspace<3,0,char>;
template DLLExport class MDEventWorkspace<4,0,char>;
}//namespace MDEvents
}//namespace Mantid
#ifndef MDBOXTEST_H
#define MDBOXTEST_H
#include <cxxtest/TestSuite.h>
#include "MantidMDEvents/MDEvent.h"
#include "MantidMDEvents/MDBox.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <memory>
#include <map>
using namespace Mantid;
using namespace Mantid::MDEvents;
class MDBoxTest : public CxxTest::TestSuite
{
public:
void testConstructor()
{
MDBox<3> b3;
TS_ASSERT_EQUALS( b3.getNumDims(), 3);
TS_ASSERT_EQUALS( b3.getNPoints(), 0);
// std::cout << sizeof(b3) << "\n";
// std::cout << sizeof(MDBox<0> ) << "\n";
// std::cout << sizeof(MDBox<1> ) << "\n";
// std::vector< int > v;
// std::cout << sizeof(v) << "\n";
}
void testAddPoint()
{
MDBox<2> b;
MDEvent<2> ev(1.2, 3.4);
ev.setCoord(0, 2.0);
ev.setCoord(1, 3.0);
b.addEvent(ev);
TS_ASSERT_EQUALS( b.getNPoints(), 1)
}
void testClear()
{
MDBox<2> b;
MDEvent<2> ev(1.2, 3.4);
b.addEvent(ev);
b.addEvent(ev);
TS_ASSERT_EQUALS( b.getNPoints(), 2)
TS_ASSERT_DELTA( b.getSignal(), 2.4, 1e-5)
b.clear();
TS_ASSERT_EQUALS( b.getNPoints(), 0)
TS_ASSERT_DELTA( b.getSignal(), 0.0, 1e-5)
TS_ASSERT_DELTA( b.getErrorSquared(), 0.0, 1e-5)
}
void test_getPoints()
{
MDBox<2> b;
MDEvent<2> ev(4.0, 3.4);
b.addEvent(ev);
b.addEvent(ev);
b.addEvent(ev);
TS_ASSERT_EQUALS( b.getPoints().size(), 3);
TS_ASSERT_EQUALS( b.getPoints()[2].getSignal(), 4.0);
}
void test_sptr()
{
MDBox<3>::sptr a( new MDBox<3>());
//TS_ASSERT_EQUALS( sizeof(a), 16);
}
};
#endif
#ifndef MDEVENTTEST_H
#define MDEVENTTEST_H
#include <cxxtest/TestSuite.h>
#include "MantidMDEvents/MDEvent.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <memory>
#include <map>
using namespace Mantid;
using namespace Mantid::MDEvents;
class MDEventTest : public CxxTest::TestSuite
{
public:
void testConstructors()
{
MDEvent<3> a;
TS_ASSERT_EQUALS( a.getNumDims(), 3);
TS_ASSERT_EQUALS( a.getSignal(), 1.0);
TS_ASSERT_EQUALS( a.getErrorSquared(), 1.0);
MDEvent<4> b(2.5, 1.5);
TS_ASSERT_EQUALS( b.getNumDims(), 4);
TS_ASSERT_EQUALS( b.getSignal(), 2.5);
TS_ASSERT_EQUALS( b.getErrorSquared(), 1.5);
TS_ASSERT_EQUALS( sizeof(a), sizeof(CoordType)*3+8);
TS_ASSERT_EQUALS( sizeof(b), sizeof(CoordType)*4+8);
}
void testConstructorsWithCoords()
{
// Fixed-size array
CoordType coords[3] = {0.123, 1.234, 2.345};
MDEvent<3> a(2.5, 1.5, coords );
TS_ASSERT_EQUALS( a.getSignal(), 2.5);
TS_ASSERT_EQUALS( a.getErrorSquared(), 1.5);
TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
TS_ASSERT_EQUALS( a.getCoord(1), 1.234);
TS_ASSERT_EQUALS( a.getCoord(2), 2.345);
// Dynamic array
CoordType * coords2 = new CoordType[5];
coords2[0] = 1.0;
coords2[1] = 2.0;
coords2[2] = 3.0;
MDEvent<3> b(2.5, 1.5, coords2 );
TS_ASSERT_EQUALS( b.getSignal(), 2.5);
TS_ASSERT_EQUALS( b.getErrorSquared(), 1.5);
TS_ASSERT_EQUALS( b.getCoord(0), 1);
TS_ASSERT_EQUALS( b.getCoord(1), 2);
TS_ASSERT_EQUALS( b.getCoord(2), 3);
}
void testCooord()
{
MDEvent<3> a;
TS_ASSERT_EQUALS( a.getNumDims(), 3);
a.setCoord(0, 0.123);
TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
a.setCoord(1, 1.234);
TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
TS_ASSERT_EQUALS( a.getCoord(1), 1.234);
a.setCoord(2, 2.345);
TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
TS_ASSERT_EQUALS( a.getCoord(1), 1.234);
TS_ASSERT_EQUALS( a.getCoord(2), 2.345);
}
void testSetCooords()
{
MDEvent<3> a;
CoordType coords[3] = {0.123, 1.234, 2.345};
a.setCoords( coords );
TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
TS_ASSERT_EQUALS( a.getCoord(1), 1.234);
TS_ASSERT_EQUALS( a.getCoord(2), 2.345);
}
void testCopyConstructor()
{
CoordType coords[3] = {0.123, 1.234, 2.345};
MDEvent<3> b(2.5, 1.5, coords );
MDEvent<3> a(b);
TS_ASSERT_EQUALS( a.getNumDims(), 3);
TS_ASSERT_EQUALS( a.getSignal(), 2.5);
TS_ASSERT_EQUALS( a.getErrorSquared(), 1.5);
TS_ASSERT_EQUALS( a.getCoord(0), 0.123);
TS_ASSERT_EQUALS( a.getCoord(1), 1.234);
TS_ASSERT_EQUALS( a.getCoord(2), 2.345);
}
void test_getError()
{
MDEvent<3> a(2.0, 4.0);
TS_ASSERT_EQUALS( a.getSignal(), 2.0);
TS_ASSERT_EQUALS( a.getError(), 2.0);
}
};
#endif
#ifndef MDEVENTWORKSPACETEST_H
#define MDEVENTWORKSPACETEST_H
#include <cxxtest/TestSuite.h>
#include "MantidMDEvents/MDEvent.h"
#include "MantidMDEvents/MDEventWorkspace.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <memory>
#include <map>
using namespace Mantid;
using namespace Mantid::MDDataObjects;
class MDEventWorkspaceTest : public CxxTest::TestSuite
{
public:
void testConstructor()
{
MDEventWorkspace<3> ew3;
TS_ASSERT_EQUALS( ew3.getNumDims(), 3);
TS_ASSERT_EQUALS( ew3.getNPoints(), 0);
}
};
#endif
#ifndef MDPointTEST_H
#define MDPointTEST_H
#include <cxxtest/TestSuite.h>
#include "MantidMDEvents/MDPoint.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <memory>
#include <map>
using namespace Mantid;
using namespace Mantid::MDDataObjects;
class MDPointTest : public CxxTest::TestSuite
{
struct MyExtraData
{
int detectorID;
char instrument;
};
public:
void testConstructors()
{
MDPoint<3> a;
TS_ASSERT_EQUALS( a.getNumDims(), 3);
TS_ASSERT_EQUALS( a.getSignal(), 1.0);
TS_ASSERT_EQUALS( a.getErrorSquared(), 1.0);
MDPoint<4> b(2.5, 1.5);
TS_ASSERT_EQUALS( b.getNumDims(), 4);
TS_ASSERT_EQUALS( b.getSignal(), 2.5);
TS_ASSERT_EQUALS( b.getErrorSquared(), 1.5);
TS_ASSERT_EQUALS( sizeof(a), sizeof(CoordType)*3+8);
TS_ASSERT_EQUALS( sizeof(b), sizeof(CoordType)*4+8);
}
void testConstructors_MoreTemplateParameters()
{
MDPoint<3,3> a;
TS_ASSERT_EQUALS( a.getNumDims(), 3);
TS_ASSERT_EQUALS( sizeof(a), sizeof(CoordType)*3*4+8);
}
void testConstructors_EvenMoreTemplateParameters()
{
MDPoint<3,3, MyExtraData> a;
TS_ASSERT_EQUALS( a.getNumDims(), 3);
TS_ASSERT_EQUALS( sizeof(a), sizeof(CoordType)*3*4 + 8 +sizeof(MyExtraData));
}
void testConstructorsWithCenters()
{
// Fixed-size array
CoordType coords[3] = {0.123, 1.234, 2.345};
MDPoint<3> a(2.5, 1.5, coords );
TS_ASSERT_EQUALS( a.getSignal(), 2.5);
TS_ASSERT_EQUALS( a.getErrorSquared(), 1.5);
TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
TS_ASSERT_EQUALS( a.getCenter(2), 2.345);
// Dynamic array
CoordType * coords2 = new CoordType[5];
coords2[0] = 1.0;
coords2[1] = 2.0;
coords2[2] = 3.0;
// The array does not have to be the same size, it is safe if it is bigger (though why would you do that?)
MDPoint<3> b(2.5, 1.5, coords2 );
TS_ASSERT_EQUALS( b.getSignal(), 2.5);
TS_ASSERT_EQUALS( b.getErrorSquared(), 1.5);
TS_ASSERT_EQUALS( b.getCenter(0), 1);
TS_ASSERT_EQUALS( b.getCenter(1), 2);
TS_ASSERT_EQUALS( b.getCenter(2), 3);
}
// =============================================================================================
// =============================================================================================
void testCenter()
{
MDPoint<3> a;
TS_ASSERT_EQUALS( a.getNumDims(), 3);
a.setCenter(0, 0.123);
TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
a.setCenter(1, 1.234);
TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
a.setCenter(2, 2.345);
TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
TS_ASSERT_EQUALS( a.getCenter(2), 2.345);
}
void testSetCenters()
{
MDPoint<3> a;
CoordType coords[3] = {0.123, 1.234, 2.345};
a.setCenters( coords );
TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
TS_ASSERT_EQUALS( a.getCenter(2), 2.345);
}
void testCopyConstructor()
{
CoordType coords[3] = {0.123, 1.234, 2.345};
MDPoint<3> b(2.5, 1.5, coords );
MDPoint<3> a(b);
TS_ASSERT_EQUALS( a.getNumDims(), 3);
TS_ASSERT_EQUALS( a.getSignal(), 2.5);
TS_ASSERT_EQUALS( a.getErrorSquared(), 1.5);
TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
TS_ASSERT_EQUALS( a.getCenter(2), 2.345);
}
void test_getError()
{
MDPoint<3> a(2.0, 4.0);
TS_ASSERT_EQUALS( a.getSignal(), 2.0);
TS_ASSERT_EQUALS( a.getError(), 2.0);
}
// =============================================================================================
// =============================================================================================
void test_getExtra()
{
MDPoint<3,0,MyExtraData> a(2.0, 4.0);
TS_ASSERT_EQUALS( a.getSignal(), 2.0);
TS_ASSERT_EQUALS( a.getError(), 2.0);
a.getExtra().detectorID = 12;
a.getExtra().instrument = 'C';
MyExtraData & e = a.getExtra();
TS_ASSERT_EQUALS( e.detectorID, 12);
TS_ASSERT_EQUALS( e.instrument, 'C');
const MyExtraData & e2 = a.getExtra();
TS_ASSERT_EQUALS( e2.detectorID, 12);
TS_ASSERT_EQUALS( e2.instrument, 'C');
}
void test_setExtra()
{
MDPoint<3,0,MyExtraData> a(2.0, 4.0);
MyExtraData e;
e.detectorID = 34;
e.instrument = 'D';
a.setExtra(e);
TS_ASSERT_EQUALS( a.getExtra().detectorID, 34);
TS_ASSERT_EQUALS( a.getExtra().instrument, 'D');
// setExtra() made a copy of the extra
TS_ASSERT_DIFFERS( &a.getExtra(), &e);
}
// =============================================================================================
// =============================================================================================
void test_setCorner_individually()
{
// 2 dimensions, 3 vertices
MDPoint<2,3> a;
a.setCorner(0, 0, 0.123);
TS_ASSERT_EQUALS( a.getCorner(0,0), 0.123);
a.setCorner(0, 1, 1.234);
a.setCorner(1, 0, 2);
a.setCorner(1, 1, 3);
a.setCorner(2, 0, 4);
a.setCorner(2, 1, 5);
TS_ASSERT_EQUALS( a.getCorner(0,0), 0.123);
TS_ASSERT_EQUALS( a.getCorner(0,1), 1.234);
TS_ASSERT_EQUALS( a.getCorner(1,0), 2);
TS_ASSERT_EQUALS( a.getCorner(1,1), 3);
}
void test_setCorner_vertex()
{
// 2 dimensions, 3 vertices
MDPoint<2,3> a;
CoordType v0[2] = {1, 2};
CoordType v1[2] = {4, 5};
CoordType v2[2] = {9, 10};
// Set the entire vertex at once
a.setCorner(0, v0);
a.setCorner(1, v1);
a.setCorner(2, v2);
// They match!
for (size_t i=0; i<2; i++)
{
TS_ASSERT_EQUALS( a.getCorner(0)[i], v0[i]);
TS_ASSERT_EQUALS( a.getCorner(1)[i], v1[i]);
TS_ASSERT_EQUALS( a.getCorner(2)[i], v2[i]);
}
// But if you change the original, they no longer match
v1[1] = 45;
TS_ASSERT_DIFFERS( a.getCorner(1)[1], v1[1]);
}
// void testCopyConstructor_with_Corners()
// {
// CoordType coords[2] = {0.123, 1.234};
// // One corner vertec
// CoordType corners[2][1] = {{5.691}, {7.2}};
// MDPoint<2,1> b(2.5, 1.5, coords );
// b.setCorners( corners);
// // Do the copy
// MDPoint<2,1> a(b);
// TS_ASSERT_EQUALS( a.getNumDims(), 2);
// TS_ASSERT_EQUALS( a.getSignal(), 2.5);
// TS_ASSERT_EQUALS( a.getErrorSquared(), 1.5);
// TS_ASSERT_EQUALS( a.getCenter(0), 0.123);
// TS_ASSERT_EQUALS( a.getCenter(1), 1.234);
// TS_ASSERT_EQUALS( a.getCorner(0, 0), 5.691);
// TS_ASSERT_EQUALS( a.getCorner(0, 1), 7.2);
// }
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment