[med-svn] [mia] 05/07: Imported Upstream version 2.0.13
Gert Wollny
gert-guest at moszumanska.debian.org
Mon Jan 20 10:53:58 UTC 2014
This is an automated email from the git hooks/post-receive script.
gert-guest pushed a commit to branch master
in repository mia.
commit d47bc63994d9952c8f7aacea66b809d801a28043
Author: Gert Wollny <gw.fossdev at gmail.com>
Date: Fri Jan 17 12:59:35 2014 +0100
Imported Upstream version 2.0.13
---
CMakeLists.txt | 6 ++--
ChangeLog | 15 ++++++++
mia/3d/fifof/label.cc | 12 +++----
mia/3d/interpolator.cxx | 34 ++++++++++++------
mia/3d/interpolator.hh | 5 +--
mia/3d/test_interpol.cc | 80 +++++++++++++++++++++++++++++++++++++++++++
mia/3d/transform.cc | 3 +-
mia/core/factory.hh | 3 +-
mia/core/iohandler.cxx | 5 +--
mia/core/splinekernel.cc | 16 ++++++++-
mia/core/splinekernel.hh | 2 ++
mia/core/test_splinekernel.cc | 29 ++++++++++++++++
src/2dimageregistration.cc | 2 ++
src/3dgetslice.cc | 17 +++++----
14 files changed, 196 insertions(+), 33 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 26a70bf..5268763 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,9 +41,9 @@ SET(VENDOR "Gert Wollny")
SET(PACKAGE_NAME "mia")
SET(MAJOR_VERSION 2)
SET(MINOR_VERSION 0)
-SET(MICRO_VERSION 12)
-SET(INTERFACE_AGE 4)
-SET(BINARY_AGE 4)
+SET(MICRO_VERSION 13)
+SET(INTERFACE_AGE 5)
+SET(BINARY_AGE 5)
SET(PACKAGE_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}")
SET(VERSION "${MAJOR_VERSION}.${MINOR_VERSION}")
diff --git a/ChangeLog b/ChangeLog
index 229385c..dc4f3d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2.0.13
+
+ Fixes for tracked bugs:
+
+ * #138 Handle compressed file extension properly when selecting the IO plugin.
+ * #143 Fix zero-fill boundary condition handling
+ * #144 Parallelize the prefiltering in the 3D interpolator
+
+ Additional fixes:
+
+ * 2dimageregistration: Exit if no cost functions are given
+ * 3dgetimage: add support for setting the minimum number of
+ digits in the output file names.
+ * factoryplugins: throw error if a factory plugin is not found
+ * make the basic interpolator operator in 3D thread save
2.0.12
diff --git a/mia/3d/fifof/label.cc b/mia/3d/fifof/label.cc
index cff4502..01bb233 100644
--- a/mia/3d/fifof/label.cc
+++ b/mia/3d/fifof/label.cc
@@ -88,8 +88,8 @@ void C2DLabelStackFilter::grow( int x, int y, C2DBitImage& input, unsigned short
void C2DLabelStackFilter::label_new_regions(C2DBitImage& input)
{
- C3DBitImage::iterator ii = input.begin();
- C3DUSImage::iterator usi = m_out_buffer.begin();
+ auto ii = input.begin();
+ auto usi = m_out_buffer.begin();
for (size_t y = 0; y < input.get_size().y; ++y)
for (size_t x = 0; x < input.get_size().x; ++x, ++usi, ++ii) {
@@ -112,7 +112,7 @@ void C2DLabelStackFilter::label_new_regions(C2DBitImage& input)
void C2DLabelStackFilter::label(C2DBitImage& input)
{
// first grow all regions that are already labeled from the last slice
- C3DUSImage::iterator usi = m_out_buffer.begin();
+ auto usi = m_out_buffer.begin();
for (size_t y = 0; y < input.get_size().y; ++y)
for (size_t x = 0; x < input.get_size().x; ++x, ++usi) {
if ( *usi )
@@ -132,9 +132,9 @@ void C2DLabelStackFilter::new_label(C2DBitImage& input)
void C2DLabelStackFilter::re_label(C2DBitImage& input)
{
- C3DUSImage::iterator usi = m_out_buffer.begin();
- C3DUSImage::iterator use = m_out_buffer.end();
- C2DBitImage::iterator ii = input.begin();
+ auto usi = m_out_buffer.begin();
+ auto use = m_out_buffer.end();
+ auto ii = input.begin();
// maintain old labeling for new slice, and clean the input at
// labeled positions
diff --git a/mia/3d/interpolator.cxx b/mia/3d/interpolator.cxx
index fba7e77..ac7ec39 100644
--- a/mia/3d/interpolator.cxx
+++ b/mia/3d/interpolator.cxx
@@ -20,6 +20,10 @@
#include <cmath>
+#include <mia/core/threadedmsg.hh>
+#include <tbb/parallel_for.h>
+#include <tbb/blocked_range.h>
+
NS_MIA_BEGIN
template <class T>
@@ -117,38 +121,44 @@ void T3DConvoluteInterpolator<T>::prefilter(const T3DDatafield<T>& image)
int cachYSize = image.get_size().y;
int cachZSize = image.get_size().z;
- {
+
+ auto filter_x = [this, cachXSize, cachYSize, poles](const tbb::blocked_range<size_t>& range_z) {
coeff_vector buffer(cachXSize);
- for (int z = 0; z < cachZSize; z++){
+ for (auto z = range_z.begin(); z != range_z.end() ; ++z){
for (int y = 0; y < cachYSize; y++) {
m_coeff.get_data_line_x(y,z,buffer);
m_xbc->filter_line(buffer, poles);
m_coeff.put_data_line_x(y,z,buffer);
}
}
- }
+ };
+ parallel_for(tbb::blocked_range<size_t>(0, cachZSize, 1), filter_x);
- {
+
+ auto filter_y = [this, cachXSize, cachYSize, poles](const tbb::blocked_range<size_t>& range_z) {
coeff_vector buffer(cachYSize);
- for (int z = 0; z < cachZSize; z++){
+ for (auto z = range_z.begin(); z != range_z.end() ; ++z){
for (int x = 0; x < cachXSize; x++) {
m_coeff.get_data_line_y(x,z,buffer);
m_ybc->filter_line(buffer, poles);
m_coeff.put_data_line_y(x,z,buffer);
}
}
- }
+ };
+ parallel_for(tbb::blocked_range<size_t>(0, cachZSize, 1), filter_y);
- {
+
+ auto filter_z = [this, cachXSize, cachZSize, poles](const tbb::blocked_range<size_t>& range_y) {
coeff_vector buffer(cachZSize);
- for (int y = 0; y < cachYSize; y++){
+ for (auto y = range_y.begin(); y != range_y.end() ; ++y){
for (int x = 0; x < cachXSize; x++) {
m_coeff.get_data_line_z(x,y,buffer);
m_zbc->filter_line(buffer, poles);
m_coeff.put_data_line_z(x,y,buffer);
}
}
- }
+ };
+ parallel_for(tbb::blocked_range<size_t>(0, cachYSize, 1), filter_z);
}
@@ -207,7 +217,8 @@ struct add_3d<T3DDatafield< T >, 1> {
const CSplineKernel::SCache& yc,
const CSplineKernel::SCache& zc)
{
- return coeff(xc.index[0], yc.index[0], zc.index[0] ) ;
+ return xc.weights[0] * yc.weights[0] * zc.weights[0] *
+ coeff(xc.index[0], yc.index[0], zc.index[0] ) ;
}
};
@@ -267,7 +278,7 @@ T T3DConvoluteInterpolator<T>::operator () (const C3DFVector& x, CWeightCache&
m_kernel->get_cached(x.y, cache.y);
if (x.z != cache.z.x)
- m_kernel->get_cached(x.z, cache.z);
+ m_kernel->get_cached(x.z, cache.z);
U result = U();
// now we give the compiler a chance to optimize based on kernel size and data type.
@@ -294,6 +305,7 @@ T T3DConvoluteInterpolator<T>::operator () (const C3DFVector& x, CWeightCache&
template <typename T>
T T3DConvoluteInterpolator<T>::operator () (const C3DFVector& x) const
{
+ CScopedLock lock(m_cache_lock);
typedef typename TCoeff3D::value_type U;
// x will usually be the fastest changing index, therefore, it is of no use to use the cache
diff --git a/mia/3d/interpolator.hh b/mia/3d/interpolator.hh
index caa65f5..4b2f838 100644
--- a/mia/3d/interpolator.hh
+++ b/mia/3d/interpolator.hh
@@ -26,7 +26,7 @@
#include <mia/core/splinekernel.hh>
#include <mia/core/boundary_conditions.hh>
#include <mia/3d/image.hh>
-
+#include <tbb/mutex.h>
NS_MIA_BEGIN
@@ -154,7 +154,8 @@ private:
T m_min;
T m_max;
-
+
+ mutable tbb::mutex m_cache_lock;
mutable CSplineKernel::SCache m_x_cache;
mutable CSplineKernel::SCache m_y_cache;
mutable CSplineKernel::SCache m_z_cache;
diff --git a/mia/3d/test_interpol.cc b/mia/3d/test_interpol.cc
index c7a746e..501781e 100644
--- a/mia/3d/test_interpol.cc
+++ b/mia/3d/test_interpol.cc
@@ -28,6 +28,7 @@
#include <mia/3d/interpolator.hh>
#include <mia/core/msgstream.hh>
+#include <mia/core/threadedmsg.hh>
NS_MIA_USE
using namespace std;
@@ -197,6 +198,45 @@ struct FParallelInterpolator {
};
+struct FParallelInterpolator2 {
+ T3DDatafield<float>& output;
+ const T3DConvoluteInterpolator<float>& src;
+ const C3DFVector& shift;
+ const T3DDatafield<float>& test_data;
+
+ FParallelInterpolator2(T3DDatafield<float>& _output,
+ const T3DConvoluteInterpolator<float>& _src,
+ const C3DFVector& _shift,
+ const T3DDatafield<float>& _test_data
+
+ ):
+ output(_output),
+ src(_src),
+ shift(_shift),
+ test_data(_test_data)
+ {
+ }
+
+ void operator()( const tbb::blocked_range<int>& range ) const {
+ CThreadMsgStream thread_stream;
+ auto cache = src.create_cache();
+ for (auto z = range.begin(); z != range.end(); ++z)
+ for (size_t y = 0; y < output.get_size().y; ++y)
+ for (size_t x = 0; x < output.get_size().x; ++x) {
+ C3DFVector loc(x,y,z);
+ output(x,y,z) = src(loc + shift, cache);
+ cvmsg() << loc << " weights:"
+ << " x = " << cache.x.weights << cache.x.index
+ << " y = " << cache.y.weights << cache.y.index
+ << " z = " << cache.z.weights << cache.z.index
+ << " res= " << output(x,y,z)
+ << " test= " << test_data(x,y,z)
+ << "\n";
+ }
+
+ }
+};
+
static void test_parallel_interpolator()
{
T3DDatafield<float> data(C3DBounds(10, 12, 11));
@@ -222,6 +262,44 @@ static void test_parallel_interpolator()
}
+static void test_parallel_interpolator_zerofill_shifted()
+{
+ C3DFVector shift(1,2,3);
+
+ T3DDatafield<float> data(C3DBounds(9, 8, 7));
+ T3DDatafield<float> test_data(C3DBounds(9, 8, 7));
+ auto kernel = produce_spline_kernel(bspline0);
+ auto bc = produce_spline_boundary_condition("zero");
+
+ auto i = data.begin();
+ for (size_t z = 0; z < data.get_size().z; ++z)
+ for (size_t y = 0; y < data.get_size().y; ++y)
+ for (size_t x = 0; x < data.get_size().x; ++x, ++i) {
+ *i = x + 10 * y + 100 * z;
+ if (x >= 1 && y >= 2 && z >= 3)
+ test_data(x - 1, y - 2, z - 3) = *i;
+ }
+
+ T3DConvoluteInterpolator<float> src(data, kernel, *bc, *bc, *bc);
+
+ T3DDatafield<float> output(data.get_size());
+ FParallelInterpolator2 worker(output, src, shift, test_data);
+
+ tbb::parallel_for(tbb::blocked_range<int>( 0, data.get_size().z), worker);
+ for (size_t z = 0; z < data.get_size().z; ++z)
+ for (size_t y = 0; y < data.get_size().y; ++y)
+ for (size_t x = 0; x < data.get_size().x; ++x) {
+ if (output(x,y,z) != test_data(x,y,z)) {
+ cvfail() << "FAIL:" << x<< "," << y << "," << z << ": "
+ << output(x,y,z) << " vs "<< test_data(x,y,z) << "\n";
+ }
+ BOOST_CHECK_CLOSE(output(x,y,z), test_data(x,y,z), 0.01);
+ }
+
+}
+
+
+
static double omoms3(double x)
{
if (x < 0)
@@ -336,4 +414,6 @@ void add_3dinterpol_tests( boost::unit_test::test_suite* suite)
suite->add( BOOST_TEST_CASE( (&test_external_cache_interpolator)));
suite->add( BOOST_TEST_CASE( (&test_parallel_interpolator)));
+ suite->add( BOOST_TEST_CASE( (&test_parallel_interpolator_zerofill_shifted)));
+
}
diff --git a/mia/3d/transform.cc b/mia/3d/transform.cc
index 6d7da39..f566d5c 100644
--- a/mia/3d/transform.cc
+++ b/mia/3d/transform.cc
@@ -302,9 +302,10 @@ void F3DTransformer<T>::operator() ( const tbb::blocked_range<int>& range ) cons
CThreadMsgStream thread_stream;
auto cache = interp.create_cache();
- auto r = result.begin_at(0,0,range.begin());
C3DBounds begin(0,0,range.begin());
C3DBounds end(result.get_size().x,result.get_size().y, range.end());
+
+ auto r = result.begin_at(0,0,range.begin());
cvdebug() << "range = " << begin << " - " << end << "\n";
diff --git a/mia/core/factory.hh b/mia/core/factory.hh
index 9123ad4..c9d850b 100644
--- a/mia/core/factory.hh
+++ b/mia/core/factory.hh
@@ -272,7 +272,8 @@ typename I::Product *TFactoryPluginHandler<I>::produce_raw(const std::string& pa
cvdebug() << "TFactoryPluginHandler<>::produce: Create plugin from '" << factory_name << "'\n";
auto factory = this->plugin(factory_name.c_str());
- DEBUG_ASSERT_RELEASE_THROW(factory, "A plug-in was not found but 'this->plugin' did not throw");
+ if (!factory)
+ throw create_exception<std::invalid_argument>("Unable to find plugin for '", factory_name.c_str(), "'");
return factory->create(param_list.begin()->second,params.c_str());
}
diff --git a/mia/core/iohandler.cxx b/mia/core/iohandler.cxx
index 3ea832c..ac08d2c 100644
--- a/mia/core/iohandler.cxx
+++ b/mia/core/iohandler.cxx
@@ -57,9 +57,10 @@ TIOPluginHandler<I>::preferred_plugin_ptr(const std::string& fname) const
std::string fsuffix = __bfs_get_extension(fpath);
if (!fsuffix.empty()) {
if (m_compress_sfx.find(fsuffix) != m_compress_sfx.end()) {
+ cvdebug() << "Got compression suffix '" << fsuffix << "\n";
// remove the last extension and get the one before
bfs::path help(fpath.stem());
- fsuffix = __bfs_get_extension(fpath);
+ fsuffix = __bfs_get_extension(help);
}
}else
fsuffix = fname;
@@ -123,7 +124,7 @@ TIOPluginHandler<I>::preferred_plugin(const std::string& fname) const
auto fsuffix = __bfs_get_extension(fpath);
if (m_compress_sfx.find(fsuffix) != m_compress_sfx.end()) {
bfs::path help(fpath.stem());
- fsuffix = __bfs_get_extension(fpath);
+ fsuffix = __bfs_get_extension(help);
}
cvdebug() << "Got suffix '" << fsuffix << "'\n";
auto p = m_suffixmap.find(fsuffix);
diff --git a/mia/core/splinekernel.cc b/mia/core/splinekernel.cc
index 205dae8..14013ae 100644
--- a/mia/core/splinekernel.cc
+++ b/mia/core/splinekernel.cc
@@ -123,8 +123,17 @@ void CSplineKernel::get_cached(double x, SCache& cache)const
{
int start_idx = get_start_idx_and_value_weights(x, cache.weights);
cache.x = x;
- if (start_idx == cache.start_idx)
+
+ // here we need an additional field that stores whether the
+ // indices crossed a boundary
+
+ // start index is same and inside the image, we can keep the new weights
+ // only zero-boundary conditions must check if weights were changed
+ if (start_idx == cache.start_idx && // cache.boundary_condition.is_zero()
+ start_idx >= 0 &&
+ cache.start_idx <= cache.index_limit )
return;
+
cache.start_idx = start_idx;
cache.is_flat = false;
fill_index(start_idx, cache.index);
@@ -237,6 +246,11 @@ int CSplineKernel::get_start_idx_and_value_weights(double x, VWeight& weights) c
return result - (int)m_half_degree;
}
+int CSplineKernel::get_start_idx(double x) const
+{
+ return fastfloor(x + m_shift) - (int)m_half_degree;
+}
+
int CSplineKernel::get_start_idx_and_derivative_weights(double x, VWeight& weights) const
{
const int result = fastfloor(x + m_shift);
diff --git a/mia/core/splinekernel.hh b/mia/core/splinekernel.hh
index fe3f8a1..e8c0ee1 100644
--- a/mia/core/splinekernel.hh
+++ b/mia/core/splinekernel.hh
@@ -262,6 +262,8 @@ protected:
void add_pole(double x);
private:
+ int get_start_idx(double x) const;
+
/**
Helper function to fill the array index with consecutive values starting with i
*/
diff --git a/mia/core/test_splinekernel.cc b/mia/core/test_splinekernel.cc
index 676233b..5ac1405 100644
--- a/mia/core/test_splinekernel.cc
+++ b/mia/core/test_splinekernel.cc
@@ -79,6 +79,35 @@ BOOST_FIXTURE_TEST_CASE( test_mirrored_big, TestSplineCacheFixture )
}
+BOOST_AUTO_TEST_CASE( test_zero_cache_outside_never_flat )
+{
+ auto bc = produce_spline_boundary_condition("zero");
+ bc->set_width(10);
+
+ CBSplineKernelMock skm;
+
+ CSplineKernel::SCache cache(skm.size(), *bc, true);
+ skm.get_cached(9, cache);
+
+ cvdebug() << "cache {"
+ << " x = " << cache.x
+ << " start_idx = " << cache.start_idx
+ << " is_flat = " << cache.is_flat
+ << " index = " << cache.index
+ << "\n";
+
+ skm.get_cached(9, cache);
+ BOOST_CHECK_EQUAL(cache.weights[0], 0);
+ BOOST_CHECK_EQUAL(cache.weights[1], 1);
+ BOOST_CHECK_EQUAL(cache.weights[2], 0);
+
+ BOOST_CHECK_EQUAL(cache.index[0], 8);
+ BOOST_CHECK_EQUAL(cache.index[1], 9);
+ BOOST_CHECK_EQUAL(cache.index[2], 0);
+
+}
+
+
CBSplineKernelMock::CBSplineKernelMock():
CSplineKernel(3, 0, ip_bspline3)
{
diff --git a/src/2dimageregistration.cc b/src/2dimageregistration.cc
index 782664b..f9fb769 100644
--- a/src/2dimageregistration.cc
+++ b/src/2dimageregistration.cc
@@ -71,6 +71,8 @@ int do_main( int argc, char *argv[] )
auto cost_descrs = options.get_remaining();
+ if (cost_descrs.empty())
+ throw runtime_error("No registration criterion given");
C2DFullCostList costs;
for (auto i = cost_descrs.begin(); i != cost_descrs.end(); ++i)
diff --git a/src/3dgetslice.cc b/src/3dgetslice.cc
index 9bb0fbe..57eb1bc 100644
--- a/src/3dgetslice.cc
+++ b/src/3dgetslice.cc
@@ -98,11 +98,12 @@ struct __dispatch<T, dir_yz> {
template <EDirection s_dir>
class TGetter : public TFilter<bool> {
public:
- TGetter(size_t start, size_t n, const string& fname, const string& type):
+ TGetter(size_t start, size_t n, const string& fname, const string& type, int digits):
m_start(start),
m_n(n),
m_fname(fname),
- m_type(type)
+ m_type(type),
+ m_digits(digits)
{
}
@@ -115,7 +116,7 @@ public:
for(size_t i = m_start; i < end; ++i) {
P2DImage pimage(new T2DImage<T>(__dispatch<T, s_dir>::get_slice(i, image)));
stringstream out_name;
- out_name << m_fname << setw(4) << setfill('0') << i << "." << m_type;
+ out_name << m_fname << setw(m_digits) << setfill('0') << i << "." << m_type;
retval &= save_image(out_name.str(), pimage);
}
return retval;
@@ -125,6 +126,7 @@ private:
size_t m_n;
string m_fname;
string m_type;
+ int m_digits;
};
int do_main( int argc, char *argv[] )
@@ -136,6 +138,7 @@ int do_main( int argc, char *argv[] )
size_t start_slice = 0;
size_t slice_number = 0;
EDirection direction = dir_xy;
+ int digits = 4;
const auto& imageio2d = C2DImageIOPluginHandler::instance();
@@ -149,6 +152,8 @@ int do_main( int argc, char *argv[] )
options.add(make_opt( out_type, imageio2d.get_set(), "type", 't', "output file type"));
options.add(make_opt( start_slice, "start", 's',"start slice number"));
options.add(make_opt( slice_number, "number", 'n', "number of slices (all=0)"));
+ options.add(make_opt( digits, "ndigits", 0, "minimum number of digits of the file name numbers"));
+
options.add(make_opt( direction, GDirectionmap, "dir", 'd',
"slice direction (xy=axial, xz=coronal, yz=saggital)"));
@@ -166,17 +171,17 @@ int do_main( int argc, char *argv[] )
switch (direction) {
case dir_xy:
result = mia::filter(TGetter<dir_xy>(start_slice, slice_number,
- out_filename, out_suffix),
+ out_filename, out_suffix, digits),
*in_image);
break;
case dir_xz:
result = mia::filter(TGetter<dir_xz>(start_slice, slice_number,
- out_filename, out_suffix),
+ out_filename, out_suffix, digits),
*in_image);
break;
case dir_yz:
result = mia::filter(TGetter<dir_yz>(start_slice, slice_number,
- out_filename, out_suffix),
+ out_filename, out_suffix, digits),
*in_image);
break;
default:
--
Alioth's /git/debian-med/git-commit-notice on /srv/git.debian.org/git/debian-med/mia.git
More information about the debian-med-commit
mailing list