CFloat32VolumeData3D& CFloat32VolumeData3D::operator-=(const float32& _fScalar)
{
	CVolumeGeometry3D * pThisGeometry = getGeometry();

	int iSliceCount = pThisGeometry->getGridSliceCount();

	for(int iSliceIndex = 0; iSliceIndex < iSliceCount; iSliceIndex++)
	{
		CFloat32VolumeData2D * pThisProjection = fetchSliceZ(iSliceIndex);

		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorIndex; iDetectorIndex++)
		{
			float32 fThisValue = pThisProjection->getData()[iDetectorIndex];

			fThisValue -= _fScalar;

			pThisProjection->getData()[iDetectorIndex] = fThisValue;
		}

		returnSliceZ(iSliceIndex, pThisProjection);

		delete pThisProjection;
	}

	return *this;
}
CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator+=(const float32& _fScalar)
{
	CProjectionGeometry3D * pThisGeometry = getGeometry();

	int iProjectionCount = pThisGeometry->getProjectionCount();

	for(int iProjectionIndex = 0; iProjectionIndex < iProjectionCount; iProjectionIndex++)
	{
		CFloat32VolumeData2D * pThisProjection = fetchProjection(iProjectionIndex);

		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorIndex; iDetectorIndex++)
		{
			float32 fThisValue = pThisProjection->getData()[iDetectorIndex];

			fThisValue += _fScalar;

			pThisProjection->getData()[iDetectorIndex] = fThisValue;
		}

		returnProjection(iProjectionIndex, pThisProjection);

		delete pThisProjection;
	}

	return *this;
}
CFloat32VolumeData3D& CFloat32VolumeData3D::operator-=(const CFloat32VolumeData3D& _data)
{
	CVolumeGeometry3D * pThisGeometry = getGeometry();

	int iSliceCount = pThisGeometry->getGridSliceCount();
#ifdef _DEBUG
	CVolumeGeometry3D * pDataGeometry = _data.getGeometry();
	int iThisSlicePixelCount = pThisGeometry->getGridRowCount() * pThisGeometry->getGridColCount();
	int iDataSlicePixelCount = pDataGeometry->getGridRowCount() * pDataGeometry->getGridColCount();

	ASTRA_ASSERT(iSliceCount == pDataGeometry->getGridSliceCount());
	ASTRA_ASSERT(iThisSlicePixelCount == iDataSlicePixelCount);
#endif

	for(int iSliceIndex = 0; iSliceIndex < iSliceCount; iSliceIndex++)
	{
		CFloat32VolumeData2D * pThisProjection = fetchSliceZ(iSliceIndex);
		CFloat32VolumeData2D * pDataProjection = _data.fetchSliceZ(iSliceIndex);

		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorIndex; iDetectorIndex++)
		{
			float32 fThisValue = pThisProjection->getData()[iDetectorIndex];
			float32 fDataValue = pDataProjection->getDataConst()[iDetectorIndex];

			fThisValue -= fDataValue;

			pThisProjection->getData()[iDetectorIndex] = fThisValue;
		}

		returnSliceZ(iSliceIndex, pThisProjection);

		delete pThisProjection;
		delete pDataProjection;
	}

	return *this;
}
CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator-=(const CFloat32ProjectionData3D& _data)
{
	CProjectionGeometry3D * pThisGeometry = getGeometry();

	int iProjectionCount = pThisGeometry->getProjectionCount();
#ifdef _DEBUG
	CProjectionGeometry3D * pDataGeometry = _data.getGeometry();
	int iThisProjectionDetectorCount = pThisGeometry->getDetectorRowCount() * pThisGeometry->getDetectorColCount();
	int iDataProjectionDetectorCount = pDataGeometry->getDetectorRowCount() * pDataGeometry->getDetectorColCount();

	ASTRA_ASSERT(iProjectionCount == pDataGeometry->getProjectionCount());
	ASTRA_ASSERT(iThisProjectionDetectorCount == iDataProjectionDetectorCount);
#endif

	for(int iProjectionIndex = 0; iProjectionIndex < iProjectionCount; iProjectionIndex++)
	{
		CFloat32VolumeData2D * pThisProjection = fetchProjection(iProjectionIndex);
		CFloat32VolumeData2D * pDataProjection = _data.fetchProjection(iProjectionIndex);

		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorIndex; iDetectorIndex++)
		{
			float32 fThisValue = pThisProjection->getData()[iDetectorIndex];
			float32 fDataValue = pDataProjection->getDataConst()[iDetectorIndex];

			fThisValue -= fDataValue;

			pThisProjection->getData()[iDetectorIndex] = fThisValue;
		}

		returnProjection(iProjectionIndex, pThisProjection);

		delete pThisProjection;
		delete pDataProjection;
	}

	return *this;
}
//----------------------------------------------------------------------------------------
// Fetch a projection
CFloat32VolumeData2D* CFloat32ProjectionData3DMemory::fetchProjection(int _iProjectionNr) const
{
	// fetch slice of the geometry
	CVolumeGeometry2D volGeom(m_pGeometry->getDetectorColCount(), m_pGeometry->getDetectorRowCount());
	// create new volume data
	CFloat32VolumeData2D* res = new CFloat32VolumeData2D(&volGeom);
	// copy data
	int row, col;
	for (row = 0; row < m_pGeometry->getDetectorRowCount(); ++row) {
		for (col = 0; col < m_pGeometry->getDetectorColCount(); ++col) {
			res->getData()[row*m_pGeometry->getDetectorColCount() + col] = 
				m_pfData[_iProjectionNr * m_pGeometry->getDetectorColCount() + m_pGeometry->getDetectorColCount()* m_pGeometry->getProjectionCount() * row + col];
		}
	}
	// return
	return res;
}