diff options
author | Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl> | 2018-12-07 16:41:40 +0100 |
---|---|---|
committer | Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl> | 2018-12-23 16:57:45 +0100 |
commit | 8220a50be6bcbddf179bb855b2f7d36436fcca6b (patch) | |
tree | 81986f22c74784ff02c88f1d071fae32186e5f89 | |
parent | cbc2e1079cf40c6f0c08d2f9c54f7b41b678e567 (diff) | |
download | astra-8220a50be6bcbddf179bb855b2f7d36436fcca6b.tar.gz astra-8220a50be6bcbddf179bb855b2f7d36436fcca6b.tar.bz2 astra-8220a50be6bcbddf179bb855b2f7d36436fcca6b.tar.xz astra-8220a50be6bcbddf179bb855b2f7d36436fcca6b.zip |
More gracefully handle config errors in geometries
-rw-r--r-- | include/astra/ConeVecProjectionGeometry3D.h | 2 | ||||
-rw-r--r-- | include/astra/FanFlatVecProjectionGeometry2D.h | 2 | ||||
-rw-r--r-- | include/astra/ParallelVecProjectionGeometry2D.h | 2 | ||||
-rw-r--r-- | include/astra/ParallelVecProjectionGeometry3D.h | 3 | ||||
-rw-r--r-- | include/astra/ProjectionGeometry2D.h | 3 | ||||
-rw-r--r-- | include/astra/ProjectionGeometry3D.h | 3 | ||||
-rw-r--r-- | include/astra/Utilities.h | 4 | ||||
-rw-r--r-- | src/ConeProjectionGeometry3D.cpp | 12 | ||||
-rw-r--r-- | src/ConeVecProjectionGeometry3D.cpp | 36 | ||||
-rw-r--r-- | src/FanFlatProjectionGeometry2D.cpp | 12 | ||||
-rw-r--r-- | src/FanFlatVecProjectionGeometry2D.cpp | 36 | ||||
-rw-r--r-- | src/ParallelVecProjectionGeometry2D.cpp | 44 | ||||
-rw-r--r-- | src/ParallelVecProjectionGeometry3D.cpp | 34 | ||||
-rw-r--r-- | src/ProjectionGeometry2D.cpp | 50 | ||||
-rw-r--r-- | src/ProjectionGeometry3D.cpp | 71 | ||||
-rw-r--r-- | src/Utilities.cpp | 10 | ||||
-rw-r--r-- | src/VolumeGeometry2D.cpp | 24 | ||||
-rw-r--r-- | src/VolumeGeometry3D.cpp | 34 |
18 files changed, 259 insertions, 123 deletions
diff --git a/include/astra/ConeVecProjectionGeometry3D.h b/include/astra/ConeVecProjectionGeometry3D.h index 0a9813c..252e32c 100644 --- a/include/astra/ConeVecProjectionGeometry3D.h +++ b/include/astra/ConeVecProjectionGeometry3D.h @@ -157,6 +157,8 @@ public: virtual void backprojectPointZ(int iAngleIndex, double fU, double fV, double fZ, double &fX, double &fY) const; +protected: + virtual bool initializeAngles(const Config& _cfg); }; } // namespace astra diff --git a/include/astra/FanFlatVecProjectionGeometry2D.h b/include/astra/FanFlatVecProjectionGeometry2D.h index cafeda8..fe4253f 100644 --- a/include/astra/FanFlatVecProjectionGeometry2D.h +++ b/include/astra/FanFlatVecProjectionGeometry2D.h @@ -157,6 +157,8 @@ public: virtual CVector3D getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex); const SFanProjection* getProjectionVectors() const { return m_pProjectionAngles; } +protected: + virtual bool initializeAngles(const Config& _cfg); }; diff --git a/include/astra/ParallelVecProjectionGeometry2D.h b/include/astra/ParallelVecProjectionGeometry2D.h index 805a142..e99fb35 100644 --- a/include/astra/ParallelVecProjectionGeometry2D.h +++ b/include/astra/ParallelVecProjectionGeometry2D.h @@ -155,6 +155,8 @@ public: const SParProjection* getProjectionVectors() const { return m_pProjectionAngles; } +protected: + virtual bool initializeAngles(const Config& _cfg); }; } // namespace astra diff --git a/include/astra/ParallelVecProjectionGeometry3D.h b/include/astra/ParallelVecProjectionGeometry3D.h index 08e7af9..04418a0 100644 --- a/include/astra/ParallelVecProjectionGeometry3D.h +++ b/include/astra/ParallelVecProjectionGeometry3D.h @@ -157,6 +157,9 @@ public: double fY, double &fX, double &fZ) const; virtual void backprojectPointZ(int iAngleIndex, double fU, double fV, double fZ, double &fX, double &fY) const; + +protected: + virtual bool initializeAngles(const Config& _cfg); }; } // namespace astra diff --git a/include/astra/ProjectionGeometry2D.h b/include/astra/ProjectionGeometry2D.h index 65b3006..66cc8ad 100644 --- a/include/astra/ProjectionGeometry2D.h +++ b/include/astra/ProjectionGeometry2D.h @@ -254,6 +254,9 @@ public: //< For Config unused argument checking ConfigCheckData* configCheckData; friend class ConfigStackCheck<CProjectionGeometry2D>; + +protected: + virtual bool initializeAngles(const Config& _cfg); }; diff --git a/include/astra/ProjectionGeometry3D.h b/include/astra/ProjectionGeometry3D.h index 092402d..11545ea 100644 --- a/include/astra/ProjectionGeometry3D.h +++ b/include/astra/ProjectionGeometry3D.h @@ -351,6 +351,9 @@ public: //< For Config unused argument checking ConfigCheckData* configCheckData; friend class ConfigStackCheck<CProjectionGeometry3D>; + +protected: + virtual bool initializeAngles(const Config& _cfg); }; diff --git a/include/astra/Utilities.h b/include/astra/Utilities.h index 7ed8ecd..e830c5d 100644 --- a/include/astra/Utilities.h +++ b/include/astra/Utilities.h @@ -51,6 +51,10 @@ public: //< Throw exception on failure. _AstraExport int stringToInt(const std::string& s); +//< Parse string as int. +//< Return fallback on failure. +_AstraExport int stringToInt(const std::string& s, int fallback); + //< Parse string as float. //< Throw exception on failure. _AstraExport float stringToFloat(const std::string& s); 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<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); + 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<CProjectionGeometry3D> 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<double> data = node.getContentNumericalArrayDouble(); + vector<double> 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<CProjectionGeometry2D> CC("FanFlatVecProjectionGeometry2D", this, _cfg); // Required: Vectors - node = _cfg.self.getSingleNode("Vectors"); - ASTRA_CONFIG_CHECK(node, "FanFlatVecProjectionGeometry3D", "No Vectors tag specified."); - vector<float32> data = node.getContentNumericalArray(); + XMLNode node = _cfg.self.getSingleNode("Vectors"); + ASTRA_CONFIG_CHECK(node, "FanFlatVecProjectionGeometry2D", "No Vectors tag specified."); + vector<float32> 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 <http://www.gnu.org/licenses/>. #include <cstring> #include <sstream> -#include <boost/lexical_cast.hpp> using namespace std; @@ -100,20 +99,29 @@ bool CParallelVecProjectionGeometry2D::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); ConfigStackCheck<CProjectionGeometry2D> 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<int>(node.getContent()); - CC.markNodeParsed("DetectorCount"); + + // success + m_bInitialized = _check(); + return m_bInitialized; +} + +bool CParallelVecProjectionGeometry2D::initializeAngles(const Config& _cfg) +{ + ConfigStackCheck<CProjectionGeometry2D> 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<float32> data = node.getContentNumericalArray(); + vector<float32> 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<string>(p.fRayX) + ","; - vectors += boost::lexical_cast<string>(p.fRayY) + ","; - vectors += boost::lexical_cast<string>(p.fDetSX + 0.5f * m_iDetectorCount * p.fDetUX) + ","; - vectors += boost::lexical_cast<string>(p.fDetSY + 0.5f * m_iDetectorCount * p.fDetUY) + ","; - vectors += boost::lexical_cast<string>(p.fDetUX) + ","; - vectors += boost::lexical_cast<string>(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<CProjectionGeometry3D> 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<double> data = node.getContentNumericalArrayDouble(); + vector<double> 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<CProjectionGeometry2D> 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<float32> angles = node.getContentNumericalArray(); + vector<float32> 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<CProjectionGeometry3D> 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<float32> angles = node.getContentNumericalArray(); + vector<float32> 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"); |