From 8220a50be6bcbddf179bb855b2f7d36436fcca6b Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Fri, 7 Dec 2018 16:41:40 +0100 Subject: More gracefully handle config errors in geometries --- src/ConeProjectionGeometry3D.cpp | 12 +++++- src/ConeVecProjectionGeometry3D.cpp | 36 ++++++++--------- src/FanFlatProjectionGeometry2D.cpp | 12 +++++- src/FanFlatVecProjectionGeometry2D.cpp | 36 +++++++++-------- src/ParallelVecProjectionGeometry2D.cpp | 44 +++++++++++--------- src/ParallelVecProjectionGeometry3D.cpp | 34 ++++++++-------- src/ProjectionGeometry2D.cpp | 50 +++++++++++++++++------ src/ProjectionGeometry3D.cpp | 71 ++++++++++++++++++++++++--------- src/Utilities.cpp | 10 +++++ src/VolumeGeometry2D.cpp | 24 ++++++++--- src/VolumeGeometry3D.cpp | 34 +++++++++++----- 11 files changed, 240 insertions(+), 123 deletions(-) (limited to 'src') diff --git a/src/ConeProjectionGeometry3D.cpp b/src/ConeProjectionGeometry3D.cpp index 90adfa8..8022591 100644 --- a/src/ConeProjectionGeometry3D.cpp +++ b/src/ConeProjectionGeometry3D.cpp @@ -88,13 +88,21 @@ bool CConeProjectionGeometry3D::initialize(const Config& _cfg) // Required: DistanceOriginDetector XMLNode node = _cfg.self.getSingleNode("DistanceOriginDetector"); ASTRA_CONFIG_CHECK(node, "ConeProjectionGeometry3D", "No DistanceOriginDetector tag specified."); - m_fOriginDetectorDistance = node.getContentNumerical(); + try { + m_fOriginDetectorDistance = node.getContentNumerical(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ConeProjectionGeometry3D", "DistanceOriginDetector must be numerical."); + } CC.markNodeParsed("DistanceOriginDetector"); // Required: DetectorOriginSource node = _cfg.self.getSingleNode("DistanceOriginSource"); ASTRA_CONFIG_CHECK(node, "ConeProjectionGeometry3D", "No DistanceOriginSource tag specified."); - m_fOriginSourceDistance = node.getContentNumerical(); + try { + m_fOriginSourceDistance = node.getContentNumerical(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ConeProjectionGeometry3D", "DistanceOriginSource must be numerical."); + } CC.markNodeParsed("DistanceOriginSource"); // success diff --git a/src/ConeVecProjectionGeometry3D.cpp b/src/ConeVecProjectionGeometry3D.cpp index 0e0f70b..177a0c7 100644 --- a/src/ConeVecProjectionGeometry3D.cpp +++ b/src/ConeVecProjectionGeometry3D.cpp @@ -72,29 +72,27 @@ bool CConeVecProjectionGeometry3D::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); ConfigStackCheck 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); + CProjectionGeometry3D::initialize(_cfg); - // Required: DetectorRowCount - node = _cfg.self.getSingleNode("DetectorRowCount"); - ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorRowCount = node.getContentInt(); - CC.markNodeParsed("DetectorRowCount"); + // success + m_bInitialized = _check(); + return m_bInitialized; +} - // Required: DetectorColCount - node = _cfg.self.getSingleNode("DetectorColCount"); - ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No DetectorColCount tag specified."); - m_iDetectorColCount = node.getContentInt(); - m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; - CC.markNodeParsed("DetectorColCount"); +bool CConeVecProjectionGeometry3D::initializeAngles(const Config& _cfg) +{ + ConfigStackCheck CC("ConeVecProjectionGeometry3D", this, _cfg); // Required: Vectors - node = _cfg.self.getSingleNode("Vectors"); + XMLNode node = _cfg.self.getSingleNode("Vectors"); ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No Vectors tag specified."); - vector data = node.getContentNumericalArrayDouble(); + vector data; + try { + data = node.getContentNumericalArrayDouble(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ConeVecProjectionGeometry3D", "Vectors must be a numerical matrix."); + } CC.markNodeParsed("Vectors"); ASTRA_CONFIG_CHECK(data.size() % 12 == 0, "ConeVecProjectionGeometry3D", "Vectors doesn't consist of 12-tuples."); m_iProjectionAngleCount = data.size() / 12; @@ -119,9 +117,7 @@ bool CConeVecProjectionGeometry3D::initialize(const Config& _cfg) 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; + return true; } //---------------------------------------------------------------------------------------- diff --git a/src/FanFlatProjectionGeometry2D.cpp b/src/FanFlatProjectionGeometry2D.cpp index da9133c..901cd7c 100644 --- a/src/FanFlatProjectionGeometry2D.cpp +++ b/src/FanFlatProjectionGeometry2D.cpp @@ -136,13 +136,21 @@ bool CFanFlatProjectionGeometry2D::initialize(const Config& _cfg) // Required: DistanceOriginDetector XMLNode node = _cfg.self.getSingleNode("DistanceOriginDetector"); ASTRA_CONFIG_CHECK(node, "FanFlatProjectionGeometry2D", "No DistanceOriginDetector tag specified."); - m_fOriginDetectorDistance = node.getContentNumerical(); + try { + m_fOriginDetectorDistance = node.getContentNumerical(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "FanFlatProjectionGeometry2D", "DistanceOriginDetector must be numerical."); + } CC.markNodeParsed("DistanceOriginDetector"); // Required: DetectorOriginSource node = _cfg.self.getSingleNode("DistanceOriginSource"); ASTRA_CONFIG_CHECK(node, "FanFlatProjectionGeometry2D", "No DistanceOriginSource tag specified."); - m_fOriginSourceDistance = node.getContentNumerical(); + try { + m_fOriginSourceDistance = node.getContentNumerical(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "FanFlatProjectionGeometry2D", "DistanceOriginSource must be numerical."); + } CC.markNodeParsed("DistanceOriginSource"); // success diff --git a/src/FanFlatVecProjectionGeometry2D.cpp b/src/FanFlatVecProjectionGeometry2D.cpp index 2a19233..074194b 100644 --- a/src/FanFlatVecProjectionGeometry2D.cpp +++ b/src/FanFlatVecProjectionGeometry2D.cpp @@ -116,22 +116,30 @@ bool CFanFlatVecProjectionGeometry2D::initialize(const Config& _cfg) XMLNode node; - // TODO: Fix up class hierarchy... this class doesn't fit very well. // initialization of parent class - //CProjectionGeometry2D::initialize(_cfg); + CProjectionGeometry2D::initialize(_cfg); - // Required: DetectorCount - node = _cfg.self.getSingleNode("DetectorCount"); - ASTRA_CONFIG_CHECK(node, "FanFlatVecProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorCount = node.getContentInt(); - CC.markNodeParsed("DetectorCount"); + + // success + m_bInitialized = _check(); + return m_bInitialized; +} + +bool CFanFlatVecProjectionGeometry2D::initializeAngles(const Config& _cfg) +{ + ConfigStackCheck CC("FanFlatVecProjectionGeometry2D", this, _cfg); // Required: Vectors - node = _cfg.self.getSingleNode("Vectors"); - ASTRA_CONFIG_CHECK(node, "FanFlatVecProjectionGeometry3D", "No Vectors tag specified."); - vector data = node.getContentNumericalArray(); + XMLNode node = _cfg.self.getSingleNode("Vectors"); + ASTRA_CONFIG_CHECK(node, "FanFlatVecProjectionGeometry2D", "No Vectors tag specified."); + vector data; + try { + data = node.getContentNumericalArray(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "FanFlatVecProjectionGeometry2D", "Vectors must be a numerical matrix."); + } CC.markNodeParsed("Vectors"); - ASTRA_CONFIG_CHECK(data.size() % 6 == 0, "FanFlatVecProjectionGeometry3D", "Vectors doesn't consist of 6-tuples."); + ASTRA_CONFIG_CHECK(data.size() % 6 == 0, "FanFlatVecProjectionGeometry2D", "Vectors doesn't consist of 6-tuples."); m_iProjectionAngleCount = data.size() / 6; m_pProjectionAngles = new SFanProjection[m_iProjectionAngleCount]; @@ -148,11 +156,7 @@ bool CFanFlatVecProjectionGeometry2D::initialize(const Config& _cfg) p.fDetSY = data[6*i + 3] - 0.5f * m_iDetectorCount * p.fDetUY; } - - - // success - m_bInitialized = _check(); - return m_bInitialized; + return true; } //---------------------------------------------------------------------------------------- diff --git a/src/ParallelVecProjectionGeometry2D.cpp b/src/ParallelVecProjectionGeometry2D.cpp index 8905a26..30682c5 100644 --- a/src/ParallelVecProjectionGeometry2D.cpp +++ b/src/ParallelVecProjectionGeometry2D.cpp @@ -29,7 +29,6 @@ along with the ASTRA Toolbox. If not, see . #include #include -#include using namespace std; @@ -100,20 +99,29 @@ bool CParallelVecProjectionGeometry2D::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); ConfigStackCheck CC("ParallelVecProjectionGeometry2D", this, _cfg); - // TODO: Fix up class hierarchy... this class doesn't fit very well. // initialization of parent class - //CProjectionGeometry2D::initialize(_cfg); + CProjectionGeometry2D::initialize(_cfg); - // Required: DetectorCount - XMLNode node = _cfg.self.getSingleNode("DetectorCount"); - ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry2D", "No DetectorRowCount tag specified."); - m_iDetectorCount = boost::lexical_cast(node.getContent()); - CC.markNodeParsed("DetectorCount"); + + // success + m_bInitialized = _check(); + return m_bInitialized; +} + +bool CParallelVecProjectionGeometry2D::initializeAngles(const Config& _cfg) +{ + ConfigStackCheck CC("ParallelVecProjectionGeometry2D", this, _cfg); // Required: Vectors - node = _cfg.self.getSingleNode("Vectors"); + XMLNode node = _cfg.self.getSingleNode("Vectors"); ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry2D", "No Vectors tag specified."); - vector data = node.getContentNumericalArray(); + vector data; + try { + data = node.getContentNumericalArray(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ParallelVecProjectionGeometry2D", "Vectors must be a numerical matrix."); + } + CC.markNodeParsed("Vectors"); ASTRA_CONFIG_CHECK(data.size() % 6 == 0, "ParallelVecProjectionGeometry2D", "Vectors doesn't consist of 6-tuples."); m_iProjectionAngleCount = data.size() / 6; @@ -132,9 +140,7 @@ bool CParallelVecProjectionGeometry2D::initialize(const Config& _cfg) p.fDetSY = data[6*i + 3] - 0.5f * m_iDetectorCount * p.fDetUY; } - // success - m_bInitialized = _check(); - return m_bInitialized; + return true; } //---------------------------------------------------------------------------------------- @@ -215,12 +221,12 @@ Config* CParallelVecProjectionGeometry2D::getConfiguration() const std::string vectors = ""; for (int i = 0; i < m_iProjectionAngleCount; ++i) { SParProjection& p = m_pProjectionAngles[i]; - vectors += boost::lexical_cast(p.fRayX) + ","; - vectors += boost::lexical_cast(p.fRayY) + ","; - vectors += boost::lexical_cast(p.fDetSX + 0.5f * m_iDetectorCount * p.fDetUX) + ","; - vectors += boost::lexical_cast(p.fDetSY + 0.5f * m_iDetectorCount * p.fDetUY) + ","; - vectors += boost::lexical_cast(p.fDetUX) + ","; - vectors += boost::lexical_cast(p.fDetUY); + vectors += StringUtil::toString(p.fRayX) + ","; + vectors += StringUtil::toString(p.fRayY) + ","; + vectors += StringUtil::toString(p.fDetSX + 0.5f * m_iDetectorCount * p.fDetUX) + ","; + vectors += StringUtil::toString(p.fDetSY + 0.5f * m_iDetectorCount * p.fDetUY) + ","; + vectors += StringUtil::toString(p.fDetUX) + ","; + vectors += StringUtil::toString(p.fDetUY); if (i < m_iProjectionAngleCount-1) vectors += ';'; } cfg->self.addChildNode("Vectors", vectors); diff --git a/src/ParallelVecProjectionGeometry3D.cpp b/src/ParallelVecProjectionGeometry3D.cpp index 58fc986..ed15b68 100644 --- a/src/ParallelVecProjectionGeometry3D.cpp +++ b/src/ParallelVecProjectionGeometry3D.cpp @@ -74,27 +74,27 @@ bool CParallelVecProjectionGeometry3D::initialize(const Config& _cfg) XMLNode node; - // TODO: Fix up class hierarchy... this class doesn't fit very well. // initialization of parent class - //CProjectionGeometry3D::initialize(_cfg); + CProjectionGeometry3D::initialize(_cfg); - // Required: DetectorRowCount - node = _cfg.self.getSingleNode("DetectorRowCount"); - ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorRowCount = node.getContentInt(); - CC.markNodeParsed("DetectorRowCount"); + // success + m_bInitialized = _check(); + return m_bInitialized; +} - // Required: DetectorCount - node = _cfg.self.getSingleNode("DetectorColCount"); - ASTRA_CONFIG_CHECK(node, "", "No DetectorColCount tag specified."); - m_iDetectorColCount = node.getContentInt(); - m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; - CC.markNodeParsed("DetectorColCount"); +bool CParallelVecProjectionGeometry3D::initializeAngles(const Config& _cfg) +{ + ConfigStackCheck CC("ParallelVecProjectionGeometry3D", this, _cfg); // Required: Vectors - node = _cfg.self.getSingleNode("Vectors"); + XMLNode node = _cfg.self.getSingleNode("Vectors"); ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry3D", "No Vectors tag specified."); - vector data = node.getContentNumericalArrayDouble(); + vector data; + try { + data = node.getContentNumericalArrayDouble(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ParallelVecProjectionGeometry3D", "Vectors must be a numerical matrix."); + } CC.markNodeParsed("Vectors"); ASTRA_CONFIG_CHECK(data.size() % 12 == 0, "ParallelVecProjectionGeometry3D", "Vectors doesn't consist of 12-tuples."); m_iProjectionAngleCount = data.size() / 12; @@ -119,9 +119,7 @@ bool CParallelVecProjectionGeometry3D::initialize(const Config& _cfg) 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; + return true; } //---------------------------------------------------------------------------------------- diff --git a/src/ProjectionGeometry2D.cpp b/src/ProjectionGeometry2D.cpp index 64674bf..15be1d5 100644 --- a/src/ProjectionGeometry2D.cpp +++ b/src/ProjectionGeometry2D.cpp @@ -116,22 +116,50 @@ bool CProjectionGeometry2D::initialize(const Config& _cfg) clear(); } + // Required: DetectorCount + XMLNode node = _cfg.self.getSingleNode("DetectorCount"); + ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No DetectorCount tag specified."); + try { + m_iDetectorCount = node.getContentInt(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ProjectionGeometry2D", "DetectorCount must be an integer."); + } + CC.markNodeParsed("DetectorCount"); + + if (!initializeAngles(_cfg)) + return false; + + // some checks + ASTRA_CONFIG_CHECK(m_iDetectorCount > 0, "ProjectionGeometry2D", "DetectorCount should be positive."); + + // Interface class, so don't return true + return false; +} + +bool CProjectionGeometry2D::initializeAngles(const Config& _cfg) +{ + ConfigStackCheck CC("ProjectionGeometry2D", this, _cfg); + // Required: DetectorWidth XMLNode node = _cfg.self.getSingleNode("DetectorWidth"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No DetectorWidth tag specified."); - m_fDetectorWidth = node.getContentNumerical(); + try { + m_fDetectorWidth = node.getContentNumerical(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ProjectionGeometry2D", "DetectorWidth must be numerical."); + } CC.markNodeParsed("DetectorWidth"); - // Required: DetectorCount - node = _cfg.self.getSingleNode("DetectorCount"); - ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No DetectorCount tag specified."); - m_iDetectorCount = node.getContentInt(); - CC.markNodeParsed("DetectorCount"); // Required: ProjectionAngles node = _cfg.self.getSingleNode("ProjectionAngles"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No ProjectionAngles tag specified."); - vector angles = node.getContentNumericalArray(); + vector angles; + try { + angles = node.getContentNumericalArray(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ProjectionGeometry2D", "ProjectionAngles must be a numerical vector."); + } m_iProjectionAngleCount = angles.size(); ASTRA_CONFIG_CHECK(m_iProjectionAngleCount > 0, "ProjectionGeometry2D", "Not enough ProjectionAngles specified."); m_pfProjectionAngles = new float32[m_iProjectionAngleCount]; @@ -139,14 +167,10 @@ bool CProjectionGeometry2D::initialize(const Config& _cfg) m_pfProjectionAngles[i] = angles[i]; } CC.markNodeParsed("ProjectionAngles"); - - // 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; + ASTRA_CONFIG_CHECK(m_fDetectorWidth > 0.0f, "ProjectionGeometry2D", "DetectorWidth should be positive."); + return true; } //---------------------------------------------------------------------------------------- diff --git a/src/ProjectionGeometry3D.cpp b/src/ProjectionGeometry3D.cpp index bea88ab..92de247 100644 --- a/src/ProjectionGeometry3D.cpp +++ b/src/ProjectionGeometry3D.cpp @@ -133,7 +133,7 @@ void CProjectionGeometry3D::clear() } //---------------------------------------------------------------------------------------- -// Initialization witha Config object +// Initialization with a Config object bool CProjectionGeometry3D::initialize(const Config& _cfg) { ASTRA_ASSERT(_cfg.self); @@ -145,35 +145,70 @@ bool CProjectionGeometry3D::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); - // Required: DetectorWidth - XMLNode node = _cfg.self.getSingleNode("DetectorSpacingX"); - ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorSpacingX tag specified."); - m_fDetectorSpacingX = node.getContentNumerical(); - CC.markNodeParsed("DetectorSpacingX"); - - // Required: DetectorHeight - node = _cfg.self.getSingleNode("DetectorSpacingY"); - ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorSpacingY tag specified."); - m_fDetectorSpacingY = node.getContentNumerical(); - CC.markNodeParsed("DetectorSpacingY"); // Required: DetectorRowCount - node = _cfg.self.getSingleNode("DetectorRowCount"); + XMLNode node = _cfg.self.getSingleNode("DetectorRowCount"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorRowCount = node.getContentInt(); + try { + m_iDetectorRowCount = node.getContentInt(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ProjectionGeometry3D", "DetectorRowCount must be an integer."); + } CC.markNodeParsed("DetectorRowCount"); // Required: DetectorCount node = _cfg.self.getSingleNode("DetectorColCount"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorColCount tag specified."); - m_iDetectorColCount = node.getContentInt(); + try { + m_iDetectorColCount = node.getContentInt(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ProjectionGeometry3D", "DetectorColCount must be an integer."); + } m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; CC.markNodeParsed("DetectorColCount"); + + if (!initializeAngles(_cfg)) + return false; + + + // Interface class, so don't return true + return false; +} + +bool CProjectionGeometry3D::initializeAngles(const Config& _cfg) +{ + ConfigStackCheck CC("ProjectionGeometry3D", this, _cfg); + + // Required: DetectorWidth + XMLNode node = _cfg.self.getSingleNode("DetectorSpacingX"); + ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorSpacingX tag specified."); + try { + m_fDetectorSpacingX = node.getContentNumerical(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ProjectionGeometry3D", "DetectorSpacingX must be numerical."); + } + CC.markNodeParsed("DetectorSpacingX"); + + // Required: DetectorHeight + node = _cfg.self.getSingleNode("DetectorSpacingY"); + ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorSpacingY tag specified."); + try { + m_fDetectorSpacingY = node.getContentNumerical(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ProjectionGeometry3D", "DetectorSpacingY must be numerical."); + } + CC.markNodeParsed("DetectorSpacingY"); + // Required: ProjectionAngles node = _cfg.self.getSingleNode("ProjectionAngles"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No ProjectionAngles tag specified."); - vector angles = node.getContentNumericalArray(); + vector angles; + try { + angles = node.getContentNumericalArray(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "ProjectionGeometry3D", "ProjectionAngles must be a numerical vector."); + } m_iProjectionAngleCount = angles.size(); ASTRA_CONFIG_CHECK(m_iProjectionAngleCount > 0, "ProjectionGeometry3D", "Not enough ProjectionAngles specified."); m_pfProjectionAngles = new float32[m_iProjectionAngleCount]; @@ -182,8 +217,8 @@ bool CProjectionGeometry3D::initialize(const Config& _cfg) } CC.markNodeParsed("ProjectionAngles"); - // Interface class, so don't return true - return false; + + return true; } //---------------------------------------------------------------------------------------- diff --git a/src/Utilities.cpp b/src/Utilities.cpp index 6346a49..dc654ea 100644 --- a/src/Utilities.cpp +++ b/src/Utilities.cpp @@ -44,7 +44,17 @@ int stringToInt(const std::string& s) if (iss.fail() || !iss.eof()) throw bad_cast(); return i; +} +int stringToInt(const std::string& s, int fallback) +{ + int i; + std::istringstream iss(s); + iss.imbue(std::locale::classic()); + iss >> i; + if (iss.fail() || !iss.eof()) + return fallback; + return i; } float stringToFloat(const std::string& s) diff --git a/src/VolumeGeometry2D.cpp b/src/VolumeGeometry2D.cpp index d7a8051..b27caa8 100644 --- a/src/VolumeGeometry2D.cpp +++ b/src/VolumeGeometry2D.cpp @@ -164,20 +164,32 @@ bool CVolumeGeometry2D::initialize(const Config& _cfg) // Required: GridColCount XMLNode node = _cfg.self.getSingleNode("GridColCount"); ASTRA_CONFIG_CHECK(node, "VolumeGeometry2D", "No GridColCount tag specified."); - m_iGridColCount = node.getContentInt(); + try { + m_iGridColCount = node.getContentInt(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "VolumeGeometry2D", "GridColCount must be an integer."); + } CC.markNodeParsed("GridColCount"); // Required: GridRowCount node = _cfg.self.getSingleNode("GridRowCount"); ASTRA_CONFIG_CHECK(node, "VolumeGeometry2D", "No GridRowCount tag specified."); - m_iGridRowCount = node.getContentInt(); + try { + m_iGridRowCount = node.getContentInt(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "VolumeGeometry2D", "GridRowCount must be an integer."); + } 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); + try { + 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); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "VolumeGeometry2D", "Window extents must be numerical."); + } CC.markOptionParsed("WindowMinX"); CC.markOptionParsed("WindowMaxX"); CC.markOptionParsed("WindowMinY"); diff --git a/src/VolumeGeometry3D.cpp b/src/VolumeGeometry3D.cpp index b8c2409..eb8cc60 100644 --- a/src/VolumeGeometry3D.cpp +++ b/src/VolumeGeometry3D.cpp @@ -193,28 +193,44 @@ bool CVolumeGeometry3D::initialize(const Config& _cfg) // Required: GridColCount XMLNode node = _cfg.self.getSingleNode("GridColCount"); ASTRA_CONFIG_CHECK(node, "VolumeGeometry3D", "No GridColCount tag specified."); - m_iGridColCount = node.getContentInt(); + try { + m_iGridColCount = node.getContentInt(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "VolumeGeometry3D", "GridColCount must be an integer."); + } CC.markNodeParsed("GridColCount"); // Required: GridRowCount node = _cfg.self.getSingleNode("GridRowCount"); ASTRA_CONFIG_CHECK(node, "VolumeGeometry3D", "No GridRowCount tag specified."); - m_iGridRowCount = node.getContentInt(); + try { + m_iGridRowCount = node.getContentInt(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "VolumeGeometry3D", "GridRowCount must be an integer."); + } CC.markNodeParsed("GridRowCount"); // Required: GridRowCount node = _cfg.self.getSingleNode("GridSliceCount"); ASTRA_CONFIG_CHECK(node, "VolumeGeometry3D", "No GridSliceCount tag specified."); - m_iGridSliceCount = node.getContentInt(); + try { + m_iGridSliceCount = node.getContentInt(); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "VolumeGeometry3D", "GridSliceCount must be an integer."); + } CC.markNodeParsed("GridSliceCount"); // 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); - m_fWindowMinZ = _cfg.self.getOptionNumerical("WindowMinZ", -m_iGridSliceCount/2.0f); - m_fWindowMaxZ = _cfg.self.getOptionNumerical("WindowMaxZ", m_iGridSliceCount/2.0f); + try { + 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); + m_fWindowMinZ = _cfg.self.getOptionNumerical("WindowMinZ", -m_iGridSliceCount/2.0f); + m_fWindowMaxZ = _cfg.self.getOptionNumerical("WindowMaxZ", m_iGridSliceCount/2.0f); + } catch (const StringUtil::bad_cast &e) { + ASTRA_CONFIG_CHECK(false, "VolumeGeometry3D", "Window extents must be numerical."); + } CC.markOptionParsed("WindowMinX"); CC.markOptionParsed("WindowMaxX"); CC.markOptionParsed("WindowMinY"); -- cgit v1.2.3