From b2fc6c70434674d74551c3a6c01ffb3233499312 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Mon, 1 Jul 2013 22:34:11 +0000 Subject: Update version to 1.3 --- src/ForwardProjectionAlgorithm.cpp | 280 +++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 src/ForwardProjectionAlgorithm.cpp (limited to 'src/ForwardProjectionAlgorithm.cpp') diff --git a/src/ForwardProjectionAlgorithm.cpp b/src/ForwardProjectionAlgorithm.cpp new file mode 100644 index 0000000..970d5b0 --- /dev/null +++ b/src/ForwardProjectionAlgorithm.cpp @@ -0,0 +1,280 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see . + +----------------------------------------------------------------------- +$Id$ +*/ + +#include "astra/ForwardProjectionAlgorithm.h" + +#include + +#include "astra/AstraObjectManager.h" +#include "astra/DataProjectorPolicies.h" + +using namespace std; + +namespace astra { + +#include "astra/Projector2DImpl.inl" + +// type of the algorithm, needed to register with CAlgorithmFactory +std::string CForwardProjectionAlgorithm::type = "FP"; + +//---------------------------------------------------------------------------------------- +// Constructor - Default +CForwardProjectionAlgorithm::CForwardProjectionAlgorithm() +{ + _clear(); +} + +//---------------------------------------------------------------------------------------- +// Constructor +CForwardProjectionAlgorithm::CForwardProjectionAlgorithm(CProjector2D* _pProjector, CFloat32VolumeData2D* _pVolume, CFloat32ProjectionData2D* _pSinogram) +{ + _clear(); + initialize(_pProjector, _pVolume, _pSinogram); +} + +//---------------------------------------------------------------------------------------- +// Destructor +CForwardProjectionAlgorithm::~CForwardProjectionAlgorithm() +{ + delete m_pForwardProjector; + clear(); +} + +//--------------------------------------------------------------------------------------- +// Clear - Constructors +void CForwardProjectionAlgorithm::_clear() +{ + m_pProjector = NULL; + m_pSinogram = NULL; + m_pVolume = NULL; + m_pForwardProjector = NULL; + m_bUseSinogramMask = false; + m_bUseVolumeMask = false; + m_bIsInitialized = false; +} + +//--------------------------------------------------------------------------------------- +// Clear - Public +void CForwardProjectionAlgorithm::clear() +{ + m_pProjector = NULL; + m_pSinogram = NULL; + m_pVolume = NULL; + m_bUseSinogramMask = false; + m_bUseVolumeMask = false; + m_bIsInitialized = false; +} + +//---------------------------------------------------------------------------------------- +// Check +bool CForwardProjectionAlgorithm::_check() +{ + // check pointers + ASTRA_CONFIG_CHECK(m_pProjector, "ForwardProjection", "Invalid Projector Object."); + ASTRA_CONFIG_CHECK(m_pSinogram, "ForwardProjection", "Invalid Projection Data Object."); + ASTRA_CONFIG_CHECK(m_pVolume, "ForwardProjection", "Invalid Volume Data Object."); + + // check initializations + ASTRA_CONFIG_CHECK(m_pProjector->isInitialized(), "ForwardProjection", "Projector Object Not Initialized."); + ASTRA_CONFIG_CHECK(m_pSinogram->isInitialized(), "ForwardProjection", "Projection Data Object Not Initialized."); + ASTRA_CONFIG_CHECK(m_pVolume->isInitialized(), "ForwardProjection", "Volume Data Object Not Initialized."); + + // check compatibility between projector and data classes + ASTRA_CONFIG_CHECK(m_pSinogram->getGeometry()->isEqual(m_pProjector->getProjectionGeometry()), "ForwardProjection", "Projection Data not compatible with the specified Projector."); + ASTRA_CONFIG_CHECK(m_pVolume->getGeometry()->isEqual(m_pProjector->getVolumeGeometry()), "ForwardProjection", "Volume Data not compatible with the specified Projector."); + + ASTRA_CONFIG_CHECK(m_pForwardProjector, "ForwardProjection", "Invalid FP Policy"); + + // success + return true; +} + +//--------------------------------------------------------------------------------------- +// Initialize, use a Config object +bool CForwardProjectionAlgorithm::initialize(const Config& _cfg) +{ + ASTRA_ASSERT(_cfg.self); + + // if already initialized, clear first + if (m_bIsInitialized) { + clear(); + } + + // projector + XMLNode* node = _cfg.self->getSingleNode("ProjectorId"); + ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No ProjectorId tag specified."); + int id = boost::lexical_cast(node->getContent()); + m_pProjector = CProjector2DManager::getSingleton().get(id); + ASTRA_DELETE(node); + + // sinogram data + node = _cfg.self->getSingleNode("ProjectionDataId"); + ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No ProjectionDataId tag specified."); + id = boost::lexical_cast(node->getContent()); + m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); + ASTRA_DELETE(node); + + // volume data + node = _cfg.self->getSingleNode("VolumeDataId"); + ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No VolumeDataId tag specified."); + id = boost::lexical_cast(node->getContent()); + m_pVolume = dynamic_cast(CData2DManager::getSingleton().get(id)); + ASTRA_DELETE(node); + + // volume mask + if (_cfg.self->hasOption("VolumeMaskId")) { + m_bUseVolumeMask = true; + id = boost::lexical_cast(_cfg.self->getOption("VolumeMaskId")); + m_pVolumeMask = dynamic_cast(CData2DManager::getSingleton().get(id)); + } + + // sino mask + if (_cfg.self->hasOption("SinogramMaskId")) { + m_bUseSinogramMask = true; + id = boost::lexical_cast(_cfg.self->getOption("SinogramMaskId")); + m_pSinogramMask = dynamic_cast(CData2DManager::getSingleton().get(id)); + } + + // ray or voxel-driven projector? + //m_bUseVoxelProjector = _cfg.self->getOptionBool("VoxelDriven", false); + + // init data projector + _init(); + + // return success + m_bIsInitialized = _check(); + return m_bIsInitialized; +} + +//--------------------------------------------------------------------------------------- +// Get Information - all +map CForwardProjectionAlgorithm::getInformation() +{ + map result; + result["ProjectorId"] = getInformation("ProjectorId"); + result["ProjectionDataId"] = getInformation("ProjectionDataId"); + result["VolumeDataId"] = getInformation("VolumeDataId"); + return mergeMap(CAlgorithm::getInformation(), result); +}; + +//--------------------------------------------------------------------------------------- +// Get Information - specific +boost::any CForwardProjectionAlgorithm::getInformation(std::string _sIdentifier) +{ + if (_sIdentifier == "ProjectorId") { + int iIndex = CProjector2DManager::getSingleton().getIndex(m_pProjector); + if (iIndex != 0) return iIndex; + return std::string("not in manager"); + } else if (_sIdentifier == "ProjectionDataId") { + int iIndex = CData2DManager::getSingleton().getIndex(m_pSinogram); + if (iIndex != 0) return iIndex; + return std::string("not in manager"); + } else if (_sIdentifier == "VolumeDataId") { + int iIndex = CData2DManager::getSingleton().getIndex(m_pVolume); + if (iIndex != 0) return iIndex; + return std::string("not in manager"); + } + return CAlgorithm::getInformation(_sIdentifier); +}; + +//---------------------------------------------------------------------------------------- +// Initialize +bool CForwardProjectionAlgorithm::initialize(CProjector2D* _pProjector, + CFloat32VolumeData2D* _pVolume, + CFloat32ProjectionData2D* _pSinogram) +{ + // store classes + m_pProjector = _pProjector; + m_pVolume = _pVolume; + m_pSinogram = _pSinogram; + + // init data projector + _init(); + + // return success + m_bIsInitialized = _check(); + return m_bIsInitialized; +} + +//--------------------------------------------------------------------------------------- +// Initialize Data Projectors - private +void CForwardProjectionAlgorithm::_init() +{ + // forward projection data projector + m_pForwardProjector = dispatchDataProjector( + m_pProjector, + SinogramMaskPolicy(m_pSinogramMask), // sinogram mask + ReconstructionMaskPolicy(m_pVolumeMask), // reconstruction mask + DefaultFPPolicy(m_pVolume, m_pSinogram), // forward projection + m_bUseSinogramMask, m_bUseVolumeMask, true // options on/off + ); +} + +//---------------------------------------------------------------------------------------- +// Set Fixed Reconstruction Mask +void CForwardProjectionAlgorithm::setVolumeMask(CFloat32VolumeData2D* _pMask, bool _bEnable) +{ + // TODO: check geometry matches volume + m_bUseVolumeMask = _bEnable; + m_pVolumeMask = _pMask; + if (m_pVolumeMask == NULL) { + m_bUseVolumeMask = false; + } +} + +//---------------------------------------------------------------------------------------- +// Set Fixed Sinogram Mask +void CForwardProjectionAlgorithm::setSinogramMask(CFloat32ProjectionData2D* _pMask, bool _bEnable) +{ + // TODO: check geometry matches sinogram + m_bUseSinogramMask = _bEnable; + m_pSinogramMask = _pMask; + if (m_pSinogramMask == NULL) { + m_bUseSinogramMask = false; + } +} + +//---------------------------------------------------------------------------------------- +// Iterate +void CForwardProjectionAlgorithm::run(int _iNrIterations) +{ + // check initialized + ASTRA_ASSERT(m_bIsInitialized); + + m_pSinogram->setData(0.0f); + +// if (m_bUseVoxelProjector) { +// m_pForwardProjector->projectAllVoxels(); +// } else { + m_pForwardProjector->project(); +// } + +} +//---------------------------------------------------------------------------------------- + +} // namespace astra -- cgit v1.2.3