diff --git a/Modules/DiffusionCmdApps/FiberProcessing/FiberClustering.cpp b/Modules/DiffusionCmdApps/FiberProcessing/FiberClustering.cpp
index 743207b..a454d3f 100644
--- a/Modules/DiffusionCmdApps/FiberProcessing/FiberClustering.cpp
+++ b/Modules/DiffusionCmdApps/FiberProcessing/FiberClustering.cpp
@@ -1,273 +1,273 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #include <mitkFiberBundle.h>
 #include <mitkDiffusionCommandLineParser.h>
 #include <mitkLexicalCast.h>
 #include <mitkIOUtil.h>
-#include <itkTractClusteringFilter.h>
+#include <mitkTractClusteringFilter.h>
 #include <mitkClusteringMetricEuclideanMean.h>
 #include <mitkClusteringMetricEuclideanMax.h>
 #include <mitkClusteringMetricEuclideanStd.h>
 #include <mitkClusteringMetricAnatomic.h>
 #include <mitkClusteringMetricScalarMap.h>
 #include <mitkClusteringMetricInnerAngles.h>
 #include <mitkClusteringMetricLength.h>
 #include <itksys/SystemTools.hxx>
 
 typedef itksys::SystemTools ist;
 
 mitk::FiberBundle::Pointer LoadFib(std::string filename)
 {
   std::vector<mitk::BaseData::Pointer> fibInfile = mitk::IOUtil::Load(filename);
   if( fibInfile.empty() )
     std::cout << "File " << filename << " could not be read!";
   mitk::BaseData::Pointer baseData = fibInfile.at(0);
   return dynamic_cast<mitk::FiberBundle*>(baseData.GetPointer());
 }
 
 /*!
 \brief Spatially cluster fibers
 */
 int main(int argc, char* argv[])
 {
   mitkDiffusionCommandLineParser parser;
 
   parser.setTitle("Fiber Clustering");
   parser.setCategory("Fiber Processing");
   parser.setContributor("MIC");
 
   parser.setArgumentPrefix("--", "-");
   parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input fiber bundle (.fib; .trk; .tck)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input);
   parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output);
 
   parser.addArgument("cluster_size", "", mitkDiffusionCommandLineParser::Int, "Cluster size:", "", 10);
   parser.addArgument("fiber_points", "", mitkDiffusionCommandLineParser::Int, "Fiber points:", "", 12);
   parser.addArgument("min_fibers", "", mitkDiffusionCommandLineParser::Int, "Min. fibers per cluster:", "", 1);
   parser.addArgument("max_clusters", "", mitkDiffusionCommandLineParser::Int, "Max. clusters:", "");
   parser.addArgument("merge_clusters", "", mitkDiffusionCommandLineParser::Float, "Merge clusters:", "Set to 0 to avoid merging and to -1 to use the original cluster size", -1.0);
   parser.addArgument("output_centroids", "", mitkDiffusionCommandLineParser::Bool, "Output centroids:", "");
   parser.addArgument("only_centroids", "", mitkDiffusionCommandLineParser::Bool, "Output only centroids:", "");
   parser.addArgument("merge_centroids", "", mitkDiffusionCommandLineParser::Bool, "Merge centroids:", "");
   parser.addArgument("metrics", "", mitkDiffusionCommandLineParser::StringList, "Metrics:", "EU_MEAN; EU_STD; EU_MAX; ANAT; MAP; LENGTH", std::string("EU_MEAN"));
   parser.addArgument("metric_weights", "", mitkDiffusionCommandLineParser::StringList, "Metric weights:", "add one float weight for each used metric");
   parser.addArgument("input_centroids", "", mitkDiffusionCommandLineParser::String, "Input centroids:", "", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input);
   parser.addArgument("scalar_map", "", mitkDiffusionCommandLineParser::String, "Scalar map:", "", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input);
   parser.addArgument("parcellation", "", mitkDiffusionCommandLineParser::String, "Parcellation:", "", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input);
   parser.addArgument("file_ending", "", mitkDiffusionCommandLineParser::String, "File ending:", "");
 
   std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
   if (parsedArgs.size()==0)
     return EXIT_FAILURE;
 
   std::string inFileName = us::any_cast<std::string>(parsedArgs["i"]);
   std::string out_root = us::any_cast<std::string>(parsedArgs["o"]);
 
   bool only_centroids = false;
   if (parsedArgs.count("only_centroids"))
     only_centroids = us::any_cast<bool>(parsedArgs["only_centroids"]);
 
   bool merge_centroids = false;
   if (parsedArgs.count("merge_centroids"))
     merge_centroids = us::any_cast<bool>(parsedArgs["merge_centroids"]);
 
   int cluster_size = 10;
   if (parsedArgs.count("cluster_size"))
     cluster_size = us::any_cast<int>(parsedArgs["cluster_size"]);
 
   int fiber_points = 12;
   if (parsedArgs.count("fiber_points"))
     fiber_points = us::any_cast<int>(parsedArgs["fiber_points"]);
 
   int min_fibers = 1;
   if (parsedArgs.count("min_fibers"))
     min_fibers = us::any_cast<int>(parsedArgs["min_fibers"]);
 
   int max_clusters = 0;
   if (parsedArgs.count("max_clusters"))
     max_clusters = us::any_cast<int>(parsedArgs["max_clusters"]);
 
   float merge_clusters = -1.0;
   if (parsedArgs.count("merge_clusters"))
     merge_clusters = us::any_cast<float>(parsedArgs["merge_clusters"]);
 
   bool output_centroids = false;
   if (parsedArgs.count("output_centroids"))
     output_centroids = us::any_cast<bool>(parsedArgs["output_centroids"]);
 
   std::vector< std::string > metric_strings = {"EU_MEAN"};
   if (parsedArgs.count("metrics"))
     metric_strings = us::any_cast<mitkDiffusionCommandLineParser::StringContainerType>(parsedArgs["metrics"]);
 
   std::vector< std::string > metric_weights = {"1.0"};
   if (parsedArgs.count("metric_weights"))
     metric_weights = us::any_cast<mitkDiffusionCommandLineParser::StringContainerType>(parsedArgs["metric_weights"]);
 
   std::string input_centroids = "";
   if (parsedArgs.count("input_centroids"))
     input_centroids = us::any_cast<std::string>(parsedArgs["input_centroids"]);
 
   std::string scalar_map = "";
   if (parsedArgs.count("scalar_map"))
     scalar_map = us::any_cast<std::string>(parsedArgs["scalar_map"]);
 
   std::string parcellation = "";
   if (parsedArgs.count("parcellation"))
     parcellation = us::any_cast<std::string>(parsedArgs["parcellation"]);
 
   std::string file_ending = ".fib";
   if (parsedArgs.count("file_ending"))
     file_ending = us::any_cast<std::string>(parsedArgs["file_ending"]);
 
   if (metric_strings.size()!=metric_weights.size())
   {
     MITK_INFO << "Each metric needs an associated metric weight!";
     return EXIT_FAILURE;
   }
 
   try
   {
     typedef itk::Image< float, 3 > FloatImageType;
     typedef itk::Image< short, 3 > ShortImageType;
 
     mitk::FiberBundle::Pointer fib = LoadFib(inFileName);
 
     float max_d = 0;
     int i=1;
     std::vector< float > distances;
     while (max_d < fib->GetGeometry()->GetDiagonalLength()/2)
     {
       distances.push_back(cluster_size*i);
       max_d = cluster_size*i;
       ++i;
     }
 
-    itk::TractClusteringFilter::Pointer clusterer = itk::TractClusteringFilter::New();
+    std::shared_ptr< mitk::TractClusteringFilter > clusterer = std::make_shared<mitk::TractClusteringFilter>();
     clusterer->SetDistances(distances);
     clusterer->SetTractogram(fib);
 
     if (input_centroids!="")
     {
 
       mitk::FiberBundle::Pointer in_centroids = LoadFib(input_centroids);
       clusterer->SetInCentroids(in_centroids);
     }
 
     std::vector< mitk::ClusteringMetric* > metrics;
 
     int mc = 0;
     for (auto m : metric_strings)
     {
       float w = boost::lexical_cast<float>(metric_weights.at(mc));
       MITK_INFO << "Metric: " << m << " (w=" << w << ")";
       if (m=="EU_MEAN")
         metrics.push_back({new mitk::ClusteringMetricEuclideanMean()});
       else if (m=="EU_STD")
         metrics.push_back({new mitk::ClusteringMetricEuclideanStd()});
       else if (m=="EU_MAX")
         metrics.push_back({new mitk::ClusteringMetricEuclideanMax()});
       else if (m=="ANGLES")
         metrics.push_back({new mitk::ClusteringMetricInnerAngles()});
       else if (m=="LENGTH")
         metrics.push_back({new mitk::ClusteringMetricLength()});
       else if (m=="MAP" && scalar_map!="")
       {
         mitk::Image::Pointer mitk_map = mitk::IOUtil::Load<mitk::Image>(scalar_map);
         if (mitk_map->GetDimension()==3)
         {
           FloatImageType::Pointer itk_map = FloatImageType::New();
           mitk::CastToItkImage(mitk_map, itk_map);
 
           mitk::ClusteringMetricScalarMap* metric = new mitk::ClusteringMetricScalarMap();
           metric->SetImages({itk_map});
           metric->SetScale(distances.at(0));
           metrics.push_back(metric);
         }
       }
       else if (m=="ANAT" && parcellation!="")
       {
         mitk::Image::Pointer mitk_map = mitk::IOUtil::Load<mitk::Image>(parcellation);
         if (mitk_map->GetDimension()==3)
         {
           ShortImageType::Pointer itk_map = ShortImageType::New();
           mitk::CastToItkImage(mitk_map, itk_map);
 
           mitk::ClusteringMetricAnatomic* metric = new mitk::ClusteringMetricAnatomic();
           metric->SetParcellations({itk_map});
           metrics.push_back(metric);
         }
       }
       metrics.back()->SetScale(w);
       mc++;
     }
 
     if (metrics.empty())
     {
       MITK_INFO << "No metric selected!";
       return EXIT_FAILURE;
     }
 
     clusterer->SetMetrics(metrics);
     clusterer->SetMergeDuplicateThreshold(merge_clusters);
     clusterer->SetNumPoints(fiber_points);
     clusterer->SetMaxClusters(max_clusters);
     clusterer->SetMinClusterSize(min_fibers);
     clusterer->Update();
     std::vector<mitk::FiberBundle::Pointer> tracts = clusterer->GetOutTractograms();
     std::vector<mitk::FiberBundle::Pointer> centroids = clusterer->GetOutCentroids();
 
     MITK_INFO << "Saving clusters";
     std::streambuf *old = cout.rdbuf(); // <-- save
     std::stringstream ss;
     std::cout.rdbuf (ss.rdbuf());       // <-- redirect
 
     if (!only_centroids)
       for (unsigned int i=0; i<tracts.size(); ++i)
         mitk::IOUtil::Save(tracts.at(i), out_root + "Cluster_" + boost::lexical_cast<std::string>(i) + file_ending);
 
 
     if (output_centroids && !merge_centroids)
     {
       for (unsigned int i=0; i<centroids.size(); ++i)
         mitk::IOUtil::Save(centroids.at(i), out_root + "Centroid_" + boost::lexical_cast<std::string>(i) + file_ending);
     }
     else if (output_centroids)
     {
       mitk::FiberBundle::Pointer centroid = mitk::FiberBundle::New();
       centroid = centroid->AddBundles(centroids);
       mitk::IOUtil::Save(centroid, out_root + ist::GetFilenameWithoutExtension(inFileName) + "_Centroids" + file_ending);
     }
 
     std::cout.rdbuf (old);              // <-- restore
 
   }
   catch (const itk::ExceptionObject& e)
   {
     std::cout << e.what();
     return EXIT_FAILURE;
   }
   catch (std::exception& e)
   {
     std::cout << e.what();
     return EXIT_FAILURE;
   }
   catch (...)
   {
     std::cout << "ERROR!?!";
     return EXIT_FAILURE;
   }
   return EXIT_SUCCESS;
 }
diff --git a/Modules/DiffusionCmdApps/TractographyEvaluation/CMakeLists.txt b/Modules/DiffusionCmdApps/TractographyEvaluation/CMakeLists.txt
index 52758e6..f80e692 100644
--- a/Modules/DiffusionCmdApps/TractographyEvaluation/CMakeLists.txt
+++ b/Modules/DiffusionCmdApps/TractographyEvaluation/CMakeLists.txt
@@ -1,46 +1,46 @@
 option(BUILD_DiffusionTractographyEvaluationCmdApps "Build commandline tools for diffusion fiber tractography evaluation" OFF)
 
 if(BUILD_DiffusionTractographyEvaluationCmdApps OR MITK_BUILD_ALL_APPS)
 
   # needed include directories
   include_directories(
     ${CMAKE_CURRENT_SOURCE_DIR}
     ${CMAKE_CURRENT_BINARY_DIR}
     )
 
     # list of diffusion cmdapps
     # if an app requires additional dependencies
     # they are added after a "^^" and separated by "_"
     set( diffusionTractographyEvaluationcmdapps
     PeaksAngularError^^
     MergeOverlappingTracts^^
     GetOverlappingTracts^^
     ExtractSimilarTracts^^
     AnchorConstrainedPlausibility^^
     CalculateOverlap^^
     CheckEpsAndOverlap^^
     ReferenceSimilarity^^
     TractDistance^^
     )
 
     foreach(diffusionTractographyEvaluationcmdapp ${diffusionTractographyEvaluationcmdapps})
       # extract cmd app name and dependencies
       string(REPLACE "^^" "\\;" cmdapp_info ${diffusionTractographyEvaluationcmdapp})
       set(cmdapp_info_list ${cmdapp_info})
       list(GET cmdapp_info_list 0 appname)
       list(GET cmdapp_info_list 1 raw_dependencies)
       string(REPLACE "_" "\\;" dependencies "${raw_dependencies}")
       set(dependencies_list ${dependencies})
 
       mitkFunctionCreateCommandLineApp(
         NAME ${appname}
-        DEPENDS MitkDiffusionCmdApps MitkMriSimulation ${dependencies_list}
+        DEPENDS MitkDiffusionCmdApps MitkFiberTracking MitkMriSimulation ${dependencies_list}
         PACKAGE_DEPENDS
       )
     endforeach()
 
   if(EXECUTABLE_IS_ENABLED)
     MITK_INSTALL_TARGETS(EXECUTABLES ${EXECUTABLE_TARGET})
   endif()
 
   endif()
diff --git a/Modules/DiffusionCmdApps/TractographyEvaluation/ExtractSimilarTracts.cpp b/Modules/DiffusionCmdApps/TractographyEvaluation/ExtractSimilarTracts.cpp
index 58a8453..58cac2c 100644
--- a/Modules/DiffusionCmdApps/TractographyEvaluation/ExtractSimilarTracts.cpp
+++ b/Modules/DiffusionCmdApps/TractographyEvaluation/ExtractSimilarTracts.cpp
@@ -1,199 +1,200 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #include <mitkFiberBundle.h>
 #include <mitkDiffusionCommandLineParser.h>
 #include <mitkLexicalCast.h>
 #include <mitkIOUtil.h>
-#include <itkTractClusteringFilter.h>
+#include <mitkTractClusteringFilter.h>
 #include <mitkClusteringMetricEuclideanMean.h>
 #include <mitkClusteringMetricEuclideanMax.h>
 #include <mitkClusteringMetricEuclideanStd.h>
 #include <mitkClusteringMetricAnatomic.h>
 #include <mitkClusteringMetricScalarMap.h>
 #include <mitkDiffusionDataIOHelper.h>
+#include <mitkTractClusteringFilter.h>
 
 typedef itk::Image<unsigned char, 3>    ItkFloatImgType;
 
 /*!
 \brief Spatially cluster fibers
 */
 int main(int argc, char* argv[])
 {
   mitkDiffusionCommandLineParser parser;
 
   parser.setTitle("Extract Similar Tracts");
   parser.setCategory("Fiber Tracking Evaluation");
   parser.setContributor("MIC");
 
   parser.setArgumentPrefix("--", "-");
   parser.addArgument("", "i", mitkDiffusionCommandLineParser::String, "Input:", "input fiber bundle (.fib, .trk, .tck)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input);
   parser.addArgument("ref_tracts", "", mitkDiffusionCommandLineParser::StringList, "Ref. Tracts:", "reference tracts (.fib, .trk, .tck)", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Input);
   parser.addArgument("ref_masks", "", mitkDiffusionCommandLineParser::StringList, "Ref. Masks:", "reference bundle masks", us::Any(), true, false, false, mitkDiffusionCommandLineParser::Input);
 
   parser.addArgument("", "o", mitkDiffusionCommandLineParser::String, "Output:", "output root", us::Any(), false, false, false, mitkDiffusionCommandLineParser::Output);
   parser.addArgument("distance", "", mitkDiffusionCommandLineParser::Int, "Distance:", "", 10);
   parser.addArgument("metric", "", mitkDiffusionCommandLineParser::String, "Metric:", "EU_MEAN (default), EU_STD, EU_MAX");
   parser.addArgument("subsample", "", mitkDiffusionCommandLineParser::Float, "Subsampling factor:", "Only use specified fraction of input fibers", 1.0);
 
   std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
   if (parsedArgs.size()==0)
     return EXIT_FAILURE;
 
   std::string in_fib = us::any_cast<std::string>(parsedArgs["i"]);
   std::string out_root = us::any_cast<std::string>(parsedArgs["o"]);
   mitkDiffusionCommandLineParser::StringContainerType ref_bundle_files = us::any_cast<mitkDiffusionCommandLineParser::StringContainerType>(parsedArgs["ref_tracts"]);
   mitkDiffusionCommandLineParser::StringContainerType ref_mask_files;
   if (parsedArgs.count("ref_masks"))
     ref_mask_files = us::any_cast<mitkDiffusionCommandLineParser::StringContainerType>(parsedArgs["ref_masks"]);
 
   if (ref_mask_files.size()>0 && ref_mask_files.size()!=ref_bundle_files.size())
   {
     MITK_INFO << "If reference masks are used, there has to be one mask per reference tract.";
     return EXIT_FAILURE;
   }
 
   int distance = 10;
   if (parsedArgs.count("distance"))
     distance = us::any_cast<int>(parsedArgs["distance"]);
 
   std::string metric = "EU_MEAN";
   if (parsedArgs.count("metric"))
     metric = us::any_cast<std::string>(parsedArgs["metric"]);
 
   float subsample = 1.0;
   if (parsedArgs.count("subsample"))
     subsample = us::any_cast<float>(parsedArgs["subsample"]);
 
   try
   {
     mitk::FiberBundle::Pointer fib = mitk::IOUtil::Load<mitk::FiberBundle>(in_fib);
 
     std::srand(0);
     if (subsample<1.0f)
       fib = fib->SubsampleFibers(subsample, true);
 
     mitk::FiberBundle::Pointer resampled_fib = fib->GetDeepCopy();
     resampled_fib->ResampleToNumPoints(12);
 
     auto ref_fibs = mitk::DiffusionDataIOHelper::load_fibs(ref_bundle_files);
     auto ref_masks = mitk::DiffusionDataIOHelper::load_itk_images<ItkFloatImgType>(ref_mask_files);
 
     std::vector< float > distances;
     distances.push_back(distance);
 
     mitk::FiberBundle::Pointer extracted = mitk::FiberBundle::New(nullptr);
     unsigned int c = 0;
     for (auto ref_fib : ref_fibs)
     {
       MITK_INFO << "Extracting " << ist::GetFilenameName(ref_bundle_files.at(c));
 
       std::streambuf *old = cout.rdbuf(); // <-- save
       std::stringstream ss;
       std::cout.rdbuf (ss.rdbuf());       // <-- redirect
       try
       {
-        itk::TractClusteringFilter::Pointer segmenter = itk::TractClusteringFilter::New();
+        std::shared_ptr< mitk::TractClusteringFilter > segmenter = std::make_shared<mitk::TractClusteringFilter>();
 
         // calculate centroids from reference bundle
         {
-          itk::TractClusteringFilter::Pointer clusterer = itk::TractClusteringFilter::New();
+          std::shared_ptr< mitk::TractClusteringFilter > clusterer = std::make_shared<mitk::TractClusteringFilter>();
           clusterer->SetDistances({10,20,30});
           clusterer->SetTractogram(ref_fib);
           clusterer->SetMetrics({new mitk::ClusteringMetricEuclideanStd()});
           clusterer->SetMergeDuplicateThreshold(0.0);
           clusterer->Update();
           std::vector<mitk::FiberBundle::Pointer> tracts = clusterer->GetOutCentroids();
           ref_fib = mitk::FiberBundle::New(nullptr);
           ref_fib = ref_fib->AddBundles(tracts);
           mitk::IOUtil::Save(ref_fib, out_root + "centroids_" + ist::GetFilenameName(ref_bundle_files.at(c)));
           segmenter->SetInCentroids(ref_fib);
         }
 
         // segment tract
         if (c<ref_masks.size())
         {
           segmenter->SetFilterMask(ref_masks.at(c));
           segmenter->SetOverlapThreshold(0.8f);
         }
         segmenter->SetDistances(distances);
         segmenter->SetTractogram(resampled_fib);
         segmenter->SetMergeDuplicateThreshold(0.0);
         segmenter->SetDoResampling(false);
         if (metric=="EU_MEAN")
           segmenter->SetMetrics({new mitk::ClusteringMetricEuclideanMean()});
         else if (metric=="EU_STD")
           segmenter->SetMetrics({new mitk::ClusteringMetricEuclideanStd()});
         else if (metric=="EU_MAX")
           segmenter->SetMetrics({new mitk::ClusteringMetricEuclideanMax()});
         segmenter->Update();
 
         std::vector< std::vector< unsigned int > > clusters = segmenter->GetOutFiberIndices();
         if (clusters.size()>0)
         {
           vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New();
 
           mitk::FiberBundle::Pointer result = mitk::FiberBundle::New(nullptr);
           std::vector< mitk::FiberBundle::Pointer > result_fibs;
           for (unsigned int cluster_index=0; cluster_index<clusters.size()-1; ++cluster_index)
             result_fibs.push_back(mitk::FiberBundle::New(fib->GeneratePolyDataByIds(clusters.at(cluster_index), weights)));
           result = result->AddBundles(result_fibs);
 
           extracted = extracted->AddBundle(result);
           mitk::IOUtil::Save(result, out_root + "extracted_" + ist::GetFilenameName(ref_bundle_files.at(c)));
 
           fib = mitk::FiberBundle::New(fib->GeneratePolyDataByIds(clusters.back(), weights));
           resampled_fib = mitk::FiberBundle::New(resampled_fib->GeneratePolyDataByIds(clusters.back(), weights));
         }
       }
       catch(itk::ExceptionObject& excpt)
       {
         MITK_INFO << "Exception while processing " << ist::GetFilenameName(ref_bundle_files.at(c));
         MITK_INFO << excpt.GetDescription();
       }
       catch(std::exception& excpt)
       {
         MITK_INFO << "Exception while processing " << ist::GetFilenameName(ref_bundle_files.at(c));
         MITK_INFO << excpt.what();
       }
       std::cout.rdbuf (old);              // <-- restore
       if (fib->GetNumFibers()==0)
         break;
       ++c;
     }
     MITK_INFO << "Extracted streamlines: " << extracted->GetNumFibers();
     mitk::IOUtil::Save(extracted, out_root + "extracted_streamlines.trk");
 
     MITK_INFO << "Residual streamlines: " << fib->GetNumFibers();
     mitk::IOUtil::Save(fib, out_root + "residual_streamlines.trk");
   }
   catch (const itk::ExceptionObject& e)
   {
     std::cout << e.what();
     return EXIT_FAILURE;
   }
   catch (std::exception& e)
   {
     std::cout << e.what();
     return EXIT_FAILURE;
   }
   catch (...)
   {
     std::cout << "ERROR!?!";
     return EXIT_FAILURE;
   }
   return EXIT_SUCCESS;
 }
diff --git a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp
index 96b7483..74e41d0 100644
--- a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp
+++ b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.cpp
@@ -1,2792 +1,2840 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #include "mitkFiberBundle.h"
 
 #include <mitkPlanarCircle.h>
 #include <mitkPlanarPolygon.h>
 #include <mitkPlanarFigureComposite.h>
 #include "mitkImagePixelReadAccessor.h"
 #include <mitkPixelTypeMultiplex.h>
 
 #include <vtkPointData.h>
 #include <vtkDataArray.h>
 #include <vtkUnsignedCharArray.h>
 #include <vtkPolyLine.h>
 #include <vtkCellArray.h>
 #include <vtkCellData.h>
 #include <vtkIdFilter.h>
 #include <vtkClipPolyData.h>
 #include <vtkPlane.h>
 #include <vtkDoubleArray.h>
 #include <vtkKochanekSpline.h>
 #include <vtkParametricFunctionSource.h>
 #include <vtkParametricSpline.h>
 #include <vtkPolygon.h>
 #include <vtkCleanPolyData.h>
 #include <boost/progress.hpp>
 #include <vtkTransformPolyDataFilter.h>
 #include <mitkTransferFunction.h>
 #include <vtkLookupTable.h>
 #include <mitkLookupTable.h>
 #include <vtkCardinalSpline.h>
 #include <vtkAppendPolyData.h>
 
 const char* mitk::FiberBundle::FIBER_ID_ARRAY = "Fiber_IDs";
 
 mitk::FiberBundle::FiberBundle( vtkPolyData* fiberPolyData )
   : m_NumFibers(0)
 {
   m_TrackVisHeader.hdr_size = 0;
   m_FiberWeights = vtkSmartPointer<vtkFloatArray>::New();
   m_FiberWeights->SetName("FIBER_WEIGHTS");
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   if (fiberPolyData != nullptr)
     m_FiberPolyData = fiberPolyData;
   else
   {
     this->m_FiberPolyData->SetPoints(vtkSmartPointer<vtkPoints>::New());
     this->m_FiberPolyData->SetLines(vtkSmartPointer<vtkCellArray>::New());
   }
 
   this->UpdateFiberGeometry();
   this->GenerateFiberIds();
   this->ColorFibersByOrientation();
 }
 
 mitk::FiberBundle::~FiberBundle()
 {
 
 }
 
 mitk::FiberBundle::Pointer mitk::FiberBundle::GetDeepCopy()
 {
   mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(m_FiberPolyData);
   newFib->SetFiberColors(this->m_FiberColors);
   newFib->SetFiberWeights(this->m_FiberWeights);
   newFib->SetTrackVisHeader(this->GetTrackVisHeader());
   return newFib;
 }
 
 vtkSmartPointer<vtkPolyData> mitk::FiberBundle::GeneratePolyDataByIds(std::vector<unsigned int> fiberIds, vtkSmartPointer<vtkFloatArray> weights)
 {
   vtkSmartPointer<vtkPolyData> newFiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   vtkSmartPointer<vtkCellArray> newLineSet = vtkSmartPointer<vtkCellArray>::New();
   vtkSmartPointer<vtkPoints> newPointSet = vtkSmartPointer<vtkPoints>::New();
   weights->SetNumberOfValues(fiberIds.size());
 
   int counter = 0;
   auto finIt = fiberIds.begin();
   while ( finIt != fiberIds.end() )
   {
     if (*finIt>GetNumFibers()){
       MITK_INFO << "FiberID can not be negative or >NumFibers!!! check id Extraction!" << *finIt;
       break;
     }
 
     vtkSmartPointer<vtkCell> fiber = m_FiberIdDataSet->GetCell(*finIt);//->DeepCopy(fiber);
     vtkSmartPointer<vtkPoints> fibPoints = fiber->GetPoints();
     vtkSmartPointer<vtkPolyLine> newFiber = vtkSmartPointer<vtkPolyLine>::New();
     newFiber->GetPointIds()->SetNumberOfIds( fibPoints->GetNumberOfPoints() );
 
     for(int i=0; i<fibPoints->GetNumberOfPoints(); i++)
     {
       newFiber->GetPointIds()->SetId(i, newPointSet->GetNumberOfPoints());
       newPointSet->InsertNextPoint(fibPoints->GetPoint(i)[0], fibPoints->GetPoint(i)[1], fibPoints->GetPoint(i)[2]);
     }
 
     weights->InsertValue(counter, this->GetFiberWeight(*finIt));
     newLineSet->InsertNextCell(newFiber);
     ++finIt;
     ++counter;
   }
 
   newFiberPolyData->SetPoints(newPointSet);
   newFiberPolyData->SetLines(newLineSet);
   return newFiberPolyData;
 }
 
 // merge two fiber bundles
 mitk::FiberBundle::Pointer mitk::FiberBundle::AddBundles(std::vector< mitk::FiberBundle::Pointer > fibs)
 {
   vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New();
   vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New();
   vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New();
 
   // add current fiber bundle
   vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New();
 
   auto num_weights = this->GetNumFibers();
   for (auto fib : fibs)
     num_weights += fib->GetNumFibers();
   weights->SetNumberOfValues(num_weights);
 
   unsigned int counter = 0;
   for (unsigned int i=0; i<m_FiberPolyData->GetNumberOfCells(); ++i)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (unsigned int j=0; j<numPoints; ++j)
     {
       double p[3];
       points->GetPoint(j, p);
 
       vtkIdType id = vNewPoints->InsertNextPoint(p);
       container->GetPointIds()->InsertNextId(id);
     }
     weights->InsertValue(counter, this->GetFiberWeight(i));
     vNewLines->InsertNextCell(container);
     counter++;
   }
 
   for (auto fib : fibs)
   {
     // add new fiber bundle
     for (unsigned int i=0; i<fib->GetFiberPolyData()->GetNumberOfCells(); i++)
     {
       vtkCell* cell = fib->GetFiberPolyData()->GetCell(i);
       auto numPoints = cell->GetNumberOfPoints();
       vtkPoints* points = cell->GetPoints();
 
       vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
       for (unsigned int j=0; j<numPoints; j++)
       {
         double p[3];
         points->GetPoint(j, p);
 
         vtkIdType id = vNewPoints->InsertNextPoint(p);
         container->GetPointIds()->InsertNextId(id);
       }
       weights->InsertValue(counter, fib->GetFiberWeight(i));
       vNewLines->InsertNextCell(container);
       counter++;
     }
   }
 
   // initialize PolyData
   vNewPolyData->SetPoints(vNewPoints);
   vNewPolyData->SetLines(vNewLines);
 
   // initialize fiber bundle
   mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData);
   newFib->SetFiberWeights(weights);
   return newFib;
 }
 
 // merge two fiber bundles
 mitk::FiberBundle::Pointer mitk::FiberBundle::AddBundle(mitk::FiberBundle* fib)
 {
   if (fib==nullptr)
     return this->GetDeepCopy();
 
   MITK_INFO << "Adding fibers";
 
   vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New();
   vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New();
   vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New();
 
   // add current fiber bundle
   vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New();
   weights->SetNumberOfValues(this->GetNumFibers()+fib->GetNumFibers());
 
   unsigned int counter = 0;
   for (unsigned int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (unsigned int j=0; j<numPoints; j++)
     {
       double p[3];
       points->GetPoint(j, p);
 
       vtkIdType id = vNewPoints->InsertNextPoint(p);
       container->GetPointIds()->InsertNextId(id);
     }
     weights->InsertValue(counter, this->GetFiberWeight(i));
     vNewLines->InsertNextCell(container);
     counter++;
   }
 
   // add new fiber bundle
   for (unsigned int i=0; i<fib->GetFiberPolyData()->GetNumberOfCells(); i++)
   {
     vtkCell* cell = fib->GetFiberPolyData()->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (unsigned int j=0; j<numPoints; j++)
     {
       double p[3];
       points->GetPoint(j, p);
 
       vtkIdType id = vNewPoints->InsertNextPoint(p);
       container->GetPointIds()->InsertNextId(id);
     }
     weights->InsertValue(counter, fib->GetFiberWeight(i));
     vNewLines->InsertNextCell(container);
     counter++;
   }
 
   // initialize PolyData
   vNewPolyData->SetPoints(vNewPoints);
   vNewPolyData->SetLines(vNewLines);
 
   // initialize fiber bundle
   mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData);
   newFib->SetFiberWeights(weights);
   return newFib;
 }
 
 // Only retain fibers with a weight larger than the specified threshold
 mitk::FiberBundle::Pointer mitk::FiberBundle::FilterByWeights(float weight_thr, bool invert)
 {
   vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New();
   vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New();
   vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New();
 
   std::vector<float> weights;
 
   for (unsigned int i=0; i<this->GetNumFibers(); i++)
   {
     if ( (invert && this->GetFiberWeight(i)>weight_thr) || (!invert && this->GetFiberWeight(i)<=weight_thr))
       continue;
 
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (int j=0; j<numPoints; j++)
     {
       double p[3];
       points->GetPoint(j, p);
 
       vtkIdType id = vNewPoints->InsertNextPoint(p);
       container->GetPointIds()->InsertNextId(id);
     }
     vNewLines->InsertNextCell(container);
     weights.push_back(this->GetFiberWeight(i));
   }
 
   // initialize PolyData
   vNewPolyData->SetPoints(vNewPoints);
   vNewPolyData->SetLines(vNewLines);
 
   // initialize fiber bundle
   mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData);
   for (unsigned int i=0; i<weights.size(); ++i)
     newFib->SetFiberWeight(i, weights.at(i));
   newFib->SetTrackVisHeader(this->GetTrackVisHeader());
   return newFib;
 }
 
 // Only retain a subsample of the fibers
 mitk::FiberBundle::Pointer mitk::FiberBundle::SubsampleFibers(float factor, bool random_seed)
 {
   vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New();
   vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New();
   vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New();
 
   unsigned int new_num_fibs = static_cast<unsigned int>(std::round(this->GetNumFibers()*factor));
   MITK_INFO << "Subsampling fibers with factor " << factor << "(" << new_num_fibs << "/" << this->GetNumFibers() << ")";
 
   // add current fiber bundle
   vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New();
   weights->SetNumberOfValues(new_num_fibs);
 
   std::vector< unsigned int > ids;
   for (unsigned int i=0; i<this->GetNumFibers(); i++)
     ids.push_back(i);
   if (random_seed)
     std::srand(static_cast<unsigned int>(std::time(nullptr)));
   else
     std::srand(0);
   std::random_shuffle(ids.begin(), ids.end());
 
   unsigned int counter = 0;
   for (unsigned int i=0; i<new_num_fibs; i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(ids.at(i));
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (int j=0; j<numPoints; j++)
     {
       double p[3];
       points->GetPoint(j, p);
 
       vtkIdType id = vNewPoints->InsertNextPoint(p);
       container->GetPointIds()->InsertNextId(id);
     }
     weights->InsertValue(counter, this->GetFiberWeight(ids.at(i)));
     vNewLines->InsertNextCell(container);
     counter++;
   }
 
   // initialize PolyData
   vNewPolyData->SetPoints(vNewPoints);
   vNewPolyData->SetLines(vNewLines);
 
   // initialize fiber bundle
   mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(vNewPolyData);
   newFib->SetFiberWeights(weights);
   newFib->SetTrackVisHeader(this->GetTrackVisHeader());
   return newFib;
 }
 
 // subtract two fiber bundles
 mitk::FiberBundle::Pointer mitk::FiberBundle::SubtractBundle(mitk::FiberBundle* fib)
 {
   if (fib==nullptr)
     return this->GetDeepCopy();
 
   MITK_INFO << "Subtracting fibers";
   vtkSmartPointer<vtkPolyData> vNewPolyData = vtkSmartPointer<vtkPolyData>::New();
   vtkSmartPointer<vtkCellArray> vNewLines = vtkSmartPointer<vtkCellArray>::New();
   vtkSmartPointer<vtkPoints> vNewPoints = vtkSmartPointer<vtkPoints>::New();
 
   std::vector< std::vector< itk::Point<float, 3> > > points1;
   for(unsigned int i=0; i<m_NumFibers; i++ )
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     if (points==nullptr || numPoints<=0)
       continue;
 
     itk::Point<float, 3> start = mitk::imv::GetItkPoint(points->GetPoint(0));
     itk::Point<float, 3> end = mitk::imv::GetItkPoint(points->GetPoint(numPoints-1));
 
     points1.push_back( {start, end} );
   }
 
   std::vector< std::vector< itk::Point<float, 3> > > points2;
   for(unsigned int i=0; i<fib->GetNumFibers(); i++ )
   {
     vtkCell* cell = fib->GetFiberPolyData()->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     if (points==nullptr || numPoints<=0)
       continue;
 
     itk::Point<float, 3> start =mitk::imv::GetItkPoint(points->GetPoint(0));
     itk::Point<float, 3> end =mitk::imv::GetItkPoint(points->GetPoint(numPoints-1));
 
     points2.push_back( {start, end} );
   }
 
   //  int progress = 0;
   std::vector< int > ids;
 #pragma omp parallel for
   for (int i=0; i<static_cast<int>(points1.size()); i++)
   {
     bool match = false;
     for (unsigned int j=0; j<points2.size(); j++)
     {
       auto v1 = points1.at(static_cast<unsigned int>(i));
       auto v2 = points2.at(j);
 
       float dist=0;
       for (unsigned int c=0; c<v1.size(); c++)
       {
         float d = v1[c][0]-v2[c][0];
         dist += d*d;
 
         d = v1[c][1]-v2[c][1];
         dist += d*d;
 
         d = v1[c][2]-v2[c][2];
         dist += d*d;
       }
       dist /= v1.size();
 
       if (dist<0.000001f)
       {
         match = true;
         break;
       }
 
       dist=0;
       for (unsigned int c=0; c<v1.size(); c++)
       {
         float d = v1[v1.size()-1-c][0]-v2[c][0];
         dist += d*d;
 
         d = v1[v1.size()-1-c][1]-v2[c][1];
         dist += d*d;
 
         d = v1[v1.size()-1-c][2]-v2[c][2];
         dist += d*d;
       }
       dist /= v1.size();
 
       if (dist<0.000001f)
       {
         match = true;
         break;
       }
     }
 
 #pragma omp critical
     if (!match)
       ids.push_back(i);
   }
 
   for( int i : ids )
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     if (points==nullptr || numPoints<=0)
       continue;
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for( int j=0; j<numPoints; j++)
     {
       vtkIdType id = vNewPoints->InsertNextPoint(points->GetPoint(j));
       container->GetPointIds()->InsertNextId(id);
     }
     vNewLines->InsertNextCell(container);
   }
   if(vNewLines->GetNumberOfCells()==0)
     return mitk::FiberBundle::New();
   // initialize PolyData
   vNewPolyData->SetPoints(vNewPoints);
   vNewPolyData->SetLines(vNewLines);
 
   // initialize fiber bundle
   return mitk::FiberBundle::New(vNewPolyData);
 }
 
 /*
  * set PolyData (additional flag to recompute fiber geometry, default = true)
  */
 void mitk::FiberBundle::SetFiberPolyData(vtkSmartPointer<vtkPolyData> fiberPD, bool updateGeometry)
 {
   if (fiberPD == nullptr)
     this->m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   else
     m_FiberPolyData->DeepCopy(fiberPD);
 
   m_NumFibers = static_cast<unsigned int>(m_FiberPolyData->GetNumberOfLines());
 
   if (updateGeometry)
     UpdateFiberGeometry();
   GenerateFiberIds();
   ColorFibersByOrientation();
 }
 
 /*
  * return vtkPolyData
  */
 vtkSmartPointer<vtkPolyData> mitk::FiberBundle::GetFiberPolyData() const
 {
   return m_FiberPolyData;
 }
 
 void mitk::FiberBundle::ColorFibersByLength(bool opacity, bool normalize, bool weight_fibers)
 {
   if (m_MaxFiberLength<=0)
     return;
 
   auto numOfPoints = this->GetNumberOfPoints();
 
   //colors and alpha value for each single point, RGBA = 4 components
   unsigned char rgba[4] = {0,0,0,0};
   m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
   m_FiberColors->Allocate(numOfPoints * 4);
   m_FiberColors->SetNumberOfComponents(4);
   m_FiberColors->SetName("FIBER_COLORS");
 
   auto numOfFibers = m_FiberPolyData->GetNumberOfLines();
   if (numOfFibers < 1)
     return;
 
   mitk::LookupTable::Pointer mitkLookup = mitk::LookupTable::New();
   vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
   lookupTable->SetTableRange(0.0, 0.8);
   lookupTable->Build();
   mitkLookup->SetVtkLookupTable(lookupTable);
   mitkLookup->SetType(mitk::LookupTable::JET);
 
   unsigned int count = 0;
   for (unsigned int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
 
     float l = m_FiberLengths.at(i)/m_MaxFiberLength;
     if (!normalize)
     {
       l = m_FiberLengths.at(i)/255.0f;
       if (l > 1.0f)
         l = 1.0;
     }
     for (int j=0; j<numPoints; j++)
     {
       double color[3];
       lookupTable->GetColor(1.0 - static_cast<double>(l), color);
 
       rgba[0] = static_cast<unsigned char>(255.0 * color[0]);
       rgba[1] = static_cast<unsigned char>(255.0 * color[1]);
       rgba[2] = static_cast<unsigned char>(255.0 * color[2]);
       if (opacity)
         rgba[3] = static_cast<unsigned char>(255.0f * l);
       else
         rgba[3] = static_cast<unsigned char>(255.0);
       m_FiberColors->InsertTypedTuple(cell->GetPointId(j), rgba);
       count++;
     }
 
     if (weight_fibers)
       this->SetFiberWeight(i, m_FiberLengths.at(i));
   }
 
   m_UpdateTime3D.Modified();
   m_UpdateTime2D.Modified();
 }
 
+void mitk::FiberBundle::ColorSinglePoint(int f_idx, int p_idx, double rgb[3])
+{
+//  vtkPoints* extrPoints = m_FiberPolyData->GetPoints();
+//  vtkIdType numOfPoints = 0;
+//  if (extrPoints!=nullptr)
+//    numOfPoints = extrPoints->GetNumberOfPoints();
+
+//  //colors and alpha value for each single point, RGBA = 4 components
+  unsigned char rgba[4] = {0,0,0,0};
+//  m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
+//  m_FiberColors->Allocate(numOfPoints * 4);
+//  m_FiberColors->SetNumberOfComponents(4);
+//  m_FiberColors->SetName("FIBER_COLORS");
+
+//  auto numOfFibers = m_FiberPolyData->GetNumberOfLines();
+//  if (numOfFibers < 1)
+//    return;
+
+//  /* extract single fibers of fiberBundle */
+//  vtkCellArray* fiberList = m_FiberPolyData->GetLines();
+//  fiberList->InitTraversal();
+
+//  for (int fi=0; fi<numOfFibers; ++fi)
+//  {
+
+//    vtkIdType* idList; // contains the point id's of the line
+//    vtkIdType num_points; // number of points for current line
+////    fiberList->GetNextCell(num_points, idList);
+//    fiberList->GetCell(f_idx, num_points, idList);
+
+    vtkCell* cell = m_FiberPolyData->GetCell(f_idx);
+
+
+//    /* single fiber checkpoints: is number of points valid */
+//    if (p_idx < num_points)
+//    {
+      rgba[0] = static_cast<unsigned char>(255.0 * rgb[0]);
+      rgba[1] = static_cast<unsigned char>(255.0 * rgb[1]);
+      rgba[2] = static_cast<unsigned char>(255.0 * rgb[2]);
+      rgba[3] = 255;
+
+      m_FiberColors->InsertTypedTuple(cell->GetPointId(p_idx), rgba);
+//    }
+//  }
+  m_UpdateTime3D.Modified();
+  m_UpdateTime2D.Modified();
+}
+
 void mitk::FiberBundle::ColorFibersByOrientation()
 {
   //===== FOR WRITING A TEST ========================
   //  colorT size == tupelComponents * tupelElements
   //  compare color results
   //  to cover this code 100% also PolyData needed, where colorarray already exists
   //  + one fiber with exactly 1 point
   //  + one fiber with 0 points
   //=================================================
 
   vtkPoints* extrPoints = m_FiberPolyData->GetPoints();
   vtkIdType numOfPoints = 0;
   if (extrPoints!=nullptr)
     numOfPoints = extrPoints->GetNumberOfPoints();
 
   //colors and alpha value for each single point, RGBA = 4 components
   unsigned char rgba[4] = {0,0,0,0};
   m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
   m_FiberColors->Allocate(numOfPoints * 4);
   m_FiberColors->SetNumberOfComponents(4);
   m_FiberColors->SetName("FIBER_COLORS");
 
   auto numOfFibers = m_FiberPolyData->GetNumberOfLines();
   if (numOfFibers < 1)
     return;
 
   /* extract single fibers of fiberBundle */
   vtkCellArray* fiberList = m_FiberPolyData->GetLines();
   fiberList->InitTraversal();
   for (int fi=0; fi<numOfFibers; ++fi) {
 
     vtkIdType* idList; // contains the point id's of the line
     vtkIdType pointsPerFiber; // number of points for current line
     fiberList->GetNextCell(pointsPerFiber, idList);
 
     /* single fiber checkpoints: is number of points valid */
     if (pointsPerFiber > 1)
     {
       /* operate on points of single fiber */
       for (int i=0; i <pointsPerFiber; ++i)
       {
         /* process all points elastV[0]ept starting and endpoint for calculating color value take current point, previous point and next point */
         if (i<pointsPerFiber-1 && i > 0)
         {
           /* The color value of the current point is influenced by the previous point and next point. */
           vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]);
           vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]);
           vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]);
 
           vnl_vector_fixed< double, 3 > diff1;
           diff1 = currentPntvtk - nextPntvtk;
 
           vnl_vector_fixed< double, 3 > diff2;
           diff2 = currentPntvtk - prevPntvtk;
 
           vnl_vector_fixed< double, 3 > diff;
           diff = (diff1 - diff2) / 2.0;
           diff.normalize();
 
           rgba[0] = static_cast<unsigned char>(255.0 * std::fabs(diff[0]));
           rgba[1] = static_cast<unsigned char>(255.0 * std::fabs(diff[1]));
           rgba[2] = static_cast<unsigned char>(255.0 * std::fabs(diff[2]));
           rgba[3] = static_cast<unsigned char>(255.0);
         }
         else if (i==0)
         {
           /* First point has no previous point, therefore only diff1 is taken */
 
           vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]);
           vnl_vector_fixed< double, 3 > nextPntvtk(extrPoints->GetPoint(idList[i+1])[0], extrPoints->GetPoint(idList[i+1])[1], extrPoints->GetPoint(idList[i+1])[2]);
 
           vnl_vector_fixed< double, 3 > diff1;
           diff1 = currentPntvtk - nextPntvtk;
           diff1.normalize();
 
           rgba[0] = static_cast<unsigned char>(255.0 * std::fabs(diff1[0]));
           rgba[1] = static_cast<unsigned char>(255.0 * std::fabs(diff1[1]));
           rgba[2] = static_cast<unsigned char>(255.0 * std::fabs(diff1[2]));
           rgba[3] = static_cast<unsigned char>(255.0);
         }
         else if (i==pointsPerFiber-1)
         {
           /* Last point has no next point, therefore only diff2 is taken */
           vnl_vector_fixed< double, 3 > currentPntvtk(extrPoints->GetPoint(idList[i])[0], extrPoints->GetPoint(idList[i])[1],extrPoints->GetPoint(idList[i])[2]);
           vnl_vector_fixed< double, 3 > prevPntvtk(extrPoints->GetPoint(idList[i-1])[0], extrPoints->GetPoint(idList[i-1])[1], extrPoints->GetPoint(idList[i-1])[2]);
 
           vnl_vector_fixed< double, 3 > diff2;
           diff2 = currentPntvtk - prevPntvtk;
           diff2.normalize();
 
           rgba[0] = static_cast<unsigned char>(255.0 * std::fabs(diff2[0]));
           rgba[1] = static_cast<unsigned char>(255.0 * std::fabs(diff2[1]));
           rgba[2] = static_cast<unsigned char>(255.0 * std::fabs(diff2[2]));
           rgba[3] = static_cast<unsigned char>(255.0);
         }
         m_FiberColors->InsertTypedTuple(idList[i], rgba);
       }
     }
     else if (pointsPerFiber == 1)
     {
       /* a single point does not define a fiber (use vertex mechanisms instead */
       continue;
     }
     else
     {
       MITK_DEBUG << "Fiber with 0 points detected... please check your tractography algorithm!" ;
       continue;
     }
   }
   m_UpdateTime3D.Modified();
   m_UpdateTime2D.Modified();
 }
 
 void mitk::FiberBundle::ColorFibersByCurvature(bool, bool normalize, bool weight_fibers)
 {
   double window = 5;
 
   //colors and alpha value for each single point, RGBA = 4 components
   unsigned char rgba[4] = {0,0,0,0};
   m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
   m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4);
   m_FiberColors->SetNumberOfComponents(4);
   m_FiberColors->SetName("FIBER_COLORS");
 
   mitk::LookupTable::Pointer mitkLookup = mitk::LookupTable::New();
   vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
   lookupTable->SetTableRange(0.0, 0.8);
   lookupTable->Build();
   mitkLookup->SetVtkLookupTable(lookupTable);
   mitkLookup->SetType(mitk::LookupTable::JET);
 
   std::vector< double > values;
   double min = 1;
   double max = 0;
   MITK_INFO << "Coloring fibers by curvature";
   boost::progress_display disp(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells()));
 
   for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
   {
     ++disp;
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
     double mean_curv = 0;
 
     // calculate curvatures
     for (int j=0; j<numPoints; j++)
     {
       double dist = 0;
       int c = j;
       std::vector< vnl_vector_fixed< double, 3 > > vectors;
       vnl_vector_fixed< double, 3 > meanV; meanV.fill(0.0);
       while(dist<window/2 && c>1)
       {
         double p1[3];
         points->GetPoint(c-1, p1);
         double p2[3];
         points->GetPoint(c, p2);
 
         vnl_vector_fixed< double, 3 > v;
         v[0] = p2[0]-p1[0];
         v[1] = p2[1]-p1[1];
         v[2] = p2[2]-p1[2];
         dist += v.magnitude();
         v.normalize();
         vectors.push_back(v);
         meanV += v;
         c--;
       }
       c = j;
       dist = 0;
       while(dist<window/2 && c<numPoints-1)
       {
         double p1[3];
         points->GetPoint(c, p1);
         double p2[3];
         points->GetPoint(c+1, p2);
 
         vnl_vector_fixed< double, 3 > v;
         v[0] = p2[0]-p1[0];
         v[1] = p2[1]-p1[1];
         v[2] = p2[2]-p1[2];
         dist += v.magnitude();
         v.normalize();
         vectors.push_back(v);
         meanV += v;
         c++;
       }
       meanV.normalize();
 
       double dev = 0;
       for (unsigned int c=0; c<vectors.size(); c++)
       {
         double angle = dot_product(meanV, vectors.at(c));
         if (angle>1.0)
           angle = 1.0;
         if (angle<-1.0)
           angle = -1.0;
         dev += acos(angle)*180/itk::Math::pi;
       }
       if (vectors.size()>0)
         dev /= vectors.size();
 
       if (weight_fibers)
         mean_curv += dev;
       dev = 1.0-dev/180.0;
       values.push_back(dev);
       if (dev<min)
         min = dev;
       if (dev>max)
         max = dev;
     }
 
     if (weight_fibers)
       this->SetFiberWeight(i, mean_curv/numPoints);
   }
 
   unsigned int count = 0;
   for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     for (int j=0; j<numPoints; j++)
     {
       double color[3];
       double dev = values.at(count);
       if (normalize)
         dev = (dev-min)/(max-min);
       else if (dev>1)
         dev = 1;
       lookupTable->GetColor(dev, color);
 
       rgba[0] = static_cast<unsigned char>(255.0 * color[0]);
       rgba[1] = static_cast<unsigned char>(255.0 * color[1]);
       rgba[2] = static_cast<unsigned char>(255.0 * color[2]);
       rgba[3] = static_cast<unsigned char>(255.0);
       m_FiberColors->InsertTypedTuple(cell->GetPointId(j), rgba);
       count++;
     }
   }
   m_UpdateTime3D.Modified();
   m_UpdateTime2D.Modified();
 }
 
 void mitk::FiberBundle::SetFiberOpacity(vtkDoubleArray* FAValArray)
 {
   for(long i=0; i<m_FiberColors->GetNumberOfTuples(); i++)
   {
     double faValue = FAValArray->GetValue(i);
     faValue = faValue * 255.0;
     m_FiberColors->SetComponent(i,3, static_cast<unsigned char>(faValue) );
   }
   m_UpdateTime3D.Modified();
   m_UpdateTime2D.Modified();
 }
 
 void mitk::FiberBundle::ResetFiberOpacity()
 {
   for(long i=0; i<m_FiberColors->GetNumberOfTuples(); i++)
     m_FiberColors->SetComponent(i,3, 255.0 );
   m_UpdateTime3D.Modified();
   m_UpdateTime2D.Modified();
 }
 
 void mitk::FiberBundle::ColorFibersByScalarMap(mitk::Image::Pointer FAimage, bool opacity, bool normalize, bool weight_fibers)
 {
   mitkPixelTypeMultiplex4( ColorFibersByScalarMap, FAimage->GetPixelType(), FAimage, opacity, normalize, weight_fibers );
   m_UpdateTime3D.Modified();
   m_UpdateTime2D.Modified();
 }
 
 template <typename TPixel>
 void mitk::FiberBundle::ColorFibersByScalarMap(const mitk::PixelType, mitk::Image::Pointer image, bool opacity, bool normalize, bool weight_fibers)
 {
   m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
   m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4);
   m_FiberColors->SetNumberOfComponents(4);
   m_FiberColors->SetName("FIBER_COLORS");
 
   mitk::ImagePixelReadAccessor<TPixel,3> readimage(image, image->GetVolumeData(0));
 
   unsigned char rgba[4] = {0,0,0,0};
   vtkPoints* pointSet = m_FiberPolyData->GetPoints();
 
   mitk::LookupTable::Pointer mitkLookup = mitk::LookupTable::New();
   vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
   lookupTable->SetTableRange(0.0, 0.8);
   lookupTable->Build();
   mitkLookup->SetVtkLookupTable(lookupTable);
   mitkLookup->SetType(mitk::LookupTable::JET);
 
   double min = 999999;
   double max = -999999;
 
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
     double mean_val = 0;
 
     for (int j=0; j<numPoints; j++)
     {
       double p[3];
       points->GetPoint(j, p);
 
       Point3D px;
       px[0] = p[0];
       px[1] = p[1];
       px[2] = p[2];
       auto pixelValue = static_cast<double>(readimage.GetPixelByWorldCoordinates(px));
 
       if (pixelValue>max)
         max = pixelValue;
       if (pixelValue<min)
         min = pixelValue;
 
       if (weight_fibers)
         mean_val += pixelValue;
     }
 
     if (weight_fibers)
       this->SetFiberWeight(i, mean_val/numPoints);
   }
 
   for(long i=0; i<m_FiberPolyData->GetNumberOfPoints(); ++i)
   {
     Point3D px;
     px[0] = pointSet->GetPoint(i)[0];
     px[1] = pointSet->GetPoint(i)[1];
     px[2] = pointSet->GetPoint(i)[2];
     auto pixelValue = static_cast<double>(readimage.GetPixelByWorldCoordinates(px));
 
     if (normalize)
       pixelValue = (pixelValue-min)/(max-min);
     else if (pixelValue>1)
       pixelValue = 1;
 
     double color[3];
     lookupTable->GetColor(1-pixelValue, color);
 
     rgba[0] = static_cast<unsigned char>(255.0 * color[0]);
     rgba[1] = static_cast<unsigned char>(255.0 * color[1]);
     rgba[2] = static_cast<unsigned char>(255.0 * color[2]);
     if (opacity)
       rgba[3] = static_cast<unsigned char>(255.0 * pixelValue);
     else
       rgba[3] = static_cast<unsigned char>(255.0);
     m_FiberColors->InsertTypedTuple(i, rgba);
   }
   m_UpdateTime3D.Modified();
   m_UpdateTime2D.Modified();
 }
 
 
 void mitk::FiberBundle::ColorFibersByFiberWeights(bool opacity, bool normalize)
 {
   m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
   m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4);
   m_FiberColors->SetNumberOfComponents(4);
   m_FiberColors->SetName("FIBER_COLORS");
 
   mitk::LookupTable::Pointer mitkLookup = mitk::LookupTable::New();
   vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
   lookupTable->SetTableRange(0.0, 0.8);
   lookupTable->Build();
   mitkLookup->SetVtkLookupTable(lookupTable);
   mitkLookup->SetType(mitk::LookupTable::JET);
 
   unsigned char rgba[4] = {0,0,0,0};
   unsigned int counter = 0;
 
   float max = -999999;
   float min = 999999;
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     float weight = this->GetFiberWeight(i);
     if (weight>max)
       max = weight;
     if (weight<min)
       min = weight;
   }
   if (fabs(max-min)<0.00001f)
   {
     max = 1;
     min = 0;
   }
 
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     auto weight = this->GetFiberWeight(i);
 
     for (int j=0; j<numPoints; j++)
     {
       float v = weight;
       if (normalize)
         v = (v-min)/(max-min);
       else if (v>1)
         v = 1;
       double color[3];
       lookupTable->GetColor(static_cast<double>(1-v), color);
 
       rgba[0] = static_cast<unsigned char>(255.0 * color[0]);
       rgba[1] = static_cast<unsigned char>(255.0 * color[1]);
       rgba[2] = static_cast<unsigned char>(255.0 * color[2]);
       if (opacity)
         rgba[3] = static_cast<unsigned char>(255.0f * v);
       else
         rgba[3] = static_cast<unsigned char>(255.0);
 
       m_FiberColors->InsertTypedTuple(counter, rgba);
       counter++;
     }
   }
 
   m_UpdateTime3D.Modified();
   m_UpdateTime2D.Modified();
 }
 
 void mitk::FiberBundle::SetFiberColors(float r, float g, float b, float alpha)
 {
   m_FiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
   m_FiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4);
   m_FiberColors->SetNumberOfComponents(4);
   m_FiberColors->SetName("FIBER_COLORS");
 
   unsigned char rgba[4] = {0,0,0,0};
   for(long i=0; i<m_FiberPolyData->GetNumberOfPoints(); ++i)
   {
     rgba[0] = static_cast<unsigned char>(r);
     rgba[1] = static_cast<unsigned char>(g);
     rgba[2] = static_cast<unsigned char>(b);
     rgba[3] = static_cast<unsigned char>(alpha);
     m_FiberColors->InsertTypedTuple(i, rgba);
   }
   m_UpdateTime3D.Modified();
   m_UpdateTime2D.Modified();
 }
 
 void mitk::FiberBundle::GenerateFiberIds()
 {
   if (m_FiberPolyData == nullptr)
     return;
 
   vtkSmartPointer<vtkIdFilter> idFiberFilter = vtkSmartPointer<vtkIdFilter>::New();
   idFiberFilter->SetInputData(m_FiberPolyData);
   idFiberFilter->CellIdsOn();
   //  idFiberFilter->PointIdsOn(); // point id's are not needed
   idFiberFilter->SetIdsArrayName(FIBER_ID_ARRAY);
   idFiberFilter->FieldDataOn();
   idFiberFilter->Update();
 
   m_FiberIdDataSet = idFiberFilter->GetOutput();
 
 }
 
 float mitk::FiberBundle::GetNumEpFractionInMask(ItkUcharImgType* mask, bool different_label)
 {
   vtkSmartPointer<vtkPolyData> PolyData = m_FiberPolyData;
 
   MITK_INFO << "Calculating EP-Fraction";
 
   boost::progress_display disp(m_NumFibers);
   unsigned int in_mask = 0;
 
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     ++disp;
     vtkCell* cell = PolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     itk::Point<float, 3> startVertex =mitk::imv::GetItkPoint(points->GetPoint(0));
     itk::Index<3> startIndex;
     mask->TransformPhysicalPointToIndex(startVertex, startIndex);
 
     itk::Point<float, 3> endVertex =mitk::imv::GetItkPoint(points->GetPoint(numPoints-1));
     itk::Index<3> endIndex;
     mask->TransformPhysicalPointToIndex(endVertex, endIndex);
 
     if (mask->GetLargestPossibleRegion().IsInside(startIndex) && mask->GetLargestPossibleRegion().IsInside(endIndex))
     {
       float v1 = mask->GetPixel(startIndex);
       if (v1 < 0.5f)
         continue;
       float v2 = mask->GetPixel(startIndex);
       if (v2 < 0.5f)
         continue;
 
       if (!different_label)
         ++in_mask;
       else if (fabs(v1-v2)>0.00001f)
         ++in_mask;
     }
   }
   return float(in_mask)/m_NumFibers;
 }
 
 std::tuple<float, float> mitk::FiberBundle::GetDirectionalOverlap(ItkUcharImgType* mask, mitk::PeakImage::ItkPeakImageType* peak_image)
 {
   vtkSmartPointer<vtkPolyData> PolyData = m_FiberPolyData;
 
   MITK_INFO << "Calculating overlap";
   auto spacing = mask->GetSpacing();
   boost::progress_display disp(m_NumFibers);
   double length_sum = 0;
   double in_mask_length = 0;
   double aligned_length = 0;
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     ++disp;
     vtkCell* cell = PolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     for (int j=0; j<numPoints-1; j++)
     {
       itk::Point<float, 3> startVertex =mitk::imv::GetItkPoint(points->GetPoint(j));
       itk::Index<3> startIndex;
       itk::ContinuousIndex<float, 3> startIndexCont;
       mask->TransformPhysicalPointToIndex(startVertex, startIndex);
       mask->TransformPhysicalPointToContinuousIndex(startVertex, startIndexCont);
 
       itk::Point<float, 3> endVertex =mitk::imv::GetItkPoint(points->GetPoint(j + 1));
       itk::Index<3> endIndex;
       itk::ContinuousIndex<float, 3> endIndexCont;
       mask->TransformPhysicalPointToIndex(endVertex, endIndex);
       mask->TransformPhysicalPointToContinuousIndex(endVertex, endIndexCont);
       
       vnl_vector_fixed< float, 3 > fdir;
       fdir[0] = endVertex[0] - startVertex[0];
       fdir[1] = endVertex[1] - startVertex[1];
       fdir[2] = endVertex[2] - startVertex[2];
       fdir.normalize();
 
       std::vector< std::pair< itk::Index<3>, double > > segments = mitk::imv::IntersectImage(spacing, startIndex, endIndex, startIndexCont, endIndexCont);
       for (std::pair< itk::Index<3>, double > segment : segments)
       {
         if ( mask->GetLargestPossibleRegion().IsInside(segment.first) && mask->GetPixel(segment.first) > 0 )
         {
           in_mask_length += segment.second;
           
           mitk::PeakImage::ItkPeakImageType::IndexType idx4; 
           idx4[0] = segment.first[0]; 
           idx4[1] = segment.first[1]; 
           idx4[2] = segment.first[2];
           
           vnl_vector_fixed< float, 3 > peak;
           idx4[3] = 0;
           peak[0] = peak_image->GetPixel(idx4);
           idx4[3] = 1;
           peak[1] = peak_image->GetPixel(idx4);
           idx4[3] = 2;
           peak[2] = peak_image->GetPixel(idx4);
           if (std::isnan(peak[0]) || std::isnan(peak[1]) || std::isnan(peak[2]) || peak.magnitude()<0.0001f)
             continue;
           peak.normalize();
           
           double f = 1.0 - std::acos(std::fabs(static_cast<double>(dot_product(fdir, peak)))) * 2.0/itk::Math::pi;
           aligned_length += segment.second * f;
         }
         length_sum += segment.second;
       }
     }
   }
 
   if (length_sum<=0.0001)
   {
     MITK_INFO << "Fiber length sum is zero!";
     return std::make_tuple(0,0);
   }
   return std::make_tuple(aligned_length/length_sum, in_mask_length/length_sum);
 }
 
 float mitk::FiberBundle::GetOverlap(ItkUcharImgType* mask)
 {
   vtkSmartPointer<vtkPolyData> PolyData = m_FiberPolyData;
 
   MITK_INFO << "Calculating overlap";
   auto spacing = mask->GetSpacing();
   boost::progress_display disp(m_NumFibers);
   double length_sum = 0;
   double in_mask_length = 0;
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     ++disp;
     vtkCell* cell = PolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     for (int j=0; j<numPoints-1; j++)
     {
       itk::Point<float, 3> startVertex =mitk::imv::GetItkPoint(points->GetPoint(j));
       itk::Index<3> startIndex;
       itk::ContinuousIndex<float, 3> startIndexCont;
       mask->TransformPhysicalPointToIndex(startVertex, startIndex);
       mask->TransformPhysicalPointToContinuousIndex(startVertex, startIndexCont);
 
       itk::Point<float, 3> endVertex =mitk::imv::GetItkPoint(points->GetPoint(j + 1));
       itk::Index<3> endIndex;
       itk::ContinuousIndex<float, 3> endIndexCont;
       mask->TransformPhysicalPointToIndex(endVertex, endIndex);
       mask->TransformPhysicalPointToContinuousIndex(endVertex, endIndexCont);
 
       std::vector< std::pair< itk::Index<3>, double > > segments = mitk::imv::IntersectImage(spacing, startIndex, endIndex, startIndexCont, endIndexCont);
       for (std::pair< itk::Index<3>, double > segment : segments)
       {
         if ( mask->GetLargestPossibleRegion().IsInside(segment.first) && mask->GetPixel(segment.first) > 0 )
           in_mask_length += segment.second;
         length_sum += segment.second;
       }
     }
   }
 
   if (length_sum<=0.000001)
   {
     MITK_INFO << "Fiber length sum is zero!";
     return 0;
   }
   return static_cast<float>(in_mask_length/length_sum);
 }
 
 mitk::FiberBundle::Pointer mitk::FiberBundle::RemoveFibersOutside(ItkUcharImgType* mask, bool invert)
 {
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   std::vector< float > fib_weights;
 
   MITK_INFO << "Cutting fibers";
   boost::progress_display disp(m_NumFibers);
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     ++disp;
 
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     int newNumPoints = 0;
     if (numPoints>1)
     {
       for (int j=0; j<numPoints; j++)
       {
         itk::Point<float, 3> itkP =mitk::imv::GetItkPoint(points->GetPoint(j));
         itk::Index<3> idx;
         mask->TransformPhysicalPointToIndex(itkP, idx);
 
         bool inside = false;
         if ( mask->GetLargestPossibleRegion().IsInside(idx) && mask->GetPixel(idx)!=0 )
           inside = true;
 
         if (inside && !invert)
         {
           vtkIdType id = vtkNewPoints->InsertNextPoint(itkP.GetDataPointer());
           container->GetPointIds()->InsertNextId(id);
           newNumPoints++;
         }
         else if ( !inside && invert )
         {
           vtkIdType id = vtkNewPoints->InsertNextPoint(itkP.GetDataPointer());
           container->GetPointIds()->InsertNextId(id);
           newNumPoints++;
         }
         else if (newNumPoints>1)
         {
           fib_weights.push_back(this->GetFiberWeight(i));
           vtkNewCells->InsertNextCell(container);
           newNumPoints = 0;
           container = vtkSmartPointer<vtkPolyLine>::New();
         }
         else
         {
           newNumPoints = 0;
           container = vtkSmartPointer<vtkPolyLine>::New();
         }
       }
 
       if (newNumPoints>1)
       {
         fib_weights.push_back(this->GetFiberWeight(i));
         vtkNewCells->InsertNextCell(container);
       }
     }
 
   }
 
   vtkSmartPointer<vtkFloatArray> newFiberWeights = vtkSmartPointer<vtkFloatArray>::New();
   newFiberWeights->SetName("FIBER_WEIGHTS");
   newFiberWeights->SetNumberOfValues(static_cast<vtkIdType>(fib_weights.size()));
 
   if (vtkNewCells->GetNumberOfCells()<=0)
     return nullptr;
 
   for (unsigned int i=0; i<newFiberWeights->GetNumberOfValues(); i++)
     newFiberWeights->SetValue(i, fib_weights.at(i));
 
 //  vtkSmartPointer<vtkUnsignedCharArray> newFiberColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
 //  newFiberColors->Allocate(m_FiberPolyData->GetNumberOfPoints() * 4);
 //  newFiberColors->SetNumberOfComponents(4);
 //  newFiberColors->SetName("FIBER_COLORS");
 
 //  unsigned char rgba[4] = {0,0,0,0};
 //  for(long i=0; i<m_FiberPolyData->GetNumberOfPoints(); ++i)
 //  {
 //    rgba[0] = (unsigned char) r;
 //    rgba[1] = (unsigned char) g;
 //    rgba[2] = (unsigned char) b;
 //    rgba[3] = (unsigned char) alpha;
 //    m_FiberColors->InsertTypedTuple(i, rgba);
 //  }
 
   vtkSmartPointer<vtkPolyData> newPolyData = vtkSmartPointer<vtkPolyData>::New();
   newPolyData->SetPoints(vtkNewPoints);
   newPolyData->SetLines(vtkNewCells);
   mitk::FiberBundle::Pointer newFib = mitk::FiberBundle::New(newPolyData);
   newFib->SetFiberWeights(newFiberWeights);
 //  newFib->Compress(0.1);
   newFib->SetTrackVisHeader(this->GetTrackVisHeader());
   return newFib;
 }
 
 mitk::FiberBundle::Pointer mitk::FiberBundle::ExtractFiberSubset(DataNode* roi, DataStorage* storage)
 {
   if (roi==nullptr || !(dynamic_cast<PlanarFigure*>(roi->GetData()) || dynamic_cast<PlanarFigureComposite*>(roi->GetData())) )
     return nullptr;
 
   std::vector<unsigned int> tmp = ExtractFiberIdSubset(roi, storage);
 
   if (tmp.size()<=0)
     return mitk::FiberBundle::New();
   vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New();
   vtkSmartPointer<vtkPolyData> pTmp = GeneratePolyDataByIds(tmp, weights);
   mitk::FiberBundle::Pointer fib = mitk::FiberBundle::New(pTmp);
   fib->SetFiberWeights(weights);
   fib->SetTrackVisHeader(this->GetTrackVisHeader());
   return fib;
 }
 
 std::vector<unsigned int> mitk::FiberBundle::ExtractFiberIdSubset(DataNode *roi, DataStorage* storage)
 {
   std::vector<unsigned int> result;
   if (roi==nullptr || roi->GetData()==nullptr)
     return result;
 
   mitk::PlanarFigureComposite::Pointer pfc = dynamic_cast<mitk::PlanarFigureComposite*>(roi->GetData());
   if (!pfc.IsNull()) // handle composite
   {
     DataStorage::SetOfObjects::ConstPointer children = storage->GetDerivations(roi);
     if (children->size()==0)
       return result;
 
     switch (pfc->getOperationType())
     {
     case 0: // AND
     {
       MITK_INFO << "AND";
       result = this->ExtractFiberIdSubset(children->ElementAt(0), storage);
       std::vector<unsigned int>::iterator it;
       for (unsigned int i=1; i<children->Size(); ++i)
       {
         std::vector<unsigned int> inRoi = this->ExtractFiberIdSubset(children->ElementAt(i), storage);
 
         std::vector<unsigned int> rest(std::min(result.size(),inRoi.size()));
         it = std::set_intersection(result.begin(), result.end(), inRoi.begin(), inRoi.end(), rest.begin() );
         rest.resize( static_cast<unsigned int>(it - rest.begin()) );
         result = rest;
       }
       break;
     }
     case 1: // OR
     {
       MITK_INFO << "OR";
       result = ExtractFiberIdSubset(children->ElementAt(0), storage);
       std::vector<unsigned int>::iterator it;
       for (unsigned int i=1; i<children->Size(); ++i)
       {
         it = result.end();
         std::vector<unsigned int> inRoi = ExtractFiberIdSubset(children->ElementAt(i), storage);
         result.insert(it, inRoi.begin(), inRoi.end());
       }
 
       // remove duplicates
       sort(result.begin(), result.end());
       it = unique(result.begin(), result.end());
       result.resize( static_cast<unsigned int>(it - result.begin()) );
       break;
     }
     case 2: // NOT
     {
       MITK_INFO << "NOT";
       for(unsigned int i=0; i<this->GetNumFibers(); i++)
         result.push_back(i);
 
       std::vector<unsigned int>::iterator it;
       for (unsigned int i=0; i<children->Size(); ++i)
       {
         std::vector<unsigned int> inRoi = ExtractFiberIdSubset(children->ElementAt(i), storage);
 
         std::vector<unsigned int> rest(result.size()-inRoi.size());
         it = std::set_difference(result.begin(), result.end(), inRoi.begin(), inRoi.end(), rest.begin() );
         rest.resize( static_cast<unsigned int>(it - rest.begin()) );
         result = rest;
       }
       break;
     }
     }
   }
   else if ( dynamic_cast<mitk::PlanarFigure*>(roi->GetData()) )  // actual extraction
   {
     if ( dynamic_cast<mitk::PlanarPolygon*>(roi->GetData()) )
     {
       mitk::PlanarFigure::Pointer planarPoly = dynamic_cast<mitk::PlanarFigure*>(roi->GetData());
 
       //create vtkPolygon using controlpoints from planarFigure polygon
       vtkSmartPointer<vtkPolygon> polygonVtk = vtkSmartPointer<vtkPolygon>::New();
       for (unsigned int i=0; i<planarPoly->GetNumberOfControlPoints(); ++i)
       {
         itk::Point<double,3> p = planarPoly->GetWorldControlPoint(i);
         vtkIdType id = polygonVtk->GetPoints()->InsertNextPoint(p[0], p[1], p[2] );
         polygonVtk->GetPointIds()->InsertNextId(id);
       }
 
       MITK_INFO << "Extracting with polygon";
       boost::progress_display disp(m_NumFibers);
       for (unsigned int i=0; i<m_NumFibers; i++)
       {
         ++disp ;
         vtkCell* cell = m_FiberPolyData->GetCell(i);
         auto numPoints = cell->GetNumberOfPoints();
         vtkPoints* points = cell->GetPoints();
 
         for (int j=0; j<numPoints-1; j++)
         {
           // Inputs
           double p1[3] = {0,0,0};
           points->GetPoint(j, p1);
           double p2[3] = {0,0,0};
           points->GetPoint(j+1, p2);
           double tolerance = 0.001;
 
           // Outputs
           double t = 0; // Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2))
           double x[3] = {0,0,0}; // The coordinate of the intersection
           double pcoords[3] = {0,0,0};
           int subId = 0;
 
           int iD = polygonVtk->IntersectWithLine(p1, p2, tolerance, t, x, pcoords, subId);
           if (iD!=0)
           {
             result.push_back(i);
             break;
           }
         }
       }
     }
     else if ( dynamic_cast<mitk::PlanarCircle*>(roi->GetData()) )
     {
       mitk::PlanarFigure::Pointer planarFigure = dynamic_cast<mitk::PlanarFigure*>(roi->GetData());
       Vector3D planeNormal = planarFigure->GetPlaneGeometry()->GetNormal();
       planeNormal.Normalize();
 
       //calculate circle radius
       mitk::Point3D V1w = planarFigure->GetWorldControlPoint(0); //centerPoint
       mitk::Point3D V2w  = planarFigure->GetWorldControlPoint(1); //radiusPoint
 
       double radius = V1w.EuclideanDistanceTo(V2w);
       radius *= radius;
 
       MITK_INFO << "Extracting with circle";
       boost::progress_display disp(m_NumFibers);
       for (unsigned int i=0; i<m_NumFibers; i++)
       {
         ++disp ;
         vtkCell* cell = m_FiberPolyData->GetCell(i);
         auto numPoints = cell->GetNumberOfPoints();
         vtkPoints* points = cell->GetPoints();
 
         for (int j=0; j<numPoints-1; j++)
         {
           // Inputs
           double p1[3] = {0,0,0};
           points->GetPoint(j, p1);
           double p2[3] = {0,0,0};
           points->GetPoint(j+1, p2);
 
           // Outputs
           double t = 0; // Parametric coordinate of intersection (0 (corresponding to p1) to 1 (corresponding to p2))
           double x[3] = {0,0,0}; // The coordinate of the intersection
 
           int iD = vtkPlane::IntersectWithLine(p1,p2,planeNormal.GetDataPointer(),V1w.GetDataPointer(),t,x);
 
           if (iD!=0)
           {
             double dist = (x[0]-V1w[0])*(x[0]-V1w[0])+(x[1]-V1w[1])*(x[1]-V1w[1])+(x[2]-V1w[2])*(x[2]-V1w[2]);
             if( dist <= radius)
             {
               result.push_back(i);
               break;
             }
           }
         }
       }
     }
     return result;
   }
 
   return result;
 }
 
 void mitk::FiberBundle::UpdateFiberGeometry()
 {
   vtkSmartPointer<vtkCleanPolyData> cleaner = vtkSmartPointer<vtkCleanPolyData>::New();
   cleaner->SetInputData(m_FiberPolyData);
   cleaner->PointMergingOff();
   cleaner->Update();
   m_FiberPolyData = cleaner->GetOutput();
 
   m_FiberLengths.clear();
   m_MeanFiberLength = 0;
   m_MedianFiberLength = 0;
   m_LengthStDev = 0;
   m_NumFibers = static_cast<unsigned int>(m_FiberPolyData->GetNumberOfCells());
 
   if (m_FiberColors==nullptr || m_FiberColors->GetNumberOfTuples()!=m_FiberPolyData->GetNumberOfPoints())
     this->ColorFibersByOrientation();
 
   if (m_FiberWeights->GetNumberOfValues()!=m_NumFibers)
   {
     m_FiberWeights = vtkSmartPointer<vtkFloatArray>::New();
     m_FiberWeights->SetName("FIBER_WEIGHTS");
     m_FiberWeights->SetNumberOfValues(m_NumFibers);
     this->SetFiberWeights(1);
   }
 
   if (m_NumFibers<=0) // no fibers present; apply default geometry
   {
     m_MinFiberLength = 0;
     m_MaxFiberLength = 0;
     mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New();
     geometry->SetImageGeometry(false);
     float b[] = {0, 1, 0, 1, 0, 1};
     geometry->SetFloatBounds(b);
     SetGeometry(geometry);
     return;
   }
   double b[6];
   m_FiberPolyData->GetBounds(b);
 
   // calculate statistics
   for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto p = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
     float length = 0;
     for (int j=0; j<p-1; j++)
     {
       double p1[3];
       points->GetPoint(j, p1);
       double p2[3];
       points->GetPoint(j+1, p2);
 
       double dist = std::sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+(p1[1]-p2[1])*(p1[1]-p2[1])+(p1[2]-p2[2])*(p1[2]-p2[2]));
       length += static_cast<float>(dist);
     }
     m_FiberLengths.push_back(length);
     m_MeanFiberLength += length;
     if (i==0)
     {
       m_MinFiberLength = length;
       m_MaxFiberLength = length;
     }
     else
     {
       if (length<m_MinFiberLength)
         m_MinFiberLength = length;
       if (length>m_MaxFiberLength)
         m_MaxFiberLength = length;
     }
   }
   m_MeanFiberLength /= m_NumFibers;
 
   std::vector< float > sortedLengths = m_FiberLengths;
   std::sort(sortedLengths.begin(), sortedLengths.end());
   for (unsigned int i=0; i<m_NumFibers; i++)
     m_LengthStDev += (m_MeanFiberLength-sortedLengths.at(i))*(m_MeanFiberLength-sortedLengths.at(i));
   if (m_NumFibers>1)
     m_LengthStDev /= (m_NumFibers-1);
   else
     m_LengthStDev = 0;
   m_LengthStDev = std::sqrt(m_LengthStDev);
   m_MedianFiberLength = sortedLengths.at(m_NumFibers/2);
 
   mitk::Geometry3D::Pointer geometry = mitk::Geometry3D::New();
   geometry->SetFloatBounds(b);
   this->SetGeometry(geometry);
 
   GetTrackVisHeader();
 
   m_UpdateTime3D.Modified();
   m_UpdateTime2D.Modified();
 }
 
 float mitk::FiberBundle::GetFiberWeight(unsigned int fiber) const
 {
   return m_FiberWeights->GetValue(fiber);
 }
 
 void mitk::FiberBundle::SetFiberWeights(float newWeight)
 {
   for (int i=0; i<m_FiberWeights->GetNumberOfValues(); i++)
     m_FiberWeights->SetValue(i, newWeight);
 }
 
 void mitk::FiberBundle::SetFiberWeights(vtkSmartPointer<vtkFloatArray> weights)
 {
   if (m_NumFibers!=weights->GetNumberOfValues())
   {
     MITK_INFO << "Weights array not equal to number of fibers! " << weights->GetNumberOfValues() << " vs " << m_NumFibers;
     return;
   }
 
   for (int i=0; i<weights->GetNumberOfValues(); i++)
     m_FiberWeights->SetValue(i, weights->GetValue(i));
 
   m_FiberWeights->SetName("FIBER_WEIGHTS");
 }
 
 void mitk::FiberBundle::SetFiberWeight(unsigned int fiber, float weight)
 {
   m_FiberWeights->SetValue(fiber, weight);
 }
 
 void mitk::FiberBundle::SetFiberColors(vtkSmartPointer<vtkUnsignedCharArray> fiberColors)
 {
   for(long i=0; i<m_FiberPolyData->GetNumberOfPoints(); ++i)
   {
     unsigned char source[4] = {0,0,0,0};
     fiberColors->GetTypedTuple(i, source);
 
     unsigned char target[4] = {0,0,0,0};
     target[0] = source[0];
     target[1] = source[1];
     target[2] = source[2];
     target[3] = source[3];
     m_FiberColors->InsertTypedTuple(i, target);
   }
   m_UpdateTime3D.Modified();
   m_UpdateTime2D.Modified();
 }
 
 itk::Matrix< double, 3, 3 > mitk::FiberBundle::TransformMatrix(itk::Matrix< double, 3, 3 > m, double rx, double ry, double rz)
 {
   rx = rx*itk::Math::pi/180;
   ry = ry*itk::Math::pi/180;
   rz = rz*itk::Math::pi/180;
 
   itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity();
   rotX[1][1] = cos(rx);
   rotX[2][2] = rotX[1][1];
   rotX[1][2] = -sin(rx);
   rotX[2][1] = -rotX[1][2];
 
   itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity();
   rotY[0][0] = cos(ry);
   rotY[2][2] = rotY[0][0];
   rotY[0][2] = sin(ry);
   rotY[2][0] = -rotY[0][2];
 
   itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity();
   rotZ[0][0] = cos(rz);
   rotZ[1][1] = rotZ[0][0];
   rotZ[0][1] = -sin(rz);
   rotZ[1][0] = -rotZ[0][1];
 
   itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX;
 
   m = rot*m;
 
   return m;
 }
 
 void mitk::FiberBundle::TransformFibers(itk::ScalableAffineTransform< mitk::ScalarType >::Pointer transform)
 {
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (int j=0; j<numPoints; j++)
     {
       itk::Point<float, 3> p =mitk::imv::GetItkPoint(points->GetPoint(j));
       p = transform->TransformPoint(p);
       vtkIdType id = vtkNewPoints->InsertNextPoint(p.GetDataPointer());
       container->GetPointIds()->InsertNextId(id);
     }
     vtkNewCells->InsertNextCell(container);
   }
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_FiberPolyData->SetPoints(vtkNewPoints);
   m_FiberPolyData->SetLines(vtkNewCells);
   this->SetFiberPolyData(m_FiberPolyData, true);
 }
 
 void mitk::FiberBundle::TransformFibers(double rx, double ry, double rz, double tx, double ty, double tz)
 {
   vnl_matrix_fixed< double, 3, 3 > rot = mitk::imv::GetRotationMatrixVnl(rx, ry, rz);
 
   mitk::BaseGeometry::Pointer geom = this->GetGeometry();
   mitk::Point3D center = geom->GetCenter();
 
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (int j=0; j<numPoints; j++)
     {
       double* p = points->GetPoint(j);
       vnl_vector_fixed< double, 3 > dir;
       dir[0] = p[0]-center[0];
       dir[1] = p[1]-center[1];
       dir[2] = p[2]-center[2];
       dir = rot*dir;
       dir[0] += center[0]+tx;
       dir[1] += center[1]+ty;
       dir[2] += center[2]+tz;
       vtkIdType id = vtkNewPoints->InsertNextPoint(dir.data_block());
       container->GetPointIds()->InsertNextId(id);
     }
     vtkNewCells->InsertNextCell(container);
   }
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_FiberPolyData->SetPoints(vtkNewPoints);
   m_FiberPolyData->SetLines(vtkNewCells);
   this->SetFiberPolyData(m_FiberPolyData, true);
 }
 
 void mitk::FiberBundle::RotateAroundAxis(double x, double y, double z)
 {
   x = x*itk::Math::pi/180;
   y = y*itk::Math::pi/180;
   z = z*itk::Math::pi/180;
 
   vnl_matrix_fixed< double, 3, 3 > rotX; rotX.set_identity();
   rotX[1][1] = cos(x);
   rotX[2][2] = rotX[1][1];
   rotX[1][2] = -sin(x);
   rotX[2][1] = -rotX[1][2];
 
   vnl_matrix_fixed< double, 3, 3 > rotY; rotY.set_identity();
   rotY[0][0] = cos(y);
   rotY[2][2] = rotY[0][0];
   rotY[0][2] = sin(y);
   rotY[2][0] = -rotY[0][2];
 
   vnl_matrix_fixed< double, 3, 3 > rotZ; rotZ.set_identity();
   rotZ[0][0] = cos(z);
   rotZ[1][1] = rotZ[0][0];
   rotZ[0][1] = -sin(z);
   rotZ[1][0] = -rotZ[0][1];
 
   mitk::BaseGeometry::Pointer geom = this->GetGeometry();
   mitk::Point3D center = geom->GetCenter();
 
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (int j=0; j<numPoints; j++)
     {
       double* p = points->GetPoint(j);
       vnl_vector_fixed< double, 3 > dir;
       dir[0] = p[0]-center[0];
       dir[1] = p[1]-center[1];
       dir[2] = p[2]-center[2];
       dir = rotZ*rotY*rotX*dir;
       dir[0] += center[0];
       dir[1] += center[1];
       dir[2] += center[2];
       vtkIdType id = vtkNewPoints->InsertNextPoint(dir.data_block());
       container->GetPointIds()->InsertNextId(id);
     }
     vtkNewCells->InsertNextCell(container);
   }
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_FiberPolyData->SetPoints(vtkNewPoints);
   m_FiberPolyData->SetLines(vtkNewCells);
   this->SetFiberPolyData(m_FiberPolyData, true);
 }
 
 void mitk::FiberBundle::ScaleFibers(double x, double y, double z, bool subtractCenter)
 {
   MITK_INFO << "Scaling fibers";
   boost::progress_display disp(m_NumFibers);
 
   mitk::BaseGeometry* geom = this->GetGeometry();
   mitk::Point3D c = geom->GetCenter();
 
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     ++disp ;
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (int j=0; j<numPoints; j++)
     {
       double* p = points->GetPoint(j);
       if (subtractCenter)
       {
         p[0] -= c[0]; p[1] -= c[1]; p[2] -= c[2];
       }
       p[0] *= x;
       p[1] *= y;
       p[2] *= z;
       if (subtractCenter)
       {
         p[0] += c[0]; p[1] += c[1]; p[2] += c[2];
       }
       vtkIdType id = vtkNewPoints->InsertNextPoint(p);
       container->GetPointIds()->InsertNextId(id);
     }
     vtkNewCells->InsertNextCell(container);
   }
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_FiberPolyData->SetPoints(vtkNewPoints);
   m_FiberPolyData->SetLines(vtkNewCells);
   this->SetFiberPolyData(m_FiberPolyData, true);
 }
 
 void mitk::FiberBundle::TranslateFibers(double x, double y, double z)
 {
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (int j=0; j<numPoints; j++)
     {
       double* p = points->GetPoint(j);
       p[0] += x;
       p[1] += y;
       p[2] += z;
       vtkIdType id = vtkNewPoints->InsertNextPoint(p);
       container->GetPointIds()->InsertNextId(id);
     }
     vtkNewCells->InsertNextCell(container);
   }
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_FiberPolyData->SetPoints(vtkNewPoints);
   m_FiberPolyData->SetLines(vtkNewCells);
   this->SetFiberPolyData(m_FiberPolyData, true);
 }
 
 void mitk::FiberBundle::MirrorFibers(unsigned int axis)
 {
   if (axis>2)
     return;
 
   MITK_INFO << "Mirroring fibers";
   boost::progress_display disp(m_NumFibers);
 
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     ++disp;
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (int j=0; j<numPoints; j++)
     {
       double* p = points->GetPoint(j);
       p[axis] = -p[axis];
       vtkIdType id = vtkNewPoints->InsertNextPoint(p);
       container->GetPointIds()->InsertNextId(id);
     }
     vtkNewCells->InsertNextCell(container);
   }
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_FiberPolyData->SetPoints(vtkNewPoints);
   m_FiberPolyData->SetLines(vtkNewCells);
   this->SetFiberPolyData(m_FiberPolyData, true);
 }
 
 void mitk::FiberBundle::RemoveDir(vnl_vector_fixed<double,3> dir, double threshold)
 {
   dir.normalize();
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   boost::progress_display disp(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells()));
   for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
   {
     ++disp ;
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     // calculate curvatures
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     bool discard = false;
     for (int j=0; j<numPoints-1; j++)
     {
       double p1[3];
       points->GetPoint(j, p1);
       double p2[3];
       points->GetPoint(j+1, p2);
 
       vnl_vector_fixed< double, 3 > v1;
       v1[0] = p2[0]-p1[0];
       v1[1] = p2[1]-p1[1];
       v1[2] = p2[2]-p1[2];
       if (v1.magnitude()>0.001)
       {
         v1.normalize();
 
         if (fabs(dot_product(v1,dir))>threshold)
         {
           discard = true;
           break;
         }
       }
     }
     if (!discard)
     {
       for (int j=0; j<numPoints; j++)
       {
         double p1[3];
         points->GetPoint(j, p1);
 
         vtkIdType id = vtkNewPoints->InsertNextPoint(p1);
         container->GetPointIds()->InsertNextId(id);
       }
       vtkNewCells->InsertNextCell(container);
     }
   }
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_FiberPolyData->SetPoints(vtkNewPoints);
   m_FiberPolyData->SetLines(vtkNewCells);
 
   this->SetFiberPolyData(m_FiberPolyData, true);
 
   //    UpdateColorCoding();
   //    UpdateFiberGeometry();
 }
 
 bool mitk::FiberBundle::ApplyCurvatureThreshold(float minRadius, bool deleteFibers)
 {
   if (minRadius<0)
     return true;
 
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   MITK_INFO << "Applying curvature threshold";
   boost::progress_display disp(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells()));
   for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
   {
     ++disp ;
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     // calculate curvatures
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     for (int j=0; j<numPoints-2; j++)
     {
       double p1[3];
       points->GetPoint(j, p1);
       double p2[3];
       points->GetPoint(j+1, p2);
       double p3[3];
       points->GetPoint(j+2, p3);
 
       vnl_vector_fixed< float, 3 > v1, v2, v3;
 
       v1[0] = static_cast<float>(p2[0]-p1[0]);
       v1[1] = static_cast<float>(p2[1]-p1[1]);
       v1[2] = static_cast<float>(p2[2]-p1[2]);
 
       v2[0] = static_cast<float>(p3[0]-p2[0]);
       v2[1] = static_cast<float>(p3[1]-p2[1]);
       v2[2] = static_cast<float>(p3[2]-p2[2]);
 
       v3[0] = static_cast<float>(p1[0]-p3[0]);
       v3[1] = static_cast<float>(p1[1]-p3[1]);
       v3[2] = static_cast<float>(p1[2]-p3[2]);
 
       float a = v1.magnitude();
       float b = v2.magnitude();
       float c = v3.magnitude();
       float r = a*b*c/std::sqrt((a+b+c)*(a+b-c)*(b+c-a)*(a-b+c)); // radius of triangle via Heron's formula (area of triangle)
 
       vtkIdType id = vtkNewPoints->InsertNextPoint(p1);
       container->GetPointIds()->InsertNextId(id);
 
       if (deleteFibers && r<minRadius)
         break;
 
       if (r<minRadius)
       {
         j += 2;
         vtkNewCells->InsertNextCell(container);
         container = vtkSmartPointer<vtkPolyLine>::New();
       }
       else if (j==numPoints-3)
       {
         id = vtkNewPoints->InsertNextPoint(p2);
         container->GetPointIds()->InsertNextId(id);
         id = vtkNewPoints->InsertNextPoint(p3);
         container->GetPointIds()->InsertNextId(id);
         vtkNewCells->InsertNextCell(container);
       }
     }
   }
 
   if (vtkNewCells->GetNumberOfCells()<=0)
     return false;
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_FiberPolyData->SetPoints(vtkNewPoints);
   m_FiberPolyData->SetLines(vtkNewCells);
   this->SetFiberPolyData(m_FiberPolyData, true);
   return true;
 }
 
 bool mitk::FiberBundle::RemoveShortFibers(float lengthInMM)
 {
   MITK_INFO << "Removing short fibers";
   if (lengthInMM<=0 || lengthInMM<m_MinFiberLength)
   {
     MITK_INFO << "No fibers shorter than " << lengthInMM << " mm found!";
     return true;
   }
 
   if (lengthInMM>m_MaxFiberLength)    // can't remove all fibers
   {
     MITK_WARN << "Process aborted. No fibers would be left!";
     return false;
   }
 
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
   float min = m_MaxFiberLength;
 
   boost::progress_display disp(m_NumFibers);
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     ++disp;
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     if (m_FiberLengths.at(i)>=lengthInMM)
     {
       vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
       for (int j=0; j<numPoints; j++)
       {
         double* p = points->GetPoint(j);
         vtkIdType id = vtkNewPoints->InsertNextPoint(p);
         container->GetPointIds()->InsertNextId(id);
       }
       vtkNewCells->InsertNextCell(container);
       if (m_FiberLengths.at(i)<min)
         min = m_FiberLengths.at(i);
     }
   }
 
   if (vtkNewCells->GetNumberOfCells()<=0)
     return false;
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_FiberPolyData->SetPoints(vtkNewPoints);
   m_FiberPolyData->SetLines(vtkNewCells);
   this->SetFiberPolyData(m_FiberPolyData, true);
   return true;
 }
 
 bool mitk::FiberBundle::RemoveLongFibers(float lengthInMM)
 {
   if (lengthInMM<=0 || lengthInMM>m_MaxFiberLength)
     return true;
 
   if (lengthInMM<m_MinFiberLength)    // can't remove all fibers
     return false;
 
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   MITK_INFO << "Removing long fibers";
   boost::progress_display disp(m_NumFibers);
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     ++disp;
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     if (m_FiberLengths.at(i)<=lengthInMM)
     {
       vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
       for (int j=0; j<numPoints; j++)
       {
         double* p = points->GetPoint(j);
         vtkIdType id = vtkNewPoints->InsertNextPoint(p);
         container->GetPointIds()->InsertNextId(id);
       }
       vtkNewCells->InsertNextCell(container);
     }
   }
 
   if (vtkNewCells->GetNumberOfCells()<=0)
     return false;
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_FiberPolyData->SetPoints(vtkNewPoints);
   m_FiberPolyData->SetLines(vtkNewCells);
   this->SetFiberPolyData(m_FiberPolyData, true);
   return true;
 }
 
 void mitk::FiberBundle::ResampleSpline(float pointDistance, double tension, double continuity, double bias )
 {
   if (pointDistance<=0)
     return;
 
   vtkSmartPointer<vtkPoints> vtkSmoothPoints = vtkSmartPointer<vtkPoints>::New(); //in smoothpoints the interpolated points representing a fiber are stored.
 
   //in vtkcells all polylines are stored, actually all id's of them are stored
   vtkSmartPointer<vtkCellArray> vtkSmoothCells = vtkSmartPointer<vtkCellArray>::New(); //cellcontainer for smoothed lines
 
   MITK_INFO << "Smoothing fibers";
   vtkSmartPointer<vtkFloatArray> newFiberWeights = vtkSmartPointer<vtkFloatArray>::New();
   newFiberWeights->SetName("FIBER_WEIGHTS");
   newFiberWeights->SetNumberOfValues(m_NumFibers);
 
   std::vector< vtkSmartPointer<vtkPolyLine> > resampled_streamlines;
   resampled_streamlines.resize(m_NumFibers);
 
   boost::progress_display disp(m_NumFibers);
 #pragma omp parallel for
   for (int i=0; i<static_cast<int>(m_NumFibers); i++)
   {
     vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New();
     float length = 0;
 #pragma omp critical
     {
       length = m_FiberLengths.at(static_cast<unsigned int>(i));
       ++disp;
       vtkCell* cell = m_FiberPolyData->GetCell(i);
       auto numPoints = cell->GetNumberOfPoints();
       vtkPoints* points = cell->GetPoints();
       for (int j=0; j<numPoints; j++)
         newPoints->InsertNextPoint(points->GetPoint(j));
     }
 
     int sampling = static_cast<int>(std::ceil(length/pointDistance));
 
     vtkSmartPointer<vtkKochanekSpline> xSpline = vtkSmartPointer<vtkKochanekSpline>::New();
     vtkSmartPointer<vtkKochanekSpline> ySpline = vtkSmartPointer<vtkKochanekSpline>::New();
     vtkSmartPointer<vtkKochanekSpline> zSpline = vtkSmartPointer<vtkKochanekSpline>::New();
     xSpline->SetDefaultBias(bias); xSpline->SetDefaultTension(tension); xSpline->SetDefaultContinuity(continuity);
     ySpline->SetDefaultBias(bias); ySpline->SetDefaultTension(tension); ySpline->SetDefaultContinuity(continuity);
     zSpline->SetDefaultBias(bias); zSpline->SetDefaultTension(tension); zSpline->SetDefaultContinuity(continuity);
 
     vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New();
     spline->SetXSpline(xSpline);
     spline->SetYSpline(ySpline);
     spline->SetZSpline(zSpline);
     spline->SetPoints(newPoints);
 
     vtkSmartPointer<vtkParametricFunctionSource> functionSource = vtkSmartPointer<vtkParametricFunctionSource>::New();
     functionSource->SetParametricFunction(spline);
     functionSource->SetUResolution(sampling);
     functionSource->SetVResolution(sampling);
     functionSource->SetWResolution(sampling);
     functionSource->Update();
 
     vtkPolyData* outputFunction = functionSource->GetOutput();
     vtkPoints* tmpSmoothPnts = outputFunction->GetPoints(); //smoothPoints of current fiber
 
     vtkSmartPointer<vtkPolyLine> smoothLine = vtkSmartPointer<vtkPolyLine>::New();
 
 #pragma omp critical
     {
       for (int j=0; j<tmpSmoothPnts->GetNumberOfPoints(); j++)
       {
         vtkIdType id = vtkSmoothPoints->InsertNextPoint(tmpSmoothPnts->GetPoint(j));
         smoothLine->GetPointIds()->InsertNextId(id);
       }
 
       resampled_streamlines[static_cast<unsigned long>(i)] = smoothLine;
     }
   }
 
   for (auto container : resampled_streamlines)
   {
     vtkSmoothCells->InsertNextCell(container);
   }
 
   m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
   m_FiberPolyData->SetPoints(vtkSmoothPoints);
   m_FiberPolyData->SetLines(vtkSmoothCells);
   this->SetFiberPolyData(m_FiberPolyData, true);
 }
 
 void mitk::FiberBundle::ResampleSpline(float pointDistance)
 {
   ResampleSpline(pointDistance, 0, 0, 0 );
 }
 
 unsigned int mitk::FiberBundle::GetNumberOfPoints() const
 {
   unsigned int points = 0;
   for (int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     points += cell->GetNumberOfPoints();
   }
   return points;
 }
 
 void mitk::FiberBundle::Compress(float error)
 {
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   MITK_INFO << "Compressing fibers with max. error " << error << "mm";
   unsigned int numRemovedPoints = 0;
   boost::progress_display disp(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells()));
   vtkSmartPointer<vtkFloatArray> newFiberWeights = vtkSmartPointer<vtkFloatArray>::New();
   newFiberWeights->SetName("FIBER_WEIGHTS");
   newFiberWeights->SetNumberOfValues(m_NumFibers);
 
 #pragma omp parallel for
   for (int i=0; i<static_cast<int>(m_FiberPolyData->GetNumberOfCells()); i++)
   {
 
     std::vector< vnl_vector_fixed< double, 3 > > vertices;
     float weight = 1;
 
 #pragma omp critical
     {
       ++disp;
       weight = m_FiberWeights->GetValue(i);
       vtkCell* cell = m_FiberPolyData->GetCell(i);
       auto numPoints = cell->GetNumberOfPoints();
       vtkPoints* points = cell->GetPoints();
 
       for (int j=0; j<numPoints; j++)
       {
         double cand[3];
         points->GetPoint(j, cand);
         vnl_vector_fixed< double, 3 > candV;
         candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2];
         vertices.push_back(candV);
       }
     }
 
     // calculate curvatures
     auto numPoints = vertices.size();
     std::vector< int > removedPoints; removedPoints.resize(numPoints, 0);
     removedPoints[0]=-1; removedPoints[numPoints-1]=-1;
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     unsigned int remCounter = 0;
 
     bool pointFound = true;
     while (pointFound)
     {
       pointFound = false;
       double minError = static_cast<double>(error);
       unsigned int removeIndex = 0;
 
       for (unsigned int j=0; j<vertices.size(); j++)
       {
         if (removedPoints[j]==0)
         {
           vnl_vector_fixed< double, 3 > candV = vertices.at(j);
 
           int validP = -1;
           vnl_vector_fixed< double, 3 > pred;
           for (int k=static_cast<int>(j)-1; k>=0; k--)
             if (removedPoints[static_cast<unsigned int>(k)]<=0)
             {
               pred = vertices.at(static_cast<unsigned int>(k));
               validP = k;
               break;
             }
           int validS = -1;
           vnl_vector_fixed< double, 3 > succ;
           for (unsigned int k=j+1; k<numPoints; k++)
             if (removedPoints[k]<=0)
             {
               succ = vertices.at(k);
               validS = static_cast<int>(k);
               break;
             }
 
           if (validP>=0 && validS>=0)
           {
             double a = (candV-pred).magnitude();
             double b = (candV-succ).magnitude();
             double c = (pred-succ).magnitude();
             double s=0.5*(a+b+c);
             double hc=(2.0/c)*sqrt(fabs(s*(s-a)*(s-b)*(s-c)));
 
             if (hc<minError)
             {
               removeIndex = j;
               minError = hc;
               pointFound = true;
             }
           }
         }
       }
 
       if (pointFound)
       {
         removedPoints[removeIndex] = 1;
         remCounter++;
       }
     }
 
     for (unsigned int j=0; j<numPoints; j++)
     {
       if (removedPoints[j]<=0)
       {
 #pragma omp critical
         {
           vtkIdType id = vtkNewPoints->InsertNextPoint(vertices.at(j).data_block());
           container->GetPointIds()->InsertNextId(id);
         }
       }
     }
 
 #pragma omp critical
     {
       newFiberWeights->SetValue(vtkNewCells->GetNumberOfCells(), weight);
       numRemovedPoints += remCounter;
       vtkNewCells->InsertNextCell(container);
     }
   }
 
   if (vtkNewCells->GetNumberOfCells()>0)
   {
     MITK_INFO << "Removed points: " << numRemovedPoints;
     SetFiberWeights(newFiberWeights);
     m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
     m_FiberPolyData->SetPoints(vtkNewPoints);
     m_FiberPolyData->SetLines(vtkNewCells);
     this->SetFiberPolyData(m_FiberPolyData, true);
   }
 }
 
 void mitk::FiberBundle::ResampleToNumPoints(unsigned int targetPoints)
 {
   if (targetPoints<2)
     mitkThrow() << "Minimum two points required for resampling!";
 
   MITK_INFO << "Resampling fibers (number of points " << targetPoints << ")";
 
   bool unequal_fibs = true;
   while (unequal_fibs)
   {
     vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
     vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
     vtkSmartPointer<vtkFloatArray> newFiberWeights = vtkSmartPointer<vtkFloatArray>::New();
     newFiberWeights->SetName("FIBER_WEIGHTS");
     newFiberWeights->SetNumberOfValues(m_NumFibers);
 
     unequal_fibs = false;
     for (unsigned int i=0; i<m_FiberPolyData->GetNumberOfCells(); i++)
     {
 
       std::vector< vnl_vector_fixed< double, 3 > > vertices;
       float weight = 1;
       double seg_len = 0;
 
       {
         weight = m_FiberWeights->GetValue(i);
         vtkCell* cell = m_FiberPolyData->GetCell(i);
         auto numPoints = cell->GetNumberOfPoints();
         if (numPoints!=targetPoints)
           seg_len = static_cast<double>(this->GetFiberLength(i)/(targetPoints-1));
         vtkPoints* points = cell->GetPoints();
 
         for (int j=0; j<numPoints; j++)
         {
           double cand[3];
           points->GetPoint(j, cand);
           vnl_vector_fixed< double, 3 > candV;
           candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2];
           vertices.push_back(candV);
         }
       }
 
       vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
       vnl_vector_fixed< double, 3 > lastV = vertices.at(0);
 
       {
         vtkIdType id = vtkNewPoints->InsertNextPoint(lastV.data_block());
         container->GetPointIds()->InsertNextId(id);
       }
       for (unsigned int j=1; j<vertices.size(); j++)
       {
         vnl_vector_fixed< double, 3 > vec = vertices.at(j) - lastV;
         double new_dist = vec.magnitude();
 
         if (new_dist >= seg_len && seg_len>0)
         {
           vnl_vector_fixed< double, 3 > newV = lastV;
           if ( new_dist-seg_len <= mitk::eps )
           {
             vec.normalize();
             newV += vec * seg_len;
           }
           else
           {
             // intersection between sphere (radius 'pointDistance', center 'lastV') and line (direction 'd' and point 'p')
             vnl_vector_fixed< double, 3 > p = vertices.at(j-1);
             vnl_vector_fixed< double, 3 > d = vertices.at(j) - p;
 
             double a = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
             double b = 2 * (d[0] * (p[0] - lastV[0]) + d[1] * (p[1] - lastV[1]) + d[2] * (p[2] - lastV[2]));
             double c = (p[0] - lastV[0])*(p[0] - lastV[0]) + (p[1] - lastV[1])*(p[1] - lastV[1]) + (p[2] - lastV[2])*(p[2] - lastV[2]) - seg_len*seg_len;
 
             double v1 =(-b + std::sqrt(b*b-4*a*c))/(2*a);
             double v2 =(-b - std::sqrt(b*b-4*a*c))/(2*a);
 
             if (v1>0)
               newV = p + d * v1;
             else if (v2>0)
               newV = p + d * v2;
             else
               MITK_INFO << "ERROR1 - linear resampling";
 
             j--;
           }
 
 //#pragma omp critical
           {
             vtkIdType id = vtkNewPoints->InsertNextPoint(newV.data_block());
             container->GetPointIds()->InsertNextId(id);
           }
           lastV = newV;
         }
         else if ( (j==vertices.size()-1 && new_dist>0.0001) || seg_len<=0.0000001)
         {
 //#pragma omp critical
           {
             vtkIdType id = vtkNewPoints->InsertNextPoint(vertices.at(j).data_block());
             container->GetPointIds()->InsertNextId(id);
           }
         }
       }
 
 //#pragma omp critical
       {
         newFiberWeights->SetValue(vtkNewCells->GetNumberOfCells(), weight);
         vtkNewCells->InsertNextCell(container);
         if (container->GetNumberOfPoints()!=targetPoints)
           unequal_fibs = true;
       }
     }
 
     if (vtkNewCells->GetNumberOfCells()>0)
     {
       SetFiberWeights(newFiberWeights);
       m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
       m_FiberPolyData->SetPoints(vtkNewPoints);
       m_FiberPolyData->SetLines(vtkNewCells);
       this->SetFiberPolyData(m_FiberPolyData, true);
     }
   }
 }
 
 void mitk::FiberBundle::ResampleLinear(double pointDistance)
 {
   vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
   vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
 
   MITK_INFO << "Resampling fibers (linear)";
   boost::progress_display disp(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells()));
   vtkSmartPointer<vtkFloatArray> newFiberWeights = vtkSmartPointer<vtkFloatArray>::New();
   newFiberWeights->SetName("FIBER_WEIGHTS");
   newFiberWeights->SetNumberOfValues(m_NumFibers);
 
   std::vector< vtkSmartPointer<vtkPolyLine> > resampled_streamlines;
   resampled_streamlines.resize(static_cast<unsigned long>(m_FiberPolyData->GetNumberOfCells()));
 
 #pragma omp parallel for
   for (int i=0; i<static_cast<int>(m_FiberPolyData->GetNumberOfCells()); i++)
   {
 
     std::vector< vnl_vector_fixed< double, 3 > > vertices;
 
 #pragma omp critical
     {
       ++disp;
       vtkCell* cell = m_FiberPolyData->GetCell(i);
       auto numPoints = cell->GetNumberOfPoints();
       vtkPoints* points = cell->GetPoints();
 
       for (int j=0; j<numPoints; j++)
       {
         double cand[3];
         points->GetPoint(j, cand);
         vnl_vector_fixed< double, 3 > candV;
         candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2];
         vertices.push_back(candV);
       }
     }
 
     vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
     vnl_vector_fixed< double, 3 > lastV = vertices.at(0);
 
 #pragma omp critical
     {
       vtkIdType id = vtkNewPoints->InsertNextPoint(lastV.data_block());
       container->GetPointIds()->InsertNextId(id);
     }
     for (unsigned int j=1; j<vertices.size(); j++)
     {
       vnl_vector_fixed< double, 3 > vec = vertices.at(j) - lastV;
       double new_dist = vec.magnitude();
 
       if (new_dist >= pointDistance)
       {
         vnl_vector_fixed< double, 3 > newV = lastV;
         if ( new_dist-pointDistance <= mitk::eps )
         {
           vec.normalize();
           newV += vec * pointDistance;
         }
         else
         {
           // intersection between sphere (radius 'pointDistance', center 'lastV') and line (direction 'd' and point 'p')
           vnl_vector_fixed< double, 3 > p = vertices.at(j-1);
           vnl_vector_fixed< double, 3 > d = vertices.at(j) - p;
 
           double a = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
           double b = 2 * (d[0] * (p[0] - lastV[0]) + d[1] * (p[1] - lastV[1]) + d[2] * (p[2] - lastV[2]));
           double c = (p[0] - lastV[0])*(p[0] - lastV[0]) + (p[1] - lastV[1])*(p[1] - lastV[1]) + (p[2] - lastV[2])*(p[2] - lastV[2]) - pointDistance*pointDistance;
 
           double v1 =(-b + std::sqrt(b*b-4*a*c))/(2*a);
           double v2 =(-b - std::sqrt(b*b-4*a*c))/(2*a);
 
           if (v1>0)
             newV = p + d * v1;
           else if (v2>0)
             newV = p + d * v2;
           else
             MITK_INFO << "ERROR1 - linear resampling";
 
           j--;
         }
 
 #pragma omp critical
         {
           vtkIdType id = vtkNewPoints->InsertNextPoint(newV.data_block());
           container->GetPointIds()->InsertNextId(id);
         }
         lastV = newV;
       }
       else if (j==vertices.size()-1 && new_dist>0.0001)
       {
 #pragma omp critical
         {
           vtkIdType id = vtkNewPoints->InsertNextPoint(vertices.at(j).data_block());
           container->GetPointIds()->InsertNextId(id);
         }
       }
     }
 
 #pragma omp critical
     {
       resampled_streamlines[static_cast<unsigned int>(i)] = container;
     }
   }
 
   for (auto container : resampled_streamlines)
   {
     vtkNewCells->InsertNextCell(container);
   }
 
   if (vtkNewCells->GetNumberOfCells()>0)
   {
     m_FiberPolyData = vtkSmartPointer<vtkPolyData>::New();
     m_FiberPolyData->SetPoints(vtkNewPoints);
     m_FiberPolyData->SetLines(vtkNewCells);
     this->SetFiberPolyData(m_FiberPolyData, true);
   }
 }
 
 // reapply selected colorcoding in case PolyData structure has changed
 bool mitk::FiberBundle::Equals(mitk::FiberBundle* fib, double eps)
 {
   if (fib==nullptr)
   {
     MITK_INFO << "Reference bundle is nullptr!";
     return false;
   }
 
   if (m_NumFibers!=fib->GetNumFibers())
   {
     MITK_INFO << "Unequal number of fibers!";
     MITK_INFO << m_NumFibers << " vs. " << fib->GetNumFibers();
     return false;
   }
 
   for (unsigned int i=0; i<m_NumFibers; i++)
   {
     vtkCell* cell = m_FiberPolyData->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vtkCell* cell2 = fib->GetFiberPolyData()->GetCell(i);
     auto numPoints2 = cell2->GetNumberOfPoints();
     vtkPoints* points2 = cell2->GetPoints();
 
     if (numPoints2!=numPoints)
     {
       MITK_INFO << "Unequal number of points in fiber " << i << "!";
       MITK_INFO << numPoints2 << " vs. " << numPoints;
       return false;
     }
 
     for (int j=0; j<numPoints; j++)
     {
       double* p1 = points->GetPoint(j);
       double* p2 = points2->GetPoint(j);
       if (fabs(p1[0]-p2[0])>eps || fabs(p1[1]-p2[1])>eps || fabs(p1[2]-p2[2])>eps)
       {
         MITK_INFO << "Unequal points in fiber " << i << " at position " << j << "!";
         MITK_INFO << "p1: " << p1[0] << ", " << p1[1] << ", " << p1[2];
         MITK_INFO << "p2: " << p2[0] << ", " << p2[1] << ", " << p2[2];
         return false;
       }
     }
   }
 
   return true;
 }
 
 void mitk::FiberBundle::PrintSelf(std::ostream &os, itk::Indent indent) const
 {
   os << indent << "Number of fibers: " << this->GetNumFibers() << std::endl;
   os << indent << "Min. fiber length: " << this->GetMinFiberLength() << std::endl;
   os << indent << "Max. fiber length: " << this->GetMaxFiberLength() << std::endl;
   os << indent << "Mean fiber length: " << this->GetMeanFiberLength() << std::endl;
   os << indent << "Median fiber length: " << this->GetMedianFiberLength() << std::endl;
   os << indent << "STDEV fiber length: " << this->GetLengthStDev() << std::endl;
   os << indent << "Number of points: " << this->GetNumberOfPoints() << std::endl;
 
   os << indent << "Extent x: " << this->GetGeometry()->GetExtentInMM(0) << "mm" << std::endl;
   os << indent << "Extent y: " << this->GetGeometry()->GetExtentInMM(1) << "mm" << std::endl;
   os << indent << "Extent z: " << this->GetGeometry()->GetExtentInMM(2) << "mm" << std::endl;
   os << indent << "Diagonal: " << this->GetGeometry()->GetDiagonalLength()  << "mm" << std::endl;
 
   os << "\nReference geometry:" << std::endl;
   os << indent << "Size: [" << std::defaultfloat << m_TrackVisHeader.dim[0] << " " << m_TrackVisHeader.dim[1] << " " << m_TrackVisHeader.dim[2] << "]" << std::endl;
   os << indent << "Voxel size: [" << m_TrackVisHeader.voxel_size[0] << " " << m_TrackVisHeader.voxel_size[1] << " " << m_TrackVisHeader.voxel_size[2] << "]" << std::endl;
   os << indent << "Origin: [" << m_TrackVisHeader.origin[0] << " " << m_TrackVisHeader.origin[1] << " " << m_TrackVisHeader.origin[2] << "]" << std::endl;
   os << indent << "Matrix: " << std::scientific << std::endl;
   os << indent << "[[" << m_TrackVisHeader.vox_to_ras[0][0] << ", " << m_TrackVisHeader.vox_to_ras[0][1] << ", " << m_TrackVisHeader.vox_to_ras[0][2] << ", " << m_TrackVisHeader.vox_to_ras[0][3] << "]" << std::endl;
   os << indent << " [" << m_TrackVisHeader.vox_to_ras[1][0] << ", " << m_TrackVisHeader.vox_to_ras[1][1] << ", " << m_TrackVisHeader.vox_to_ras[1][2] << ", " << m_TrackVisHeader.vox_to_ras[1][3] << "]" << std::endl;
   os << indent << " [" << m_TrackVisHeader.vox_to_ras[2][0] << ", " << m_TrackVisHeader.vox_to_ras[2][1] << ", " << m_TrackVisHeader.vox_to_ras[2][2] << ", " << m_TrackVisHeader.vox_to_ras[2][3] << "]" << std::endl;
   os << indent << " [" << m_TrackVisHeader.vox_to_ras[3][0] << ", " << m_TrackVisHeader.vox_to_ras[3][1] << ", " << m_TrackVisHeader.vox_to_ras[3][2] << ", " << m_TrackVisHeader.vox_to_ras[3][3] << "]]" << std::defaultfloat << std::endl;
 
   if (m_FiberWeights!=nullptr)
   {
     std::vector< float > weights;
     for (int i=0; i<m_FiberWeights->GetSize(); i++)
       weights.push_back(m_FiberWeights->GetValue(i));
 
     std::sort(weights.begin(), weights.end());
 
     os << "\nFiber weight statistics" << std::endl;
     os << indent << "Min: " << weights.front() << std::endl;
     os << indent << "1% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.01)) << std::endl;
     os << indent << "5% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.05)) << std::endl;
     os << indent << "25% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.25)) << std::endl;
     os << indent << "Median: " << weights.at(static_cast<unsigned long>(weights.size()*0.5)) << std::endl;
     os << indent << "75% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.75)) << std::endl;
     os << indent << "95% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.95)) << std::endl;
     os << indent << "99% quantile: " << weights.at(static_cast<unsigned long>(weights.size()*0.99)) << std::endl;
     os << indent << "Max: " << weights.back() << std::endl;
   }
   else
     os << indent << "\n\nNo fiber weight array found." << std::endl;
 
   Superclass::PrintSelf(os, 0);
 }
 
 mitk::FiberBundle::TrackVis_header mitk::FiberBundle::GetTrackVisHeader()
 {
   if (m_TrackVisHeader.hdr_size==0)
   {
     mitk::Geometry3D::Pointer geom = dynamic_cast<mitk::Geometry3D*>(this->GetGeometry());
     SetTrackVisHeader(geom);
   }
   return m_TrackVisHeader;
 }
 
 void mitk::FiberBundle::SetTrackVisHeader(const mitk::FiberBundle::TrackVis_header &TrackVisHeader)
 {
   m_TrackVisHeader = TrackVisHeader;
 }
 
 void mitk::FiberBundle::SetTrackVisHeader(mitk::BaseGeometry* geometry)
 {
   vtkSmartPointer< vtkMatrix4x4 > matrix = vtkSmartPointer< vtkMatrix4x4 >::New();
   matrix->Identity();
 
   if (geometry==nullptr)
     return;
 
   for(int i=0; i<3 ;i++)
   {
     m_TrackVisHeader.dim[i]            = geometry->GetExtent(i);
     m_TrackVisHeader.voxel_size[i]     = geometry->GetSpacing()[i];
     m_TrackVisHeader.origin[i]         = geometry->GetOrigin()[i];
     matrix = geometry->GetVtkMatrix();
   }
 
   for (int i=0; i<4; ++i)
     for (int j=0; j<4; ++j)
       m_TrackVisHeader.vox_to_ras[i][j] = matrix->GetElement(i, j);
 
   m_TrackVisHeader.n_scalars = 0;
   m_TrackVisHeader.n_properties = 0;
   sprintf(m_TrackVisHeader.voxel_order,"LPS");
   m_TrackVisHeader.image_orientation_patient[0] = 1.0;
   m_TrackVisHeader.image_orientation_patient[1] = 0.0;
   m_TrackVisHeader.image_orientation_patient[2] = 0.0;
   m_TrackVisHeader.image_orientation_patient[3] = 0.0;
   m_TrackVisHeader.image_orientation_patient[4] = 1.0;
   m_TrackVisHeader.image_orientation_patient[5] = 0.0;
   m_TrackVisHeader.pad1[0] = 0;
   m_TrackVisHeader.pad1[1] = 0;
   m_TrackVisHeader.pad2[0] = 0;
   m_TrackVisHeader.pad2[1] = 0;
   m_TrackVisHeader.invert_x = 0;
   m_TrackVisHeader.invert_y = 0;
   m_TrackVisHeader.invert_z = 0;
   m_TrackVisHeader.swap_xy = 0;
   m_TrackVisHeader.swap_yz = 0;
   m_TrackVisHeader.swap_zx = 0;
   m_TrackVisHeader.n_count = 0;
   m_TrackVisHeader.version = 2;
   m_TrackVisHeader.hdr_size = 1000;
   std::string id = "TRACK";
   strcpy(m_TrackVisHeader.id_string, id.c_str());
 }
 
 /* ESSENTIAL IMPLEMENTATION OF SUPERCLASS METHODS */
 void mitk::FiberBundle::UpdateOutputInformation()
 {
 
 }
 void mitk::FiberBundle::SetRequestedRegionToLargestPossibleRegion()
 {
 
 }
 bool mitk::FiberBundle::RequestedRegionIsOutsideOfTheBufferedRegion()
 {
   return false;
 }
 bool mitk::FiberBundle::VerifyRequestedRegion()
 {
   return true;
 }
 void mitk::FiberBundle::SetRequestedRegion(const itk::DataObject* )
 {
 
 }
diff --git a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h
index 542b91d..71e5b29 100644
--- a/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h
+++ b/Modules/DiffusionCore/IODataStructures/mitkFiberBundle.h
@@ -1,245 +1,246 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 
 #ifndef _MITK_FiberBundle_H
 #define _MITK_FiberBundle_H
 
 //includes for MITK datastructure
 #include <mitkBaseData.h>
 #include <MitkDiffusionCoreExports.h>
 #include <mitkImage.h>
 #include <mitkDataStorage.h>
 #include <mitkPlanarFigure.h>
 #include <mitkPixelTypeTraits.h>
 #include <mitkPlanarFigureComposite.h>
 #include <mitkPeakImage.h>
 
 //includes storing fiberdata
 #include <vtkSmartPointer.h>
 #include <vtkPolyData.h>
 #include <vtkPoints.h>
 #include <vtkDataSet.h>
 #include <vtkTransform.h>
 #include <vtkFloatArray.h>
 #include <itkScalableAffineTransform.h>
 #include <mitkDiffusionFunctionCollection.h>
 
 namespace mitk {
 
 /**
    * \brief Base Class for Fiber Bundles;   */
 class MITKDIFFUSIONCORE_EXPORT FiberBundle : public BaseData
 {
 public:
 
     typedef itk::Image<unsigned char, 3> ItkUcharImgType;
 
     // fiber colorcodings
     static const char* FIBER_ID_ARRAY;
 
     void UpdateOutputInformation() override;
     void SetRequestedRegionToLargestPossibleRegion() override;
     bool RequestedRegionIsOutsideOfTheBufferedRegion() override;
     bool VerifyRequestedRegion() override;
     void SetRequestedRegion(const itk::DataObject*) override;
 
     mitkClassMacro( FiberBundle, BaseData )
     itkFactorylessNewMacro(Self)
     itkCloneMacro(Self)
     mitkNewMacro1Param(Self, vtkSmartPointer<vtkPolyData>) // custom constructor
 
     // colorcoding related methods
+    void ColorSinglePoint(int f_idx, int p_idx, double rgb[3]);
     void ColorFibersByFiberWeights(bool opacity, bool normalize);
     void ColorFibersByCurvature(bool opacity, bool normalize, bool weight_fibers);
     void ColorFibersByLength(bool opacity, bool normalize, bool weight_fibers);
     void ColorFibersByScalarMap(mitk::Image::Pointer, bool opacity, bool normalize, bool weight_fibers);
     template <typename TPixel>
     void ColorFibersByScalarMap(const mitk::PixelType pixelType, mitk::Image::Pointer, bool opacity, bool normalize, bool weight_fibers);
     void ColorFibersByOrientation();
     void SetFiberOpacity(vtkDoubleArray *FAValArray);
     void ResetFiberOpacity();
     void SetFiberColors(vtkSmartPointer<vtkUnsignedCharArray> fiberColors);
     void SetFiberColors(float r, float g, float b, float alpha=255);
     vtkSmartPointer<vtkUnsignedCharArray> GetFiberColors() const { return m_FiberColors; }
 
     // fiber compression
     void Compress(float error = 0.0);
 
     // fiber resampling
     void ResampleSpline(float pointDistance=1);
     void ResampleSpline(float pointDistance, double tension, double continuity, double bias );
     void ResampleLinear(double pointDistance=1);
     void ResampleToNumPoints(unsigned int targetPoints);
 
     mitk::FiberBundle::Pointer FilterByWeights(float weight_thr, bool invert=false);
     bool RemoveShortFibers(float lengthInMM);
     bool RemoveLongFibers(float lengthInMM);
     bool ApplyCurvatureThreshold(float minRadius, bool deleteFibers);
     void MirrorFibers(unsigned int axis);
     void RotateAroundAxis(double x, double y, double z);
     void TranslateFibers(double x, double y, double z);
     void ScaleFibers(double x, double y, double z, bool subtractCenter=true);
     void TransformFibers(double rx, double ry, double rz, double tx, double ty, double tz);
     void TransformFibers(itk::ScalableAffineTransform< mitk::ScalarType >::Pointer transform);
     void RemoveDir(vnl_vector_fixed<double,3> dir, double threshold);
 
     template< class TType=float >
     void TransformPoint(itk::Point<TType, 3>& point, itk::Matrix< TType, 3, 3>& rot, TType& tx, TType& ty, TType& tz)
     {
       mitk::Point3D center = this->GetGeometry()->GetCenter();
 
       point[0] -= center[0];
       point[1] -= center[1];
       point[2] -= center[2];
       point = rot*point;
       point[0] += center[0]+tx;
       point[1] += center[1]+ty;
       point[2] += center[2]+tz;
     }
 
     template< class TType=float >
     void TransformPoint(itk::Point<TType, 3>& point, TType rx, TType ry, TType rz, TType tx, TType ty, TType tz)
     {
       auto rot = mitk::imv::GetRotationMatrixItk<TType>(rx, ry, rz);
       mitk::Point3D center = this->GetGeometry()->GetCenter();
 
       point[0] -= center[0];
       point[1] -= center[1];
       point[2] -= center[2];
       point = rot*point;
       point[0] += center[0]+tx;
       point[1] += center[1]+ty;
       point[2] += center[2]+tz;
     }
 
     itk::Matrix< double, 3, 3 > TransformMatrix(itk::Matrix< double, 3, 3 > m, double rx, double ry, double rz);
 
     // add/subtract fibers
     FiberBundle::Pointer AddBundle(FiberBundle* fib);
     mitk::FiberBundle::Pointer AddBundles(std::vector< mitk::FiberBundle::Pointer > fibs);
     FiberBundle::Pointer SubtractBundle(FiberBundle* fib);
 
     // fiber subset extraction
     FiberBundle::Pointer           ExtractFiberSubset(DataNode *roi, DataStorage* storage);
     std::vector<unsigned int>      ExtractFiberIdSubset(DataNode* roi, DataStorage* storage);
     FiberBundle::Pointer           RemoveFibersOutside(ItkUcharImgType* mask, bool invert=false);
     float                          GetOverlap(ItkUcharImgType* mask);
     std::tuple<float, float>       GetDirectionalOverlap(ItkUcharImgType* mask, mitk::PeakImage::ItkPeakImageType* peak_image);
     float                          GetNumEpFractionInMask(ItkUcharImgType* mask, bool different_label);
     mitk::FiberBundle::Pointer     SubsampleFibers(float factor, bool random_seed);
 
     // get/set data
     float GetFiberLength(unsigned int index) const { return m_FiberLengths.at(index); }
     vtkSmartPointer<vtkFloatArray> GetFiberWeights() const { return m_FiberWeights; }
     float GetFiberWeight(unsigned int fiber) const;
     void SetFiberWeights(float newWeight);
     void SetFiberWeight(unsigned int fiber, float weight);
     void SetFiberWeights(vtkSmartPointer<vtkFloatArray> weights);
     void SetFiberPolyData(vtkSmartPointer<vtkPolyData>, bool updateGeometry = true);
     vtkSmartPointer<vtkPolyData> GetFiberPolyData() const;
     itkGetConstMacro( NumFibers, unsigned int)
     //itkGetMacro( FiberSampling, int)
     itkGetConstMacro( MinFiberLength, float )
     itkGetConstMacro( MaxFiberLength, float )
     itkGetConstMacro( MeanFiberLength, float )
     itkGetConstMacro( MedianFiberLength, float )
     itkGetConstMacro( LengthStDev, float )
     itkGetConstMacro( UpdateTime2D, itk::TimeStamp )
     itkGetConstMacro( UpdateTime3D, itk::TimeStamp )
     void RequestUpdate2D(){ m_UpdateTime2D.Modified(); }
     void RequestUpdate3D(){ m_UpdateTime3D.Modified(); }
     void RequestUpdate(){ m_UpdateTime2D.Modified(); m_UpdateTime3D.Modified(); }
 
     unsigned int GetNumberOfPoints() const;
 
     // copy fiber bundle
     mitk::FiberBundle::Pointer GetDeepCopy();
 
     // compare fiber bundles
     bool Equals(FiberBundle* fib, double eps=0.01);
 
     vtkSmartPointer<vtkPolyData>    GeneratePolyDataByIds(std::vector<unsigned int> fiberIds, vtkSmartPointer<vtkFloatArray> weights);
 
     // Structure to hold metadata of a TrackVis file
     struct TrackVis_header
     {
         char                id_string[6];
         short int           dim[3];
         float               voxel_size[3];
         float               origin[3];
         short int           n_scalars;
         char                scalar_name[10][20];
         short int           n_properties;
         char                property_name[10][20];
         float               vox_to_ras[4][4];
         char                reserved[444];
         char                voxel_order[4];
         char                pad2[4];
         float               image_orientation_patient[6];
         char                pad1[2];
         unsigned char       invert_x;
         unsigned char       invert_y;
         unsigned char       invert_z;
         unsigned char       swap_xy;
         unsigned char       swap_yz;
         unsigned char       swap_zx;
         int                 n_count;
         int                 version;
         int                 hdr_size;
     };
 
     TrackVis_header GetTrackVisHeader();
     void SetTrackVisHeader(const TrackVis_header &TrackVisHeader);
     void SetTrackVisHeader(BaseGeometry *geometry);
 
     void PrintSelf(std::ostream &os, itk::Indent indent) const override;
 
 protected:
 
     FiberBundle( vtkPolyData* fiberPolyData = nullptr );
     ~FiberBundle() override;
 
     void                            GenerateFiberIds();
     void                            UpdateFiberGeometry();
 
 private:
 
     // actual fiber container
     vtkSmartPointer<vtkPolyData>  m_FiberPolyData;
 
     // contains fiber ids
     vtkSmartPointer<vtkDataSet>   m_FiberIdDataSet;
 
     unsigned int m_NumFibers;
 
     vtkSmartPointer<vtkUnsignedCharArray> m_FiberColors;
     vtkSmartPointer<vtkFloatArray> m_FiberWeights;
     std::vector< float > m_FiberLengths;
     float   m_MinFiberLength;
     float   m_MaxFiberLength;
     float   m_MeanFiberLength;
     float   m_MedianFiberLength;
     float   m_LengthStDev;
     itk::TimeStamp m_UpdateTime2D;
     itk::TimeStamp m_UpdateTime3D;
 
     TrackVis_header     m_TrackVisHeader;
 };
 
 } // namespace mitk
 
 #endif /*  _MITK_FiberBundle_H */
diff --git a/Modules/FiberTracking/Algorithms/ClusteringMetrics/mitkClusteringMetric.h b/Modules/FiberTracking/Algorithms/ClusteringMetrics/mitkClusteringMetric.h
index 5fd32ab..7f6f124 100644
--- a/Modules/FiberTracking/Algorithms/ClusteringMetrics/mitkClusteringMetric.h
+++ b/Modules/FiberTracking/Algorithms/ClusteringMetrics/mitkClusteringMetric.h
@@ -1,61 +1,57 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #ifndef _ClusteringMetric
 #define _ClusteringMetric
 
 #include <mitkDiffusionFunctionCollection.h>
 
 namespace mitk
 {
 
 /**
 * \brief Base class for fiber clustering metrics  */
 
 class ClusteringMetric
 {
 
 public:
 
   ClusteringMetric()
     : m_Scale(1.0)
   {}
   virtual ~ClusteringMetric(){}
 
   virtual float CalculateDistance(vnl_matrix<float>& s, vnl_matrix<float>& t, bool &flipped) = 0;
 
-  float GetScale() const;
-  void SetScale(float Scale);
+  float GetScale() const
+  {
+    return m_Scale;
+  }
+  void SetScale(float Scale)
+  {
+    m_Scale = Scale;
+  }
 
 protected:
 
   float m_Scale;
 
 };
 
-float ClusteringMetric::GetScale() const
-{
-  return m_Scale;
-}
-
-void ClusteringMetric::SetScale(float Scale)
-{
-  m_Scale = Scale;
-}
-
 }
 
 #endif
diff --git a/Modules/FiberTracking/Algorithms/itkTractClusteringFilter.cpp b/Modules/FiberTracking/Algorithms/mitkTractClusteringFilter.cpp
similarity index 91%
rename from Modules/FiberTracking/Algorithms/itkTractClusteringFilter.cpp
rename to Modules/FiberTracking/Algorithms/mitkTractClusteringFilter.cpp
index 38318b1..cb1b076 100644
--- a/Modules/FiberTracking/Algorithms/itkTractClusteringFilter.cpp
+++ b/Modules/FiberTracking/Algorithms/mitkTractClusteringFilter.cpp
@@ -1,558 +1,608 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
-#include "itkTractClusteringFilter.h"
+#include "mitkTractClusteringFilter.h"
 
 #define _USE_MATH_DEFINES
 #include <math.h>
 #include <boost/progress.hpp>
 #include <vnl/vnl_sparse_matrix.h>
 
-namespace itk{
+namespace mitk{
 
 TractClusteringFilter::TractClusteringFilter()
   : m_NumPoints(12)
   , m_InCentroids(nullptr)
   , m_MinClusterSize(1)
   , m_MaxClusters(0)
   , m_MergeDuplicateThreshold(-1)
   , m_DoResampling(true)
   , m_FilterMask(nullptr)
   , m_OverlapThreshold(0.0)
 {
 
 }
 
 TractClusteringFilter::~TractClusteringFilter()
 {
   for (auto m : m_Metrics)
     delete m;
 }
 
 std::vector<std::vector<unsigned int> > TractClusteringFilter::GetOutFiberIndices() const
 {
   return m_OutFiberIndices;
 }
 
 void TractClusteringFilter::SetMetrics(const std::vector<mitk::ClusteringMetric *> &Metrics)
 {
   m_Metrics = Metrics;
 }
 
 std::vector<TractClusteringFilter::Cluster> TractClusteringFilter::GetOutClusters() const
 {
   return m_OutClusters;
 }
 
 std::vector<mitk::FiberBundle::Pointer> TractClusteringFilter::GetOutCentroids() const
 {
   return m_OutCentroids;
 }
 
 std::vector<mitk::FiberBundle::Pointer> TractClusteringFilter::GetOutTractograms() const
 {
   return m_OutTractograms;
 }
 
 void TractClusteringFilter::SetDistances(const std::vector<float> &Distances)
 {
   m_Distances = Distances;
 }
 
 float TractClusteringFilter::CalcOverlap(vnl_matrix<float>& t)
 {
   float overlap = 0;
   if (m_FilterMask.IsNotNull())
   {
 
     for (unsigned int i=0; i<m_NumPoints; ++i)
     {
       vnl_vector<float> p = t.get_column(i);
       itk::Point<float,3> point;
       point[0] = p[0];
       point[1] = p[1];
       point[2] = p[2];
       itk::Index<3> idx;
       m_FilterMask->TransformPhysicalPointToIndex(point, idx);
       if (m_FilterMask->GetLargestPossibleRegion().IsInside(idx) && m_FilterMask->GetPixel(idx)>0)
         overlap += 1;
     }
     overlap /= m_NumPoints;
   }
   else
     return 1.0;
 
   return overlap;
 }
 
 std::vector<vnl_matrix<float> > TractClusteringFilter::ResampleFibers(mitk::FiberBundle::Pointer tractogram)
 {
   mitk::FiberBundle::Pointer temp_fib = tractogram->GetDeepCopy();
   if (m_DoResampling)
     temp_fib->ResampleToNumPoints(m_NumPoints);
 
   std::vector< vnl_matrix<float> > out_fib;
 
   for (int i=0; i<temp_fib->GetFiberPolyData()->GetNumberOfCells(); i++)
   {
     vtkCell* cell = temp_fib->GetFiberPolyData()->GetCell(i);
     int numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     vnl_matrix<float> streamline;
     streamline.set_size(3, m_NumPoints);
     streamline.fill(0.0);
 
     for (int j=0; j<numPoints; j++)
     {
       double cand[3];
       points->GetPoint(j, cand);
 
       vnl_vector_fixed< float, 3 > candV;
       candV[0]=cand[0]; candV[1]=cand[1]; candV[2]=cand[2];
       streamline.set_column(j, candV);
     }
 
     out_fib.push_back(streamline);
   }
 
   return out_fib;
 }
 
 std::vector< TractClusteringFilter::Cluster > TractClusteringFilter::ClusterStep(std::vector< unsigned int > f_indices, std::vector<float> distances)
 {
   float dist_thres = distances.back();
   distances.pop_back();
   std::vector< Cluster > C;
 
   int N = f_indices.size();
 
   Cluster c1;
   c1.I.push_back(f_indices.at(0));
   c1.h = T[f_indices.at(0)];
   c1.n = 1;
   C.push_back(c1);
   if (f_indices.size()==1)
     return C;
 
   for (int i=1; i<N; ++i)
   {
     vnl_matrix<float> t = T.at(f_indices.at(i));
 
     int min_cluster_index = -1;
     float min_cluster_distance = 99999;
     bool flip = false;
 
     for (unsigned int k=0; k<C.size(); ++k)
     {
       vnl_matrix<float> v = C.at(k).h / C.at(k).n;
       bool f = false;
       float d = 0;
       for (auto m : m_Metrics)
         d += m->CalculateDistance(t, v, f);
       d /= m_Metrics.size();
 
       if (d<min_cluster_distance)
       {
         min_cluster_distance = d;
         min_cluster_index = k;
         flip = f;
       }
     }
 
     if (min_cluster_index>=0 && min_cluster_distance<dist_thres)
     {
       C[min_cluster_index].I.push_back(f_indices.at(i));
       if (!flip)
         C[min_cluster_index].h += t;
       else
         C[min_cluster_index].h += t.fliplr();
       C[min_cluster_index].n += 1;
     }
     else
     {
       Cluster c;
       c.I.push_back(f_indices.at(i));
       c.h = t;
       c.n = 1;
       C.push_back(c);
     }
   }
 
   if (!distances.empty())
   {
     std::vector< Cluster > outC;
 #pragma omp parallel for
     for (int c=0; c<(int)C.size(); c++)
     {
 
       std::vector< Cluster > tempC = ClusterStep(C.at(c).I, distances);
 #pragma omp critical
       AppendCluster(outC, tempC);
     }
     return outC;
   }
   else
     return C;
 }
 
 void TractClusteringFilter::AppendCluster(std::vector< Cluster >& a, std::vector< Cluster >&b)
 {
   for (auto c : b)
     a.push_back(c);
 }
 
+unsigned int TractClusteringFilter::GetDiscardedClusters() const
+{
+  return m_DiscardedClusters;
+}
+
+void TractClusteringFilter::SetDoResampling(bool DoResampling)
+{
+  m_DoResampling = DoResampling;
+}
+
+void TractClusteringFilter::SetOverlapThreshold(float OverlapThreshold)
+{
+  m_OverlapThreshold = OverlapThreshold;
+}
+
+void TractClusteringFilter::SetFilterMask(const UcharImageType::Pointer &FilterMask)
+{
+  m_FilterMask = FilterMask;
+}
+
+void TractClusteringFilter::SetMinClusterSize(unsigned int MinClusterSize)
+{
+  m_MinClusterSize = MinClusterSize;
+}
+
+void TractClusteringFilter::SetMaxClusters(unsigned int MaxClusters)
+{
+  m_MaxClusters = MaxClusters;
+}
+
+void TractClusteringFilter::SetNumPoints(unsigned int NumPoints)
+{
+  m_NumPoints = NumPoints;
+}
+
+void TractClusteringFilter::SetMergeDuplicateThreshold(float MergeDuplicateThreshold)
+{
+  m_MergeDuplicateThreshold = MergeDuplicateThreshold;
+}
+
+void TractClusteringFilter::SetInCentroids(const mitk::FiberBundle::Pointer &InCentroids)
+{
+  m_InCentroids = InCentroids;
+}
+
+void TractClusteringFilter::SetTractogram(const mitk::FiberBundle::Pointer &Tractogram)
+{
+  m_Tractogram = Tractogram;
+}
+
 std::vector< TractClusteringFilter::Cluster > TractClusteringFilter::MergeDuplicateClusters2(std::vector< TractClusteringFilter::Cluster >& clusters)
 {
   if (m_MergeDuplicateThreshold<0)
     m_MergeDuplicateThreshold = m_Distances.at(0)/2;
   else if (m_MergeDuplicateThreshold==0)
     return clusters;
 
   MITK_INFO << "Merging duplicate clusters with distance threshold " << m_MergeDuplicateThreshold;
 
   std::vector< TractClusteringFilter::Cluster > new_clusters;
   for (Cluster c1 : clusters)
   {
     vnl_matrix<float> t = c1.h / c1.n;
 
     int min_idx = -1;
     float min_d = 99999;
     bool flip = false;
 
 #pragma omp parallel for
     for (int k2=0; k2<(int)new_clusters.size(); ++k2)
     {
       Cluster c2 = new_clusters.at(k2);
       vnl_matrix<float> v = c2.h / c2.n;
 
       bool f = false;
       float d = 0;
       for (auto m : m_Metrics)
         d += m->CalculateDistance(t, v, f);
       d /= m_Metrics.size();
 
 #pragma omp critical
       if (d<min_d && d<m_MergeDuplicateThreshold)
       {
         min_d = d;
         min_idx = k2;
         flip = f;
       }
     }
 
     if (min_idx<0)
       new_clusters.push_back(c1);
     else
     {
       for (int i=0; i<c1.n; ++i)
       {
         new_clusters[min_idx].I.push_back(c1.I.at(i));
         new_clusters[min_idx].n += 1;
       }
       if (!flip)
         new_clusters[min_idx].h += c1.h;
       else
         new_clusters[min_idx].h += c1.h.fliplr();
     }
   }
 
   MITK_INFO << "\nNumber of clusters after merging duplicates: " << new_clusters.size();
   return new_clusters;
 }
 
 void TractClusteringFilter::MergeDuplicateClusters(std::vector< TractClusteringFilter::Cluster >& clusters)
 {
   if (m_MergeDuplicateThreshold<0)
     m_MergeDuplicateThreshold = m_Distances.at(0)/2;
   bool found = true;
 
 
   MITK_INFO << "Merging duplicate clusters with distance threshold " << m_MergeDuplicateThreshold;
   int start = 0;
   while (found && m_MergeDuplicateThreshold>mitk::eps)
   {
     std::cout << "                                                                                                     \r";
     std::cout << "Number of clusters: " << clusters.size() << '\r';
     cout.flush();
 
     found = false;
     for (int k1=start; k1<(int)clusters.size(); ++k1)
     {
       Cluster c1 = clusters.at(k1);
       vnl_matrix<float> t = c1.h / c1.n;
 
       std::vector< int > merge_indices;
       std::vector< bool > flip_indices;
 
 #pragma omp parallel for
       for (int k2=start+1; k2<(int)clusters.size(); ++k2)
       {
         if (k1!=k2)
         {
           Cluster c2 = clusters.at(k2);
           vnl_matrix<float> v = c2.h / c2.n;
           bool f = false;
 
           float d = 0;
           for (auto m : m_Metrics)
             d += m->CalculateDistance(t, v, f);
           d /= m_Metrics.size();
 
 #pragma omp critical
           if (d<m_MergeDuplicateThreshold)
           {
             merge_indices.push_back(k2);
             flip_indices.push_back(f);
           }
         }
       }
 
       for (unsigned int i=0; i<merge_indices.size(); ++i)
       {
         Cluster c2 = clusters.at(merge_indices.at(i));
         for (int i=0; i<c2.n; ++i)
         {
           clusters[k1].I.push_back(c2.I.at(i));
           clusters[k1].n += 1;
         }
         if (!flip_indices.at(i))
           clusters[k1].h += c2.h;
         else
           clusters[k1].h += c2.h.fliplr();
       }
 
       std::sort(merge_indices.begin(), merge_indices.end());
       for (unsigned int i=0; i<merge_indices.size(); ++i)
       {
         clusters.erase (clusters.begin()+merge_indices.at(i)-i);
         found = true;
       }
       if (found)
         break;
     }
     ++start;
   }
   MITK_INFO << "\nNumber of clusters after merging duplicates: " << clusters.size();
 }
 
 std::vector<TractClusteringFilter::Cluster> TractClusteringFilter::AddToKnownClusters(std::vector< unsigned int > f_indices, std::vector<vnl_matrix<float> >& centroids)
 {
   float dist_thres = m_Distances.at(0);
   int N = f_indices.size();
 
   std::vector< Cluster > C;
   vnl_matrix<float> zero_h; zero_h.set_size(T.at(0).rows(), T.at(0).cols()); zero_h.fill(0.0);
   Cluster no_fit;
   no_fit.h = zero_h;
 
   for (unsigned int i=0; i<centroids.size(); ++i)
   {
     Cluster c;
     c.h.set_size(T.at(0).rows(), T.at(0).cols()); c.h.fill(0.0);
     c.f_id = i;
     C.push_back(c);
   }
 
 #pragma omp parallel for
   for (int i=0; i<N; ++i)
   {
     vnl_matrix<float> t = T.at(f_indices.at(i));
 
     int min_cluster_index = -1;
     float min_cluster_distance = 99999;
     bool flip = false;
 
     if (CalcOverlap(t)>=m_OverlapThreshold)
     {
       int c_idx = 0;
       for (vnl_matrix<float> centroid : centroids)
       {
         bool f = false;
         float d = 0;
         for (auto m : m_Metrics)
           d += m->CalculateDistance(t, centroid, f);
         d /= m_Metrics.size();
 
         if (d<min_cluster_distance)
         {
           min_cluster_distance = d;
           min_cluster_index = c_idx;
           flip = f;
         }
         ++c_idx;
       }
     }
 
     if (min_cluster_index>=0 && min_cluster_distance<dist_thres)
     {
 #pragma omp critical
       {
         C[min_cluster_index].I.push_back(f_indices.at(i));
         if (!flip)
           C[min_cluster_index].h += t;
         else
           C[min_cluster_index].h += t.fliplr();
         C[min_cluster_index].n += 1;
       }
     }
     else
     {
 #pragma omp critical
       {
         no_fit.I.push_back(f_indices.at(i));
         no_fit.n++;
       }
     }
   }
   C.push_back(no_fit);
   return C;
 }
 
 
 
 void TractClusteringFilter::GenerateData()
 {
   m_OutTractograms.clear();
   m_OutCentroids.clear();
   m_OutClusters.clear();
 
   if (m_Metrics.empty())
   {
     mitkThrow() << "No metric selected!";
     return;
   }
 
   T = ResampleFibers(m_Tractogram);
   if (T.empty())
   {
     MITK_INFO << "No fibers in tractogram!";
     return;
   }
 
   std::vector< unsigned int > f_indices;
   for (unsigned int i=0; i<T.size(); ++i)
     f_indices.push_back(i);
   //  std::random_shuffle(f_indices.begin(), f_indices.end());
 
   Cluster no_match;
   std::vector< Cluster > clusters;
   if (m_InCentroids.IsNull())
   {
     MITK_INFO << "Clustering fibers";
     clusters = ClusterStep(f_indices, m_Distances);
     MITK_INFO << "Number of clusters: " << clusters.size();
     clusters = MergeDuplicateClusters2(clusters);
     std::sort(clusters.begin(),clusters.end());
   }
   else
   {
     std::vector<vnl_matrix<float> > centroids = ResampleFibers(m_InCentroids);
     if (centroids.empty())
     {
       MITK_INFO << "No fibers in centroid tractogram!";
       return;
     }
     MITK_INFO << "Clustering with input centroids";
     clusters = AddToKnownClusters(f_indices, centroids);
     no_match = clusters.back();
     clusters.pop_back();
     MITK_INFO << "Number of clusters: " << clusters.size();
     clusters = MergeDuplicateClusters2(clusters);
   }
 
   MITK_INFO << "Clustering finished";
   int max = clusters.size()-1;
   if (m_MaxClusters>0 && clusters.size()-1>m_MaxClusters)
     max = m_MaxClusters;
-  int skipped = 0;
+  m_DiscardedClusters = 0;
   for (int i=clusters.size()-1; i>=0; --i)
   {
     Cluster c = clusters.at(i);
     if ( c.n>=(int)m_MinClusterSize && !(m_MaxClusters>0 && clusters.size()-i>m_MaxClusters) )
     {
       m_OutClusters.push_back(c);
 
       vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New();
       vtkSmartPointer<vtkPolyData> pTmp = m_Tractogram->GeneratePolyDataByIds(c.I, weights);
       mitk::FiberBundle::Pointer fib = mitk::FiberBundle::New(pTmp);
       if (max>0)
         fib->SetFiberWeights((float)i/max);
       m_OutTractograms.push_back(fib);
       m_OutFiberIndices.push_back(c.I);
 
       // create centroid
       vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();
       vtkSmartPointer<vtkCellArray> vtkNewCells = vtkSmartPointer<vtkCellArray>::New();
       vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
       vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
       vnl_matrix<float> centroid_points = c.h / c.n;
       for (unsigned int j=0; j<centroid_points.cols(); j++)
       {
         double p[3];
         p[0] = centroid_points.get(0,j);
         p[1] = centroid_points.get(1,j);
         p[2] = centroid_points.get(2,j);
 
         vtkIdType id = vtkNewPoints->InsertNextPoint(p);
         container->GetPointIds()->InsertNextId(id);
       }
       vtkNewCells->InsertNextCell(container);
       polyData->SetPoints(vtkNewPoints);
       polyData->SetLines(vtkNewCells);
       mitk::FiberBundle::Pointer centroid = mitk::FiberBundle::New(polyData);
       centroid->SetFiberColors(255, 255, 255);
       m_OutCentroids.push_back(centroid);
     }
     else
     {
-      skipped++;
+      m_DiscardedClusters++;
     }
   }
-  MITK_INFO << "Final number of clusters: " << m_OutTractograms.size() << " (discarded " << skipped << " clusters)";
+  MITK_INFO << "Final number of clusters: " << m_OutTractograms.size() << " (discarded " << m_DiscardedClusters << " clusters)";
 
   int w = 0;
   for (auto fib : m_OutTractograms)
   {
     if (m_OutTractograms.size()>1)
     {
       fib->SetFiberWeights((float)w/(m_OutTractograms.size()-1));
       m_OutCentroids.at(w)->SetFiberWeights((float)w/(m_OutTractograms.size()-1));
     }
     else
     {
       fib->SetFiberWeights(1);
       m_OutCentroids.at(w)->SetFiberWeights(1);
     }
     fib->ColorFibersByFiberWeights(false, false);
     ++w;
   }
 
   if (no_match.n>0)
   {
     vtkSmartPointer<vtkFloatArray> weights = vtkSmartPointer<vtkFloatArray>::New();
     vtkSmartPointer<vtkPolyData> pTmp = m_Tractogram->GeneratePolyDataByIds(no_match.I, weights);
     mitk::FiberBundle::Pointer fib = mitk::FiberBundle::New(pTmp);
     fib->SetFiberColors(0, 0, 0);
     m_OutFiberIndices.push_back(no_match.I);
     m_OutTractograms.push_back(fib);
   }
 }
 
 }
 
 
 
 
diff --git a/Modules/FiberTracking/Algorithms/itkTractClusteringFilter.h b/Modules/FiberTracking/Algorithms/mitkTractClusteringFilter.h
similarity index 53%
rename from Modules/FiberTracking/Algorithms/itkTractClusteringFilter.h
rename to Modules/FiberTracking/Algorithms/mitkTractClusteringFilter.h
index b18e2bb..75b574a 100644
--- a/Modules/FiberTracking/Algorithms/itkTractClusteringFilter.h
+++ b/Modules/FiberTracking/Algorithms/mitkTractClusteringFilter.h
@@ -1,140 +1,131 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
-#ifndef itkTractClusteringFilter_h
-#define itkTractClusteringFilter_h
+#ifndef TractClusteringFilter_h
+#define TractClusteringFilter_h
 
 // MITK
+#include <MitkFiberTrackingExports.h>
 #include <mitkPlanarEllipse.h>
 #include <mitkFiberBundle.h>
-#include <mitkFiberfoxParameters.h>
 #include <mitkClusteringMetric.h>
 
 // ITK
 #include <itkProcessObject.h>
 
 // VTK
 #include <vtkSmartPointer.h>
 #include <vtkPolyData.h>
 #include <vtkCellArray.h>
 #include <vtkPoints.h>
 #include <vtkPolyLine.h>
 
-namespace itk{
+namespace mitk{
 
 /**
 * \brief    */
 
-class TractClusteringFilter : public ProcessObject
+class MITKFIBERTRACKING_EXPORT TractClusteringFilter
 {
 public:
 
   struct Cluster
   {
     Cluster() : n(0), f_id(-1) {}
 
     vnl_matrix<float> h;
     std::vector< unsigned int > I;
     int n;
     int f_id;
 
     bool operator <(Cluster const& b) const
     {
       return this->n < b.n;
     }
   };
 
-  typedef TractClusteringFilter Self;
-  typedef ProcessObject                                       Superclass;
-  typedef SmartPointer< Self >                                Pointer;
-  typedef SmartPointer< const Self >                          ConstPointer;
+  TractClusteringFilter();
+  ~TractClusteringFilter();
+
   typedef itk::Image< float, 3 >                              FloatImageType;
   typedef itk::Image< unsigned char, 3 >                      UcharImageType;
 
-  itkFactorylessNewMacro(Self)
-  itkCloneMacro(Self)
-  itkTypeMacro( TractClusteringFilter, ProcessObject )
-
-  itkSetMacro(NumPoints, unsigned int)  ///< Fibers are resampled to the specified number of points. If scalar maps are used, a larger number of points is recommended.
-  itkGetMacro(NumPoints, unsigned int)  ///< Fibers are resampled to the specified number of points. If scalar maps are used, a larger number of points is recommended.
-  itkSetMacro(MinClusterSize, unsigned int) ///< Clusters with too few fibers are discarded
-  itkGetMacro(MinClusterSize, unsigned int) ///< Clusters with too few fibers are discarded
-  itkSetMacro(MaxClusters, unsigned int) ///< Only the N largest clusters are kept
-  itkGetMacro(MaxClusters, unsigned int) ///< Only the N largest clusters are kept
-  itkSetMacro(MergeDuplicateThreshold, float) ///< Clusters with centroids very close to each other are merged. Set to 0 to avoid merging and to -1 to use the original cluster size.
-  itkGetMacro(MergeDuplicateThreshold, float) ///< Clusters with centroids very close to each other are merged. Set to 0 to avoid merging and to -1 to use the original cluster size.
-  itkSetMacro(DoResampling, bool) ///< Resample fibers to equal number of points. This is mandatory, but can be performed outside of the filter if desired.
-  itkGetMacro(DoResampling, bool) ///< Resample fibers to equal number of points. This is mandatory, but can be performed outside of the filter if desired.
-  itkSetMacro(OverlapThreshold, float)  ///< Overlap threshold used in conjunction with the filter mask when clustering around known centroids.
-  itkGetMacro(OverlapThreshold, float)  ///< Overlap threshold used in conjunction with the filter mask when clustering around known centroids.
-
-  itkSetMacro(Tractogram, mitk::FiberBundle::Pointer)   ///< The streamlines to be clustered
-  itkSetMacro(InCentroids, mitk::FiberBundle::Pointer)  ///< If a tractogram containing known tract centroids is set, the input fibers are assigned to the closest centroid. If no centroid is found within the specified smallest clustering distance, the fiber is assigned to the no-fit cluster.
-  itkSetMacro(FilterMask, UcharImageType::Pointer)  ///< If fibers are clustered around the nearest input centroids (see SetInCentroids), the complete input tractogram can additionally be pre-filtered with this binary mask and a given overlap threshold (see SetOverlapThreshold).
-
-  virtual void Update() override{
+  void Update(){
     this->GenerateData();
   }
 
   void SetDistances(const std::vector<float> &Distances); ///< Set clustering distances that are traversed recoursively. The distances have to be sorted in an ascending manner. The actual cluster size is determined by the smallest entry in the distance-list (index 0).
 
   std::vector<mitk::FiberBundle::Pointer> GetOutTractograms() const;
   std::vector<mitk::FiberBundle::Pointer> GetOutCentroids() const;
   std::vector<Cluster> GetOutClusters() const;
+  std::vector<std::vector<unsigned int> > GetOutFiberIndices() const;
 
   void SetMetrics(const std::vector<mitk::ClusteringMetric *> &Metrics);
 
-  std::vector<std::vector<unsigned int> > GetOutFiberIndices() const;
+  void SetTractogram(const mitk::FiberBundle::Pointer &Tractogram);
+
+  void SetInCentroids(const mitk::FiberBundle::Pointer &InCentroids);
+
+  void SetMergeDuplicateThreshold(float MergeDuplicateThreshold);
+
+  void SetNumPoints(unsigned int NumPoints);
+
+  void SetMaxClusters(unsigned int MaxClusters);
+
+  void SetMinClusterSize(unsigned int MinClusterSize);
+
+  void SetFilterMask(const UcharImageType::Pointer &FilterMask);
+
+  void SetOverlapThreshold(float OverlapThreshold);
+
+  void SetDoResampling(bool DoResampling);
+
+  unsigned int GetDiscardedClusters() const;
 
 protected:
 
-  void GenerateData() override;
+  void GenerateData();
   std::vector< vnl_matrix<float> > ResampleFibers(FiberBundle::Pointer tractogram);
   float CalcOverlap(vnl_matrix<float>& t);
 
   std::vector< Cluster > ClusterStep(std::vector< unsigned int > f_indices, std::vector< float > distances);
 
   std::vector< TractClusteringFilter::Cluster > MergeDuplicateClusters2(std::vector< TractClusteringFilter::Cluster >& clusters);
   void MergeDuplicateClusters(std::vector< TractClusteringFilter::Cluster >& clusters);
   std::vector< Cluster > AddToKnownClusters(std::vector< unsigned int > f_indices, std::vector<vnl_matrix<float> > &centroids);
   void AppendCluster(std::vector< Cluster >& a, std::vector< Cluster >&b);
 
-  TractClusteringFilter();
-  virtual ~TractClusteringFilter();
-
   unsigned int                                m_NumPoints;
   std::vector< float >                        m_Distances;
   mitk::FiberBundle::Pointer                  m_Tractogram;
   mitk::FiberBundle::Pointer                  m_InCentroids;
   std::vector< mitk::FiberBundle::Pointer >   m_OutTractograms;
   std::vector< mitk::FiberBundle::Pointer >   m_OutCentroids;
   std::vector<vnl_matrix<float> >             T;
   unsigned int                                m_MinClusterSize;
   unsigned int                                m_MaxClusters;
+  unsigned int                                m_DiscardedClusters;
   float                                       m_MergeDuplicateThreshold;
   std::vector< Cluster >                      m_OutClusters;
   bool                                        m_DoResampling;
   UcharImageType::Pointer                     m_FilterMask;
   float                                       m_OverlapThreshold;
   std::vector< mitk::ClusteringMetric* >      m_Metrics;
   std::vector< std::vector< unsigned int > >          m_OutFiberIndices;
 };
 }
 
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "itkTractClusteringFilter.cpp"
-#endif
-
 #endif
diff --git a/Modules/FiberTracking/Testing/mitkStreamlineTractographyTest.cpp b/Modules/FiberTracking/Testing/mitkStreamlineTractographyTest.cpp
index 8922705..a5e07f6 100644
--- a/Modules/FiberTracking/Testing/mitkStreamlineTractographyTest.cpp
+++ b/Modules/FiberTracking/Testing/mitkStreamlineTractographyTest.cpp
@@ -1,438 +1,439 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #include <mitkImageCast.h>
 #include <mitkImageToItk.h>
 #include <mitkTensorImage.h>
 #include <mitkOdfImage.h>
 #include <mitkIOUtil.h>
 #include <mitkFiberBundle.h>
 #include <itkStreamlineTrackingFilter.h>
 #include <Algorithms/TrackingHandlers/mitkTrackingDataHandler.h>
 #include <Algorithms/TrackingHandlers/mitkTrackingHandlerOdf.h>
 #include <Algorithms/TrackingHandlers/mitkTrackingHandlerPeaks.h>
 #include <Algorithms/TrackingHandlers/mitkTrackingHandlerTensor.h>
 #include <itkDiffusionTensor3D.h>
 #include <mitkTestingMacros.h>
 #include <mitkTestFixture.h>
 #include <mitkFiberBundle.h>
 #include <omp.h>
 #include <itksys/SystemTools.hxx>
 #include <mitkEqual.h>
 #include <mitkStreamlineTractographyParameters.h>
 
 class mitkStreamlineTractographyTestSuite : public mitk::TestFixture
 {
 
   CPPUNIT_TEST_SUITE(mitkStreamlineTractographyTestSuite);
   MITK_TEST(Test_Peak1);
   MITK_TEST(Test_Peak2);
   MITK_TEST(Test_Tensor1);
   MITK_TEST(Test_Tensor2);
   MITK_TEST(Test_Tensor3);
   MITK_TEST(Test_Odf1);
   MITK_TEST(Test_Odf2);
   MITK_TEST(Test_Odf3);
   MITK_TEST(Test_Odf4);
   MITK_TEST(Test_Odf5);
   MITK_TEST(Test_Odf6);
   CPPUNIT_TEST_SUITE_END();
 
   typedef itk::VectorImage< short, 3>   ItkDwiType;
 
 private:
 
 public:
 
   /** Members used inside the different (sub-)tests. All members are initialized via setUp().*/
 
   typedef itk::Image<float, 3> ItkFloatImgType;
 
   mitk::TrackingHandlerOdf::ItkOdfImageType::Pointer itk_odf_image;
   mitk::TrackingHandlerTensor::ItkTensorImageType::ConstPointer itk_tensor_image;
   mitk::TrackingHandlerPeaks::PeakImgType::Pointer itk_peak_image;
   ItkFloatImgType::Pointer itk_seed_image;
   ItkFloatImgType::Pointer itk_mask_image;
   ItkFloatImgType::Pointer itk_gfa_image;
 
   float gfa_threshold;
   float odf_threshold;
   float peak_threshold;
   std::shared_ptr<mitk::StreamlineTractographyParameters> params;
 
   itk::StreamlineTrackingFilter::Pointer tracker;
 
   void setUp() override
   {
     omp_set_num_threads(1);
 
     gfa_threshold = 0.2f;
     odf_threshold = 0.1f;
     peak_threshold = 0.1f;
 
     mitk::Image::Pointer odf_image = mitk::IOUtil::Load<mitk::Image>(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/qball_image.qbi"));
     mitk::Image::Pointer tensor_image = mitk::IOUtil::Load<mitk::Image>(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/tensor_image.dti"));
     mitk::Image::Pointer peak_image = mitk::IOUtil::Load<mitk::Image>(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/qball_peak_image.nii.gz"));
     mitk::Image::Pointer seed_image = mitk::IOUtil::Load<mitk::Image>(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/seed_image.nii.gz"));
     mitk::Image::Pointer mask_image = mitk::IOUtil::Load<mitk::Image>(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/mask_image.nii.gz"));
     mitk::Image::Pointer gfa_image = mitk::IOUtil::Load<mitk::Image>(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/gfa_image.nii.gz"));
 
     params = std::make_shared<mitk::StreamlineTractographyParameters>();
     params->m_FixRandomSeed = true;
     params->m_InterpolateRoiImages = false;
+    params->SetLoopCheckDeg(-1);  // todo: test loop check
 
     {
       typedef mitk::ImageToItk< mitk::TrackingHandlerPeaks::PeakImgType > CasterType;
       CasterType::Pointer caster = CasterType::New();
       caster->SetInput(peak_image);
       caster->Update();
       itk_peak_image = caster->GetOutput();
     }
 
     {
       typedef mitk::ImageToItk< mitk::TrackingHandlerTensor::ItkTensorImageType > CasterType;
       CasterType::Pointer caster = CasterType::New();
       caster->SetInput(tensor_image);
       caster->Update();
       itk_tensor_image = caster->GetOutput();
     }
 
     {
       typedef mitk::ImageToItk< mitk::TrackingHandlerOdf::ItkOdfImageType > CasterType;
       CasterType::Pointer caster = CasterType::New();
       caster->SetInput(odf_image);
       caster->Update();
       itk_odf_image = caster->GetOutput();
     }
 
     itk_gfa_image = ItkFloatImgType::New();
     mitk::CastToItkImage(gfa_image, itk_gfa_image);
 
     itk_seed_image = ItkFloatImgType::New();
     mitk::CastToItkImage(seed_image, itk_seed_image);
 
     itk_mask_image = ItkFloatImgType::New();
     mitk::CastToItkImage(mask_image, itk_mask_image);
   }
 
   mitk::FiberBundle::Pointer LoadReferenceFib(std::string filename)
   {
     mitk::FiberBundle::Pointer fib = nullptr;
 
     if (itksys::SystemTools::FileExists(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/ReferenceFibs/" + filename)))
     {
       mitk::BaseData::Pointer baseData = mitk::IOUtil::Load(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/ReferenceFibs/" + filename)).at(0);
       fib = dynamic_cast<mitk::FiberBundle*>(baseData.GetPointer());
     }
     return fib;
   }
 
   mitk::Image::Pointer LoadReferenceImage(std::string filename)
   {
     mitk::Image::Pointer img = nullptr;
 
     if (itksys::SystemTools::FileExists(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/ReferenceFibs/" + filename)))
     {
       img = mitk::IOUtil::Load<mitk::Image>(GetTestDataFilePath("DiffusionImaging/StreamlineTractography/ReferenceFibs/" + filename));
     }
     return img;
   }
 
   void SetupTracker(mitk::TrackingDataHandler* handler)
   {
 
     tracker = itk::StreamlineTrackingFilter::New();
 
 //    tracker->SetInterpolateMasks(false);
 //    tracker->SetNumberOfSamples(0);
 //    tracker->SetAngularThreshold(-1);
     tracker->SetMaskImage(itk_mask_image);
     tracker->SetSeedImage(itk_seed_image);
     tracker->SetStoppingRegions(nullptr);
 //    tracker->SetSeedsPerVoxel(1);
 //    tracker->SetStepSize(0.5);
 //    tracker->SetSamplingDistance(0.25);
 //    tracker->SetUseStopVotes(true);
 //    tracker->SetOnlyForwardSamples(true);
 //    tracker->SetMinTractLength(20);
 //    tracker->SetMaxNumTracts(-1);
     tracker->SetTrackingHandler(handler);
 //    tracker->SetUseOutputProbabilityMap(false);
     tracker->SetParameters(params);
   }
 
   void tearDown() override
   {
 
   }
 
   void CheckFibResult(std::string ref_file, mitk::FiberBundle::Pointer test_fib)
   {
     mitk::FiberBundle::Pointer ref = LoadReferenceFib(ref_file);
     if (ref.IsNull())
     {
       mitk::IOUtil::Save(test_fib, mitk::IOUtil::GetTempPath()+ref_file);
       CPPUNIT_FAIL("Reference file not found. Saving test file to " + mitk::IOUtil::GetTempPath() + ref_file);
     }
     else
     {
       bool is_equal = ref->Equals(test_fib);
       if (!is_equal)
       {
         mitk::IOUtil::Save(test_fib, mitk::IOUtil::GetTempPath()+ref_file);
         CPPUNIT_FAIL("Tractograms are not equal! Saving test file to " + mitk::IOUtil::GetTempPath() + ref_file);
       }
     }
   }
 
   void CheckImageResult(std::string ref_file, mitk::Image::Pointer test_img)
   {
     mitk::Image::Pointer ref = LoadReferenceImage(ref_file);
     if (ref.IsNull())
     {
       mitk::IOUtil::Save(test_img, mitk::IOUtil::GetTempPath()+ref_file);
       CPPUNIT_FAIL("Reference file not found. Saving test file to " + mitk::IOUtil::GetTempPath() + ref_file);
     }
     else
     {
       MITK_ASSERT_EQUAL(test_img, ref, "Images should be equal");
     }
   }
 
   void Test_Peak1()
   {
     mitk::TrackingHandlerPeaks* handler = new mitk::TrackingHandlerPeaks();
     handler->SetPeakImage(itk_peak_image);
     params->m_Cutoff = peak_threshold;
 
     SetupTracker(handler);
     tracker->Update();
 
     vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData();
     mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly);
 
     CheckFibResult("Test_Peak1.fib", outFib);
 
     delete handler;
   }
 
   void Test_Peak2()
   {
     mitk::TrackingHandlerPeaks* handler = new mitk::TrackingHandlerPeaks();
     handler->SetPeakImage(itk_peak_image);
     params->m_Cutoff = peak_threshold;
     params->m_InterpolateTractographyData = false;
 
     SetupTracker(handler);
     tracker->Update();
 
     vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData();
     mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly);
 
     CheckFibResult("Test_Peak2.fib", outFib);
 
     delete handler;
   }
 
   void Test_Tensor1()
   {
     mitk::TrackingHandlerTensor* handler = new mitk::TrackingHandlerTensor();
     handler->SetTensorImage(itk_tensor_image);
     params->m_Cutoff = gfa_threshold;
 
     SetupTracker(handler);
     tracker->Update();
 
     vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData();
     mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly);
 
     CheckFibResult("Test_Tensor1.fib", outFib);
 
     delete handler;
   }
 
   void Test_Tensor2()
   {
     mitk::TrackingHandlerTensor* handler = new mitk::TrackingHandlerTensor();
     handler->SetTensorImage(itk_tensor_image);
     params->m_Cutoff = gfa_threshold;
     params->m_InterpolateTractographyData = false;
 
     SetupTracker(handler);
     tracker->Update();
 
     vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData();
     mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly);
 
     CheckFibResult("Test_Tensor2.fib", outFib);
 
     delete handler;
   }
 
   void Test_Tensor3()
   {
     mitk::TrackingHandlerTensor* handler = new mitk::TrackingHandlerTensor();
     handler->SetTensorImage(itk_tensor_image);
     params->m_Cutoff = gfa_threshold;
     params->m_InterpolateTractographyData = false;
     params->m_F = 0;
     params->m_G = 1;
 
     SetupTracker(handler);
     tracker->Update();
 
     vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData();
     mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly);
 
     CheckFibResult("Test_Tensor3.fib", outFib);
 
     delete handler;
   }
 
   void Test_Odf1()
   {
     mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf();
     handler->SetOdfImage(itk_odf_image);
 
     params->m_Cutoff = gfa_threshold;
     params->m_OdfCutoff = 0;
     params->m_SharpenOdfs = true;
 
     SetupTracker(handler);
     tracker->Update();
 
     vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData();
     mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly);
 
     CheckFibResult("Test_Odf1.fib", outFib);
 
     delete handler;
   }
 
   void Test_Odf2()
   {
     mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf();
     handler->SetOdfImage(itk_odf_image);
 
     params->m_Cutoff = gfa_threshold;
     params->m_OdfCutoff = 0;
     params->m_SharpenOdfs = false;
 
     SetupTracker(handler);
     tracker->Update();
 
     vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData();
     mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly);
 
     CheckFibResult("Test_Odf2.fib", outFib);
 
     delete handler;
   }
 
 
   void Test_Odf3()
   {
     mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf();
     handler->SetOdfImage(itk_odf_image);
 
     params->m_Cutoff = gfa_threshold;
     params->m_OdfCutoff = 0;
     params->m_SharpenOdfs = true;
     params->m_InterpolateTractographyData = false;
 
     SetupTracker(handler);
     tracker->Update();
 
     vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData();
     mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly);
 
     CheckFibResult("Test_Odf3.fib", outFib);
 
     delete handler;
   }
 
   void Test_Odf4()
   {
     mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf();
     handler->SetOdfImage(itk_odf_image);
 
     params->m_Cutoff = gfa_threshold;
     params->m_OdfCutoff = 0;
     params->m_SharpenOdfs = true;
     params->m_SeedsPerVoxel = 3;
 
     SetupTracker(handler);
     tracker->Update();
 
     vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData();
     mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly);
 
     CheckFibResult("Test_Odf4.fib", outFib);
 
     delete handler;
   }
 
   void Test_Odf5()
   {
     mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf();
     handler->SetOdfImage(itk_odf_image);
 
     params->m_Cutoff = gfa_threshold;
     params->m_OdfCutoff = 0;
     params->m_SharpenOdfs = true;
     params->m_SeedsPerVoxel = 3;
     params->m_Mode = mitk::TrackingDataHandler::MODE::PROBABILISTIC;
 
     SetupTracker(handler);
     tracker->Update();
 
     vtkSmartPointer< vtkPolyData > poly = tracker->GetFiberPolyData();
     mitk::FiberBundle::Pointer outFib = mitk::FiberBundle::New(poly);
 
     CheckFibResult("Test_Odf5.fib", outFib);
 
     delete handler;
   }
 
   void Test_Odf6()
   {
     mitk::TrackingHandlerOdf* handler = new mitk::TrackingHandlerOdf();
     handler->SetOdfImage(itk_odf_image);
 
     params->m_Cutoff = gfa_threshold;
     params->m_OdfCutoff = 0;
     params->m_SharpenOdfs = true;
     params->m_SeedsPerVoxel = 10;
     params->m_Mode = mitk::TrackingDataHandler::MODE::PROBABILISTIC;
     params->m_OutputProbMap = true;
 
     SetupTracker(handler);
     tracker->Update();
 
     itk::StreamlineTrackingFilter::ItkDoubleImgType::Pointer outImg = tracker->GetOutputProbabilityMap();
     mitk::Image::Pointer img = mitk::Image::New();
     img->InitializeByItk(outImg.GetPointer());
     img->SetVolume(outImg->GetBufferPointer());
 
     mitk::IOUtil::Save(img, mitk::IOUtil::GetTempPath()+"Test_Odf6.nrrd");
     CheckImageResult("Test_Odf6.nrrd", img);
 
     delete handler;
   }
 
 };
 
 MITK_TEST_SUITE_REGISTRATION(mitkStreamlineTractography)
diff --git a/Modules/FiberTracking/files.cmake b/Modules/FiberTracking/files.cmake
index be71c70..6e5c97c 100644
--- a/Modules/FiberTracking/files.cmake
+++ b/Modules/FiberTracking/files.cmake
@@ -1,70 +1,71 @@
 set(CPP_FILES
   mitkStreamlineTractographyParameters.cpp
 
   # Tractography
   Algorithms/GibbsTracking/mitkParticleGrid.cpp
   Algorithms/GibbsTracking/mitkMetropolisHastingsSampler.cpp
   Algorithms/GibbsTracking/mitkEnergyComputer.cpp
   Algorithms/GibbsTracking/mitkGibbsEnergyComputer.cpp
   Algorithms/GibbsTracking/mitkFiberBuilder.cpp
   Algorithms/GibbsTracking/mitkSphereInterpolator.cpp
 
+  Algorithms/mitkTractClusteringFilter.cpp
   Algorithms/itkStreamlineTrackingFilter.cpp
   Algorithms/TrackingHandlers/mitkTrackingDataHandler.cpp
   Algorithms/TrackingHandlers/mitkTrackingHandlerTensor.cpp
   Algorithms/TrackingHandlers/mitkTrackingHandlerPeaks.cpp
   Algorithms/TrackingHandlers/mitkTrackingHandlerOdf.cpp
 )
 
 set(H_FILES
   mitkStreamlineTractographyParameters.h
 
   # Algorithms
   Algorithms/itkTractDensityImageFilter.h
   Algorithms/itkTractsToFiberEndingsImageFilter.h
   Algorithms/itkTractsToRgbaImageFilter.h
   Algorithms/itkTractsToVectorImageFilter.h
   Algorithms/itkEvaluateDirectionImagesFilter.h
   Algorithms/itkEvaluateTractogramDirectionsFilter.h
   Algorithms/itkFiberCurvatureFilter.h
-  Algorithms/itkTractClusteringFilter.h
+  Algorithms/mitkTractClusteringFilter.h
   Algorithms/itkTractDistanceFilter.h
   Algorithms/itkFiberExtractionFilter.h
   Algorithms/itkTdiToVolumeFractionFilter.h
 
   # Tractography
   Algorithms/TrackingHandlers/mitkTrackingDataHandler.h
   Algorithms/TrackingHandlers/mitkTrackingHandlerRandomForest.h
   Algorithms/TrackingHandlers/mitkTrackingHandlerTensor.h
   Algorithms/TrackingHandlers/mitkTrackingHandlerPeaks.h
   Algorithms/TrackingHandlers/mitkTrackingHandlerOdf.h
 
   Algorithms/itkGibbsTrackingFilter.h
   Algorithms/itkStochasticTractographyFilter.h
   Algorithms/GibbsTracking/mitkParticle.h
   Algorithms/GibbsTracking/mitkParticleGrid.h
   Algorithms/GibbsTracking/mitkMetropolisHastingsSampler.h
   Algorithms/GibbsTracking/mitkSimpSamp.h
   Algorithms/GibbsTracking/mitkEnergyComputer.h
   Algorithms/GibbsTracking/mitkGibbsEnergyComputer.h
   Algorithms/GibbsTracking/mitkSphereInterpolator.h
   Algorithms/GibbsTracking/mitkFiberBuilder.h
 
   Algorithms/itkStreamlineTrackingFilter.h
 
   # Clustering
   Algorithms/ClusteringMetrics/mitkClusteringMetric.h
   Algorithms/ClusteringMetrics/mitkClusteringMetricEuclideanMean.h
   Algorithms/ClusteringMetrics/mitkClusteringMetricEuclideanMax.h
   Algorithms/ClusteringMetrics/mitkClusteringMetricEuclideanStd.h
   Algorithms/ClusteringMetrics/mitkClusteringMetricAnatomic.h
   Algorithms/ClusteringMetrics/mitkClusteringMetricScalarMap.h
   Algorithms/ClusteringMetrics/mitkClusteringMetricInnerAngles.h
   Algorithms/ClusteringMetrics/mitkClusteringMetricLength.h
 )
 
 set(RESOURCE_FILES
   # Binary directory resources
   FiberTrackingLUTBaryCoords.bin
   FiberTrackingLUTIndices.bin
 )
diff --git a/Modules/FiberTracking/mitkStreamlineTractographyParameters.h b/Modules/FiberTracking/mitkStreamlineTractographyParameters.h
index 96fe4a8..7f35ad4 100644
--- a/Modules/FiberTracking/mitkStreamlineTractographyParameters.h
+++ b/Modules/FiberTracking/mitkStreamlineTractographyParameters.h
@@ -1,163 +1,163 @@
 #pragma once
 
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #include <mitkImage.h>
 #include <mitkDiffusionPropertyHelper.h>
 #include <boost/property_tree/ptree.hpp>
 #include <boost/property_tree/json_parser.hpp>
 #include <MitkFiberTrackingExports.h>
 
 namespace mitk
 {
   /**
   * \brief Datastructure to manage streamline tractography parameters.
   *
   */
   class MITKFIBERTRACKING_EXPORT StreamlineTractographyParameters
   {
 
   public:
 
     enum EndpointConstraints {
       NONE,                     ///< No constraints on endpoint locations
       EPS_IN_TARGET,            ///< Both EPs are required to be located in the target image
       EPS_IN_TARGET_LABELDIFF,  ///< Both EPs are required to be located in the target image and the image values at the respective position needs to be distinct
       EPS_IN_SEED_AND_TARGET,   ///< One EP is required to be located in the seed image and one in the target image
       MIN_ONE_EP_IN_TARGET,     ///< At least one EP is required to be located in the target image
       ONE_EP_IN_TARGET,         ///< Exactly one EP is required to be located in the target image
       NO_EP_IN_TARGET           ///< No EP is allowed to be located in the target image
     };
 
     enum MODE {
       DETERMINISTIC,
       PROBABILISTIC
     };
 
     typedef itk::Image<float, 3>                            ItkFloatImgType;
     typedef itk::Image<double, 3>                           ItkDoubleImgType;
     typedef itk::Image<unsigned char, 3>                    ItkUcharImgType;
 
     StreamlineTractographyParameters();
     StreamlineTractographyParameters(const StreamlineTractographyParameters &params) = default;
     ~StreamlineTractographyParameters();
 
     void SaveParameters(std::string filename);  ///< Save image generation parameters to .stp file.
     void LoadParameters(std::string filename);  ///< Load image generation parameters from .stp file.
 
     template< class ParameterType >
     ParameterType ReadVal(boost::property_tree::ptree::value_type const& v, std::string tag, ParameterType defaultValue, bool essential=false);
 
     // seeding
     unsigned int m_SeedsPerVoxel = 1;
     unsigned int m_TrialsPerSeed = 10;
     int m_MaxNumFibers = -1;
     // - seed image
 
     // interactive
     float m_InteractiveRadiusMm = 2;
     unsigned int m_NumInteractiveSeeds = 50;
     bool m_EnableInteractive = false;
 
     // ROI constraints
     EndpointConstraints m_EpConstraints;
     // - mask image
     // - stop image
     // - exclusion image
     // - target image
 
     // tractography
     MODE m_Mode= MODE::DETERMINISTIC;
     bool m_SharpenOdfs = false;
     float m_Cutoff = 0.1;
     // - fa/gfa image
     float m_OdfCutoff = 0.00025;
     float m_MinTractLengthMm = 20;
     float m_MaxTractLengthMm = 400;
     float m_F = 1;
     float m_G = 0;
     bool m_FixRandomSeed = false;
     unsigned int m_NumPreviousDirections = 1;
     float m_PeakJitter = 0.01; // actual jitter is drawn from a normal distribution with m_PeakJitter*fabs(direction_value) as standard deviation
 
     // prior
     // - peak image
     float m_Weight = 0.5;
     bool m_RestrictToPrior = true;
     bool m_NewDirectionsFromPrior = true;
     bool m_PriorFlipX = false;
     bool m_PriorFlipY = false;
     bool m_PriorFlipZ = false;
 
     // neighborhood sampling
     unsigned int m_NumSamples = 0;
     bool m_OnlyForwardSamples = false;
     bool m_StopVotes = false;
     bool m_AvoidStop = true;
     bool m_RandomSampling = false;
     float m_DeflectionMod = 1.0;
 
     // data handling
     bool m_FlipX = false;
     bool m_FlipY = false;
     bool m_FlipZ = false;
     bool m_InterpolateTractographyData = true;
     bool m_InterpolateRoiImages;
     bool m_ApplyDirectionMatrix = false;
 
     // output and postprocessing
     bool m_CompressFibers = true;
     float m_Compression = 0.1;
     bool m_OutputProbMap = false;
 
     float GetAngularThresholdDot() const;
     float GetAngularThresholdDeg() const;
     void SetAngularThresholdDeg(float angular_threshold_deg);
 
     float GetLoopCheckDeg() const;
     void SetLoopCheckDeg(float loop_check_deg);
 
     float GetStepSizeMm() const;
     float GetStepSizeVox() const;
     void SetStepSizeVox(float step_size_vox);
 
     float GetSamplingDistanceMm() const;
     float GetSamplingDistanceVox() const;
     void SetSamplingDistanceVox(float sampling_distance_vox);
 
     void SetMinVoxelSizeMm(float min_voxel_size_mm);
     float GetMinVoxelSizeMm() const;
 
   private:
 
     void AutoAdjust();
 
     float m_SamplingDistanceVox = -1;
     float m_SamplingDistanceMm;
 
     float m_AngularThresholdDeg = -1;
     float m_AngularThresholdDot;
 
-    float m_LoopCheckDeg = -1;
+    float m_LoopCheckDeg = 30;
 
     float m_StepSizeVox = -1;
     float m_StepSizeMm;
 
     float m_MinVoxelSizeMm = 1.0;
   };
 }
 
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp
index 5cea14d..038ed58 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/Perspectives/QmitkFiberProcessingPerspective.cpp
@@ -1,51 +1,52 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #include "QmitkFiberProcessingPerspective.h"
 #include "berryIViewLayout.h"
 
 void QmitkFiberProcessingPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout)
 {
   /////////////////////////////////////////////////////
   // all di-app perspectives should have the following:
   /////////////////////////////////////////////////////
 
   QString editorArea = layout->GetEditorArea();
 
   layout->AddStandaloneViewPlaceholder("org.mitk.views.viewnavigatorview", berry::IPageLayout::LEFT, 0.3f, editorArea, false);
 
   layout->AddStandaloneView("org.mitk.views.datamanager",
                             false, berry::IPageLayout::LEFT, 0.3f, editorArea);
 
   layout->AddStandaloneView("org.mitk.views.controlvisualizationpropertiesview",
                             false, berry::IPageLayout::BOTTOM, .15f, "org.mitk.views.datamanager");
 
   berry::IFolderLayout::Pointer left =
       layout->CreateFolder("org.mbi.diffusionimaginginternal.leftcontrols",
                            berry::IPageLayout::BOTTOM, 0.15f, "org.mitk.views.controlvisualizationpropertiesview");
 
   layout->AddStandaloneViewPlaceholder("org.mitk.views.imagenavigator",
                                        berry::IPageLayout::BOTTOM, .7f, "org.mbi.diffusionimaginginternal.leftcontrols", false);
 
   /////////////////////////////////////////////
   // here goes the perspective specific stuff
   /////////////////////////////////////////////
 
   left->AddView("org.mitk.views.fiberprocessing");
   left->AddView("org.mitk.views.fiberquantification");
   left->AddView("org.mitk.views.fiberclustering");
   left->AddView("org.mitk.views.fiberfit");
+  left->AddView("org.mitk.views.tractometry");
 }
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberClusteringView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberClusteringView.cpp
index 4a642f2..9d6a150 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberClusteringView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberClusteringView.cpp
@@ -1,232 +1,233 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 
 // Blueberry
 #include <berryISelectionService.h>
 #include <berryIWorkbenchWindow.h>
 
 #include "QmitkFiberClusteringView.h"
 
 #include <mitkNodePredicateDataType.h>
 #include <mitkNodePredicateDimension.h>
 #include <mitkNodePredicateAnd.h>
 #include <mitkImageCast.h>
 #include <mitkImageAccessByItk.h>
-#include <itkTractClusteringFilter.h>
+#include <mitkTractClusteringFilter.h>
 #include <mitkFiberBundle.h>
 #include <mitkClusteringMetricEuclideanMean.h>
 #include <mitkClusteringMetricEuclideanMax.h>
 #include <mitkClusteringMetricEuclideanStd.h>
 #include <mitkClusteringMetricAnatomic.h>
 #include <mitkClusteringMetricScalarMap.h>
 #include <mitkClusteringMetricInnerAngles.h>
 #include <mitkClusteringMetricLength.h>
 #include <QMessageBox>
+#include <boost/lexical_cast.hpp>
 
 const std::string QmitkFiberClusteringView::VIEW_ID = "org.mitk.views.fiberclustering";
 using namespace mitk;
 
 QmitkFiberClusteringView::QmitkFiberClusteringView()
   : QmitkAbstractView()
   , m_Controls( nullptr )
 {
 
 }
 
 // Destructor
 QmitkFiberClusteringView::~QmitkFiberClusteringView()
 {
 
 }
 
 void QmitkFiberClusteringView::CreateQtPartControl( QWidget *parent )
 {
   // build up qt view, unless already done
   if ( !m_Controls )
   {
     // create GUI widgets from the Qt Designer's .ui file
     m_Controls = new Ui::QmitkFiberClusteringViewControls;
     m_Controls->setupUi( parent );
 
     connect( m_Controls->m_StartButton, SIGNAL(clicked()), this, SLOT(StartClustering()) );
     connect( m_Controls->m_TractBox, SIGNAL(currentIndexChanged(int)), this, SLOT(FiberSelectionChanged()) );
 
     mitk::TNodePredicateDataType<mitk::FiberBundle>::Pointer isFib = mitk::TNodePredicateDataType<mitk::FiberBundle>::New();
     m_Controls->m_TractBox->SetDataStorage(this->GetDataStorage());
     m_Controls->m_TractBox->SetPredicate(isFib);
 
     m_Controls->m_InCentroidsBox->SetDataStorage(this->GetDataStorage());
     m_Controls->m_InCentroidsBox->SetPredicate(isFib);
     m_Controls->m_InCentroidsBox->SetZeroEntryText("--");
 
 
     mitk::TNodePredicateDataType<mitk::Image>::Pointer imageP = mitk::TNodePredicateDataType<mitk::Image>::New();
     mitk::NodePredicateDimension::Pointer dimP = mitk::NodePredicateDimension::New(3);
 
     m_Controls->m_MapBox->SetDataStorage(this->GetDataStorage());
     m_Controls->m_MapBox->SetPredicate(mitk::NodePredicateAnd::New(imageP, dimP));
 
     m_Controls->m_ParcellationBox->SetDataStorage(this->GetDataStorage());
     m_Controls->m_ParcellationBox->SetPredicate(mitk::NodePredicateAnd::New(imageP, dimP));
 
     m_Controls->m_MetricBox6->setVisible(false);
     m_Controls->m_MetricWeight6->setVisible(false);
 
     FiberSelectionChanged();
   }
 
 }
 
 void QmitkFiberClusteringView::SetFocus()
 {
   FiberSelectionChanged();
 }
 
 void QmitkFiberClusteringView::FiberSelectionChanged()
 {
   if (m_Controls->m_TractBox->GetSelectedNode().IsNull())
     m_Controls->m_StartButton->setEnabled(false);
   else
     m_Controls->m_StartButton->setEnabled(true);
 }
 
 void QmitkFiberClusteringView::StartClustering()
 {
   if (m_Controls->m_TractBox->GetSelectedNode().IsNull())
     return;
 
   mitk::DataNode::Pointer node = m_Controls->m_TractBox->GetSelectedNode();
   float clusterSize = m_Controls->m_ClusterSizeBox->value();
 
   mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
 
   float max_d = 0;
   int i=1;
   std::vector< float > distances;
   while (max_d < fib->GetGeometry()->GetDiagonalLength()/2)
   {
     distances.push_back(clusterSize*i);
     max_d = clusterSize*i;
     ++i;
   }
 
-  itk::TractClusteringFilter::Pointer clusterer = itk::TractClusteringFilter::New();
+  std::shared_ptr< mitk::TractClusteringFilter > clusterer = std::make_shared<mitk::TractClusteringFilter>();
   clusterer->SetDistances(distances);
   clusterer->SetTractogram(fib);
   if (m_Controls->m_InCentroidsBox->GetSelectedNode().IsNotNull())
   {
     mitk::FiberBundle::Pointer in_centroids = dynamic_cast<mitk::FiberBundle*>(m_Controls->m_InCentroidsBox->GetSelectedNode()->GetData());
     clusterer->SetInCentroids(in_centroids);
   }
 
   std::vector< mitk::ClusteringMetric* > metrics;
   if (m_Controls->m_MetricBox1->isChecked())
   {
     mitk::ClusteringMetricEuclideanMean* metric = new mitk::ClusteringMetricEuclideanMean();
     metric->SetScale(m_Controls->m_MetricWeight1->value());
     metrics.push_back(metric);
   }
   if (m_Controls->m_MetricBox2->isChecked())
   {
     mitk::ClusteringMetricEuclideanStd* metric = new mitk::ClusteringMetricEuclideanStd();
     metric->SetScale(m_Controls->m_MetricWeight2->value());
     metrics.push_back(metric);
   }
   if (m_Controls->m_MetricBox3->isChecked())
   {
     mitk::ClusteringMetricEuclideanMax* metric = new mitk::ClusteringMetricEuclideanMax();
     metric->SetScale(m_Controls->m_MetricWeight3->value());
     metrics.push_back(metric);
   }
   if (m_Controls->m_MetricBox6->isChecked())
   {
     mitk::ClusteringMetricInnerAngles* metric = new mitk::ClusteringMetricInnerAngles();
     metric->SetScale(m_Controls->m_MetricWeight6->value());
     metrics.push_back(metric);
   }
   if (m_Controls->m_MetricBox7->isChecked())
   {
     mitk::ClusteringMetricLength* metric = new mitk::ClusteringMetricLength();
     metric->SetScale(m_Controls->m_MetricWeight7->value());
     metrics.push_back(metric);
   }
 
   if (m_Controls->m_ParcellationBox->GetSelectedNode().IsNotNull() && m_Controls->m_MetricBox4->isChecked())
   {
     mitk::Image::Pointer mitk_map = dynamic_cast<mitk::Image*>(m_Controls->m_ParcellationBox->GetSelectedNode()->GetData());
 
     ShortImageType::Pointer itk_map = ShortImageType::New();
     mitk::CastToItkImage(mitk_map, itk_map);
     mitk::ClusteringMetricAnatomic* metric = new mitk::ClusteringMetricAnatomic();
     metric->SetParcellations({itk_map});
     metric->SetScale(m_Controls->m_MetricWeight4->value());
     metrics.push_back(metric);
   }
   if (m_Controls->m_MapBox->GetSelectedNode().IsNotNull() && m_Controls->m_MetricBox5->isChecked())
   {
     mitk::Image::Pointer mitk_map = dynamic_cast<mitk::Image*>(m_Controls->m_MapBox->GetSelectedNode()->GetData());
 
     FloatImageType::Pointer itk_map = FloatImageType::New();
     mitk::CastToItkImage(mitk_map, itk_map);
     mitk::ClusteringMetricScalarMap* metric = new mitk::ClusteringMetricScalarMap();
     metric->SetImages({itk_map});
     metric->SetScale(m_Controls->m_MetricWeight5->value());
     metrics.push_back(metric);
   }
 
   if (metrics.empty())
   {
     QMessageBox::warning(nullptr, "Warning", "No metric selected!");
     return;
   }
 
   clusterer->SetMetrics(metrics);
   clusterer->SetMergeDuplicateThreshold(m_Controls->m_MergeDuplicatesBox->value());
   clusterer->SetNumPoints(m_Controls->m_FiberPointsBox->value());
   clusterer->SetMaxClusters(m_Controls->m_MaxClustersBox->value());
   clusterer->SetMinClusterSize(m_Controls->m_MinFibersBox->value());
   clusterer->Update();
   std::vector<mitk::FiberBundle::Pointer> tracts = clusterer->GetOutTractograms();
   std::vector<mitk::FiberBundle::Pointer> centroids = clusterer->GetOutCentroids();
 
   unsigned int c = 0;
   for (auto f : tracts)
   {
     mitk::DataNode::Pointer new_node = mitk::DataNode::New();
     new_node->SetData(f);
     new_node->SetName("Cluster_" + boost::lexical_cast<std::string>(c));
     if (m_Controls->m_InCentroidsBox->GetSelectedNode().IsNotNull())
       this->GetDataStorage()->Add(new_node, m_Controls->m_InCentroidsBox->GetSelectedNode());
     else
       this->GetDataStorage()->Add(new_node, node);
     node->SetVisibility(false);
 
     if (m_Controls->m_CentroidsBox->isChecked())
     {
       mitk::DataNode::Pointer new_node2 = mitk::DataNode::New();
       new_node2->SetData(centroids.at(c));
       new_node2->SetName("Centroid_" + boost::lexical_cast<std::string>(c));
       this->GetDataStorage()->Add(new_node2, new_node);
     }
     ++c;
   }
 }
 
 void QmitkFiberClusteringView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList<mitk::DataNode::Pointer>& )
 {
 
 }
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberProcessingViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberProcessingViewControls.ui
index 787549c..1bd48b6 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberProcessingViewControls.ui
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberProcessingViewControls.ui
@@ -1,1744 +1,1744 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>QmitkFiberProcessingViewControls</class>
  <widget class="QWidget" name="QmitkFiberProcessingViewControls">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>385</width>
     <height>711</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
   <property name="styleSheet">
    <string>QCommandLinkButton:disabled {
   border: none;
 }
 
 QGroupBox {
   background-color: transparent;
 }</string>
   </property>
   <layout class="QGridLayout" name="gridLayout_3">
    <property name="leftMargin">
     <number>9</number>
    </property>
    <property name="topMargin">
     <number>9</number>
    </property>
    <property name="rightMargin">
     <number>9</number>
    </property>
    <property name="bottomMargin">
     <number>9</number>
    </property>
    <item row="1" column="0">
     <widget class="QToolBox" name="toolBoxx">
      <property name="font">
       <font>
        <weight>75</weight>
        <bold>true</bold>
       </font>
      </property>
      <property name="currentIndex">
       <number>0</number>
      </property>
      <property name="tabSpacing">
       <number>5</number>
      </property>
      <widget class="QWidget" name="page">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>353</width>
         <height>503</height>
        </rect>
       </property>
       <attribute name="label">
        <string>Fiber Extraction</string>
       </attribute>
       <attribute name="toolTip">
        <string>Extract a fiber subset from the selected fiber bundle using manually placed planar figures as waypoints or binary regions of interest.</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_14">
        <item row="7" column="0">
         <spacer name="verticalSpacer_5">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
        <item row="4" column="0">
         <widget class="QFrame" name="m_MaskExtractionFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_19">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <item row="2" column="0">
            <widget class="QLabel" name="m_FiberExtractionFractionLabel">
             <property name="text">
              <string>Min. overlap:</string>
             </property>
            </widget>
           </item>
           <item row="3" column="0">
            <widget class="QLabel" name="m_FiberExtractionThresholdLabel">
             <property name="text">
              <string>Threshold:</string>
             </property>
            </widget>
           </item>
           <item row="4" column="0">
            <widget class="QLabel" name="label_20">
             <property name="text">
              <string>Min. num. fibers:</string>
             </property>
            </widget>
           </item>
           <item row="3" column="2">
            <widget class="QDoubleSpinBox" name="m_FiberExtractionThresholdBox">
             <property name="toolTip">
              <string>Threshold on ROI image for positions to be considered as positive.</string>
             </property>
             <property name="decimals">
              <number>3</number>
             </property>
             <property name="maximum">
              <double>9999.000000000000000</double>
             </property>
             <property name="singleStep">
              <double>0.100000000000000</double>
             </property>
             <property name="value">
              <double>0.500000000000000</double>
             </property>
            </widget>
           </item>
           <item row="0" column="2">
            <widget class="QComboBox" name="m_ExtractionBoxMask">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
             <item>
              <property name="text">
               <string>Ending in ROI</string>
              </property>
             </item>
             <item>
              <property name="text">
               <string>Not ending in ROI</string>
              </property>
             </item>
             <item>
              <property name="text">
               <string>Passing ROI</string>
              </property>
             </item>
             <item>
              <property name="text">
               <string>Not passing ROI</string>
              </property>
             </item>
             <item>
              <property name="text">
               <string>Labelmap</string>
              </property>
             </item>
            </widget>
           </item>
           <item row="7" column="0">
            <widget class="QCheckBox" name="m_BothEnds">
             <property name="text">
              <string>Both ends</string>
             </property>
             <property name="checked">
              <bool>true</bool>
             </property>
            </widget>
           </item>
           <item row="6" column="0">
            <widget class="QCheckBox" name="m_InterpolateRoiBox">
             <property name="text">
              <string>Interpolate ROI </string>
             </property>
             <property name="checked">
              <bool>true</bool>
             </property>
            </widget>
           </item>
           <item row="4" column="2">
            <widget class="QSpinBox" name="m_MinExtractedFibersBox">
             <property name="minimum">
              <number>1</number>
             </property>
             <property name="maximum">
              <number>999999999</number>
             </property>
            </widget>
           </item>
           <item row="0" column="0">
            <widget class="QLabel" name="label_16">
             <property name="text">
              <string>Extract fibers:</string>
             </property>
            </widget>
           </item>
           <item row="2" column="2">
            <widget class="QDoubleSpinBox" name="m_FiberExtractionFractionBox">
             <property name="toolTip">
              <string>Minimum overlap of streamlines and ROI in terms of streamline length. Zero means that one streamline point inside the ROI is enough to be considered as &quot;overlapping&quot;.</string>
             </property>
             <property name="decimals">
              <number>3</number>
             </property>
             <property name="maximum">
              <double>1.000000000000000</double>
             </property>
             <property name="singleStep">
              <double>0.100000000000000</double>
             </property>
            </widget>
           </item>
           <item row="5" column="0">
            <widget class="QLabel" name="m_LabelsLabel">
             <property name="text">
              <string>Labels:</string>
             </property>
            </widget>
           </item>
           <item row="5" column="2">
            <widget class="QLineEdit" name="m_LabelsBox">
             <property name="toolTip">
              <string>Label values seperated by whitespace.</string>
             </property>
             <property name="text">
              <string>ALL</string>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="6" column="0">
         <widget class="QCommandLinkButton" name="m_ExtractFibersButton">
          <property name="enabled">
           <bool>false</bool>
          </property>
          <property name="sizePolicy">
           <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="maximumSize">
           <size>
            <width>200</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="font">
           <font>
            <pointsize>11</pointsize>
           </font>
          </property>
          <property name="toolTip">
           <string>Extract fibers passing through selected ROI or composite ROI. Select ROI and fiber bundle to execute.</string>
          </property>
          <property name="text">
           <string>Extract</string>
          </property>
         </widget>
        </item>
        <item row="0" column="0">
         <widget class="QComboBox" name="m_ExtractionMethodBox">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <item>
           <property name="text">
            <string>Extract using planar figures</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Extract using ROI image</string>
           </property>
          </item>
         </widget>
        </item>
        <item row="3" column="0">
         <widget class="QFrame" name="m_ExtactionFramePF">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_8">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <property name="spacing">
            <number>6</number>
           </property>
           <item row="3" column="0">
            <widget class="QCheckBox" name="m_InteractiveBox">
             <property name="text">
-             <string>Interactive Extraction </string>
+             <string>Interactive Extraction</string>
             </property>
            </widget>
           </item>
           <item row="0" column="0">
            <widget class="QFrame" name="m_PlanarFigureButtonsFrame">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
             <property name="minimumSize">
              <size>
               <width>200</width>
               <height>0</height>
              </size>
             </property>
             <property name="maximumSize">
              <size>
               <width>16777215</width>
               <height>60</height>
              </size>
             </property>
             <property name="frameShape">
              <enum>QFrame::NoFrame</enum>
             </property>
             <property name="frameShadow">
              <enum>QFrame::Raised</enum>
             </property>
             <layout class="QGridLayout" name="gridLayout">
              <property name="leftMargin">
               <number>0</number>
              </property>
              <property name="topMargin">
               <number>0</number>
              </property>
              <property name="rightMargin">
               <number>0</number>
              </property>
              <property name="bottomMargin">
               <number>0</number>
              </property>
              <item row="0" column="0">
               <widget class="QPushButton" name="m_CircleButton">
                <property name="maximumSize">
                 <size>
                  <width>30</width>
                  <height>30</height>
                 </size>
                </property>
                <property name="toolTip">
                 <string>Draw circular ROI. Select reference fiber bundle to execute.</string>
                </property>
                <property name="text">
                 <string/>
                </property>
                <property name="icon">
                 <iconset resource="../../../../../release/MITK-build/private_plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/org_mitk_gui_qt_diffusionimaging_fiberprocessing_cached.qrc">
                  <normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/circle.png</normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/circle.png</iconset>
                </property>
                <property name="iconSize">
                 <size>
                  <width>32</width>
                  <height>32</height>
                 </size>
                </property>
                <property name="checkable">
                 <bool>false</bool>
                </property>
                <property name="flat">
                 <bool>true</bool>
                </property>
               </widget>
              </item>
              <item row="0" column="2">
               <spacer name="horizontalSpacer">
                <property name="orientation">
                 <enum>Qt::Horizontal</enum>
                </property>
                <property name="sizeHint" stdset="0">
                 <size>
                  <width>40</width>
                  <height>20</height>
                 </size>
                </property>
               </spacer>
              </item>
              <item row="0" column="1">
               <widget class="QPushButton" name="m_PolygonButton">
                <property name="maximumSize">
                 <size>
                  <width>30</width>
                  <height>30</height>
                 </size>
                </property>
                <property name="toolTip">
                 <string>Draw polygonal ROI. Select reference fiber bundle to execute.</string>
                </property>
                <property name="text">
                 <string/>
                </property>
                <property name="icon">
                 <iconset resource="../../../../../release/MITK-build/private_plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/org_mitk_gui_qt_diffusionimaging_fiberprocessing_cached.qrc">
                  <normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/polygon.png</normaloff>:/org.mitk.gui.qt.diffusionimaging.fiberprocessing/resources/polygon.png</iconset>
                </property>
                <property name="iconSize">
                 <size>
                  <width>32</width>
                  <height>32</height>
                 </size>
                </property>
                <property name="checkable">
                 <bool>true</bool>
                </property>
                <property name="flat">
                 <bool>true</bool>
                </property>
               </widget>
              </item>
             </layout>
            </widget>
           </item>
           <item row="1" column="0">
            <widget class="QFrame" name="m_PlanarFigureButtonsFrame_2">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
             <property name="minimumSize">
              <size>
               <width>200</width>
               <height>0</height>
              </size>
             </property>
             <property name="maximumSize">
              <size>
               <width>16777215</width>
               <height>60</height>
              </size>
             </property>
             <property name="frameShape">
              <enum>QFrame::NoFrame</enum>
             </property>
             <property name="frameShadow">
              <enum>QFrame::Raised</enum>
             </property>
             <layout class="QGridLayout" name="gridLayout_5">
              <property name="leftMargin">
               <number>0</number>
              </property>
              <property name="topMargin">
               <number>0</number>
              </property>
              <property name="rightMargin">
               <number>0</number>
              </property>
              <property name="bottomMargin">
               <number>0</number>
              </property>
              <item row="0" column="2">
               <widget class="QCommandLinkButton" name="PFCompoNOTButton">
                <property name="enabled">
                 <bool>false</bool>
                </property>
                <property name="maximumSize">
                 <size>
                  <width>60</width>
                  <height>16777215</height>
                 </size>
                </property>
                <property name="toolTip">
                 <string>Create NOT composition from selected ROI.</string>
                </property>
                <property name="text">
                 <string>NOT</string>
                </property>
               </widget>
              </item>
              <item row="0" column="1">
               <widget class="QCommandLinkButton" name="PFCompoORButton">
                <property name="enabled">
                 <bool>false</bool>
                </property>
                <property name="maximumSize">
                 <size>
                  <width>60</width>
                  <height>16777215</height>
                 </size>
                </property>
                <property name="toolTip">
                 <string>Create OR composition with selected ROIs.</string>
                </property>
                <property name="text">
                 <string>OR</string>
                </property>
               </widget>
              </item>
              <item row="0" column="3">
               <spacer name="horizontalSpacer_3">
                <property name="orientation">
                 <enum>Qt::Horizontal</enum>
                </property>
                <property name="sizeHint" stdset="0">
                 <size>
                  <width>40</width>
                  <height>20</height>
                 </size>
                </property>
               </spacer>
              </item>
              <item row="0" column="0">
               <widget class="QCommandLinkButton" name="PFCompoANDButton">
                <property name="enabled">
                 <bool>false</bool>
                </property>
                <property name="maximumSize">
                 <size>
                  <width>60</width>
                  <height>16777215</height>
                 </size>
                </property>
                <property name="toolTip">
                 <string>Create AND composition with selected ROIs.</string>
                </property>
                <property name="text">
                 <string>AND</string>
                </property>
               </widget>
              </item>
             </layout>
            </widget>
           </item>
           <item row="2" column="0">
            <widget class="QCommandLinkButton" name="m_GenerateRoiImage">
             <property name="enabled">
              <bool>false</bool>
             </property>
             <property name="sizePolicy">
              <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
             <property name="maximumSize">
              <size>
               <width>16777215</width>
               <height>16777215</height>
              </size>
             </property>
             <property name="font">
              <font>
               <pointsize>11</pointsize>
              </font>
             </property>
             <property name="toolTip">
              <string>Generate a binary image containing all selected ROIs. Select at least one ROI (planar figure) and a reference fiber bundle or image.</string>
             </property>
             <property name="text">
              <string>Generate ROI Image</string>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="page_3">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>353</width>
         <height>456</height>
        </rect>
       </property>
       <attribute name="label">
        <string>Fiber Removal</string>
       </attribute>
       <attribute name="toolTip">
        <string>Remove fibers that satisfy certain criteria from the selected bundle.</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_4">
        <item row="1" column="0">
         <widget class="QFrame" name="m_RemoveDirectionFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_2">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <property name="horizontalSpacing">
            <number>0</number>
           </property>
           <item row="0" column="0">
            <widget class="QLabel" name="label">
             <property name="text">
              <string>X:</string>
             </property>
            </widget>
           </item>
           <item row="1" column="0">
            <widget class="QLabel" name="label_3">
             <property name="text">
              <string>Y:</string>
             </property>
            </widget>
           </item>
           <item row="0" column="1">
            <widget class="QDoubleSpinBox" name="m_ExtractDirX"/>
           </item>
           <item row="1" column="1">
            <widget class="QDoubleSpinBox" name="m_ExtractDirY"/>
           </item>
           <item row="2" column="0">
            <widget class="QLabel" name="label_4">
             <property name="text">
              <string>Z:</string>
             </property>
            </widget>
           </item>
           <item row="2" column="1">
            <widget class="QDoubleSpinBox" name="m_ExtractDirZ"/>
           </item>
           <item row="3" column="0">
            <widget class="QLabel" name="label_5">
             <property name="text">
              <string>Angle:</string>
             </property>
            </widget>
           </item>
           <item row="3" column="1">
            <widget class="QDoubleSpinBox" name="m_ExtractAngle">
             <property name="toolTip">
              <string>Angular deviation threshold in degree</string>
             </property>
             <property name="decimals">
              <number>1</number>
             </property>
             <property name="maximum">
              <double>90.000000000000000</double>
             </property>
             <property name="singleStep">
              <double>1.000000000000000</double>
             </property>
             <property name="value">
              <double>25.000000000000000</double>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="4" column="0">
         <widget class="QFrame" name="m_RemoveByWeightFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_20">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <property name="spacing">
            <number>0</number>
           </property>
           <item row="1" column="0">
            <widget class="QLabel" name="label_18">
             <property name="text">
              <string>Weight threshold:</string>
             </property>
            </widget>
           </item>
           <item row="1" column="1">
            <widget class="QDoubleSpinBox" name="m_WeightThresholdBox">
             <property name="toolTip">
              <string>Only fibers with weight larger than this threshold are kept.</string>
             </property>
             <property name="decimals">
              <number>5</number>
             </property>
             <property name="maximum">
              <double>99999.000000000000000</double>
             </property>
             <property name="singleStep">
              <double>0.100000000000000</double>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="6" column="0">
         <widget class="QCommandLinkButton" name="m_RemoveButton">
          <property name="enabled">
           <bool>false</bool>
          </property>
          <property name="sizePolicy">
           <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="maximumSize">
           <size>
            <width>200</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="font">
           <font>
            <pointsize>11</pointsize>
           </font>
          </property>
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Remove</string>
          </property>
         </widget>
        </item>
        <item row="0" column="0">
         <widget class="QComboBox" name="m_RemovalMethodBox">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <item>
           <property name="text">
            <string>Remove fibers in direction</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Remove fibers by length</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Remove fibers by curvature</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Remove fiber parts outside mask</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Remove fiber parts inside mask</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Remove fibers by weight</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Remove fibers by tract density</string>
           </property>
          </item>
         </widget>
        </item>
        <item row="3" column="0">
         <widget class="QFrame" name="m_RemoveCurvatureFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_11">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <item row="2" column="2">
            <widget class="QCheckBox" name="m_RemoveCurvedFibersBox">
             <property name="toolTip">
              <string>If unchecked, the fiber exceeding the threshold will be split in two instead of removed.</string>
             </property>
             <property name="text">
              <string>Remove Fiber</string>
             </property>
             <property name="checked">
              <bool>false</bool>
             </property>
            </widget>
           </item>
           <item row="1" column="2">
            <widget class="QFrame" name="frame">
             <property name="frameShape">
              <enum>QFrame::NoFrame</enum>
             </property>
             <property name="frameShadow">
              <enum>QFrame::Raised</enum>
             </property>
             <layout class="QGridLayout" name="gridLayout_12">
              <property name="leftMargin">
               <number>0</number>
              </property>
              <property name="topMargin">
               <number>0</number>
              </property>
              <property name="rightMargin">
               <number>0</number>
              </property>
              <property name="bottomMargin">
               <number>0</number>
              </property>
              <property name="verticalSpacing">
               <number>0</number>
              </property>
              <item row="0" column="0">
               <widget class="QLabel" name="label_8">
                <property name="text">
                 <string>Max. Angular Deviation:</string>
                </property>
               </widget>
              </item>
              <item row="0" column="2">
               <spacer name="horizontalSpacer_5">
                <property name="orientation">
                 <enum>Qt::Horizontal</enum>
                </property>
                <property name="sizeHint" stdset="0">
                 <size>
                  <width>40</width>
                  <height>20</height>
                 </size>
                </property>
               </spacer>
              </item>
              <item row="0" column="1">
               <widget class="QDoubleSpinBox" name="m_CurvSpinBox">
                <property name="toolTip">
                 <string>Maximum angular deviation in degree</string>
                </property>
                <property name="maximum">
                 <double>180.000000000000000</double>
                </property>
                <property name="singleStep">
                 <double>0.100000000000000</double>
                </property>
                <property name="value">
                 <double>30.000000000000000</double>
                </property>
               </widget>
              </item>
              <item row="1" column="0">
               <widget class="QLabel" name="label_14">
                <property name="text">
                 <string>Distance:</string>
                </property>
               </widget>
              </item>
              <item row="1" column="1">
               <widget class="QDoubleSpinBox" name="m_CurvDistanceSpinBox">
                <property name="toolTip">
                 <string>Distance in mm</string>
                </property>
                <property name="decimals">
                 <number>1</number>
                </property>
                <property name="maximum">
                 <double>999.000000000000000</double>
                </property>
                <property name="singleStep">
                 <double>1.000000000000000</double>
                </property>
                <property name="value">
                 <double>10.000000000000000</double>
                </property>
               </widget>
              </item>
             </layout>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="7" column="0">
         <spacer name="verticalSpacer_4">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
        <item row="2" column="0">
         <widget class="QFrame" name="m_RemoveLengthFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_6">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <item row="0" column="2">
            <spacer name="horizontalSpacer_4">
             <property name="orientation">
              <enum>Qt::Horizontal</enum>
             </property>
             <property name="sizeHint" stdset="0">
              <size>
               <width>40</width>
               <height>20</height>
              </size>
             </property>
            </spacer>
           </item>
           <item row="0" column="1">
            <widget class="QSpinBox" name="m_PruneFibersMinBox">
             <property name="toolTip">
              <string>Minimum fiber length in mm</string>
             </property>
             <property name="minimum">
              <number>0</number>
             </property>
             <property name="maximum">
              <number>999999999</number>
             </property>
             <property name="value">
              <number>20</number>
             </property>
            </widget>
           </item>
           <item row="1" column="0">
            <widget class="QLabel" name="label_9">
             <property name="text">
              <string>Max. Length:</string>
             </property>
            </widget>
           </item>
           <item row="0" column="0">
            <widget class="QLabel" name="label_7">
             <property name="text">
              <string>Min. Length:</string>
             </property>
            </widget>
           </item>
           <item row="1" column="1">
            <widget class="QSpinBox" name="m_PruneFibersMaxBox">
             <property name="toolTip">
              <string>Maximum fiber length in mm</string>
             </property>
             <property name="minimum">
              <number>0</number>
             </property>
             <property name="maximum">
              <number>999999999</number>
             </property>
             <property name="value">
              <number>300</number>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="5" column="0">
         <widget class="QFrame" name="m_RemoveByDensityFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_21">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <property name="horizontalSpacing">
            <number>0</number>
           </property>
           <property name="verticalSpacing">
            <number>6</number>
           </property>
           <item row="1" column="1">
            <widget class="QDoubleSpinBox" name="m_DensityThresholdBox">
             <property name="toolTip">
-             <string/>
+             <string>Relative tract density (value between 0.0 and 1.0)</string>
             </property>
             <property name="decimals">
              <number>5</number>
             </property>
             <property name="minimum">
              <double>0.000000000000000</double>
             </property>
             <property name="maximum">
-             <double>10.000000000000000</double>
+             <double>1.000000000000000</double>
             </property>
             <property name="singleStep">
              <double>0.100000000000000</double>
             </property>
             <property name="value">
-             <double>0.010000000000000</double>
+             <double>0.050000000000000</double>
             </property>
            </widget>
           </item>
           <item row="1" column="0">
            <widget class="QLabel" name="label_19">
             <property name="text">
              <string>Density threshold:</string>
             </property>
            </widget>
           </item>
           <item row="2" column="0">
            <widget class="QLabel" name="label_21">
             <property name="text">
              <string>Min. overlap:</string>
             </property>
            </widget>
           </item>
           <item row="2" column="1">
            <widget class="QDoubleSpinBox" name="m_DensityOverlapBox">
             <property name="toolTip">
              <string>Tracts have to spend at least this fraction of their length inside the specified density region.</string>
             </property>
             <property name="decimals">
              <number>3</number>
             </property>
             <property name="maximum">
              <double>1.000000000000000</double>
             </property>
             <property name="singleStep">
              <double>0.100000000000000</double>
             </property>
             <property name="value">
              <double>0.500000000000000</double>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="page_4">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>353</width>
         <height>426</height>
        </rect>
       </property>
       <attribute name="label">
        <string>Bundle Modification</string>
       </attribute>
       <attribute name="toolTip">
        <string>Modify the selected bundle with operations such as fiber resampling, FA coloring, etc.</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_10">
        <item row="2" column="0">
         <widget class="QFrame" name="m_CompressFibersFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_15">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <property name="horizontalSpacing">
            <number>0</number>
           </property>
           <property name="verticalSpacing">
            <number>6</number>
           </property>
           <item row="0" column="0">
            <widget class="QLabel" name="label_10">
             <property name="text">
              <string>Error threshold in mm:</string>
             </property>
            </widget>
           </item>
           <item row="1" column="0">
            <widget class="QDoubleSpinBox" name="m_ErrorThresholdBox">
             <property name="maximum">
              <double>999999999.000000000000000</double>
             </property>
             <property name="singleStep">
              <double>0.100000000000000</double>
             </property>
             <property name="value">
              <double>0.100000000000000</double>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="4" column="0">
         <widget class="QFrame" name="m_MirrorFibersFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_17">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <property name="horizontalSpacing">
            <number>0</number>
           </property>
           <property name="verticalSpacing">
            <number>6</number>
           </property>
           <item row="1" column="0">
            <widget class="QComboBox" name="m_MirrorFibersBox">
             <item>
              <property name="text">
               <string>Sagittal</string>
              </property>
             </item>
             <item>
              <property name="text">
               <string>Coronal</string>
              </property>
             </item>
             <item>
              <property name="text">
               <string>Axial</string>
              </property>
             </item>
            </widget>
           </item>
           <item row="0" column="0">
            <widget class="QLabel" name="label_13">
             <property name="text">
              <string>Select direction:</string>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="3" column="0">
         <widget class="QFrame" name="m_ColorFibersFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_16">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <property name="horizontalSpacing">
            <number>0</number>
           </property>
           <property name="verticalSpacing">
            <number>6</number>
           </property>
           <item row="0" column="0">
            <widget class="QLabel" name="label_12">
             <property name="text">
              <string>Scalar map:</string>
             </property>
            </widget>
           </item>
           <item row="1" column="0">
            <widget class="QCheckBox" name="m_FiberOpacityBox">
             <property name="toolTip">
              <string>If checked, the image values are not only used to color the fibers but are also used as opaxity values.</string>
             </property>
             <property name="text">
              <string>Values as opacity</string>
             </property>
             <property name="checked">
              <bool>false</bool>
             </property>
            </widget>
           </item>
           <item row="3" column="0">
            <widget class="QCheckBox" name="m_NormalizeColorValues">
             <property name="toolTip">
              <string>The values used to color the fibers are min-max normalized. If not checked, the values should be between 0 and 1.</string>
             </property>
             <property name="text">
              <string>Normalize color values</string>
             </property>
             <property name="checked">
              <bool>true</bool>
             </property>
            </widget>
           </item>
           <item row="4" column="0">
            <widget class="QmitkDataStorageComboBox" name="m_ColorMapBox"/>
           </item>
           <item row="2" column="0">
            <widget class="QCheckBox" name="m_ValueAsWeightBox">
             <property name="toolTip">
              <string>If checked, the (mean) unnormalized values per fiber are also used as fiber weights, e.g. the fiber length in mm.</string>
             </property>
             <property name="text">
              <string>Values as weight</string>
             </property>
             <property name="checked">
              <bool>false</bool>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="0" column="0">
         <widget class="QComboBox" name="m_ModificationMethodBox">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <item>
           <property name="text">
            <string>Resample fibers (spline)</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Resample fibers (linear)</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Compress fibers</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Mirror fibers</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Weight bundle</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Color fibers by fiber weights</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Color &amp; weight fibers by curvature</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Color &amp; weight fibers by length</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Color &amp; weight fibers by scalar map (e.g. FA)</string>
           </property>
          </item>
         </widget>
        </item>
        <item row="1" column="0">
         <widget class="QFrame" name="m_SmoothFibersFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_7">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <property name="horizontalSpacing">
            <number>0</number>
           </property>
           <property name="verticalSpacing">
            <number>6</number>
           </property>
           <item row="1" column="0">
            <widget class="QDoubleSpinBox" name="m_SmoothFibersBox">
             <property name="minimum">
              <double>0.010000000000000</double>
             </property>
             <property name="maximum">
              <double>999999999.000000000000000</double>
             </property>
             <property name="singleStep">
              <double>0.100000000000000</double>
             </property>
             <property name="value">
              <double>1.000000000000000</double>
             </property>
            </widget>
           </item>
           <item row="0" column="0">
            <widget class="QLabel" name="label_11">
             <property name="text">
              <string>Point distance in mm:</string>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="7" column="0">
         <spacer name="verticalSpacer_3">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
        <item row="6" column="0">
         <widget class="QCommandLinkButton" name="m_ModifyButton">
          <property name="enabled">
           <bool>false</bool>
          </property>
          <property name="sizePolicy">
           <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="maximumSize">
           <size>
            <width>200</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="font">
           <font>
            <pointsize>11</pointsize>
           </font>
          </property>
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Execute</string>
          </property>
         </widget>
        </item>
        <item row="5" column="0">
         <widget class="QFrame" name="m_BundleWeightFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_18">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <property name="spacing">
            <number>0</number>
           </property>
           <item row="0" column="0">
            <widget class="QLabel" name="label_15">
             <property name="text">
              <string>Weight:</string>
             </property>
            </widget>
           </item>
           <item row="0" column="1">
            <widget class="QDoubleSpinBox" name="m_BundleWeightBox">
             <property name="decimals">
              <number>7</number>
             </property>
             <property name="maximum">
              <double>999999999.000000000000000</double>
             </property>
             <property name="singleStep">
              <double>0.100000000000000</double>
             </property>
             <property name="value">
              <double>1.000000000000000</double>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="page_2">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>367</width>
         <height>182</height>
        </rect>
       </property>
       <attribute name="label">
        <string>Bundle Operations</string>
       </attribute>
       <attribute name="toolTip">
        <string>Join, subtract or copy bundles.</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_13">
        <item row="0" column="0">
         <widget class="QCommandLinkButton" name="m_SubstractBundles">
          <property name="enabled">
           <bool>false</bool>
          </property>
          <property name="sizePolicy">
           <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="maximumSize">
           <size>
            <width>200</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="font">
           <font>
            <pointsize>11</pointsize>
           </font>
          </property>
          <property name="toolTip">
           <string>Returns all fibers contained in bundle X that are not contained in bundle Y (not commutative!). Select at least two fiber bundles to execute.</string>
          </property>
          <property name="text">
           <string>Substract</string>
          </property>
         </widget>
        </item>
        <item row="2" column="0">
         <spacer name="verticalSpacer_2">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
        <item row="0" column="2">
         <widget class="QCommandLinkButton" name="m_JoinBundles">
          <property name="enabled">
           <bool>false</bool>
          </property>
          <property name="sizePolicy">
           <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="maximumSize">
           <size>
            <width>200</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="font">
           <font>
            <pointsize>11</pointsize>
           </font>
          </property>
          <property name="toolTip">
           <string>Merge selected fiber bundles. Select at least two fiber bundles to execute.</string>
          </property>
          <property name="text">
           <string>Join</string>
          </property>
         </widget>
        </item>
        <item row="1" column="0">
         <widget class="QCommandLinkButton" name="m_CopyBundle">
          <property name="enabled">
           <bool>false</bool>
          </property>
          <property name="sizePolicy">
           <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="maximumSize">
           <size>
            <width>200</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="font">
           <font>
            <pointsize>11</pointsize>
           </font>
          </property>
          <property name="toolTip">
           <string>Merge selected fiber bundles. Select at least two fiber bundles to execute.</string>
          </property>
          <property name="text">
           <string>Copy</string>
          </property>
         </widget>
        </item>
       </layout>
      </widget>
     </widget>
    </item>
    <item row="0" column="0">
     <widget class="QGroupBox" name="m_InputData">
      <property name="title">
       <string>Please Select Input Data</string>
      </property>
      <layout class="QGridLayout" name="gridLayout_9">
       <property name="leftMargin">
        <number>6</number>
       </property>
       <property name="topMargin">
        <number>6</number>
       </property>
       <property name="rightMargin">
        <number>6</number>
       </property>
       <property name="bottomMargin">
        <number>6</number>
       </property>
       <item row="0" column="1">
        <widget class="QLabel" name="m_FibLabel">
         <property name="text">
          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#ff0000;&quot;&gt;mandatory&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
         </property>
         <property name="wordWrap">
          <bool>true</bool>
         </property>
        </widget>
       </item>
       <item row="1" column="1">
        <widget class="QLabel" name="m_PfLabel">
         <property name="text">
          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#969696;&quot;&gt;needed for extraction&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
         </property>
         <property name="wordWrap">
          <bool>true</bool>
         </property>
        </widget>
       </item>
       <item row="0" column="0">
        <widget class="QLabel" name="label_2">
         <property name="toolTip">
          <string>Input DTI</string>
         </property>
         <property name="text">
          <string>Fiber Bundle:</string>
         </property>
        </widget>
       </item>
       <item row="1" column="0">
        <widget class="QLabel" name="label_6">
         <property name="toolTip">
          <string>Binary seed ROI. If not specified, the whole image area is seeded.</string>
         </property>
         <property name="text">
          <string>ROI:</string>
         </property>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
    <item row="3" column="0">
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>40</height>
       </size>
      </property>
     </spacer>
    </item>
   </layout>
  </widget>
  <customwidgets>
   <customwidget>
    <class>QmitkDataStorageComboBox</class>
    <extends>QComboBox</extends>
    <header location="global">QmitkDataStorageComboBox.h</header>
   </customwidget>
  </customwidgets>
  <resources>
   <include location="../../../../../release/MITK-build/private_plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/org_mitk_gui_qt_diffusionimaging_fiberprocessing_cached.qrc"/>
  </resources>
  <connections/>
 </ui>
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationView.cpp
index 1c622f4..88a9f88 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationView.cpp
@@ -1,461 +1,539 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 
 // Blueberry
 #include <berryISelectionService.h>
 #include <berryIWorkbenchWindow.h>
 
 // Qmitk
 #include "QmitkFiberQuantificationView.h"
 
 // Qt
 #include <QMessageBox>
 
 // MITK
 #include <mitkNodePredicateDataType.h>
 #include <mitkNodePredicateDimension.h>
 #include <mitkNodePredicateAnd.h>
 #include <mitkImageCast.h>
 #include <mitkPeakImage.h>
 #include <mitkLabelSetImage.h>
 #include <mitkDICOMSegmentationConstants.h>
 #include <mitkDICOMSegmentationPropertyHelper.cpp>
 #include <mitkDICOMQIPropertyHelper.h>
 
 // ITK
 #include <itkTractDensityImageFilter.h>
 #include <itkTractsToRgbaImageFilter.h>
 #include <itkTractsToVectorImageFilter.h>
 #include <itkTractsToFiberEndingsImageFilter.h>
+#include <itkSignedMaurerDistanceMapImageFilter.h>
+#include <itkBinaryThinningImageFilter.h>
 
 #include <mitkLexicalCast.h>
 
 const std::string QmitkFiberQuantificationView::VIEW_ID = "org.mitk.views.fiberquantification";
 using namespace mitk;
 
 QmitkFiberQuantificationView::QmitkFiberQuantificationView()
   : QmitkAbstractView()
   , m_Controls( 0 )
   , m_UpsamplingFactor(5)
   , m_Visible(false)
 {
 
 }
 
 // Destructor
 QmitkFiberQuantificationView::~QmitkFiberQuantificationView()
 {
 
 }
 
 void QmitkFiberQuantificationView::CreateQtPartControl( QWidget *parent )
 {
   // build up qt view, unless already done
   if ( !m_Controls )
   {
     // create GUI widgets from the Qt Designer's .ui file
     m_Controls = new Ui::QmitkFiberQuantificationViewControls;
     m_Controls->setupUi( parent );
 
     connect( m_Controls->m_ProcessFiberBundleButton, SIGNAL(clicked()), this, SLOT(ProcessSelectedBundles()) );
     connect( m_Controls->m_ExtractFiberPeaks, SIGNAL(clicked()), this, SLOT(CalculateFiberDirections()) );
 
     m_Controls->m_TractBox->SetDataStorage(this->GetDataStorage());
     mitk::TNodePredicateDataType<mitk::FiberBundle>::Pointer isFib = mitk::TNodePredicateDataType<mitk::FiberBundle>::New();
     m_Controls->m_TractBox->SetPredicate( isFib );
 
     m_Controls->m_ImageBox->SetDataStorage(this->GetDataStorage());
     m_Controls->m_ImageBox->SetZeroEntryText("--");
     mitk::TNodePredicateDataType<mitk::Image>::Pointer isImagePredicate = mitk::TNodePredicateDataType<mitk::Image>::New();
     mitk::NodePredicateDimension::Pointer is3D = mitk::NodePredicateDimension::New(3);
     m_Controls->m_ImageBox->SetPredicate( mitk::NodePredicateAnd::New(isImagePredicate, is3D) );
 
     connect( (QObject*)(m_Controls->m_TractBox), SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()));
     connect( (QObject*)(m_Controls->m_ImageBox), SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()));
   }
 }
 
 void QmitkFiberQuantificationView::Activated()
 {
 
 }
 
 void QmitkFiberQuantificationView::Deactivated()
 {
 
 }
 
 void QmitkFiberQuantificationView::Visible()
 {
   m_Visible = true;
 }
 
 void QmitkFiberQuantificationView::Hidden()
 {
   m_Visible = false;
 }
 
 void QmitkFiberQuantificationView::SetFocus()
 {
   m_Controls->m_ProcessFiberBundleButton->setFocus();
 }
 
 void QmitkFiberQuantificationView::CalculateFiberDirections()
 {
   typedef itk::Image<unsigned char, 3>                                            ItkUcharImgType;
 
   // load fiber bundle
   mitk::FiberBundle::Pointer inputTractogram = dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.back()->GetData());
 
   itk::TractsToVectorImageFilter<float>::Pointer fOdfFilter = itk::TractsToVectorImageFilter<float>::New();
   if (m_SelectedImage.IsNotNull())
   {
     ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New();
     mitk::CastToItkImage<ItkUcharImgType>(m_SelectedImage, itkMaskImage);
     fOdfFilter->SetMaskImage(itkMaskImage);
   }
 
   // extract directions from fiber bundle
   fOdfFilter->SetFiberBundle(inputTractogram);
   fOdfFilter->SetAngularThreshold(cos(m_Controls->m_AngularThreshold->value()*itk::Math::pi/180));
   switch (m_Controls->m_FiberDirNormBox->currentIndex())
   {
   case 0:
     fOdfFilter->SetNormalizationMethod(itk::TractsToVectorImageFilter<float>::NormalizationMethods::GLOBAL_MAX);
     break;
   case 1:
     fOdfFilter->SetNormalizationMethod(itk::TractsToVectorImageFilter<float>::NormalizationMethods::SINGLE_VEC_NORM);
     break;
   case 2:
     fOdfFilter->SetNormalizationMethod(itk::TractsToVectorImageFilter<float>::NormalizationMethods::MAX_VEC_NORM);
     break;
   }
   fOdfFilter->SetSizeThreshold(m_Controls->m_PeakThreshold->value());
   fOdfFilter->SetMaxNumDirections(m_Controls->m_MaxNumDirections->value());
   fOdfFilter->Update();
 
   QString name = m_SelectedFB.back()->GetName().c_str();
 
   if (m_Controls->m_NumDirectionsBox->isChecked())
   {
     mitk::Image::Pointer mitkImage = mitk::Image::New();
     mitkImage->InitializeByItk( fOdfFilter->GetNumDirectionsImage().GetPointer() );
     mitkImage->SetVolume( fOdfFilter->GetNumDirectionsImage()->GetBufferPointer() );
 
     mitk::DataNode::Pointer node = mitk::DataNode::New();
     node->SetData(mitkImage);
     node->SetName((name+"_NUM_DIRECTIONS").toStdString().c_str());
     GetDataStorage()->Add(node, m_SelectedFB.back());
   }
 
   Image::Pointer mitkImage = dynamic_cast<Image*>(PeakImage::New().GetPointer());
   mitk::CastToMitkImage(fOdfFilter->GetDirectionImage(), mitkImage);
   mitkImage->SetVolume(fOdfFilter->GetDirectionImage()->GetBufferPointer());
 
   mitk::DataNode::Pointer node = mitk::DataNode::New();
   node->SetData(mitkImage);
   node->SetName( (name+"_DIRECTIONS").toStdString().c_str());
   GetDataStorage()->Add(node, m_SelectedFB.back());
 }
 
 void QmitkFiberQuantificationView::UpdateGui()
 {
   m_SelectedFB.clear();
   if (m_Controls->m_TractBox->GetSelectedNode().IsNotNull())
     m_SelectedFB.push_back(m_Controls->m_TractBox->GetSelectedNode());
 
   m_SelectedImage = nullptr;
   if (m_Controls->m_ImageBox->GetSelectedNode().IsNotNull())
     m_SelectedImage = dynamic_cast<mitk::Image*>(m_Controls->m_ImageBox->GetSelectedNode()->GetData());
 
   m_Controls->m_ProcessFiberBundleButton->setEnabled(!m_SelectedFB.empty());
   m_Controls->m_ExtractFiberPeaks->setEnabled(!m_SelectedFB.empty());
 }
 
 void QmitkFiberQuantificationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList<mitk::DataNode::Pointer>& )
 {
   UpdateGui();
 }
 
 void QmitkFiberQuantificationView::ProcessSelectedBundles()
 {
   if ( m_SelectedFB.empty() ){
     QMessageBox::information( nullptr, "Warning", "No fibe bundle selected!");
     MITK_WARN("QmitkFiberQuantificationView") << "no fibe bundle selected";
     return;
   }
 
   int generationMethod = m_Controls->m_GenerationBox->currentIndex();
 
   for( unsigned int i=0; i<m_SelectedFB.size(); i++ )
   {
     mitk::DataNode::Pointer node = m_SelectedFB[i];
     if (node.IsNotNull() && dynamic_cast<mitk::FiberBundle*>(node->GetData()))
     {
       mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
       QString name(node->GetName().c_str());
       DataNode::Pointer newNode = nullptr;
       switch(generationMethod){
       case 0:
         newNode = GenerateTractDensityImage(fib, false, true, node->GetName());
         name += "_TDI";
         break;
       case 1:
         newNode = GenerateTractDensityImage(fib, false, false, node->GetName());
         name += "_TDI";
         break;
       case 2:
         newNode = GenerateTractDensityImage(fib, true, false, node->GetName());
         name += "_envelope";
         break;
       case 3:
         newNode = GenerateColorHeatmap(fib);
         break;
       case 4:
         newNode = GenerateFiberEndingsImage(fib);
         name += "_fiber_endings";
         break;
       case 5:
         newNode = GenerateFiberEndingsPointSet(fib);
         name += "_fiber_endings";
         break;
+      case 6:
+        newNode = GenerateDistanceMap(fib);
+        name += "_distance_map";
+        break;
+      case 7:
+        newNode = GenerateBinarySkeleton(fib);
+        name += "_skeleton";
+        break;
       }
       if (newNode.IsNotNull())
       {
         newNode->SetName(name.toStdString());
         GetDataStorage()->Add(newNode);
       }
     }
   }
 }
 
 // generate pointset displaying the fiber endings
 mitk::DataNode::Pointer QmitkFiberQuantificationView::GenerateFiberEndingsPointSet(mitk::FiberBundle::Pointer fib)
 {
   mitk::PointSet::Pointer pointSet = mitk::PointSet::New();
   vtkSmartPointer<vtkPolyData> fiberPolyData = fib->GetFiberPolyData();
 
   int count = 0;
   int numFibers = fib->GetNumFibers();
   for( int i=0; i<numFibers; i++ )
   {
     vtkCell* cell = fiberPolyData->GetCell(i);
     int numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     if (numPoints>0)
     {
       double* point = points->GetPoint(0);
       itk::Point<float,3> itkPoint = mitk::imv::GetItkPoint(point);
       pointSet->InsertPoint(count, itkPoint);
       count++;
     }
     if (numPoints>2)
     {
       double* point = points->GetPoint(numPoints-1);
       itk::Point<float,3> itkPoint = mitk::imv::GetItkPoint(point);
       pointSet->InsertPoint(count, itkPoint);
       count++;
     }
   }
 
   mitk::DataNode::Pointer node = mitk::DataNode::New();
   node->SetData( pointSet );
   return node;
 }
 
 // generate image displaying the fiber endings
 mitk::DataNode::Pointer QmitkFiberQuantificationView::GenerateFiberEndingsImage(mitk::FiberBundle::Pointer fib)
 {
   typedef unsigned int OutPixType;
   typedef itk::Image<OutPixType,3> OutImageType;
 
   typedef itk::TractsToFiberEndingsImageFilter< OutImageType > ImageGeneratorType;
   ImageGeneratorType::Pointer generator = ImageGeneratorType::New();
   generator->SetFiberBundle(fib);
   generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value());
   if (m_SelectedImage.IsNotNull())
   {
     OutImageType::Pointer itkImage = OutImageType::New();
     CastToItkImage(m_SelectedImage, itkImage);
     generator->SetInputImage(itkImage);
     generator->SetUseImageGeometry(true);
   }
   generator->Update();
 
   // get output image
   OutImageType::Pointer outImg = generator->GetOutput();
   mitk::Image::Pointer img = mitk::Image::New();
   img->InitializeByItk(outImg.GetPointer());
   img->SetVolume(outImg->GetBufferPointer());
 
   // init data node
   mitk::DataNode::Pointer node = mitk::DataNode::New();
   node->SetData(img);
   return node;
 }
 
 // generate rgba heatmap from fiber bundle
 mitk::DataNode::Pointer QmitkFiberQuantificationView::GenerateColorHeatmap(mitk::FiberBundle::Pointer fib)
 {
   typedef itk::RGBAPixel<unsigned char> OutPixType;
   typedef itk::Image<OutPixType, 3> OutImageType;
   typedef itk::TractsToRgbaImageFilter< OutImageType > ImageGeneratorType;
   ImageGeneratorType::Pointer generator = ImageGeneratorType::New();
   generator->SetFiberBundle(fib);
   generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value());
   if (m_SelectedImage.IsNotNull())
   {
     itk::Image<unsigned char, 3>::Pointer itkImage = itk::Image<unsigned char, 3>::New();
     CastToItkImage(m_SelectedImage, itkImage);
     generator->SetInputImage(itkImage);
     generator->SetUseImageGeometry(true);
   }
   generator->Update();
 
   // get output image
   typedef itk::Image<OutPixType,3> OutType;
   OutType::Pointer outImg = generator->GetOutput();
   mitk::Image::Pointer img = mitk::Image::New();
   img->InitializeByItk(outImg.GetPointer());
   img->SetVolume(outImg->GetBufferPointer());
 
   // init data node
   mitk::DataNode::Pointer node = mitk::DataNode::New();
   node->SetData(img);
   return node;
 }
 
+mitk::DataNode::Pointer QmitkFiberQuantificationView::GenerateBinarySkeleton(mitk::FiberBundle::Pointer fib)
+{
+  typedef itk::Image<unsigned char, 3> UcharImageType;
+
+  itk::TractDensityImageFilter< UcharImageType >::Pointer envelope_generator = itk::TractDensityImageFilter< UcharImageType >::New();
+  envelope_generator->SetFiberBundle(fib);
+  envelope_generator->SetBinaryOutput(true);
+  envelope_generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value());
+  if (m_SelectedImage.IsNotNull())
+  {
+    UcharImageType::Pointer itkImage = UcharImageType::New();
+    CastToItkImage(m_SelectedImage, itkImage);
+    envelope_generator->SetInputImage(itkImage);
+    envelope_generator->SetUseImageGeometry(true);
+
+  }
+  envelope_generator->Update();
+
+  itk::BinaryThinningImageFilter<UcharImageType, UcharImageType>::Pointer map_generator = itk::BinaryThinningImageFilter<UcharImageType, UcharImageType>::New();
+  map_generator->SetInput(envelope_generator->GetOutput());
+  map_generator->Update();
+
+  UcharImageType::Pointer outImg = map_generator->GetOutput();
+  mitk::Image::Pointer img = mitk::Image::New();
+  img->InitializeByItk(outImg.GetPointer());
+  img->SetVolume(outImg->GetBufferPointer());
+
+  mitk::DataNode::Pointer node = mitk::DataNode::New();
+  node->SetData(img);
+  return node;
+}
+
+mitk::DataNode::Pointer QmitkFiberQuantificationView::GenerateDistanceMap(mitk::FiberBundle::Pointer fib)
+{
+  typedef itk::Image<unsigned char, 3> UcharImageType;
+  typedef itk::Image<float, 3> FloatImageType;
+
+  itk::TractDensityImageFilter< UcharImageType >::Pointer envelope_generator = itk::TractDensityImageFilter< UcharImageType >::New();
+  envelope_generator->SetFiberBundle(fib);
+  envelope_generator->SetBinaryOutput(true);
+  envelope_generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value());
+  if (m_SelectedImage.IsNotNull())
+  {
+    UcharImageType::Pointer itkImage = UcharImageType::New();
+    CastToItkImage(m_SelectedImage, itkImage);
+    envelope_generator->SetInputImage(itkImage);
+    envelope_generator->SetUseImageGeometry(true);
+
+  }
+  envelope_generator->Update();
+
+  itk::SignedMaurerDistanceMapImageFilter<UcharImageType, FloatImageType>::Pointer map_generator = itk::SignedMaurerDistanceMapImageFilter<UcharImageType, FloatImageType>::New();
+  map_generator->SetInput(envelope_generator->GetOutput());
+  map_generator->SetUseImageSpacing(true);
+  map_generator->SetSquaredDistance(false);
+  map_generator->SetInsideIsPositive(true);
+  map_generator->Update();
+
+  FloatImageType::Pointer outImg = map_generator->GetOutput();
+  mitk::Image::Pointer img = mitk::Image::New();
+  img->InitializeByItk(outImg.GetPointer());
+  img->SetVolume(outImg->GetBufferPointer());
+
+  mitk::DataNode::Pointer node = mitk::DataNode::New();
+  node->SetData(img);
+  return node;
+}
+
 // generate tract density image from fiber bundle
 mitk::DataNode::Pointer QmitkFiberQuantificationView::GenerateTractDensityImage(mitk::FiberBundle::Pointer fib, bool binary, bool absolute, std::string name)
 {
   mitk::DataNode::Pointer node = mitk::DataNode::New();
   if (binary)
   {
     typedef unsigned char OutPixType;
     typedef itk::Image<OutPixType, 3> OutImageType;
 
     itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New();
     generator->SetFiberBundle(fib);
     generator->SetBinaryOutput(binary);
     generator->SetOutputAbsoluteValues(absolute);
     generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value());
     if (m_SelectedImage.IsNotNull())
     {
       OutImageType::Pointer itkImage = OutImageType::New();
       CastToItkImage(m_SelectedImage, itkImage);
       generator->SetInputImage(itkImage);
       generator->SetUseImageGeometry(true);
 
     }
     generator->Update();
 
     // get output image
     typedef itk::Image<OutPixType,3> OutType;
     OutType::Pointer outImg = generator->GetOutput();
     mitk::Image::Pointer img = mitk::Image::New();
     img->InitializeByItk(outImg.GetPointer());
     img->SetVolume(outImg->GetBufferPointer());
 
 
     if (m_SelectedImage.IsNotNull())
     {
       mitk::LabelSetImage::Pointer multilabelImage = mitk::LabelSetImage::New();
       multilabelImage->InitializeByLabeledImage(img);
       multilabelImage->GetActiveLabelSet()->SetActiveLabel(1);
       mitk::Label::Pointer label = multilabelImage->GetActiveLabel();
       label->SetName("Tractogram");
 
       // Add Segmented Property Category Code Sequence tags (0062, 0003): Sequence defining the general category of this
       // segment.
       // (0008,0100) Code Value
       label->SetProperty(
             DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_VALUE_PATH()).c_str(),
             TemporoSpatialStringProperty::New("T-D000A"));
 
       // (0008,0102) Coding Scheme Designator
       label->SetProperty(
             DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_SCHEME_PATH()).c_str(),
             TemporoSpatialStringProperty::New("SRT"));
 
       // (0008,0104) Code Meaning
       label->SetProperty(
             DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_CATEGORY_CODE_MEANING_PATH()).c_str(),
             TemporoSpatialStringProperty::New("Anatomical Structure"));
       //------------------------------------------------------------
       // Add Segmented Property Type Code Sequence (0062, 000F): Sequence defining the specific property type of this
       // segment.
       // (0008,0100) Code Value
       label->SetProperty(
             DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_VALUE_PATH()).c_str(),
             TemporoSpatialStringProperty::New("DUMMY"));
 
       // (0008,0102) Coding Scheme Designator
       label->SetProperty(
             DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_SCHEME_PATH()).c_str(),
             TemporoSpatialStringProperty::New("SRT"));
 
       // (0008,0104) Code Meaning
       label->SetProperty(
             DICOMTagPathToPropertyName(DICOMSegmentationConstants::SEGMENT_TYPE_CODE_MEANING_PATH()).c_str(),
             TemporoSpatialStringProperty::New(name));
 
       //Error: is undeclared//      mitk::DICOMQIPropertyHandler::DeriveDICOMSourceProperties(m_SelectedImage, multilabelImage);
 
       // init data node
       node->SetData(multilabelImage);
     }
     else
     {
       // init data node
       node->SetData(img);
     }
 
   }
   else
   {
     typedef float OutPixType;
     typedef itk::Image<OutPixType, 3> OutImageType;
 
     itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New();
     generator->SetFiberBundle(fib);
     generator->SetBinaryOutput(binary);
     generator->SetOutputAbsoluteValues(absolute);
     generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value());
     if (m_SelectedImage.IsNotNull())
     {
       OutImageType::Pointer itkImage = OutImageType::New();
       CastToItkImage(m_SelectedImage, itkImage);
       generator->SetInputImage(itkImage);
       generator->SetUseImageGeometry(true);
 
     }
     //generator->SetDoFiberResampling(false);
     generator->Update();
 
     // get output image
     typedef itk::Image<OutPixType,3> OutType;
     OutType::Pointer outImg = generator->GetOutput();
     mitk::Image::Pointer img = mitk::Image::New();
     img->InitializeByItk(outImg.GetPointer());
     img->SetVolume(outImg->GetBufferPointer());
 
     // init data node
     node->SetData(img);
   }
   return node;
 }
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationView.h b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationView.h
index 5fb5380..bb3d808 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationView.h
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationView.h
@@ -1,86 +1,89 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #ifndef QmitkFiberQuantificationView_h
 #define QmitkFiberQuantificationView_h
 
 #include <QmitkAbstractView.h>
 #include "ui_QmitkFiberQuantificationViewControls.h"
 
 #include <mitkFiberBundle.h>
 #include <mitkPointSet.h>
 #include <itkCastImageFilter.h>
 #include <mitkILifecycleAwarePart.h>
 
 /*!
 \brief Generation of images from fiber bundles (TDI, envelopes, endpoint distribution) and extraction of principal fiber directions from tractograms.
 
 */
 class QmitkFiberQuantificationView : public QmitkAbstractView, public mitk::ILifecycleAwarePart
 {
   // this is needed for all Qt objects that should have a Qt meta-object
   // (everything that derives from QObject and wants to have signal/slots)
   Q_OBJECT
 
 public:
 
   typedef itk::Image< unsigned char, 3 >    itkUCharImageType;
 
   static const std::string VIEW_ID;
 
   QmitkFiberQuantificationView();
   virtual ~QmitkFiberQuantificationView();
 
   virtual void CreateQtPartControl(QWidget *parent) override;
 
   ///
   /// Sets the focus to an internal widget.
   ///
   virtual void SetFocus() override;
 
   virtual void Activated() override;
   virtual void Deactivated() override;
   virtual void Visible() override;
   virtual void Hidden() override;
 
 protected slots:
 
   void ProcessSelectedBundles();    ///< start selected operation on fiber bundle (e.g. tract density image generation)
   void CalculateFiberDirections();  ///< Calculate main fiber directions from tractogram
   void UpdateGui();     ///< update button activity etc. dpending on current datamanager selection
 
 protected:
 
   /// \brief called by QmitkAbstractView when DataManager's selection has changed
   virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList<mitk::DataNode::Pointer>& nodes) override;
 
   Ui::QmitkFiberQuantificationViewControls* m_Controls;
 
   std::vector<mitk::DataNode::Pointer>  m_SelectedFB;       ///< selected fiber bundle nodes
   mitk::Image::Pointer                  m_SelectedImage;
   float                                 m_UpsamplingFactor; ///< upsampling factor for all image generations
 
   mitk::DataNode::Pointer GenerateTractDensityImage(mitk::FiberBundle::Pointer fib, bool binary, bool absolute, std::string name);
   mitk::DataNode::Pointer GenerateColorHeatmap(mitk::FiberBundle::Pointer fib);
   mitk::DataNode::Pointer GenerateFiberEndingsImage(mitk::FiberBundle::Pointer fib);
   mitk::DataNode::Pointer GenerateFiberEndingsPointSet(mitk::FiberBundle::Pointer fib);
+  mitk::DataNode::Pointer GenerateDistanceMap(mitk::FiberBundle::Pointer fib);
+  mitk::DataNode::Pointer GenerateBinarySkeleton(mitk::FiberBundle::Pointer fib);
+
   bool  m_Visible;
 };
 
 
 
 #endif // _QMITKFIBERTRACKINGVIEW_H_INCLUDED
 
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationViewControls.ui
index a2cd044..c427969 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationViewControls.ui
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkFiberQuantificationViewControls.ui
@@ -1,420 +1,430 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>QmitkFiberQuantificationViewControls</class>
  <widget class="QWidget" name="QmitkFiberQuantificationViewControls">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>365</width>
     <height>581</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
   <property name="styleSheet">
    <string>QCommandLinkButton:disabled {
   border: none;
 }
 
 QGroupBox {
   background-color: transparent;
 }</string>
   </property>
   <layout class="QGridLayout" name="gridLayout_10">
    <property name="verticalSpacing">
     <number>25</number>
    </property>
    <item row="1" column="0">
     <widget class="QGroupBox" name="groupBox_2">
      <property name="title">
       <string>Fiber-derived images</string>
      </property>
      <layout class="QGridLayout" name="gridLayout_3">
       <property name="leftMargin">
        <number>6</number>
       </property>
       <property name="topMargin">
        <number>6</number>
       </property>
       <property name="rightMargin">
        <number>6</number>
       </property>
       <property name="bottomMargin">
        <number>6</number>
       </property>
       <item row="1" column="0">
        <widget class="QCommandLinkButton" name="m_ProcessFiberBundleButton">
         <property name="enabled">
          <bool>false</bool>
         </property>
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="maximumSize">
          <size>
           <width>200</width>
           <height>16777215</height>
          </size>
         </property>
         <property name="font">
          <font>
           <pointsize>11</pointsize>
          </font>
         </property>
         <property name="toolTip">
          <string>Perform selected operation on all selected fiber bundles.</string>
         </property>
         <property name="text">
          <string>Generate Image</string>
         </property>
        </widget>
       </item>
       <item row="0" column="1">
        <widget class="QDoubleSpinBox" name="m_UpsamplingSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="toolTip">
          <string>Upsampling factor</string>
         </property>
         <property name="decimals">
          <number>1</number>
         </property>
         <property name="minimum">
          <double>0.100000000000000</double>
         </property>
         <property name="maximum">
          <double>10.000000000000000</double>
         </property>
         <property name="singleStep">
          <double>0.100000000000000</double>
         </property>
         <property name="value">
          <double>1.000000000000000</double>
         </property>
        </widget>
       </item>
       <item row="0" column="0">
        <widget class="QComboBox" name="m_GenerationBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <item>
          <property name="text">
           <string>Tract Density Image (TDI)</string>
          </property>
         </item>
         <item>
          <property name="text">
           <string>Normalized TDI</string>
          </property>
         </item>
         <item>
          <property name="text">
           <string>Binary Envelope</string>
          </property>
         </item>
         <item>
          <property name="text">
           <string>Fiber Bundle Image</string>
          </property>
         </item>
         <item>
          <property name="text">
           <string>Fiber Endings Image</string>
          </property>
         </item>
         <item>
          <property name="text">
           <string>Fiber Endings Pointset</string>
          </property>
         </item>
+        <item>
+         <property name="text">
+          <string>Distance Map</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Binary Skeleton</string>
+         </property>
+        </item>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
    <item row="2" column="0">
     <widget class="QGroupBox" name="groupBox_4">
      <property name="title">
       <string>Principal Fiber Directions</string>
      </property>
      <layout class="QGridLayout" name="gridLayout_6">
       <property name="leftMargin">
        <number>6</number>
       </property>
       <property name="topMargin">
        <number>6</number>
       </property>
       <property name="rightMargin">
        <number>6</number>
       </property>
       <property name="bottomMargin">
        <number>6</number>
       </property>
       <item row="0" column="0">
        <widget class="QFrame" name="frame_2">
         <property name="frameShape">
          <enum>QFrame::NoFrame</enum>
         </property>
         <property name="frameShadow">
          <enum>QFrame::Raised</enum>
         </property>
         <layout class="QGridLayout" name="gridLayout_5">
          <property name="leftMargin">
           <number>0</number>
          </property>
          <property name="topMargin">
           <number>0</number>
          </property>
          <property name="rightMargin">
           <number>0</number>
          </property>
          <property name="bottomMargin">
           <number>0</number>
          </property>
          <item row="1" column="1">
           <widget class="QDoubleSpinBox" name="m_AngularThreshold">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <property name="toolTip">
             <string>Fiber directions with an angle smaller than the defined threshold are clustered.</string>
            </property>
            <property name="decimals">
             <number>2</number>
            </property>
            <property name="minimum">
             <double>0.000000000000000</double>
            </property>
            <property name="maximum">
             <double>90.000000000000000</double>
            </property>
            <property name="singleStep">
             <double>1.000000000000000</double>
            </property>
            <property name="value">
             <double>30.000000000000000</double>
            </property>
           </widget>
          </item>
          <item row="2" column="1">
           <widget class="QDoubleSpinBox" name="m_PeakThreshold">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <property name="toolTip">
             <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Directions shorter than the defined threshold are discarded.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
            </property>
            <property name="decimals">
             <number>3</number>
            </property>
            <property name="maximum">
             <double>1.000000000000000</double>
            </property>
            <property name="singleStep">
             <double>0.100000000000000</double>
            </property>
            <property name="value">
             <double>0.300000000000000</double>
            </property>
           </widget>
          </item>
          <item row="1" column="0">
           <widget class="QLabel" name="label">
            <property name="text">
             <string>Angular Threshold:</string>
            </property>
           </widget>
          </item>
          <item row="0" column="0">
           <widget class="QLabel" name="label_2">
            <property name="text">
             <string>Max. Peaks:</string>
            </property>
           </widget>
          </item>
          <item row="2" column="0">
           <widget class="QLabel" name="label_3">
            <property name="text">
             <string>Size Threshold:</string>
            </property>
           </widget>
          </item>
          <item row="0" column="1">
           <widget class="QSpinBox" name="m_MaxNumDirections">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <property name="toolTip">
             <string>Maximum number of fiber directions per voxel.</string>
            </property>
            <property name="maximum">
             <number>100</number>
            </property>
            <property name="value">
             <number>3</number>
            </property>
           </widget>
          </item>
          <item row="3" column="0">
           <widget class="QLabel" name="label_4">
            <property name="text">
             <string>Normalization:</string>
            </property>
           </widget>
          </item>
          <item row="3" column="1">
           <widget class="QComboBox" name="m_FiberDirNormBox">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <property name="currentIndex">
             <number>0</number>
            </property>
            <item>
             <property name="text">
              <string>Global maximum</string>
             </property>
            </item>
            <item>
             <property name="text">
              <string>Single vector</string>
             </property>
            </item>
            <item>
             <property name="text">
              <string>Voxel-wise maximum</string>
             </property>
            </item>
           </widget>
          </item>
         </layout>
        </widget>
       </item>
       <item row="1" column="0">
        <widget class="QCheckBox" name="m_NumDirectionsBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="toolTip">
          <string>Image containing the number of distinct fiber clusters per voxel.</string>
         </property>
         <property name="text">
          <string>Output #Directions per Voxel</string>
         </property>
         <property name="checked">
          <bool>false</bool>
         </property>
        </widget>
       </item>
       <item row="2" column="0">
        <widget class="QCommandLinkButton" name="m_ExtractFiberPeaks">
         <property name="enabled">
          <bool>false</bool>
         </property>
         <property name="text">
          <string>Generate Directions</string>
         </property>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
    <item row="0" column="0">
     <widget class="QGroupBox" name="groupBox">
      <property name="title">
       <string>Input Data</string>
      </property>
      <layout class="QGridLayout" name="gridLayout">
       <property name="leftMargin">
        <number>6</number>
       </property>
       <property name="topMargin">
        <number>6</number>
       </property>
       <property name="rightMargin">
        <number>6</number>
       </property>
       <property name="bottomMargin">
        <number>6</number>
       </property>
       <item row="0" column="1">
-       <widget class="QmitkDataStorageComboBox" name="m_TractBox"></widget>
+       <widget class="QmitkDataStorageComboBox" name="m_TractBox"/>
       </item>
       <item row="1" column="1">
-       <widget class="QmitkDataStorageComboBoxWithSelectNone" name="m_ImageBox"></widget>
+       <widget class="QmitkDataStorageComboBoxWithSelectNone" name="m_ImageBox"/>
       </item>
       <item row="0" column="0">
        <widget class="QLabel" name="label_5">
         <property name="text">
          <string>Tractogram:</string>
         </property>
        </widget>
       </item>
       <item row="1" column="0">
        <widget class="QLabel" name="label_6">
         <property name="text">
          <string>Reference Image:</string>
         </property>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
    <item row="3" column="0">
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>40</height>
       </size>
      </property>
     </spacer>
    </item>
   </layout>
  </widget>
  <customwidgets>
   <customwidget>
    <class>QmitkDataStorageComboBox</class>
    <extends>QComboBox</extends>
    <header location="global">QmitkDataStorageComboBox.h</header>
   </customwidget>
   <customwidget>
    <class>QmitkDataStorageComboBoxWithSelectNone</class>
    <extends>QComboBox</extends>
    <header>QmitkDataStorageComboBoxWithSelectNone.h</header>
   </customwidget>
  </customwidgets>
- <resources></resources>
- <connections></connections>
-</ui>
\ No newline at end of file
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp
index 7b5988e..ff92686 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.cpp
@@ -1,352 +1,598 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 
 #include <berryISelectionService.h>
 #include <berryIWorkbenchWindow.h>
 
 #include "QmitkTractometryView.h"
 
 #include <mitkNodePredicateDataType.h>
 #include <mitkNodePredicateDimension.h>
 #include <mitkNodePredicateAnd.h>
 #include <mitkImageCast.h>
 #include <mitkImageAccessByItk.h>
 #include <mitkImage.h>
 #include <mitkFiberBundle.h>
 #include <mitkDiffusionPropertyHelper.h>
 #include <mitkITKImageImport.h>
 #include <mitkPixelTypeMultiplex.h>
 #include <mitkImagePixelReadAccessor.h>
 #include <berryIPreferences.h>
 #include <berryWorkbenchPlugin.h>
 #include <berryQtPreferences.h>
 #include <vtkLookupTable.h>
 #include <QClipboard>
 #include <mitkLexicalCast.h>
 #include <QmitkChartWidget.h>
+#include <mitkLookupTable.h>
+#include <mitkTractClusteringFilter.h>
+#include <mitkClusteringMetricEuclideanStd.h>
 
 
 const std::string QmitkTractometryView::VIEW_ID = "org.mitk.views.tractometry";
 using namespace mitk;
 
 QmitkTractometryView::QmitkTractometryView()
   : QmitkAbstractView()
   , m_Controls( nullptr )
   , m_Visible(false)
 {
 
 }
 
 // Destructor
 QmitkTractometryView::~QmitkTractometryView()
 {
 
 }
 
 void QmitkTractometryView::CreateQtPartControl( QWidget *parent )
 {
   // build up qt view, unless already done
   if ( !m_Controls )
   {
     // create GUI widgets from the Qt Designer's .ui file
     m_Controls = new Ui::QmitkTractometryViewControls;
     m_Controls->setupUi( parent );
 
-    connect( m_Controls->m_SamplingPointsBox, SIGNAL(valueChanged(int)), this, SLOT(UpdateGui()) );
-    connect( m_Controls->m_StDevBox, SIGNAL(stateChanged(int)), this, SLOT(UpdateGui()) );
+    connect( m_Controls->m_MethodBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()) );
+    connect( m_Controls->m_StartButton, SIGNAL(clicked()), this, SLOT(StartTractometry()) );
 
     mitk::TNodePredicateDataType<mitk::Image>::Pointer imageP = mitk::TNodePredicateDataType<mitk::Image>::New();
     mitk::NodePredicateDimension::Pointer dimP = mitk::NodePredicateDimension::New(3);
 
     m_Controls->m_ImageBox->SetDataStorage(this->GetDataStorage());
     m_Controls->m_ImageBox->SetPredicate(mitk::NodePredicateAnd::New(imageP, dimP));
 
     m_Controls->m_ChartWidget->SetTheme(GetColorTheme());
     m_Controls->m_ChartWidget->SetXAxisLabel("Tract position");
     m_Controls->m_ChartWidget->SetYAxisLabel("Image Value");
 
   }
 }
 
 ::QmitkChartWidget::ColorTheme QmitkTractometryView::GetColorTheme()
 {
   berry::IPreferencesService* prefService = berry::WorkbenchPlugin::GetDefault()->GetPreferencesService();
   berry::IPreferences::Pointer m_StylePref = prefService->GetSystemPreferences()->Node(berry::QtPreferences::QT_STYLES_NODE);
 
   QString styleName = m_StylePref->Get(berry::QtPreferences::QT_STYLE_NAME, "");
 
   if (styleName == ":/org.blueberry.ui.qt/darkstyle.qss")
   {
     return QmitkChartWidget::ColorTheme::darkstyle;
   }
   else
   {
     return QmitkChartWidget::ColorTheme::lightstyle;
   }
 }
 
 void QmitkTractometryView::SetFocus()
 {
 }
 
 void QmitkTractometryView::UpdateGui()
 {
   berry::IWorkbenchPart::Pointer nullPart;
   OnSelectionChanged(nullPart, QList<mitk::DataNode::Pointer>(m_CurrentSelection));
 }
 
 bool QmitkTractometryView::Flip(vtkSmartPointer< vtkPolyData > polydata1, int i, vtkSmartPointer< vtkPolyData > ref_poly)
 {
   double d_direct = 0;
   double d_flipped = 0;
 
   vtkCell* cell1 = polydata1->GetCell(0);
   if (ref_poly!=nullptr)
     cell1 = ref_poly->GetCell(0);
   auto numPoints1 = cell1->GetNumberOfPoints();
   vtkPoints* points1 = cell1->GetPoints();
 
   std::vector<itk::Point<double, 3>> ref_points;
   for (int j=0; j<numPoints1; ++j)
   {
     double* p1 = points1->GetPoint(j);
     itk::Point<double, 3> itk_p;
     itk_p[0] = p1[0];
     itk_p[1] = p1[1];
     itk_p[2] = p1[2];
     ref_points.push_back(itk_p);
   }
 
   vtkCell* cell2 = polydata1->GetCell(i);
   vtkPoints* points2 = cell2->GetPoints();
 
   for (int j=0; j<numPoints1; ++j)
   {
     auto p1 = ref_points.at(j);
 
     double* p2 = points2->GetPoint(j);
     d_direct = (p1[0]-p2[0])*(p1[0]-p2[0]) + (p1[1]-p2[1])*(p1[1]-p2[1]) + (p1[2]-p2[2])*(p1[2]-p2[2]);
 
     double* p3 = points2->GetPoint(numPoints1-j-1);
     d_flipped = (p1[0]-p3[0])*(p1[0]-p3[0]) + (p1[1]-p3[1])*(p1[1]-p3[1]) + (p1[2]-p3[2])*(p1[2]-p3[2]);
   }
 
   if (d_direct>d_flipped)
     return true;
   return false;
 }
 
 template <typename TPixel>
-void QmitkTractometryView::ImageValuesAlongTract(const mitk::PixelType, mitk::Image::Pointer image, mitk::FiberBundle::Pointer fib, std::vector<std::vector<double> > &data, std::string& clipboard_string)
+void QmitkTractometryView::StaticResamplingTractometry(const mitk::PixelType, mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector<std::vector<double> > &data, std::string& clipboard_string)
 {
+  mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
+
   unsigned int num_points = m_Controls->m_SamplingPointsBox->value();
   mitk::ImagePixelReadAccessor<TPixel,3> readimage(image, image->GetVolumeData(0));
   mitk::FiberBundle::Pointer working_fib = fib->GetDeepCopy();
   working_fib->ResampleToNumPoints(num_points);
   vtkSmartPointer< vtkPolyData > polydata = working_fib->GetFiberPolyData();
 
+  double rgb[3] = {0,0,0};
+
+  mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New();
+  lookupTable->SetType(mitk::LookupTable::MULTILABEL);
+
   std::vector<std::vector<double> > all_values;
   std::vector< double > mean_values;
   for (unsigned int i=0; i<num_points; ++i)
     mean_values.push_back(0);
 
   double min = 100000.0;
   double max = 0;
   double mean = 0;
   for (unsigned int i=0; i<working_fib->GetNumFibers(); ++i)
   {
     vtkCell* cell = polydata->GetCell(i);
     auto numPoints = cell->GetNumberOfPoints();
     vtkPoints* points = cell->GetPoints();
 
     std::vector< double > fib_vals;
 
     bool flip = false;
     if (i>0)
       flip = Flip(polydata, i);
     else if (m_ReferencePolyData!=nullptr)
       flip = Flip(polydata, 0, m_ReferencePolyData);
 
     for (int j=0; j<numPoints; j++)
     {
+      lookupTable->GetTableValue(j, rgb);
+
       double* p;
       if (flip)
-        p = points->GetPoint(numPoints - j - 1);
+      {
+        auto p_idx = numPoints - j - 1;
+        p = points->GetPoint(p_idx);
+
+        working_fib->ColorSinglePoint(i, p_idx, rgb);
+      }
       else
+      {
         p = points->GetPoint(j);
 
+        working_fib->ColorSinglePoint(i, j, rgb);
+      }
+
       Point3D px;
       px[0] = p[0];
       px[1] = p[1];
       px[2] = p[2];
       double pixelValue = static_cast<double>(readimage.GetPixelByWorldCoordinates(px));
       fib_vals.push_back(pixelValue);
       mean += pixelValue;
       if (pixelValue<min)
         min = pixelValue;
       else if (pixelValue>max)
         max = pixelValue;
 
       mean_values.at(j) += pixelValue;
+
     }
 
     all_values.push_back(fib_vals);
   }
 
   if (m_ReferencePolyData==nullptr)
     m_ReferencePolyData = polydata;
 
   std::vector< double > std_values1;
   std::vector< double > std_values2;
   for (unsigned int i=0; i<num_points; ++i)
   {
     mean_values.at(i) /= working_fib->GetNumFibers();
     double stdev = 0;
 
     for (unsigned int j=0; j<all_values.size(); ++j)
     {
       double diff = mean_values.at(i) - all_values.at(j).at(i);
       diff *= diff;
       stdev += diff;
     }
     stdev /= all_values.size();
     stdev = std::sqrt(stdev);
     std_values1.push_back(mean_values.at(i) + stdev);
     std_values2.push_back(mean_values.at(i) - stdev);
 
     clipboard_string += boost::lexical_cast<std::string>(mean_values.at(i));
     clipboard_string += " ";
     clipboard_string += boost::lexical_cast<std::string>(stdev);
     clipboard_string += "\n";
   }
   clipboard_string += "\n";
 
   data.push_back(mean_values);
   data.push_back(std_values1);
   data.push_back(std_values2);
 
   MITK_INFO << "Min: " << min;
   MITK_INFO << "Max: " << max;
   MITK_INFO << "Mean: " << mean/working_fib->GetNumberOfPoints();
+
+  if (m_Controls->m_ShowBinned->isChecked())
+  {
+    mitk::DataNode::Pointer new_node = mitk::DataNode::New();
+    auto children = GetDataStorage()->GetDerivations(node);
+    for (unsigned int i=0; i<children->size(); ++i)
+    {
+      if (children->at(i)->GetName() == "binned_static")
+      {
+        new_node = children->at(i);
+        new_node->SetData(working_fib);
+        new_node->SetVisibility(true);
+        node->SetVisibility(false);
+        mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+        return;
+      }
+    }
+
+    new_node->SetData(working_fib);
+    new_node->SetName("binned_static");
+    new_node->SetVisibility(true);
+    node->SetVisibility(false);
+    GetDataStorage()->Add(new_node, node);
+  }
+}
+
+template <typename TPixel>
+void QmitkTractometryView::NearestCentroidPointTractometry(const mitk::PixelType, mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector< std::vector< double > >& data, std::string& clipboard_string)
+{
+  mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
+
+  unsigned int num_points = m_Controls->m_SamplingPointsBox->value();
+  mitk::ImagePixelReadAccessor<TPixel,3> readimage(image, image->GetVolumeData(0));
+  mitk::FiberBundle::Pointer working_fib = fib->GetDeepCopy();
+  working_fib->ResampleSpline(1.0);
+  vtkSmartPointer< vtkPolyData > working_polydata = working_fib->GetFiberPolyData();
+
+  // clustering
+  std::vector< mitk::ClusteringMetric* > metrics;
+  metrics.push_back({new mitk::ClusteringMetricEuclideanStd()});
+
+  mitk::FiberBundle::Pointer fib_static_resampled = fib->GetDeepCopy();
+  fib_static_resampled->ResampleToNumPoints(num_points);
+  vtkSmartPointer< vtkPolyData > polydata_static_resampled = fib_static_resampled->GetFiberPolyData();
+
+  std::vector<mitk::FiberBundle::Pointer> centroids;
+  std::shared_ptr< mitk::TractClusteringFilter > clusterer = std::make_shared<mitk::TractClusteringFilter>();
+  int c=0;
+  while (c<30 && (centroids.empty() || centroids.size()>static_cast<unsigned long>(m_Controls->m_MaxCentroids->value())))
+  {
+    float cluster_size = m_Controls->m_ClusterSize->value() + m_Controls->m_ClusterSize->value()*c*0.2;
+    float max_d = 0;
+    int i=1;
+    std::vector< float > distances;
+    while (max_d < working_fib->GetGeometry()->GetDiagonalLength()/2)
+    {
+      distances.push_back(cluster_size*i);
+      max_d = cluster_size*i;
+      ++i;
+    }
+
+    clusterer->SetDistances(distances);
+    clusterer->SetTractogram(fib_static_resampled);
+    clusterer->SetMetrics(metrics);
+    clusterer->SetMergeDuplicateThreshold(cluster_size);
+    clusterer->SetDoResampling(false);
+    clusterer->SetNumPoints(num_points);
+  //  clusterer->SetMaxClusters(m_Controls->m_MaxCentroids->value());
+    clusterer->SetMinClusterSize(1);
+    clusterer->Update();
+    centroids = clusterer->GetOutCentroids();
+    ++c;
+  }
+
+  double rgb[3] = {0,0,0};
+  mitk::LookupTable::Pointer lookupTable = mitk::LookupTable::New();
+  lookupTable->SetType(mitk::LookupTable::MULTILABEL);
+
+  std::vector<std::vector<double> > all_values;
+  std::vector< double > mean_values;
+  std::vector< unsigned int > value_count;
+  for (unsigned int i=0; i<num_points; ++i)
+  {
+    mean_values.push_back(0);
+    value_count.push_back(0);
+  }
+
+  double min = 100000.0;
+  double max = 0;
+  double mean = 0;
+  for (unsigned int i=0; i<working_fib->GetNumFibers(); ++i)
+  {
+    vtkCell* cell = working_polydata->GetCell(i);
+    auto numPoints = cell->GetNumberOfPoints();
+    vtkPoints* points = cell->GetPoints();
+
+    std::vector< double > fib_vals;
+    for (int j=0; j<numPoints; j++)
+    {
+      double* p = points->GetPoint(j);
+
+      int min_bin = 0;
+      float d=999999;
+      for (auto centroid : centroids)
+      {
+        auto centroid_polydata = centroid->GetFiberPolyData();
+
+        vtkCell* centroid_cell = centroid_polydata->GetCell(0);
+        auto centroid_numPoints = centroid_cell->GetNumberOfPoints();
+        vtkPoints* centroid_points = centroid_cell->GetPoints();
+
+        bool centroid_flip = Flip(centroid_polydata, 0, centroids.at(0)->GetFiberPolyData());
+
+        for (int bin=0; bin<centroid_numPoints; ++bin)
+        {
+          double* centroid_p;
+          centroid_p = centroid_points->GetPoint(bin);
+          float temp_d = std::sqrt((p[0]-centroid_p[0])*(p[0]-centroid_p[0]) + (p[1]-centroid_p[1])*(p[1]-centroid_p[1]) + (p[2]-centroid_p[2])*(p[2]-centroid_p[2]));
+          if (temp_d<d)
+          {
+            d = temp_d;
+            if (centroid_flip)
+              min_bin = centroid_numPoints-bin-1;
+            else
+              min_bin = bin;
+          }
+        }
+
+      }
+
+      lookupTable->GetTableValue(min_bin, rgb);
+      working_fib->ColorSinglePoint(i, j, rgb);
+
+      Point3D px;
+      px[0] = p[0];
+      px[1] = p[1];
+      px[2] = p[2];
+      double pixelValue = static_cast<double>(readimage.GetPixelByWorldCoordinates(px));
+      fib_vals.push_back(pixelValue);
+      mean += pixelValue;
+      if (pixelValue<min)
+        min = pixelValue;
+      else if (pixelValue>max)
+        max = pixelValue;
+
+      mean_values.at(min_bin) += pixelValue;
+      value_count.at(min_bin) += 1;
+    }
+
+    all_values.push_back(fib_vals);
+  }
+
+  if (m_ReferencePolyData==nullptr)
+    m_ReferencePolyData = working_polydata;
+
+  std::vector< double > std_values1;
+  std::vector< double > std_values2;
+  for (unsigned int i=0; i<num_points; ++i)
+  {
+    mean_values.at(i) /= value_count.at(i);
+    double stdev = 0;
+
+    for (unsigned int j=0; j<all_values.size(); ++j)
+    {
+      double diff = mean_values.at(i) - all_values.at(j).at(i);
+      diff *= diff;
+      stdev += diff;
+    }
+    stdev /= all_values.size();
+    stdev = std::sqrt(stdev);
+    std_values1.push_back(mean_values.at(i) + stdev);
+    std_values2.push_back(mean_values.at(i) - stdev);
+
+    clipboard_string += boost::lexical_cast<std::string>(mean_values.at(i));
+    clipboard_string += " ";
+    clipboard_string += boost::lexical_cast<std::string>(stdev);
+    clipboard_string += "\n";
+  }
+  clipboard_string += "\n";
+
+  data.push_back(mean_values);
+  data.push_back(std_values1);
+  data.push_back(std_values2);
+
+  MITK_INFO << "Min: " << min;
+  MITK_INFO << "Max: " << max;
+  MITK_INFO << "Mean: " << mean/working_fib->GetNumberOfPoints();
+
+  if (m_Controls->m_ShowBinned->isChecked())
+  {
+    mitk::DataNode::Pointer new_node = mitk::DataNode::New();
+//    mitk::DataNode::Pointer new_node2;
+    auto children = GetDataStorage()->GetDerivations(node);
+    for (unsigned int i=0; i<children->size(); ++i)
+    {
+      if (children->at(i)->GetName() == "binned_centroid")
+      {
+        new_node = children->at(i);
+        new_node->SetData(working_fib);
+        new_node->SetVisibility(true);
+        node->SetVisibility(false);
+        mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+        return;
+      }
+    }
+    new_node->SetData(working_fib);
+    new_node->SetName("binned_centroid");
+    new_node->SetVisibility(true);
+    node->SetVisibility(false);
+    GetDataStorage()->Add(new_node, node);
+  }
 }
 
 void QmitkTractometryView::Activated()
 {
 
 }
 
 void QmitkTractometryView::Deactivated()
 {
 
 }
 
 void QmitkTractometryView::Visible()
 {
   m_Visible = true;
   QList<mitk::DataNode::Pointer> selection = GetDataManagerSelection();
   berry::IWorkbenchPart::Pointer nullPart;
   OnSelectionChanged(nullPart, selection);
 }
 
 void QmitkTractometryView::Hidden()
 {
   m_Visible = false;
 }
 
 std::string QmitkTractometryView::RGBToHexString(double *rgb)
 {
   std::ostringstream os;
   for (int i = 0; i < 3; ++i)
     {
     os << std::setw(2) << std::setfill('0') << std::hex
        << static_cast<int>(rgb[i] * 255);
     }
   return os.str();
 }
 
-void QmitkTractometryView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList<mitk::DataNode::Pointer>& nodes)
+void QmitkTractometryView::StartTractometry()
 {
-  if (!m_Visible)
-    return;
-
-  m_CurrentSelection.clear();
-  if(m_Controls->m_ImageBox->GetSelectedNode().IsNull())
-    return;
-
-  std::string clipboardString = "";
   m_ReferencePolyData = nullptr;
-  mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(m_Controls->m_ImageBox->GetSelectedNode()->GetData());
 
   vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
   lookupTable->SetTableRange(0.0, 1.0);
   lookupTable->Build();
 
-  int num_tracts = 0;
-  for (auto node: nodes)
-    if ( dynamic_cast<mitk::FiberBundle*>(node->GetData()) )
-      num_tracts++;
+  mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(m_Controls->m_ImageBox->GetSelectedNode()->GetData());
 
-  int c = 1;
   this->m_Controls->m_ChartWidget->Clear();
-  for (auto node: nodes)
+  std::string clipboardString = "";
+  int c = 1;
+  for (auto node : m_CurrentSelection)
   {
-    if ( dynamic_cast<mitk::FiberBundle*>(node->GetData()) )
-    {
-      clipboardString += node->GetName() + "\n";
-      clipboardString += "mean stdev\n";
-      mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
-      m_CurrentSelection.push_back(node);
+    clipboardString += node->GetName() + "\n";
+    clipboardString += "mean stdev\n";
 
-      std::vector< std::vector< double > > data;
-      mitkPixelTypeMultiplex4( ImageValuesAlongTract, image->GetPixelType(), image, fib, data, clipboardString );
-
-      m_Controls->m_ChartWidget->AddData1D(data.at(0), node->GetName() + " Mean", QmitkChartWidget::ChartType::line);
-      if (m_Controls->m_StDevBox->isChecked())
-      {
-        this->m_Controls->m_ChartWidget->AddData1D(data.at(1), node->GetName() + " +STDEV", QmitkChartWidget::ChartType::line);
-        this->m_Controls->m_ChartWidget->AddData1D(data.at(2), node->GetName() + " -STDEV", QmitkChartWidget::ChartType::line);
-      }
+    std::vector< std::vector< double > > data;
+    if (m_Controls->m_MethodBox->currentIndex()==0)
+    {
+      mitkPixelTypeMultiplex4( StaticResamplingTractometry, image->GetPixelType(), image, node, data, clipboardString );
+    }
+    else
+    {
+      mitkPixelTypeMultiplex4( NearestCentroidPointTractometry, image->GetPixelType(), image, node, data, clipboardString );
+    }
 
-      double color[3];
-      if (num_tracts>1)
-      {
-        float scalar_color = ( (float)c/num_tracts - 1.0/num_tracts )/(1.0-1.0/num_tracts);
-        lookupTable->GetColor(1.0 - scalar_color, color);
-      }
-      else
-        lookupTable->GetColor(0, color);
+    m_Controls->m_ChartWidget->AddData1D(data.at(0), node->GetName() + " Mean", QmitkChartWidget::ChartType::line);
+    if (m_Controls->m_StDevBox->isChecked())
+    {
+      this->m_Controls->m_ChartWidget->AddData1D(data.at(1), node->GetName() + " +STDEV", QmitkChartWidget::ChartType::line);
+      this->m_Controls->m_ChartWidget->AddData1D(data.at(2), node->GetName() + " -STDEV", QmitkChartWidget::ChartType::line);
+    }
 
-      this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " Mean", RGBToHexString(color));
+    double color[3];
+    if (m_CurrentSelection.size()>1)
+    {
+      float scalar_color = ( (float)c/m_CurrentSelection.size() - 1.0/m_CurrentSelection.size() )/(1.0-1.0/m_CurrentSelection.size());
+      lookupTable->GetColor(1.0 - scalar_color, color);
+    }
+    else
+      lookupTable->GetColor(0, color);
 
-      if (m_Controls->m_StDevBox->isChecked())
-      {
-        color[0] *= 0.5;
-        color[1] *= 0.5;
-        color[2] *= 0.5;
-        this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " +STDEV", RGBToHexString(color));
-        this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " -STDEV", RGBToHexString(color));
-      }
+    this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " Mean", RGBToHexString(color));
 
-      this->m_Controls->m_ChartWidget->Show(true);
-      this->m_Controls->m_ChartWidget->SetShowDataPoints(false);
-      ++c;
+    if (m_Controls->m_StDevBox->isChecked())
+    {
+      color[0] *= 0.5;
+      color[1] *= 0.5;
+      color[2] *= 0.5;
+      this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " +STDEV", RGBToHexString(color));
+      this->m_Controls->m_ChartWidget->SetColor(node->GetName() + " -STDEV", RGBToHexString(color));
     }
+
+    this->m_Controls->m_ChartWidget->Show(true);
+    this->m_Controls->m_ChartWidget->SetShowDataPoints(false);
+    ++c;
   }
 
   QApplication::clipboard()->setText(clipboardString.c_str(), QClipboard::Clipboard);
+}
 
+void QmitkTractometryView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList<mitk::DataNode::Pointer>& nodes)
+{
+  m_Controls->m_StartButton->setEnabled(false);
+
+  if (!m_Visible)
+    return;
+
+  if (m_Controls->m_MethodBox->currentIndex()==0)
+    m_Controls->m_ClusterFrame->setVisible(false);
+  else
+    m_Controls->m_ClusterFrame->setVisible(true);
+
+  m_CurrentSelection.clear();
+  if(m_Controls->m_ImageBox->GetSelectedNode().IsNull())
+    return;
+
+  for (auto node: nodes)
+    if ( dynamic_cast<mitk::FiberBundle*>(node->GetData()) )
+      m_CurrentSelection.push_back(node);
+  if (!m_CurrentSelection.empty())
+    m_Controls->m_StartButton->setEnabled(true);
 }
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h
index 27ac1a0..d8939fb 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryView.h
@@ -1,81 +1,85 @@
 /*===================================================================
 
 The Medical Imaging Interaction Toolkit (MITK)
 
 Copyright (c) German Cancer Research Center.
 
 All rights reserved.
 
 This software is distributed WITHOUT ANY WARRANTY; without
 even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.
 
 See LICENSE.txt or http://www.mitk.org for details.
 
 ===================================================================*/
 
 #ifndef QmitkTractometryView_h
 #define QmitkTractometryView_h
 
 #include <QmitkAbstractView.h>
 #include "ui_QmitkTractometryViewControls.h"
 #include <itkImage.h>
 #include <mitkImage.h>
 #include <mitkPixelType.h>
 #include <mitkFiberBundle.h>
 #include <mitkILifecycleAwarePart.h>
 #include <QmitkChartWidget.h>
 
 /*!
 \brief Weight fibers by linearly fitting them to the image data.
 
 */
 class QmitkTractometryView : public QmitkAbstractView, public mitk::ILifecycleAwarePart
 {
   // this is needed for all Qt objects that should have a Qt meta-object
   // (everything that derives from QObject and wants to have signal/slots)
   Q_OBJECT
 
 public:
 
   static const std::string VIEW_ID;
 
   QmitkTractometryView();
   virtual ~QmitkTractometryView();
 
   virtual void CreateQtPartControl(QWidget *parent) override;
 
   template <typename TPixel>
-  void ImageValuesAlongTract(const mitk::PixelType, mitk::Image::Pointer image, mitk::FiberBundle::Pointer fib, std::vector< std::vector< double > >& data, std::string& clipboard_string);
+  void StaticResamplingTractometry(const mitk::PixelType, mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector< std::vector< double > >& data, std::string& clipboard_string);
+
+  template <typename TPixel>
+  void NearestCentroidPointTractometry(const mitk::PixelType, mitk::Image::Pointer image, mitk::DataNode::Pointer node, std::vector< std::vector< double > >& data, std::string& clipboard_string);
 
   virtual void SetFocus() override;
 
   virtual void Activated() override;
   virtual void Deactivated() override;
   virtual void Visible() override;
   virtual void Hidden() override;
 
 protected slots:
 
   void UpdateGui();
+  void StartTractometry();
 
 protected:
 
   /// \brief called by QmitkAbstractView when DataManager's selection has changed
   virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList<mitk::DataNode::Pointer>& nodes) override;
   QmitkChartWidget::ColorTheme GetColorTheme();
 
   Ui::QmitkTractometryViewControls* m_Controls;
 
   bool Flip(vtkSmartPointer< vtkPolyData > polydata1, int i, vtkSmartPointer<vtkPolyData> ref_poly=nullptr);
   std::string RGBToHexString(double *rgb);
 
   vtkSmartPointer< vtkPolyData > m_ReferencePolyData;
   QList<mitk::DataNode::Pointer> m_CurrentSelection;
   bool  m_Visible;
 };
 
 
 
 #endif // _QMITKFIBERTRACKINGVIEW_H_INCLUDED
 
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryViewControls.ui
index ed26c90..5123bbe 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryViewControls.ui
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging.fiberprocessing/src/internal/QmitkTractometryViewControls.ui
@@ -1,136 +1,217 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>QmitkTractometryViewControls</class>
  <widget class="QWidget" name="QmitkTractometryViewControls">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>484</width>
-    <height>574</height>
+    <height>744</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
   <property name="styleSheet">
    <string>QCommandLinkButton:disabled {
   border: none;
 }
 
 QGroupBox {
   background-color: transparent;
 }</string>
   </property>
   <layout class="QGridLayout" name="gridLayout_10">
+   <item row="6" column="0">
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>40</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="3" column="0">
+    <widget class="QCheckBox" name="m_StDevBox">
+     <property name="text">
+      <string>Show STDEV</string>
+     </property>
+     <property name="checked">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="0">
+    <widget class="QCheckBox" name="m_ShowBinned">
+     <property name="text">
+      <string>Show binned tract</string>
+     </property>
+     <property name="checked">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="0">
+    <widget class="QmitkChartWidget" name="m_ChartWidget" native="true">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>600</height>
+      </size>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QGroupBox" name="m_ClusterFrame">
+     <property name="title">
+      <string>Centroid Options</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_6">
+        <property name="text">
+         <string>Cluster Size:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_5">
+        <property name="text">
+         <string>Max. Number of Centroids:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QSpinBox" name="m_MaxCentroids">
+        <property name="minimum">
+         <number>1</number>
+        </property>
+        <property name="maximum">
+         <number>99</number>
+        </property>
+        <property name="value">
+         <number>1</number>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QDoubleSpinBox" name="m_ClusterSize">
+        <property name="value">
+         <double>15.000000000000000</double>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
    <item row="0" column="0">
     <widget class="QFrame" name="frame">
      <property name="frameShape">
       <enum>QFrame::NoFrame</enum>
      </property>
      <property name="frameShadow">
       <enum>QFrame::Raised</enum>
      </property>
      <layout class="QGridLayout" name="gridLayout_2">
       <property name="leftMargin">
        <number>0</number>
       </property>
       <property name="topMargin">
        <number>0</number>
       </property>
       <property name="rightMargin">
        <number>0</number>
       </property>
       <property name="bottomMargin">
        <number>0</number>
       </property>
       <property name="spacing">
        <number>6</number>
       </property>
       <item row="0" column="1">
        <widget class="QmitkDataStorageComboBox" name="m_ImageBox">
         <property name="toolTip">
          <string/>
         </property>
        </widget>
       </item>
-      <item row="0" column="0">
-       <widget class="QLabel" name="label_3">
-        <property name="text">
-         <string>Input Image:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
+      <item row="2" column="1">
        <widget class="QSpinBox" name="m_SamplingPointsBox">
         <property name="minimum">
          <number>3</number>
         </property>
         <property name="maximum">
          <number>99999</number>
         </property>
         <property name="value">
          <number>20</number>
         </property>
        </widget>
       </item>
-      <item row="1" column="0">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_3">
+        <property name="text">
+         <string>Input Image:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
        <widget class="QLabel" name="label_4">
         <property name="text">
          <string>Sampling Points:</string>
         </property>
        </widget>
       </item>
+      <item row="1" column="1">
+       <widget class="QComboBox" name="m_MethodBox">
+        <item>
+         <property name="text">
+          <string>Static Resampling</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Centroid Based</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_7">
+        <property name="text">
+         <string>Binning Method:</string>
+        </property>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>
-   <item row="3" column="0">
-    <spacer name="verticalSpacer">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>40</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item row="2" column="0">
-    <widget class="QmitkChartWidget" name="m_ChartWidget" native="true">
-     <property name="minimumSize">
-      <size>
-       <width>0</width>
-       <height>600</height>
-      </size>
-     </property>
-    </widget>
-   </item>
    <item row="1" column="0">
-    <widget class="QCheckBox" name="m_StDevBox">
+    <widget class="QCommandLinkButton" name="m_StartButton">
      <property name="text">
-      <string>Show STDEV</string>
-     </property>
-     <property name="checked">
-      <bool>true</bool>
+      <string>Start Tractometry</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
  <customwidgets>
   <customwidget>
    <class>QmitkDataStorageComboBox</class>
    <extends>QComboBox</extends>
    <header location="global">QmitkDataStorageComboBox.h</header>
   </customwidget>
   <customwidget>
    <class>QmitkChartWidget</class>
    <extends>QWidget</extends>
    <header location="global">QmitkChartWidget.h</header>
   </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
 </ui>
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingViewControls.ui
index 66f5d48..89eedb8 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingViewControls.ui
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingViewControls.ui
@@ -1,1652 +1,1652 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>QmitkStreamlineTrackingViewControls</class>
  <widget class="QWidget" name="QmitkStreamlineTrackingViewControls">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>453</width>
     <height>859</height>
    </rect>
   </property>
   <property name="minimumSize">
    <size>
     <width>0</width>
     <height>0</height>
    </size>
   </property>
   <property name="windowTitle">
    <string>QmitkTemplate</string>
   </property>
   <property name="styleSheet">
    <string>QCommandLinkButton:disabled {
   border: none;
 }
 
 QGroupBox {
   background-color: transparent;
 }</string>
   </property>
   <layout class="QGridLayout" name="gridLayout_11">
    <property name="topMargin">
     <number>3</number>
    </property>
    <property name="bottomMargin">
     <number>3</number>
    </property>
    <property name="horizontalSpacing">
     <number>0</number>
    </property>
    <property name="verticalSpacing">
     <number>40</number>
    </property>
    <item row="1" column="0">
     <widget class="QFrame" name="frame_6">
      <property name="frameShape">
       <enum>QFrame::NoFrame</enum>
      </property>
      <property name="frameShadow">
       <enum>QFrame::Raised</enum>
      </property>
      <layout class="QGridLayout" name="gridLayout_12">
       <property name="leftMargin">
        <number>0</number>
       </property>
       <property name="topMargin">
        <number>15</number>
       </property>
       <property name="rightMargin">
        <number>0</number>
       </property>
       <property name="bottomMargin">
        <number>0</number>
       </property>
       <property name="horizontalSpacing">
        <number>6</number>
       </property>
       <property name="verticalSpacing">
        <number>15</number>
       </property>
       <item row="1" column="0">
        <widget class="QTextEdit" name="m_StatusTextBox">
         <property name="enabled">
          <bool>true</bool>
         </property>
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="readOnly">
          <bool>true</bool>
         </property>
        </widget>
       </item>
       <item row="4" column="0">
        <widget class="QFrame" name="frame_11">
         <property name="frameShape">
          <enum>QFrame::NoFrame</enum>
         </property>
         <property name="frameShadow">
          <enum>QFrame::Raised</enum>
         </property>
         <layout class="QGridLayout" name="gridLayout_21">
          <property name="leftMargin">
           <number>0</number>
          </property>
          <property name="topMargin">
           <number>0</number>
          </property>
          <property name="rightMargin">
           <number>0</number>
          </property>
          <property name="bottomMargin">
           <number>0</number>
          </property>
          <property name="verticalSpacing">
           <number>0</number>
          </property>
          <item row="0" column="1">
           <widget class="QCommandLinkButton" name="m_SaveParametersButton">
            <property name="enabled">
             <bool>true</bool>
            </property>
            <property name="toolTip">
             <string>Save parameters to json file</string>
            </property>
            <property name="text">
             <string>Save Parameters</string>
            </property>
            <property name="icon">
             <iconset resource="../../resources/QmitkTractography.qrc">
              <normaloff>:/QmitkTractography/download.png</normaloff>:/QmitkTractography/download.png</iconset>
            </property>
           </widget>
          </item>
          <item row="0" column="0">
           <widget class="QCommandLinkButton" name="m_LoadParametersButton">
            <property name="enabled">
             <bool>true</bool>
            </property>
            <property name="toolTip">
             <string>Load parameters from json file</string>
            </property>
            <property name="text">
             <string>Load Parameters</string>
            </property>
            <property name="icon">
             <iconset resource="../../resources/QmitkTractography.qrc">
              <normaloff>:/QmitkTractography/upload.png</normaloff>:/QmitkTractography/upload.png</iconset>
            </property>
           </widget>
          </item>
         </layout>
        </widget>
       </item>
       <item row="3" column="0">
        <widget class="QCommandLinkButton" name="commandLinkButton">
         <property name="enabled">
          <bool>false</bool>
         </property>
         <property name="text">
          <string>Start Tractography</string>
         </property>
         <property name="icon">
          <iconset resource="../../resources/QmitkTractography.qrc">
           <normaloff>:/QmitkTractography/right.png</normaloff>:/QmitkTractography/right.png</iconset>
         </property>
        </widget>
       </item>
       <item row="2" column="0">
        <widget class="QCommandLinkButton" name="commandLinkButton_2">
         <property name="enabled">
          <bool>true</bool>
         </property>
         <property name="toolTip">
          <string>Stop tractography and return all fibers reconstructed until now.</string>
         </property>
         <property name="text">
          <string>Stop Tractography</string>
         </property>
         <property name="icon">
          <iconset resource="../../resources/QmitkTractography.qrc">
           <normaloff>:/QmitkTractography/stop.png</normaloff>:/QmitkTractography/stop.png</iconset>
         </property>
        </widget>
       </item>
       <item row="0" column="0">
        <widget class="QFrame" name="frame_9">
         <property name="frameShape">
          <enum>QFrame::NoFrame</enum>
         </property>
         <property name="frameShadow">
          <enum>QFrame::Raised</enum>
         </property>
         <layout class="QGridLayout" name="gridLayout_19">
          <property name="leftMargin">
           <number>0</number>
          </property>
          <property name="topMargin">
           <number>0</number>
          </property>
          <property name="rightMargin">
           <number>0</number>
          </property>
          <property name="bottomMargin">
           <number>0</number>
          </property>
          <item row="0" column="0">
           <widget class="QLabel" name="label_2">
            <property name="toolTip">
             <string>Input Image. ODF, tensor and peak images are currently supported.</string>
            </property>
            <property name="text">
             <string>Input Image:</string>
            </property>
           </widget>
          </item>
          <item row="0" column="1">
           <widget class="QLabel" name="m_TensorImageLabel">
            <property name="toolTip">
             <string>Input Image. ODF, tensor, peak, and, in case of ML tractography, raw diffusion-weighted images are currently supported.</string>
            </property>
            <property name="text">
             <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#ff0000;&quot;&gt;select image in data-manager&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
            </property>
            <property name="wordWrap">
             <bool>true</bool>
            </property>
           </widget>
          </item>
          <item row="1" column="0">
           <widget class="QLabel" name="m_ForestLabel">
            <property name="toolTip">
             <string/>
            </property>
            <property name="text">
             <string>Tractography Forest:</string>
            </property>
           </widget>
          </item>
          <item row="1" column="1">
           <widget class="QmitkSingleNodeSelectionWidget" name="m_ForestSelectionWidget" native="true">
            <property name="styleSheet">
             <string notr="true"/>
            </property>
           </widget>
          </item>
         </layout>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
    <item row="2" column="0" rowspan="6">
     <widget class="QToolBox" name="toolBox">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="minimumSize">
       <size>
        <width>0</width>
        <height>0</height>
       </size>
      </property>
      <property name="font">
       <font>
        <weight>75</weight>
        <bold>true</bold>
       </font>
      </property>
      <property name="currentIndex">
       <number>0</number>
      </property>
      <widget class="QWidget" name="page_seed">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>421</width>
         <height>254</height>
        </rect>
       </property>
       <attribute name="label">
        <string>Seeding</string>
       </attribute>
       <attribute name="toolTip">
        <string>Specify how, where and how many tractography seed points are placed.</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_17">
        <item row="0" column="0">
         <widget class="QFrame" name="m_InteractiveSeedingFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_15">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <item row="1" column="0">
            <widget class="QFrame" name="frame_7">
             <property name="frameShape">
              <enum>QFrame::NoFrame</enum>
             </property>
             <property name="frameShadow">
              <enum>QFrame::Raised</enum>
             </property>
             <layout class="QGridLayout" name="gridLayout_13">
              <property name="leftMargin">
               <number>0</number>
              </property>
              <property name="topMargin">
               <number>0</number>
              </property>
              <property name="rightMargin">
               <number>0</number>
              </property>
              <property name="bottomMargin">
               <number>0</number>
              </property>
              <item row="2" column="1">
               <widget class="QSpinBox" name="m_NumSeedsBox">
                <property name="toolTip">
                 <string>Number of seed points equally distributed around selected position. </string>
                </property>
                <property name="minimum">
                 <number>1</number>
                </property>
                <property name="maximum">
                 <number>9999999</number>
                </property>
                <property name="value">
                 <number>50</number>
                </property>
               </widget>
              </item>
              <item row="1" column="0">
               <widget class="QLabel" name="m_FaThresholdLabel_4">
                <property name="toolTip">
                 <string/>
                </property>
                <property name="text">
                 <string>Radius: </string>
                </property>
               </widget>
              </item>
              <item row="1" column="1">
               <widget class="QDoubleSpinBox" name="m_SeedRadiusBox">
                <property name="toolTip">
                 <string>Seedpoints are equally distributed within a sphere centered at the selected position with the specified radius (in mm).</string>
                </property>
                <property name="decimals">
                 <number>2</number>
                </property>
                <property name="maximum">
                 <double>50.000000000000000</double>
                </property>
                <property name="singleStep">
                 <double>0.100000000000000</double>
                </property>
                <property name="value">
                 <double>2.000000000000000</double>
                </property>
               </widget>
              </item>
              <item row="2" column="0">
               <widget class="QLabel" name="m_SeedsPerVoxelLabel_4">
                <property name="toolTip">
                 <string/>
                </property>
                <property name="text">
                 <string>Num. Seeds:</string>
                </property>
               </widget>
              </item>
             </layout>
            </widget>
           </item>
           <item row="0" column="0">
            <widget class="QCheckBox" name="m_ParamUpdateBox">
             <property name="enabled">
              <bool>true</bool>
             </property>
             <property name="toolTip">
              <string>When checked, parameter changes cause instant retracking while in interactive mode.</string>
             </property>
             <property name="text">
              <string>Update on Parameter Change </string>
             </property>
             <property name="checked">
              <bool>true</bool>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="2" column="0">
         <widget class="QFrame" name="frame_8">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_16">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <item row="0" column="1">
            <widget class="QSpinBox" name="m_TrialsPerSeedBox">
             <property name="toolTip">
              <string>Try each seed N times until a valid streamline is obtained (only for probabilistic tractography).</string>
             </property>
             <property name="statusTip">
              <string>Minimum fiber length (in mm)</string>
             </property>
             <property name="minimum">
              <number>1</number>
             </property>
             <property name="maximum">
              <number>999</number>
             </property>
             <property name="value">
              <number>10</number>
             </property>
            </widget>
           </item>
           <item row="0" column="0">
            <widget class="QLabel" name="m_TrialsPerSeedLabel">
             <property name="toolTip">
              <string/>
             </property>
             <property name="text">
              <string>Trials Per Seed:</string>
             </property>
            </widget>
           </item>
           <item row="1" column="0">
            <widget class="QLabel" name="m_FaThresholdLabel_2">
             <property name="toolTip">
              <string/>
             </property>
             <property name="text">
              <string>Max. Num. Fibers:</string>
             </property>
            </widget>
           </item>
           <item row="1" column="1">
            <widget class="QSpinBox" name="m_NumFibersBox">
             <property name="toolTip">
              <string>Tractography is stopped after the desired number of fibers is reached, even before all seed points are processed (-1 means no limit).</string>
             </property>
             <property name="minimum">
              <number>-1</number>
             </property>
             <property name="maximum">
              <number>999999999</number>
             </property>
             <property name="value">
              <number>-1</number>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="1" column="0">
         <widget class="QFrame" name="m_StaticSeedingFrame">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_2">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <item row="2" column="0">
            <widget class="QLabel" name="m_SeedsPerVoxelLabel">
             <property name="toolTip">
              <string/>
             </property>
             <property name="text">
              <string>Seeds per Voxel:</string>
             </property>
            </widget>
           </item>
           <item row="0" column="0">
            <widget class="QLabel" name="label_6">
             <property name="toolTip">
              <string/>
             </property>
             <property name="text">
              <string>Seed Image:</string>
             </property>
            </widget>
           </item>
           <item row="2" column="1">
            <widget class="QSpinBox" name="m_SeedsPerVoxelBox">
             <property name="toolTip">
              <string>Number of seed points placed in each voxel.</string>
             </property>
             <property name="minimum">
              <number>1</number>
             </property>
             <property name="maximum">
              <number>9999999</number>
             </property>
            </widget>
           </item>
           <item row="0" column="1">
            <widget class="QmitkSingleNodeSelectionWidget" name="m_SeedImageSelectionWidget" native="true">
             <property name="styleSheet">
              <string notr="true"/>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="3" column="0">
         <widget class="QCheckBox" name="m_InteractiveBox">
          <property name="enabled">
           <bool>true</bool>
          </property>
          <property name="toolTip">
           <string>Dynamically pick a seed location by click into image.</string>
          </property>
          <property name="text">
           <string>Enable Interactive Tractography</string>
          </property>
         </widget>
        </item>
        <item row="4" column="0">
         <spacer name="verticalSpacer">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="page_constraints">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>435</width>
-        <height>184</height>
+        <height>181</height>
        </rect>
       </property>
       <attribute name="label">
        <string>ROI Constraints</string>
       </attribute>
       <attribute name="toolTip">
        <string>Specify various ROI and mask images to constrain the tractography process.</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout">
        <item row="0" column="0">
         <widget class="QLabel" name="label_7">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Mask Image:</string>
          </property>
         </widget>
        </item>
        <item row="3" column="1">
         <widget class="QComboBox" name="m_EpConstraintsBox">
          <property name="toolTip">
           <string>Select which fibers should be accepted or rejected based on the location of their endpoints.</string>
          </property>
          <property name="sizeAdjustPolicy">
           <enum>QComboBox::AdjustToMinimumContentsLength</enum>
          </property>
          <item>
           <property name="text">
            <string>No Constraints on EP locations</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Both EPs in Target Image</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Both EPs in Target Image But Different Label</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>One EP in Seed Image and One EP in Target Image</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>At Least One EP in Target Image</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Exactly One EP in Target Image</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>No EP in Target Image</string>
           </property>
          </item>
         </widget>
        </item>
        <item row="3" column="0">
         <widget class="QLabel" name="label_10">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Endpoint Constraints:</string>
          </property>
         </widget>
        </item>
        <item row="1" column="0">
         <widget class="QLabel" name="label_9">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Stop ROI Image:</string>
          </property>
         </widget>
        </item>
        <item row="2" column="0">
         <widget class="QLabel" name="label_11">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Exclusion ROI Image:</string>
          </property>
         </widget>
        </item>
        <item row="4" column="0">
         <widget class="QLabel" name="m_TargetImageLabel">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Target ROI Image:</string>
          </property>
         </widget>
        </item>
        <item row="6" column="0">
         <spacer name="verticalSpacer_6">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
        <item row="0" column="1">
         <widget class="QmitkSingleNodeSelectionWidget" name="m_MaskImageSelectionWidget" native="true"/>
        </item>
        <item row="1" column="1">
         <widget class="QmitkSingleNodeSelectionWidget" name="m_StopImageSelectionWidget" native="true"/>
        </item>
        <item row="2" column="1">
         <widget class="QmitkSingleNodeSelectionWidget" name="m_ExclusionImageSelectionWidget" native="true"/>
        </item>
        <item row="4" column="1">
         <widget class="QmitkSingleNodeSelectionWidget" name="m_TargetImageSelectionWidget" native="true"/>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="page_trackingparam">
       <property name="geometry">
        <rect>
         <x>0</x>
-        <y>0</y>
+        <y>-191</y>
         <width>421</width>
         <height>428</height>
        </rect>
       </property>
       <attribute name="label">
        <string>Tractography Parameters</string>
       </attribute>
       <attribute name="toolTip">
        <string>Specify the behavior of the tractography at each streamline integration step (step size, deterministic/probabilistic, ...).</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_14">
        <item row="8" column="1">
         <widget class="QDoubleSpinBox" name="m_MinTractLengthBox">
          <property name="toolTip">
           <string>Minimum tract length in mm. Shorter fibers are discarded.</string>
          </property>
          <property name="statusTip">
           <string>Minimum fiber length (in mm)</string>
          </property>
          <property name="decimals">
           <number>1</number>
          </property>
          <property name="maximum">
           <double>999.000000000000000</double>
          </property>
          <property name="singleStep">
           <double>1.000000000000000</double>
          </property>
          <property name="value">
           <double>20.000000000000000</double>
          </property>
         </widget>
        </item>
        <item row="12" column="0">
         <widget class="QLabel" name="m_fLabel">
          <property name="toolTip">
           <string>f parameter of tensor tractography. f=1 + g=0 means FACT (depending on the chosen interpolation). f=0 and g=1 means TEND (disable interpolation for this mode!).</string>
          </property>
          <property name="text">
           <string>f:</string>
          </property>
         </widget>
        </item>
        <item row="13" column="1">
         <widget class="QDoubleSpinBox" name="m_gBox">
          <property name="toolTip">
           <string>f=1 + g=0 means FACT (depending on the chosen interpolation). f=0 and g=1 means TEND (disable interpolation for this mode!).</string>
          </property>
          <property name="decimals">
           <number>2</number>
          </property>
          <property name="maximum">
           <double>1.000000000000000</double>
          </property>
          <property name="singleStep">
           <double>0.100000000000000</double>
          </property>
          <property name="value">
           <double>0.000000000000000</double>
          </property>
         </widget>
        </item>
        <item row="2" column="0">
         <widget class="QLabel" name="m_FaThresholdLabel_5">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Sharpen ODFs:</string>
          </property>
         </widget>
        </item>
        <item row="15" column="0">
         <widget class="QLabel" name="m_FaThresholdLabel_6">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Fix Random Seed:</string>
          </property>
         </widget>
        </item>
        <item row="11" column="1">
         <widget class="QSpinBox" name="m_LoopCheckBox">
          <property name="toolTip">
-          <string>Maximum allowed angular SDTEV over 4 voxel lengths. Default: no loop check.</string>
+          <string>Maximum allowed angular SDTEV over 4 voxel lengths. Default: 30°</string>
          </property>
          <property name="statusTip">
           <string/>
          </property>
          <property name="minimum">
           <number>-1</number>
          </property>
          <property name="maximum">
           <number>180</number>
          </property>
          <property name="value">
-          <number>-1</number>
+          <number>30</number>
          </property>
         </widget>
        </item>
        <item row="10" column="0">
         <widget class="QLabel" name="m_AngularThresholdLabel">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Angular Threshold:</string>
          </property>
         </widget>
        </item>
        <item row="9" column="0">
         <widget class="QLabel" name="m_MinTractLengthLabel_2">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Max. Tract Length:</string>
          </property>
         </widget>
        </item>
        <item row="3" column="0">
         <widget class="QLabel" name="m_FaThresholdLabel">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Cutoff:</string>
          </property>
         </widget>
        </item>
        <item row="2" column="1">
         <widget class="QCheckBox" name="m_SharpenOdfsBox">
          <property name="toolTip">
           <string>If you are using dODF images as input, it is advisable to sharpen the ODFs (min-max normalize and raise to the power of 4). This is not necessary for CSD fODFs, since they are naturally much sharper.</string>
          </property>
          <property name="text">
           <string/>
          </property>
         </widget>
        </item>
        <item row="10" column="1">
         <widget class="QSpinBox" name="m_AngularThresholdBox">
          <property name="toolTip">
           <string>Angular threshold between two steps (in degree). Default: 90° * step_size</string>
          </property>
          <property name="minimum">
           <number>-1</number>
          </property>
          <property name="maximum">
           <number>90</number>
          </property>
          <property name="singleStep">
           <number>1</number>
          </property>
          <property name="value">
           <number>-1</number>
          </property>
         </widget>
        </item>
        <item row="16" column="0">
         <spacer name="verticalSpacer_2">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
        <item row="12" column="1">
         <widget class="QDoubleSpinBox" name="m_fBox">
          <property name="toolTip">
           <string>f=1 + g=0 means FACT (depending on the chosen interpolation). f=0 and g=1 means TEND (disable interpolation for this mode!).</string>
          </property>
          <property name="decimals">
           <number>2</number>
          </property>
          <property name="maximum">
           <double>1.000000000000000</double>
          </property>
          <property name="singleStep">
           <double>0.100000000000000</double>
          </property>
          <property name="value">
           <double>1.000000000000000</double>
          </property>
         </widget>
        </item>
        <item row="1" column="1">
         <widget class="QComboBox" name="m_ModeBox">
          <property name="toolTip">
           <string>Toggle between deterministic and probabilistic tractography. Some modes might not be available for all types of tractography.</string>
          </property>
          <item>
           <property name="text">
            <string>Deterministic</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Probabilistic</string>
           </property>
          </item>
         </widget>
        </item>
        <item row="1" column="0">
         <widget class="QLabel" name="m_FaThresholdLabel_3">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Mode:</string>
          </property>
         </widget>
        </item>
        <item row="5" column="1">
         <widget class="QDoubleSpinBox" name="m_OdfCutoffBox">
          <property name="toolTip">
           <string>Additional threshold on the ODF magnitude. This is useful in case of CSD fODF tractography. For fODFs a good default value is 0.1, for normalized dODFs, e.g. Q-ball ODFs, this threshold should be very low (0.00025) or 0.</string>
          </property>
          <property name="decimals">
           <number>5</number>
          </property>
          <property name="maximum">
           <double>1.000000000000000</double>
          </property>
          <property name="singleStep">
           <double>0.100000000000000</double>
          </property>
          <property name="value">
           <double>0.000250000000000</double>
          </property>
         </widget>
        </item>
        <item row="8" column="0">
         <widget class="QLabel" name="m_MinTractLengthLabel">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Min. Tract Length:</string>
          </property>
         </widget>
        </item>
        <item row="4" column="0">
         <widget class="QLabel" name="mFaImageLabel">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>FA/GFA Image:</string>
          </property>
         </widget>
        </item>
        <item row="11" column="0">
         <widget class="QLabel" name="m_LoopCheckLabel">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Loop Check:</string>
          </property>
         </widget>
        </item>
        <item row="9" column="1">
         <widget class="QDoubleSpinBox" name="m_MaxTractLengthBox">
          <property name="toolTip">
           <string>Minimum tract length in mm. Shorter fibers are discarded.</string>
          </property>
          <property name="statusTip">
           <string>Maximum fiber length (in mm)</string>
          </property>
          <property name="decimals">
           <number>1</number>
          </property>
          <property name="maximum">
           <double>999.000000000000000</double>
          </property>
          <property name="singleStep">
           <double>1.000000000000000</double>
          </property>
          <property name="value">
           <double>400.000000000000000</double>
          </property>
         </widget>
        </item>
        <item row="15" column="1">
         <widget class="QCheckBox" name="m_FixSeedBox">
          <property name="toolTip">
           <string>Always produce the same random numbers.</string>
          </property>
          <property name="text">
           <string/>
          </property>
         </widget>
        </item>
        <item row="6" column="0">
         <widget class="QLabel" name="m_StepsizeLabel">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Step Size:</string>
          </property>
         </widget>
        </item>
        <item row="5" column="0">
         <widget class="QLabel" name="m_OdfCutoffLabel">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>ODF Cutoff:</string>
          </property>
         </widget>
        </item>
        <item row="6" column="1">
         <widget class="QDoubleSpinBox" name="m_StepSizeBox">
          <property name="toolTip">
           <string>Step size (in voxels)</string>
          </property>
          <property name="decimals">
           <number>2</number>
          </property>
          <property name="minimum">
           <double>0.010000000000000</double>
          </property>
          <property name="maximum">
           <double>10.000000000000000</double>
          </property>
          <property name="singleStep">
           <double>0.100000000000000</double>
          </property>
          <property name="value">
           <double>0.500000000000000</double>
          </property>
         </widget>
        </item>
        <item row="13" column="0">
         <widget class="QLabel" name="m_gLabel">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>g:</string>
          </property>
         </widget>
        </item>
        <item row="4" column="1">
         <widget class="QmitkSingleNodeSelectionWidget" name="m_FaImageSelectionWidget" native="true"/>
        </item>
        <item row="3" column="1">
         <widget class="QDoubleSpinBox" name="m_ScalarThresholdBox">
          <property name="toolTip">
           <string>Threshold on peak magnitude, FA, GFA, ...</string>
          </property>
          <property name="decimals">
           <number>5</number>
          </property>
          <property name="maximum">
           <double>1.000000000000000</double>
          </property>
          <property name="singleStep">
           <double>0.100000000000000</double>
          </property>
          <property name="value">
           <double>0.100000000000000</double>
          </property>
         </widget>
        </item>
        <item row="14" column="0">
         <widget class="QLabel" name="m_PeakJitterLabel">
          <property name="toolTip">
           <string/>
          </property>
          <property name="text">
           <string>Peak Jitter:</string>
          </property>
         </widget>
        </item>
        <item row="14" column="1">
         <widget class="QDoubleSpinBox" name="m_PeakJitterBox">
          <property name="toolTip">
           <string>Important for probabilistic peak tractography and peak prior. Actual jitter is drawn from a normal distribution with peak_jitter*fabs(direction_value) as standard deviation.</string>
          </property>
          <property name="decimals">
           <number>3</number>
          </property>
          <property name="maximum">
           <double>1.000000000000000</double>
          </property>
          <property name="singleStep">
           <double>0.100000000000000</double>
          </property>
          <property name="value">
           <double>0.010000000000000</double>
          </property>
         </widget>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="page_prior">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>435</width>
-        <height>184</height>
+        <height>181</height>
        </rect>
       </property>
       <attribute name="label">
        <string>Tractography Prior</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_9">
        <item row="1" column="0">
         <widget class="QLabel" name="m_PriorLabel_2">
          <property name="text">
           <string>Weight:</string>
          </property>
         </widget>
        </item>
        <item row="1" column="1">
         <widget class="QDoubleSpinBox" name="m_PriorWeightBox">
          <property name="toolTip">
           <string>Weighting factor between prior and data.</string>
          </property>
          <property name="maximum">
           <double>1.000000000000000</double>
          </property>
          <property name="singleStep">
           <double>0.100000000000000</double>
          </property>
          <property name="value">
           <double>0.500000000000000</double>
          </property>
         </widget>
        </item>
        <item row="0" column="0">
         <widget class="QLabel" name="m_PriorLabel">
          <property name="text">
           <string>Peak Image:</string>
          </property>
         </widget>
        </item>
        <item row="5" column="0">
         <spacer name="verticalSpacer_7">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
        <item row="3" column="1">
         <widget class="QCheckBox" name="m_NewDirectionsFromPriorBox">
          <property name="toolTip">
           <string>If unchecked, the prior cannot create directions where there are none in the data.</string>
          </property>
          <property name="text">
           <string/>
          </property>
          <property name="checked">
           <bool>true</bool>
          </property>
         </widget>
        </item>
        <item row="3" column="0">
         <widget class="QLabel" name="m_PriorLabel_4">
          <property name="text">
           <string>New Directions from Prior:</string>
          </property>
         </widget>
        </item>
        <item row="2" column="0">
         <widget class="QLabel" name="m_PriorLabel_3">
          <property name="text">
           <string>Restrict to Prior:</string>
          </property>
         </widget>
        </item>
        <item row="0" column="1">
         <widget class="QmitkSingleNodeSelectionWidget" name="m_PriorImageSelectionWidget" native="true"/>
        </item>
        <item row="2" column="1">
         <widget class="QCheckBox" name="m_PriorAsMaskBox">
          <property name="toolTip">
           <string>Restrict tractography to regions where the prior is valid.</string>
          </property>
          <property name="text">
           <string/>
          </property>
          <property name="checked">
           <bool>true</bool>
          </property>
         </widget>
        </item>
        <item row="4" column="1">
         <widget class="QFrame" name="frame_10">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_20">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <property name="spacing">
            <number>0</number>
           </property>
           <item row="0" column="1">
            <widget class="QCheckBox" name="m_PriorFlipYBox">
             <property name="text">
              <string>y</string>
             </property>
            </widget>
           </item>
           <item row="0" column="0">
            <widget class="QCheckBox" name="m_PriorFlipXBox">
             <property name="text">
              <string>x</string>
             </property>
            </widget>
           </item>
           <item row="0" column="2">
            <widget class="QCheckBox" name="m_PriorFlipZBox">
             <property name="text">
              <string>z</string>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="4" column="0">
         <widget class="QLabel" name="m_PriorLabel_5">
          <property name="text">
           <string>Flip Directions:</string>
          </property>
         </widget>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="page_neighborhood">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>435</width>
-        <height>184</height>
+        <height>181</height>
        </rect>
       </property>
       <attribute name="label">
        <string>Neighborhood Sampling</string>
       </attribute>
       <attribute name="toolTip">
        <string>Specify if and how information about the current streamline neighborhood should be used.</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_18">
        <item row="1" column="0">
         <widget class="QCheckBox" name="m_FrontalSamplesBox">
          <property name="toolTip">
           <string>Only neighborhood samples in front of the current streamline position are considered.</string>
          </property>
          <property name="text">
           <string>Use Only Frontal Samples</string>
          </property>
          <property name="checked">
           <bool>false</bool>
          </property>
         </widget>
        </item>
        <item row="2" column="0">
         <widget class="QCheckBox" name="m_StopVotesBox">
          <property name="toolTip">
           <string>If checked, the majority of sampling points has to place a stop-vote for the streamline to terminate. If not checked, all sampling positions have to vote for a streamline termination.</string>
          </property>
          <property name="text">
           <string>Use Stop-Votes</string>
          </property>
          <property name="checked">
           <bool>false</bool>
          </property>
         </widget>
        </item>
        <item row="0" column="0">
         <widget class="QFrame" name="frame_4">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_10">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <item row="0" column="0">
            <widget class="QLabel" name="m_SeedsPerVoxelLabel_2">
             <property name="toolTip">
              <string/>
             </property>
             <property name="text">
              <string>Num. Samples:</string>
             </property>
            </widget>
           </item>
           <item row="0" column="1">
            <widget class="QSpinBox" name="m_NumSamplesBox">
             <property name="toolTip">
              <string>Number of neighborhood samples that are used to determine the next fiber progression direction.</string>
             </property>
             <property name="maximum">
              <number>50</number>
             </property>
            </widget>
           </item>
           <item row="1" column="0">
            <widget class="QLabel" name="m_SamplingDistanceLabel">
             <property name="toolTip">
              <string/>
             </property>
             <property name="text">
              <string>Sampling Distance:</string>
             </property>
            </widget>
           </item>
           <item row="1" column="1">
            <widget class="QDoubleSpinBox" name="m_SamplingDistanceBox">
             <property name="toolTip">
              <string>Sampling distance (in voxels)</string>
             </property>
             <property name="decimals">
              <number>2</number>
             </property>
             <property name="maximum">
              <double>10.000000000000000</double>
             </property>
             <property name="singleStep">
              <double>0.100000000000000</double>
             </property>
             <property name="value">
              <double>0.250000000000000</double>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="3" column="0">
         <spacer name="verticalSpacer_3">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="page_data">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>435</width>
-        <height>184</height>
+        <height>181</height>
        </rect>
       </property>
       <attribute name="label">
        <string>Data Handling</string>
       </attribute>
       <attribute name="toolTip">
        <string>Specify interpolation and direction flips.</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_6">
        <item row="1" column="0">
         <widget class="QFrame" name="frame_3">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_7">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <item row="0" column="0">
            <widget class="QCheckBox" name="m_InterpolationBox">
             <property name="toolTip">
              <string>Trilinearly interpolate the input image used for tractography.</string>
             </property>
             <property name="text">
              <string>Interpolate Tractography Data</string>
             </property>
             <property name="checked">
              <bool>true</bool>
             </property>
            </widget>
           </item>
           <item row="1" column="0">
            <widget class="QCheckBox" name="m_MaskInterpolationBox">
             <property name="toolTip">
              <string>Trilinearly interpolate the ROI images used to constrain the tractography.</string>
             </property>
             <property name="text">
              <string>Interpolate ROI Images</string>
             </property>
             <property name="checked">
              <bool>true</bool>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="0" column="0">
         <widget class="QFrame" name="frame_2">
          <property name="frameShape">
           <enum>QFrame::NoFrame</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QGridLayout" name="gridLayout_3">
           <property name="leftMargin">
            <number>0</number>
           </property>
           <property name="topMargin">
            <number>0</number>
           </property>
           <property name="rightMargin">
            <number>0</number>
           </property>
           <property name="bottomMargin">
            <number>0</number>
           </property>
           <item row="7" column="1">
            <widget class="QFrame" name="frame">
             <property name="frameShape">
              <enum>QFrame::NoFrame</enum>
             </property>
             <property name="frameShadow">
              <enum>QFrame::Raised</enum>
             </property>
             <layout class="QGridLayout" name="gridLayout_4">
              <property name="leftMargin">
               <number>0</number>
              </property>
              <property name="topMargin">
               <number>0</number>
              </property>
              <property name="rightMargin">
               <number>0</number>
              </property>
              <property name="bottomMargin">
               <number>0</number>
              </property>
              <item row="0" column="0">
               <widget class="QCheckBox" name="m_FlipXBox">
                <property name="toolTip">
                 <string>Internally flips progression directions. This might be necessary depending on the input data.</string>
                </property>
                <property name="text">
                 <string>x</string>
                </property>
               </widget>
              </item>
              <item row="0" column="1">
               <widget class="QCheckBox" name="m_FlipYBox">
                <property name="toolTip">
                 <string>Internally flips progression directions. This might be necessary depending on the input data.</string>
                </property>
                <property name="text">
                 <string>y</string>
                </property>
               </widget>
              </item>
              <item row="0" column="2">
               <widget class="QCheckBox" name="m_FlipZBox">
                <property name="toolTip">
                 <string>Internally flips progression directions. This might be necessary depending on the input data.</string>
                </property>
                <property name="text">
                 <string>z</string>
                </property>
               </widget>
              </item>
             </layout>
            </widget>
           </item>
           <item row="7" column="0">
            <widget class="QLabel" name="m_SeedsPerVoxelLabel_3">
             <property name="toolTip">
              <string/>
             </property>
             <property name="text">
              <string>Flip directions:</string>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="2" column="0">
         <spacer name="verticalSpacer_4">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="page_output">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>435</width>
-        <height>184</height>
+        <height>181</height>
        </rect>
       </property>
       <attribute name="label">
        <string>Output and Postprocessing</string>
       </attribute>
       <attribute name="toolTip">
        <string>Specify the tractography output (streamlines or probability maps) and postprocessing steps.</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout_5">
        <item row="3" column="0">
         <spacer name="verticalSpacer_5">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>40</height>
           </size>
          </property>
         </spacer>
        </item>
        <item row="1" column="0">
         <widget class="QCheckBox" name="m_ResampleFibersBox">
          <property name="toolTip">
           <string>Compress fibers using the specified error constraint.</string>
          </property>
          <property name="text">
           <string>Compress Fibers</string>
          </property>
          <property name="checked">
           <bool>true</bool>
          </property>
         </widget>
        </item>
        <item row="2" column="0">
         <widget class="QCheckBox" name="m_OutputProbMap">
          <property name="toolTip">
           <string>Output map with voxel-wise visitation counts instead of streamlines.</string>
          </property>
          <property name="text">
           <string>Output Probability Map</string>
          </property>
          <property name="checked">
           <bool>false</bool>
          </property>
         </widget>
        </item>
       </layout>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
  <customwidgets>
   <customwidget>
    <class>QmitkSingleNodeSelectionWidget</class>
    <extends>QWidget</extends>
    <header>QmitkSingleNodeSelectionWidget.h</header>
    <container>1</container>
   </customwidget>
  </customwidgets>
  <resources>
   <include location="../../resources/QmitkTractography.qrc"/>
  </resources>
  <connections/>
 </ui>