Skip to content

Commit

Permalink
Refs #4036 binary ops mdhw
Browse files Browse the repository at this point in the history
  • Loading branch information
Janik Zikovsky committed Nov 3, 2011
1 parent 1eed5bf commit ee66d6c
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include "MantidGeometry/MDGeometry/MDImplicitFunction.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/System.h"
#include "MantidDataObjects/WorkspaceSingleValue.h"

using Mantid::DataObjects::WorkspaceSingleValue;


namespace Mantid
Expand Down Expand Up @@ -57,6 +60,23 @@ namespace MDEvents
/// Creates a new iterator pointing to the first cell in the workspace
virtual Mantid::API::IMDIterator* createIterator(Mantid::Geometry::MDImplicitFunction * function = NULL) const;

void checkWorkspaceSize(const MDHistoWorkspace & other, std::string operation);

// --------------------------------------------------------------------------------------------
MDHistoWorkspace & operator+=(const MDHistoWorkspace & b);
MDHistoWorkspace & operator+=(const Mantid::DataObjects::WorkspaceSingleValue & b);

MDHistoWorkspace & operator-=(const MDHistoWorkspace & b);
MDHistoWorkspace & operator-=(const Mantid::DataObjects::WorkspaceSingleValue & b);

MDHistoWorkspace & operator*=(const MDHistoWorkspace & b);
MDHistoWorkspace & operator*=(const Mantid::DataObjects::WorkspaceSingleValue & b);

MDHistoWorkspace & operator/=(const MDHistoWorkspace & b);
MDHistoWorkspace & operator/=(const Mantid::DataObjects::WorkspaceSingleValue & b);



// --------------------------------------------------------------------------------------------
/** @return a const reference to the indexMultiplier array.
* To find the index into the linear array, dim0 + indexMultiplier[0]*dim1 + ...
Expand All @@ -81,12 +101,12 @@ namespace MDEvents
/** @return the direct pointer to the error squared array. For speed */
signal_t * getErrorSquaredArray()
{
return m_errors;
return m_errorsSquared;
}

void setTo(signal_t signal, signal_t error);
void setTo(signal_t signal, signal_t errorSquared);

void applyImplicitFunction(Mantid::Geometry::MDImplicitFunction * function, signal_t signal, signal_t error);
void applyImplicitFunction(Mantid::Geometry::MDImplicitFunction * function, signal_t signal, signal_t errorSquared);

coord_t * getVertexesArray(size_t linearIndex, size_t & numVertices) const;

Expand All @@ -101,35 +121,35 @@ namespace MDEvents
m_signals[index] = value;
}

/// Sets the error at the specified index.
/// Sets the error (squared) at the specified index.
void setErrorAt(size_t index, signal_t value)
{
m_errors[index] = value;
m_errorsSquared[index] = value;
}


/// Get the error of the signal at the specified index.
signal_t getErrorAt(size_t index) const
{
return m_errors[index];
return m_errorsSquared[index];
}

/// Get the error at the specified index given in 4 dimensions (typically X,Y,Z,t)
signal_t getErrorAt(size_t index1, size_t index2) const
{
return m_errors[index1 + indexMultiplier[0]*index2];
return m_errorsSquared[index1 + indexMultiplier[0]*index2];
}

/// Get the error at the specified index given in 4 dimensions (typically X,Y,Z,t)
signal_t getErrorAt(size_t index1, size_t index2, size_t index3) const
{
return m_errors[index1 + indexMultiplier[0]*index2 + indexMultiplier[1]*index3];
return m_errorsSquared[index1 + indexMultiplier[0]*index2 + indexMultiplier[1]*index3];
}

/// Get the error at the specified index given in 4 dimensions (typically X,Y,Z,t)
signal_t getErrorAt(size_t index1, size_t index2, size_t index3, size_t index4) const
{
return m_errors[index1 + indexMultiplier[0]*index2 + indexMultiplier[1]*index3 + indexMultiplier[2]*index4];
return m_errorsSquared[index1 + indexMultiplier[0]*index2 + indexMultiplier[1]*index3 + indexMultiplier[2]*index4];
}


Expand Down Expand Up @@ -190,7 +210,7 @@ namespace MDEvents
/// Get the error of the signal at the specified index, normalized by cell volume
signal_t getErrorNormalizedAt(size_t index) const
{
return m_errors[index] * m_inverseVolume;
return m_errorsSquared[index] * m_inverseVolume;
}

/// Get the signal at the specified index given in 4 dimensions (typically X,Y,Z,t), normalized by cell volume
Expand Down Expand Up @@ -230,9 +250,9 @@ namespace MDEvents
signal_t * m_signals;

/// Linear array of errors for each bin
signal_t * m_errors;
signal_t * m_errorsSquared;

/// Length of the m_signals / m_errors arrays.
/// Length of the m_signals / m_errorsSquared arrays.
size_t m_length;

/// To find the index into the linear array, dim0 + indexMultiplier[0]*dim1 + ...
Expand Down
59 changes: 51 additions & 8 deletions Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace MDEvents
MDHistoWorkspace::~MDHistoWorkspace()
{
delete [] m_signals;
delete [] m_errors;
delete [] m_errorsSquared;
delete [] indexMultiplier;
delete [] m_vertexesArray;
delete [] m_boxLength;
Expand Down Expand Up @@ -91,7 +91,7 @@ namespace MDEvents

// Allocate the linear arrays
m_signals = new signal_t[m_length];
m_errors = new signal_t[m_length];
m_errorsSquared = new signal_t[m_length];

// Initialize them to NAN (quickly)
signal_t nan = std::numeric_limits<signal_t>::quiet_NaN();
Expand All @@ -112,14 +112,14 @@ namespace MDEvents
/** Sets all signals/errors in the workspace to the given values
*
* @param signal :: signal value to set
* @param error :: error value to set
* @param errorSquared :: error (squared) value to set
*/
void MDHistoWorkspace::setTo(signal_t signal, signal_t error)
void MDHistoWorkspace::setTo(signal_t signal, signal_t errorSquared)
{
for (size_t i=0; i < m_length; i++)
{
m_signals[i] = signal;
m_errors[i] = error;
m_errorsSquared[i] = errorSquared;
}
}

Expand All @@ -129,7 +129,7 @@ namespace MDEvents
* @param signal :: signal value to set when function evaluates to false
* @param error :: error value to set when function evaluates to false
*/
void MDHistoWorkspace::applyImplicitFunction(Mantid::Geometry::MDImplicitFunction * function, signal_t signal, signal_t error)
void MDHistoWorkspace::applyImplicitFunction(Mantid::Geometry::MDImplicitFunction * function, signal_t signal, signal_t errorSquared)
{
if (numDimensions<3) throw std::invalid_argument("Need 3 dimensions for ImplicitFunction.");
Mantid::coord_t coord[3];
Expand All @@ -146,7 +146,7 @@ namespace MDEvents
if (!function->isPointContained(coord))
{
m_signals[x + indexMultiplier[0]*y + indexMultiplier[1]*z] = signal;
m_errors[x + indexMultiplier[0]*y + indexMultiplier[1]*z] = error;
m_errorsSquared[x + indexMultiplier[0]*y + indexMultiplier[1]*z] = errorSquared;
}
}
}
Expand Down Expand Up @@ -319,11 +319,54 @@ namespace MDEvents
std::vector<signal_t> out;
out.resize(m_length, 0.0);
for (size_t i=0; i<m_length; ++i)
out[i] = m_errors[i];
out[i] = m_errorsSquared[i];
// This copies again! :(
return out;
}

void MDHistoWorkspace::checkWorkspaceSize(const MDHistoWorkspace & other, std::string operation)
{
if (other.getNumDims() != this->getNumDims())
throw std::invalid_argument("Cannot perform the " + operation + " operation on this workspace. The number of dimensions does not match.");
if (other.m_length != this->m_length)
throw std::invalid_argument("Cannot perform the " + operation + " operation on this workspace. The length of the signals vector does not match.");
}

//----------------------------------------------------------------------------------------------
/** Perform the += operation, element-by-element, for two MDHistoWorkspace's
*
* @param b :: workspace on the RHS of the operation
* @return *this after operation */
MDHistoWorkspace & MDHistoWorkspace::operator+=(const MDHistoWorkspace & b)
{
checkWorkspaceSize(b, "+=");
for (size_t i=0; i<m_length; ++i)
{
m_signals[i] += b.m_signals[i];
m_errorsSquared[i] += b.m_errorsSquared[i];
}
return *this;
}

//----------------------------------------------------------------------------------------------
/** Perform the += operation with a scalar as the RHS argument
*
* @param b :: WorkspaceSingleValue (signal and error) as the RHS argument
* @return *this after operation */
MDHistoWorkspace & MDHistoWorkspace::operator+=(const Mantid::DataObjects::WorkspaceSingleValue & b)
{
signal_t signal = b.dataY(0)[0];
signal_t errorSquared = b.dataE(0)[0];
errorSquared *= errorSquared;
for (size_t i=0; i<m_length; ++i)
{
m_signals[i] += signal;
m_errorsSquared[i] += errorSquared;
}
return *this;
}


} // namespace Mantid
} // namespace MDEvents

19 changes: 18 additions & 1 deletion Code/Mantid/Framework/MDEvents/test/MDHistoWorkspaceTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@ using namespace Mantid;
class MDHistoWorkspaceTest : public CxxTest::TestSuite
{
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static MDHistoWorkspaceTest *createSuite() { return new MDHistoWorkspaceTest(); }
static void destroySuite( MDHistoWorkspaceTest *suite ) { delete suite; }

MDHistoWorkspace_sptr two;
MDHistoWorkspace_sptr three;

MDHistoWorkspace_sptr ma

MDHistoWorkspaceTest()
{
MDEventsTestHelper::makeFakeMDHistoWorkspace(
two.
}



void test_constructor()
{
Expand Down Expand Up @@ -347,7 +364,7 @@ class MDHistoWorkspaceTest : public CxxTest::TestSuite
void test_getSignalAtCoord()
{
// 2D workspace with signal[i] = i (linear index)
MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 10);
MDHistoWorkspace_sptr ws = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 1.0, 2, 10);
for (size_t i=0; i<100; i++)
ws->setSignalAt(i, double(i));
IMDWorkspace_sptr iws(ws);
Expand Down

0 comments on commit ee66d6c

Please sign in to comment.