//---------------------------------------------------------------------------------------
// Initialize - Config
bool CConeVecProjectionGeometry3D::initialize(const Config& _cfg)
{
	ASTRA_ASSERT(_cfg.self);
	ConfigStackCheck<CProjectionGeometry3D> CC("ConeVecProjectionGeometry3D", this, _cfg);	

	XMLNode* node;

	// TODO: Fix up class hierarchy... this class doesn't fit very well.
	// initialization of parent class
	//CProjectionGeometry3D::initialize(_cfg);

	// Required: DetectorRowCount
	node = _cfg.self->getSingleNode("DetectorRowCount");
	ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No DetectorRowCount tag specified.");
	m_iDetectorRowCount = boost::lexical_cast<int>(node->getContent());
	ASTRA_DELETE(node);
	CC.markNodeParsed("DetectorRowCount");

	// Required: DetectorColCount
	node = _cfg.self->getSingleNode("DetectorColCount");
	ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No DetectorColCount tag specified.");
	m_iDetectorColCount = boost::lexical_cast<int>(node->getContent());
	m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount;
	ASTRA_DELETE(node);
	CC.markNodeParsed("DetectorColCount");

	// Required: Vectors
	node = _cfg.self->getSingleNode("Vectors");
	ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No Vectors tag specified.");
	vector<double> data = node->getContentNumericalArrayDouble();
	CC.markNodeParsed("Vectors");
	ASTRA_DELETE(node);
	ASTRA_CONFIG_CHECK(data.size() % 12 == 0, "ConeVecProjectionGeometry3D", "Vectors doesn't consist of 12-tuples.");
	m_iProjectionAngleCount = data.size() / 12;
	m_pProjectionAngles = new SConeProjection[m_iProjectionAngleCount];

	for (int i = 0; i < m_iProjectionAngleCount; ++i) {
		SConeProjection& p = m_pProjectionAngles[i];
		p.fSrcX  = data[12*i +  0];
		p.fSrcY  = data[12*i +  1];
		p.fSrcZ  = data[12*i +  2];
		p.fDetUX = data[12*i +  6];
		p.fDetUY = data[12*i +  7];
		p.fDetUZ = data[12*i +  8];
		p.fDetVX = data[12*i +  9];
		p.fDetVY = data[12*i + 10];
		p.fDetVZ = data[12*i + 11];

		// The backend code currently expects the corner of the detector, while
		// the matlab interface supplies the center
		p.fDetSX = data[12*i +  3] - 0.5f * m_iDetectorRowCount * p.fDetVX - 0.5f * m_iDetectorColCount * p.fDetUX;
		p.fDetSY = data[12*i +  4] - 0.5f * m_iDetectorRowCount * p.fDetVY - 0.5f * m_iDetectorColCount * p.fDetUY;
		p.fDetSZ = data[12*i +  5] - 0.5f * m_iDetectorRowCount * p.fDetVZ - 0.5f * m_iDetectorColCount * p.fDetUZ;
	}

	// success
	m_bInitialized = _check();
	return m_bInitialized;
}
//----------------------------------------------------------------------------------------
// Initialization with a Config object
bool CProjectionGeometry2D::initialize(const Config& _cfg)
{
	ASTRA_ASSERT(_cfg.self);
	ConfigStackCheck<CProjectionGeometry2D> CC("ProjectionGeometry2D", this, _cfg);	

	// uninitialize if the object was initialized before
	if (m_bInitialized)	{
		clear();
	}

	// Required: DetectorWidth
	XMLNode* node = _cfg.self->getSingleNode("DetectorWidth");
	ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No DetectorWidth tag specified.");
	m_fDetectorWidth = boost::lexical_cast<float32>(node->getContent());
	ASTRA_DELETE(node);
	CC.markNodeParsed("DetectorWidth");

	// Required: DetectorCount
	node = _cfg.self->getSingleNode("DetectorCount");
	ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No DetectorCount tag specified.");
	m_iDetectorCount = boost::lexical_cast<int>(node->getContent());
	ASTRA_DELETE(node);
	CC.markNodeParsed("DetectorCount");

	// Required: ProjectionAngles
	node = _cfg.self->getSingleNode("ProjectionAngles");
	ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No ProjectionAngles tag specified.");
	vector<float32> angles = node->getContentNumericalArray();
	delete node;
	m_iProjectionAngleCount = angles.size();
	ASTRA_CONFIG_CHECK(m_iProjectionAngleCount > 0, "ProjectionGeometry2D", "Not enough ProjectionAngles specified.");
	m_pfProjectionAngles = new float32[m_iProjectionAngleCount];
	for (int i = 0; i < m_iProjectionAngleCount; i++) {
		m_pfProjectionAngles[i] = angles[i];
	}
	CC.markNodeParsed("ProjectionAngles");

	vector<float32> offset = _cfg.self->getOptionNumericalArray("ExtraDetectorOffset");
	m_pfExtraDetectorOffset = new float32[m_iProjectionAngleCount];
	if (offset.size() == (size_t)m_iProjectionAngleCount) {
		for (int i = 0; i < m_iProjectionAngleCount; i++) {
			m_pfExtraDetectorOffset[i] = offset[i];
		}
	} else {
		for (int i = 0; i < m_iProjectionAngleCount; i++) {
			m_pfExtraDetectorOffset[i] = 0.0f;
		}	
	}
	CC.markOptionParsed("ExtraDetectorOffset");

	// some checks
	ASTRA_CONFIG_CHECK(m_iDetectorCount > 0, "ProjectionGeometry2D", "DetectorCount should be positive.");
	ASTRA_CONFIG_CHECK(m_fDetectorWidth > 0.0f, "ProjectionGeometry2D", "DetectorWidth should be positive.");
	ASTRA_CONFIG_CHECK(m_pfProjectionAngles != NULL, "ProjectionGeometry2D", "ProjectionAngles not initialized");

	// Interface class, so don't return true
	return false;
}
//---------------------------------------------------------------------------------------
// Clear - Public
void CSirtAlgorithm::clear()
{
    CReconstructionAlgorithm2D::_clear();
    m_bIsInitialized = false;

    ASTRA_DELETE(m_pTotalRayLength);
    ASTRA_DELETE(m_pTotalPixelWeight);
    ASTRA_DELETE(m_pDiffSinogram);
    ASTRA_DELETE(m_pTmpVolume);

    m_iIterationCount = 0;
}
//----------------------------------------------------------------------------------------
// Initialization witha Config object
bool CVolumeGeometry2D::initialize(const Config& _cfg)
{
	ASTRA_ASSERT(_cfg.self);
	ConfigStackCheck<CVolumeGeometry2D> CC("VolumeGeometry2D", this, _cfg);
	
	// uninitialize if the object was initialized before
	if (m_bInitialized)	{
		clear();
	}

	// Required: GridColCount
	XMLNode* node = _cfg.self->getSingleNode("GridColCount");
	ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridColCount tag specified.");
	m_iGridColCount = boost::lexical_cast<int>(node->getContent());
	ASTRA_DELETE(node);
	CC.markNodeParsed("GridColCount");

	// Required: GridRowCount
	node = _cfg.self->getSingleNode("GridRowCount");
	ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridRowCount tag specified.");
	m_iGridRowCount = boost::lexical_cast<int>(node->getContent());
	ASTRA_DELETE(node);
	CC.markNodeParsed("GridRowCount");

	// Optional: Window minima and maxima
	m_fWindowMinX = _cfg.self->getOptionNumerical("WindowMinX", -m_iGridColCount/2.0f);
	m_fWindowMaxX = _cfg.self->getOptionNumerical("WindowMaxX", m_iGridColCount/2.0f);
	m_fWindowMinY = _cfg.self->getOptionNumerical("WindowMinY", -m_iGridRowCount/2.0f);
	m_fWindowMaxY = _cfg.self->getOptionNumerical("WindowMaxY", m_iGridRowCount/2.0f);
	CC.markOptionParsed("WindowMinX");
	CC.markOptionParsed("WindowMaxX");
	CC.markOptionParsed("WindowMinY");
	CC.markOptionParsed("WindowMaxY");

	_calculateDependents();

	// success
	m_bInitialized = _check();
	return m_bInitialized;
}
Beispiel #5
0
//---------------------------------------------------------------------------------------
// Clear - Public
void CCglsAlgorithm::clear()
{
	CReconstructionAlgorithm2D::_clear();
	ASTRA_DELETE(r);
	ASTRA_DELETE(w);
	ASTRA_DELETE(z);
	ASTRA_DELETE(p);
	ASTRA_DELETE(t);
	ASTRA_DELETE(c);
	alpha = 0.0f;
	beta = 0.0f;
	gamma = 0.0f;
	m_iIteration = 0;
	m_bIsInitialized = false;
}
//----------------------------------------------------------------------------------------
// Iterate
void CBackProjectionAlgorithm::run(int _iNrIterations)
{
	// check initialized
	ASTRA_ASSERT(m_bIsInitialized);

	m_bShouldAbort = false;

	CDataProjectorInterface* pBackProjector;

	pBackProjector = dispatchDataProjector(
			m_pProjector, 
			SinogramMaskPolicy(m_pSinogramMask),														// sinogram mask
			ReconstructionMaskPolicy(m_pReconstructionMask),											// reconstruction mask
			DefaultBPPolicy(m_pReconstruction, m_pSinogram), // backprojection
			m_bUseSinogramMask, m_bUseReconstructionMask, true // options on/off
		); 

	m_pReconstruction->setData(0.0f);
	pBackProjector->project();

	ASTRA_DELETE(pBackProjector);
}
Beispiel #7
0
//----------------------------------------------------------------------------------------
// Clear
void CProjector3D::clear()
{
	ASTRA_DELETE(m_pProjectionGeometry);
	ASTRA_DELETE(m_pVolumeGeometry);
	m_bIsInitialized = false;
}
Beispiel #8
0
//----------------------------------------------------------------------------------------
// Iterate
void CCglsAlgorithm::run(int _iNrIterations)
{
	// check initialized
	ASTRA_ASSERT(m_bIsInitialized);

	// data projectors
	CDataProjectorInterface* pForwardProjector;
	CDataProjectorInterface* pFirstForwardProjector;
	CDataProjectorInterface* pBackProjector;

	// Clear reconstruction volume.
	if (m_bClearReconstruction) {
		m_pReconstruction->setData(0.0f);
	}

	// forward projection data projector
	if (m_bUseJacobiPreconditioner) {
		// w = A t
		pForwardProjector = dispatchDataProjector(
			m_pProjector, 
				SinogramMaskPolicy(m_pSinogramMask),					// sinogram mask
				ReconstructionMaskPolicy(m_pReconstructionMask),		// reconstruction mask
				DefaultFPPolicy(t, w),									// forward projection
				m_bUseSinogramMask, m_bUseReconstructionMask, true		// options on/off
			); 
	} else {
		// w = A p
		pForwardProjector = dispatchDataProjector(
			m_pProjector, 
				SinogramMaskPolicy(m_pSinogramMask),					// sinogram mask
				ReconstructionMaskPolicy(m_pReconstructionMask),		// reconstruction mask
				DefaultFPPolicy(p, w),									// forward projection
				m_bUseSinogramMask, m_bUseReconstructionMask, true		// options on/off
			); 
	}

	// backprojection data projector
	pBackProjector = dispatchDataProjector(
			m_pProjector, 
			SinogramMaskPolicy(m_pSinogramMask),														// sinogram mask
			ReconstructionMaskPolicy(m_pReconstructionMask),											// reconstruction mask
			DefaultBPPolicy(z, r),																		//  backprojection
			m_bUseSinogramMask, m_bUseReconstructionMask, true // options on/off
		); 

	// First forward projector to compute the Jacobi preconditioner, which
	// is just the norm squares of the columns of the projection matrix A
	// (it is diagonal of A' * A)
	pFirstForwardProjector = dispatchDataProjector(
		m_pProjector, 
			SinogramMaskPolicy(m_pSinogramMask),					// sinogram mask
			ReconstructionMaskPolicy(m_pReconstructionMask),		// reconstruction mask
			TotalPixelWeightPolicy(c, false, true),									// forward projection
			m_bUseSinogramMask, m_bUseReconstructionMask, true		// options on/off
		); 
	// Compute the Jacobi preconditioner.
	if (m_bUseJacobiPreconditioner) {
		c->setData(0.f);
		pFirstForwardProjector->project();
		// Compute sqrt
		c->sqrt();
	}

	int i;

	if (m_iIteration == 0) {
		// r = b;
		r->copyData(m_pSinogram->getData());
		// w = A*x0
		p->copyData(m_pReconstruction->getData());
		pForwardProjector->project();
		// r = b - A*x0
		*r -= *w;

		// z = A' * (b - A * x0) = A' * r
		z->setData(0.0f);
		pBackProjector->project();
		// CHECK
		//if (m_bUseMinConstraint)
		//	z->clampMin(m_fMinValue);
		//if (m_bUseMaxConstraint)
		//	z->clampMax(m_fMaxValue);

		// Precondition?
		if (m_bUseJacobiPreconditioner) {
			*z /= *c;
		}

		// p = z;
		p->copyData(z->getData());
		
		// gamma = dot(z,z);
		gamma = 0.0f;
		for (i = 0; i < z->getSize(); ++i) {
			gamma += z->getData()[i] * z->getData()[i];
		}

		m_iIteration++;
	}

	// start iterations
	//for (int iIteration = _iNrIterations-1; iIteration >= 0; --iIteration) {
	for (int iIteration = 0; iIteration < _iNrIterations; ++iIteration) {
		// start timer
		m_ulTimer = CPlatformDepSystemCode::getMSCount();

		if (m_bUseJacobiPreconditioner) {
			// t = C^-1 p
			t->copyData(p->getData());
			*t /= *c;
		}	

		// w = A*p (or A*t if precondioning)
		w->setData(0);
		pForwardProjector->project();
	
		// alpha = gamma/dot(w,w);
		float32 tmp = 0;
		for (i = 0; i < w->getSize(); ++i) {
			tmp += w->getData()[i] * w->getData()[i];
		}
		alpha = gamma / tmp;

		if (m_bUseJacobiPreconditioner) {
			// x = x + alpha*t;
			for (i = 0; i < m_pReconstruction->getSize(); ++i) {
				m_pReconstruction->getData()[i] += alpha * t->getData()[i];
			}
		} else {
			// x = x + alpha*p;
			for (i = 0; i < m_pReconstruction->getSize(); ++i) {
				m_pReconstruction->getData()[i] += alpha * p->getData()[i];
			}
		}

		// r = r - alpha*w;
		for (i = 0; i < r->getSize(); ++i) {
			r->getData()[i] -= alpha * w->getData()[i];
		}

		// z = A'*r;
		z->setData(0.0f);
		pBackProjector->project();

		// Precondition?
		if (m_bUseJacobiPreconditioner) {
			// z = C^-1 C
			*z /= *c;
		}

		// CHECKME: should these be here?
		// This was z. CHECK
		if (m_bUseMinConstraint)
			m_pReconstruction->clampMin(m_fMinValue);
		if (m_bUseMaxConstraint)
			m_pReconstruction->clampMax(m_fMaxValue);

		// beta = 1/gamma;
		beta = 1.0f / gamma;

		// gamma = dot(z,z);
		gamma = 0;
		for (i = 0; i < z->getSize(); ++i) {
			gamma += z->getData()[i] * z->getData()[i];
		}

		// beta = gamma*beta;
		beta *= gamma; 

		// p = z + beta*p;
		for (i = 0; i < z->getSize(); ++i) {
			p->getData()[i] = z->getData()[i] + beta * p->getData()[i];
		}
		
		// end timer
		m_ulTimer = CPlatformDepSystemCode::getMSCount() - m_ulTimer;

		// Compute metrics.
		computeIterationMetrics(iIteration, _iNrIterations, r);

		m_iIteration++;
	}

	ASTRA_DELETE(pForwardProjector);
	ASTRA_DELETE(pBackProjector);
	ASTRA_DELETE(pFirstForwardProjector);

	//if (m_iIteration == 0) {
	//	// r = b;
	//	r->copyData(m_pSinogram->getData());

	//	// z = A'*b;
	//	z->setData(0.0f);
	//	pBackProjector->project();
	//	// CHECK
	//	//if (m_bUseMinConstraint)
	//	//	z->clampMin(m_fMinValue);
	//	//if (m_bUseMaxConstraint)
	//	//	z->clampMax(m_fMaxValue);

	//	// p = z;
	//	p->copyData(z->getData());

	//	// gamma = dot(z,z);
	//	gamma = 0.0f;
	//	for (i = 0; i < z->getSize(); ++i) {
	//		gamma += z->getData()[i] * z->getData()[i];
	//	}
	//	
	//	m_iIteration++;
	//}


	//// start iterations
	////for (int iIteration = _iNrIterations-1; iIteration >= 0; --iIteration) {
	//for (int iIteration = 0; iIteration < _iNrIterations; ++iIteration) {
	//	// start timer
	//	m_ulTimer = CPlatformDepSystemCode::getMSCount();
	//
	//	// w = A*p;
	//	pForwardProjector->project();
	//
	//	// alpha = gamma/dot(w,w);
	//	float32 tmp = 0;
	//	for (i = 0; i < w->getSize(); ++i) {
	//		tmp += w->getData()[i] * w->getData()[i];
	//	}
	//	alpha = gamma / tmp;

	//	// x = x + alpha*p;
	//	for (i = 0; i < m_pReconstruction->getSize(); ++i) {
	//		m_pReconstruction->getData()[i] += alpha * p->getData()[i];
	//	}

	//	// r = r - alpha*w;
	//	for (i = 0; i < r->getSize(); ++i) {
	//		r->getData()[i] -= alpha * w->getData()[i];
	//	}

	//	// z = A'*r;
	//	z->setData(0.0f);
	//	pBackProjector->project();

	//	// CHECKME: should these be here?
	//	// This was z. CHECK
	//	if (m_bUseMinConstraint)
	//		m_pReconstruction->clampMin(m_fMinValue);
	//	if (m_bUseMaxConstraint)
	//		m_pReconstruction->clampMax(m_fMaxValue);

	//	// beta = 1/gamma;
	//	beta = 1.0f / gamma;

	//	// gamma = dot(z,z);
	//	gamma = 0;
	//	for (i = 0; i < z->getSize(); ++i) {
	//		gamma += z->getData()[i] * z->getData()[i];
	//	}

	//	// beta = gamma*beta;
	//	beta *= gamma; 

	//	// p = z + beta*p;
	//	for (i = 0; i < z->getSize(); ++i) {
	//		p->getData()[i] = z->getData()[i] + beta * p->getData()[i];
	//	}
	//	
	//	// end timer
	//	m_ulTotalTime += CPlatformDepSystemCode::getMSCount() - m_ulTimer;

	//	// Compute metrics.
	//	computeIterationMetrics(iIteration, _iNrIterations);

	//	m_iIteration++;
	//}

}
//----------------------------------------------------------------------------------------
// Iterate
void CSirtAlgorithm::run(int _iNrIterations)
{
    // check initialized
    ASTRA_ASSERT(m_bIsInitialized);

    m_bShouldAbort = false;

    int iIteration = 0;

    // data projectors
    CDataProjectorInterface* pForwardProjector;
    CDataProjectorInterface* pBackProjector;
    CDataProjectorInterface* pFirstForwardProjector;

    m_pTotalRayLength->setData(0.0f);
    m_pTotalPixelWeight->setData(0.0f);

    // forward projection data projector
    pForwardProjector = dispatchDataProjector(
                            m_pProjector,
                            SinogramMaskPolicy(m_pSinogramMask),														// sinogram mask
                            ReconstructionMaskPolicy(m_pReconstructionMask),											// reconstruction mask
                            DiffFPPolicy(m_pReconstruction, m_pDiffSinogram, m_pSinogram),								// forward projection with difference calculation
                            m_bUseSinogramMask, m_bUseReconstructionMask, true											// options on/off
                        );

    // backprojection data projector
    pBackProjector = dispatchDataProjector(
                         m_pProjector,
                         SinogramMaskPolicy(m_pSinogramMask),														// sinogram mask
                         ReconstructionMaskPolicy(m_pReconstructionMask),											// reconstruction mask
                         DefaultBPPolicy(m_pTmpVolume, m_pDiffSinogram), // backprojection
                         m_bUseSinogramMask, m_bUseReconstructionMask, true // options on/off
                     );

    // first time forward projection data projector,
    // also computes total pixel weight and total ray length
    pFirstForwardProjector = dispatchDataProjector(
                                 m_pProjector,
                                 SinogramMaskPolicy(m_pSinogramMask),														// sinogram mask
                                 ReconstructionMaskPolicy(m_pReconstructionMask),											// reconstruction mask
                                 Combine3Policy<DiffFPPolicy, TotalPixelWeightPolicy, TotalRayLengthPolicy>(					// 3 basic operations
                                     DiffFPPolicy(m_pReconstruction, m_pDiffSinogram, m_pSinogram),								// forward projection with difference calculation
                                     TotalPixelWeightPolicy(m_pTotalPixelWeight),												// calculate the total pixel weights
                                     TotalRayLengthPolicy(m_pTotalRayLength)),													// calculate the total ray lengths
                                 m_bUseSinogramMask, m_bUseReconstructionMask, true											 // options on/off
                             );



    // forward projection, difference calculation and raylength/pixelweight computation
    pFirstForwardProjector->project();

    float32* pfT = m_pTotalPixelWeight->getData();
    for (int i = 0; i < m_pTotalPixelWeight->getSize(); ++i) {
        float32 x = pfT[i];
        if (x < -eps || x > eps)
            x = 1.0f / x;
        else
            x = 0.0f;
        pfT[i] = x;
    }
    pfT = m_pTotalRayLength->getData();
    for (int i = 0; i < m_pTotalRayLength->getSize(); ++i) {
        float32 x = pfT[i];
        if (x < -eps || x > eps)
            x = 1.0f / x;
        else
            x = 0.0f;
        pfT[i] = x;
    }

    // divide by line weights
    (*m_pDiffSinogram) *= (*m_pTotalRayLength);

    // backprojection
    m_pTmpVolume->setData(0.0f);
    pBackProjector->project();

    // divide by pixel weights
    (*m_pTmpVolume) *= (*m_pTotalPixelWeight);
    (*m_pReconstruction) += (*m_pTmpVolume);

    if (m_bUseMinConstraint)
        m_pReconstruction->clampMin(m_fMinValue);
    if (m_bUseMaxConstraint)
        m_pReconstruction->clampMax(m_fMaxValue);

    // update iteration count
    m_iIterationCount++;
    iIteration++;




    // iteration loop
    for (; iIteration < _iNrIterations && !m_bShouldAbort; ++iIteration) {
        // forward projection and difference calculation
        pForwardProjector->project();

        // divide by line weights
        (*m_pDiffSinogram) *= (*m_pTotalRayLength);


        // backprojection
        m_pTmpVolume->setData(0.0f);
        pBackProjector->project();

        // divide by pixel weights
        (*m_pTmpVolume) *= (*m_pTotalPixelWeight);
        (*m_pReconstruction) += (*m_pTmpVolume);

        if (m_bUseMinConstraint)
            m_pReconstruction->clampMin(m_fMinValue);
        if (m_bUseMaxConstraint)
            m_pReconstruction->clampMax(m_fMaxValue);

        // update iteration count
        m_iIterationCount++;
    }


    ASTRA_DELETE(pForwardProjector);
    ASTRA_DELETE(pBackProjector);
    ASTRA_DELETE(pFirstForwardProjector);
}
Beispiel #10
0
//----------------------------------------------------------------------------------------
// Iterate
void CSirtAlgorithm::run(int _iNrIterations)
{
	// check initialized
	ASTRA_ASSERT(m_bIsInitialized);

	m_bShouldAbort = false;

	// data projectors
	CDataProjectorInterface* pForwardProjector;
	CDataProjectorInterface* pBackProjector;
	CDataProjectorInterface* pFirstForwardProjector;

	// Initialize m_pReconstruction to zero.
	if (m_bClearReconstruction) {
		m_pReconstruction->setData(0.f);
	}

	// forward projection data projector
	pForwardProjector = dispatchDataProjector(
		m_pProjector, 
			SinogramMaskPolicy(m_pSinogramMask),														// sinogram mask
			ReconstructionMaskPolicy(m_pReconstructionMask),											// reconstruction mask
			DiffFPPolicy(m_pReconstruction, m_pDiffSinogram, m_pSinogram),								// forward projection with difference calculation
			m_bUseSinogramMask, m_bUseReconstructionMask, true											// options on/off
		); 

	// backprojection data projector
	pBackProjector = dispatchDataProjector(
			m_pProjector, 
			SinogramMaskPolicy(m_pSinogramMask),														// sinogram mask
			ReconstructionMaskPolicy(m_pReconstructionMask),											// reconstruction mask
			SIRTBPPolicy(m_pReconstruction, m_pDiffSinogram, 
			m_pTotalPixelWeight, m_pTotalRayLength, m_fAlpha),  // SIRT backprojection
			m_bUseSinogramMask, m_bUseReconstructionMask, true // options on/off
		); 

	// first time forward projection data projector,
	// also computes total pixel weight and total ray length
	pFirstForwardProjector = dispatchDataProjector(
			m_pProjector, 
			SinogramMaskPolicy(m_pSinogramMask),														// sinogram mask
			ReconstructionMaskPolicy(m_pReconstructionMask),											// reconstruction mask
			Combine3Policy<DiffFPPolicy, TotalPixelWeightPolicy, TotalRayLengthPolicy>(					// 3 basic operations
				DiffFPPolicy(m_pReconstruction, m_pDiffSinogram, m_pSinogram),								// forward projection with difference calculation
				TotalPixelWeightPolicy(m_pTotalPixelWeight),												// calculate the total pixel weights
				TotalRayLengthPolicy(m_pTotalRayLength)),													// calculate the total ray lengths
			m_bUseSinogramMask, m_bUseReconstructionMask, true											 // options on/off
		);

	// Perform the first forward projection to compute ray lengths and pixel weights
	m_pTotalRayLength->setData(0.0f);
	m_pTotalPixelWeight->setData(0.0f);
	pFirstForwardProjector->project();

	// iteration loop, each iteration loops over all available projections
	for (int iIteration = 0; iIteration < _iNrIterations && !m_bShouldAbort; ++iIteration) {
		// start timer
		m_ulTimer = CPlatformDepSystemCode::getMSCount();
		// forward projection to compute differences.
		pForwardProjector->project(); 
		// backprojection
		pBackProjector->project(); 
		// update iteration count
		m_iIterationCount++;

		if (m_bUseMinConstraint)
			m_pReconstruction->clampMin(m_fMinValue);
		if (m_bUseMaxConstraint)
			m_pReconstruction->clampMax(m_fMaxValue);

		// end timer
		m_ulTimer = CPlatformDepSystemCode::getMSCount() - m_ulTimer;

		// Compute metrics.
		computeIterationMetrics(iIteration, _iNrIterations, m_pDiffSinogram);
	}

	ASTRA_DELETE(pForwardProjector);
	ASTRA_DELETE(pBackProjector);
	ASTRA_DELETE(pFirstForwardProjector);


	//// check initialized
	//ASTRA_ASSERT(m_bIsInitialized);

	//m_bShouldAbort = false;

	//int iIteration = 0;

	//// data projectors
	//CDataProjectorInterface* pForwardProjector;
	//CDataProjectorInterface* pBackProjector;
	//CDataProjectorInterface* pFirstForwardProjector;

	//m_pTotalRayLength->setData(0.0f);
	//m_pTotalPixelWeight->setData(0.0f);

	//// forward projection data projector
	//pForwardProjector = dispatchDataProjector(
	//	m_pProjector, 
	//		SinogramMaskPolicy(m_pSinogramMask),														// sinogram mask
	//		ReconstructionMaskPolicy(m_pReconstructionMask),											// reconstruction mask
	//		DiffFPPolicy(m_pReconstruction, m_pDiffSinogram, m_pSinogram),								// forward projection with difference calculation
	//		m_bUseSinogramMask, m_bUseReconstructionMask, true											// options on/off
	//	); 

	//// backprojection data projector
	//pBackProjector = dispatchDataProjector(
	//		m_pProjector, 
	//		SinogramMaskPolicy(m_pSinogramMask),														// sinogram mask
	//		ReconstructionMaskPolicy(m_pReconstructionMask),											// reconstruction mask
	//		DefaultBPPolicy(m_pTmpVolume, m_pDiffSinogram), // backprojection
	//		m_bUseSinogramMask, m_bUseReconstructionMask, true // options on/off
	//	); 

	//// first time forward projection data projector,
	//// also computes total pixel weight and total ray length
	//pFirstForwardProjector = dispatchDataProjector(
	//		m_pProjector, 
	//		SinogramMaskPolicy(m_pSinogramMask),														// sinogram mask
	//		ReconstructionMaskPolicy(m_pReconstructionMask),											// reconstruction mask
	//		Combine3Policy<DiffFPPolicy, TotalPixelWeightPolicy, TotalRayLengthPolicy>(					// 3 basic operations
	//			DiffFPPolicy(m_pReconstruction, m_pDiffSinogram, m_pSinogram),								// forward projection with difference calculation
	//			TotalPixelWeightPolicy(m_pTotalPixelWeight),												// calculate the total pixel weights
	//			TotalRayLengthPolicy(m_pTotalRayLength)),													// calculate the total ray lengths
	//		m_bUseSinogramMask, m_bUseReconstructionMask, true											 // options on/off
	//	);



	//// forward projection, difference calculation and raylength/pixelweight computation
	//pFirstForwardProjector->project();

	//float32* pfT = m_pTotalPixelWeight->getData();
	//for (int i = 0; i < m_pTotalPixelWeight->getSize(); ++i) {
	//	float32 x = pfT[i];
	//	if (x < -eps || x > eps)
	//		x = 1.0f / x;
	//	else
	//		x = 0.0f;
	//	pfT[i] = x;
	//}
	//pfT = m_pTotalRayLength->getData();
	//for (int i = 0; i < m_pTotalRayLength->getSize(); ++i) {
	//	float32 x = pfT[i];
	//	if (x < -eps || x > eps)
	//		x = 1.0f / x;
	//	else
	//		x = 0.0f;
	//	pfT[i] = x;
	//}

	//// divide by line weights
	//(*m_pDiffSinogram) *= (*m_pTotalRayLength);

	//// backprojection
	//m_pTmpVolume->setData(0.0f);
	//pBackProjector->project();

	//// divide by pixel weights
	//(*m_pTmpVolume) *= (*m_pTotalPixelWeight);
	//(*m_pReconstruction) += (*m_pTmpVolume);

	//if (m_bUseMinConstraint)
	//	m_pReconstruction->clampMin(m_fMinValue);
	//if (m_bUseMaxConstraint)
	//	m_pReconstruction->clampMax(m_fMaxValue);

	//// update iteration count
	//m_iIterationCount++;
	//iIteration++;


	//

	//// iteration loop
	//for (; iIteration < _iNrIterations && !m_bShouldAbort; ++iIteration) {
	//	// forward projection and difference calculation
	//	pForwardProjector->project();

	//	// divide by line weights
	//	(*m_pDiffSinogram) *= (*m_pTotalRayLength);


	//	// backprojection
	//	m_pTmpVolume->setData(0.0f);
	//	pBackProjector->project();

	//	// divide by pixel weights
	//	(*m_pTmpVolume) *= (*m_pTotalPixelWeight);
	//	(*m_pReconstruction) += (*m_pTmpVolume);

	//	if (m_bUseMinConstraint)
	//		m_pReconstruction->clampMin(m_fMinValue);
	//	if (m_bUseMaxConstraint)
	//		m_pReconstruction->clampMax(m_fMaxValue);

	//	// update iteration count
	//	m_iIterationCount++;
	//}


	//ASTRA_DELETE(pForwardProjector);
	//ASTRA_DELETE(pBackProjector);
	//ASTRA_DELETE(pFirstForwardProjector);
}
//---------------------------------------------------------------------------------------
// Initialize - Config
bool CReconstructionAlgorithmMultiSlice2D::initialize(const Config& _cfg)
{
	ASTRA_ASSERT(_cfg.self);
	ConfigStackCheck<CAlgorithm> CC("ReconstructionAlgorithmMultiSlice2D", this, _cfg);
	
	// projector
	XMLNode* node = _cfg.self->getSingleNode("ProjectorId");
	ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ProjectorId tag specified.");
	int id = node->getContentInt();
	m_pProjector = CProjector2DManager::getSingleton().get(id);
	ASTRA_DELETE(node);
	CC.markNodeParsed("ProjectorId");

	// sinogram data
	node = _cfg.self->getSingleNode("ProjectionDataId");
	ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ProjectionDataId tag specified.");
	vector<float32> tmpvector = node->getContentNumericalArray();
	for (unsigned int i = 0; i < tmpvector.size(); ++i) {
		m_vpSinogram.push_back(dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(int(tmpvector[i]))));
	}
	m_iSliceCount = tmpvector.size();
	ASTRA_DELETE(node);
	CC.markNodeParsed("ProjectionDataId");

	// reconstruction data
	node = _cfg.self->getSingleNode("ReconstructionDataId");
	ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ReconstructionDataId tag specified.");
	tmpvector =  node->getContentNumericalArray();
	for (unsigned int i = 0; i < tmpvector.size(); ++i) {
		m_vpReconstruction.push_back(dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(int(tmpvector[i]))));
	}
	ASTRA_DELETE(node);
	CC.markNodeParsed("ReconstructionDataId");

	// reconstruction masks
	if (_cfg.self->hasOption("ReconstructionMaskId")) {
		m_bUseReconstructionMask = true;
		id = _cfg.self->getOptionInt("ReconstructionMaskId");
		m_pReconstructionMask = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id));
	}
	CC.markOptionParsed("ReconstructionMaskId");

	// sinogram masks
	if (_cfg.self->hasOption("SinogramMaskId")) {
		m_bUseSinogramMask = true;
		id = _cfg.self->getOptionInt("SinogramMaskId");
		m_pSinogramMask = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));
	}
	CC.markOptionParsed("SinogramMaskId");

	// Constraints - NEW
	if (_cfg.self->hasOption("MinConstraint")) {
		m_bUseMinConstraint = true;
		m_fMinValue = _cfg.self->getOptionNumerical("MinConstraint", 0.0f);
		CC.markOptionParsed("MinConstraint");
	} else {
		// Constraint - OLD
		m_bUseMinConstraint = _cfg.self->getOptionBool("UseMinConstraint", false);
		CC.markOptionParsed("UseMinConstraint");
		if (m_bUseMinConstraint) {
			m_fMinValue = _cfg.self->getOptionNumerical("MinConstraintValue", 0.0f);
			CC.markOptionParsed("MinConstraintValue");
		}
	}
	if (_cfg.self->hasOption("MaxConstraint")) {
		m_bUseMaxConstraint = true;
		m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraint", 255.0f);
		CC.markOptionParsed("MaxConstraint");
	} else {
		// Constraint - OLD
		m_bUseMaxConstraint = _cfg.self->getOptionBool("UseMaxConstraint", false);
		CC.markOptionParsed("UseMaxConstraint");
		if (m_bUseMaxConstraint) {
			m_fMaxValue = _cfg.self->getOptionNumerical("MaxConstraintValue", 0.0f);
			CC.markOptionParsed("MaxConstraintValue");
		}
	}

	// return success
	return _check();
}
//---------------------------------------------------------------------------------------
// Initialize, use a Config object
bool CFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)
{
	ASTRA_ASSERT(_cfg.self);
	
	// projector
	XMLNode* node = _cfg.self->getSingleNode("ProjectorId");
	ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ProjectorId tag specified.");
	int id = boost::lexical_cast<int>(node->getContent());
	m_pProjector = CProjector2DManager::getSingleton().get(id);
	ASTRA_DELETE(node);

	// sinogram data
	node = _cfg.self->getSingleNode("ProjectionDataId");
	ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ProjectionDataId tag specified.");
	id = boost::lexical_cast<int>(node->getContent());
	m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));
	ASTRA_DELETE(node);

	// volume data
	node = _cfg.self->getSingleNode("ReconstructionDataId");
	ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ReconstructionDataId tag specified.");
	id = boost::lexical_cast<int>(node->getContent());
	m_pReconstruction = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id));
	ASTRA_DELETE(node);

	node = _cfg.self->getSingleNode("ProjectionIndex");
	if (node) 
	{
		vector<float32> projectionIndex = node->getContentNumericalArray();

		int angleCount = projectionIndex.size();
		int detectorCount = m_pProjector->getProjectionGeometry()->getDetectorCount();

		float32 * sinogramData2D = new float32[angleCount* detectorCount];
		float32 ** sinogramData = new float32*[angleCount];
		for (int i = 0; i < angleCount; i++)
		{
			sinogramData[i] = &(sinogramData2D[i * detectorCount]);
		}

		float32 * projectionAngles = new float32[angleCount];
		float32 detectorWidth = m_pProjector->getProjectionGeometry()->getDetectorWidth();

		for (int i = 0; i < angleCount; i ++) {
			if (projectionIndex[i] > m_pProjector->getProjectionGeometry()->getProjectionAngleCount() -1 )
			{
				cout << "Invalid Projection Index" << endl;
				return false;
			} else {
				int orgIndex = (int)projectionIndex[i];

				for (int iDetector=0; iDetector < detectorCount; iDetector++) 
				{
					sinogramData2D[i*detectorCount+ iDetector] = m_pSinogram->getData2D()[orgIndex][iDetector];
				}
//				sinogramData[i] = m_pSinogram->getSingleProjectionData(projectionIndex[i]);
				projectionAngles[i] = m_pProjector->getProjectionGeometry()->getProjectionAngle((int)projectionIndex[i] );

			}
		}

		CParallelProjectionGeometry2D * pg = new CParallelProjectionGeometry2D(angleCount, detectorCount,detectorWidth,projectionAngles);
		m_pProjector = new CParallelBeamLineKernelProjector2D(pg,m_pReconstruction->getGeometry());
		m_pSinogram = new CFloat32ProjectionData2D(pg, sinogramData2D);
	}
	ASTRA_DELETE(node);

	// TODO: check that the angles are linearly spaced between 0 and pi

	// success
	m_bIsInitialized = _check();
	return m_bIsInitialized;
}