//--------------------------------------------------------------------------------------- // 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; }
//--------------------------------------------------------------------------------------- // 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); }
//---------------------------------------------------------------------------------------- // Clear void CProjector3D::clear() { ASTRA_DELETE(m_pProjectionGeometry); ASTRA_DELETE(m_pVolumeGeometry); m_bIsInitialized = false; }
//---------------------------------------------------------------------------------------- // 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); }
//---------------------------------------------------------------------------------------- // 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; }