summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWillem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>2018-12-07 16:41:40 +0100
committerWillem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>2018-12-23 16:57:45 +0100
commit8220a50be6bcbddf179bb855b2f7d36436fcca6b (patch)
tree81986f22c74784ff02c88f1d071fae32186e5f89
parentcbc2e1079cf40c6f0c08d2f9c54f7b41b678e567 (diff)
downloadastra-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.h2
-rw-r--r--include/astra/FanFlatVecProjectionGeometry2D.h2
-rw-r--r--include/astra/ParallelVecProjectionGeometry2D.h2
-rw-r--r--include/astra/ParallelVecProjectionGeometry3D.h3
-rw-r--r--include/astra/ProjectionGeometry2D.h3
-rw-r--r--include/astra/ProjectionGeometry3D.h3
-rw-r--r--include/astra/Utilities.h4
-rw-r--r--src/ConeProjectionGeometry3D.cpp12
-rw-r--r--src/ConeVecProjectionGeometry3D.cpp36
-rw-r--r--src/FanFlatProjectionGeometry2D.cpp12
-rw-r--r--src/FanFlatVecProjectionGeometry2D.cpp36
-rw-r--r--src/ParallelVecProjectionGeometry2D.cpp44
-rw-r--r--src/ParallelVecProjectionGeometry3D.cpp34
-rw-r--r--src/ProjectionGeometry2D.cpp50
-rw-r--r--src/ProjectionGeometry3D.cpp71
-rw-r--r--src/Utilities.cpp10
-rw-r--r--src/VolumeGeometry2D.cpp24
-rw-r--r--src/VolumeGeometry3D.cpp34
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");