void StartSimulation(FiberfoxParameters<double> parameters, FiberBundle::Pointer fiberBundle, mitk::Image::Pointer refImage, string message)
{
    itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New();
    tractsToDwiFilter->SetUseConstantRandSeed(true);
    tractsToDwiFilter->SetParameters(parameters);
    tractsToDwiFilter->SetFiberBundle(fiberBundle);
    tractsToDwiFilter->Update();

    mitk::Image::Pointer testImage = mitk::GrabItkImageMemory( tractsToDwiFilter->GetOutput() );
    testImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( parameters.m_SignalGen.GetGradientDirections() ) );
    testImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( parameters.m_SignalGen.m_Bvalue ) );

    mitk::DiffusionPropertyHelper propertyHelper( testImage );
    propertyHelper.InitializeImage();

    if (refImage.IsNotNull())
    {
        if( static_cast<mitk::GradientDirectionsProperty*>( refImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer().IsNotNull() )
        {
            ItkDwiType::Pointer itkTestImagePointer = ItkDwiType::New();
            mitk::CastToItkImage(testImage, itkTestImagePointer);
            ItkDwiType::Pointer itkRefImagePointer = ItkDwiType::New();
            mitk::CastToItkImage(refImage, itkRefImagePointer);

            bool cond = CompareDwi(itkTestImagePointer, itkRefImagePointer);
            if (!cond)
            {
                MITK_INFO << "Saving test and rference image to " << mitk::IOUtil::GetTempPath();
                mitk::IOUtil::SaveBaseData(testImage, mitk::IOUtil::GetTempPath()+"testImage.dwi");
                mitk::IOUtil::SaveBaseData(refImage, mitk::IOUtil::GetTempPath()+"refImage.dwi");
            }
            MITK_TEST_CONDITION_REQUIRED(cond, message);
        }
    }
}
mitk::Image::Pointer ResampleDWIbySpacing(mitk::Image::Pointer input, float* spacing, bool useLinInt = true)
{

  itk::Vector<double, 3> spacingVector;
  spacingVector[0] = spacing[0];
  spacingVector[1] = spacing[1];
  spacingVector[2] = spacing[2];

  typedef itk::ResampleDwiImageFilter<short> ResampleFilterType;

  mitk::DiffusionPropertyHelper::ImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::ImageType::New();
  mitk::CastToItkImage(input, itkVectorImagePointer);

  ResampleFilterType::Pointer resampler = ResampleFilterType::New();
  resampler->SetInput( itkVectorImagePointer );
  resampler->SetInterpolation(ResampleFilterType::Interpolate_Linear);
  resampler->SetNewSpacing(spacingVector);
  resampler->Update();

  mitk::Image::Pointer output = mitk::GrabItkImageMemory( resampler->GetOutput() );
  output->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( mitk::DiffusionPropertyHelper::GetGradientContainer(input) ) );
  output->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( mitk::DiffusionPropertyHelper::GetReferenceBValue(input) ) );
  mitk::DiffusionPropertyHelper propertyHelper( output );
  propertyHelper.InitializeImage();

  return output;
}
bool mitk::DiffusionDICOMFileReader
::LoadSingleOutputImage( DiffusionHeaderDICOMFileReader::DICOMHeaderListType retrievedHeader,
                         DICOMImageBlockDescriptor& block, bool is_mosaic)
{
  // prepare data reading
  DiffusionDICOMFileReaderHelper helper;
  DiffusionDICOMFileReaderHelper::VolumeFileNamesContainer filenames;

  const DICOMImageFrameList& frames = block.GetImageFrameList();
  int numberOfDWImages = block.GetIntProperty("timesteps", 1);

  int numberOfFramesPerDWImage = frames.size() / numberOfDWImages;

  assert( int( double((double) frames.size() / (double) numberOfDWImages)) == numberOfFramesPerDWImage );
  for( int idx = 0; idx < numberOfDWImages; idx++ )
  {
    std::vector< std::string > FileNamesPerVolume;

    auto timeStepStart = frames.begin() + idx * numberOfFramesPerDWImage;
    auto timeStepEnd   = frames.begin() + (idx+1) * numberOfFramesPerDWImage;
    for (auto frameIter = timeStepStart;
         frameIter != timeStepEnd;
         ++frameIter)
    {
      FileNamesPerVolume.push_back( (*frameIter)->Filename );
    }

    filenames.push_back( FileNamesPerVolume );
  }

  // TODO : only prototyping to test loading of diffusion images
  // we need some solution for the different types
  mitk::Image::Pointer output_image = mitk::Image::New();

  mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer directions =
      mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::New();


  double max_bvalue = 0;
  for( int idx = 0; idx < numberOfDWImages; idx++ )
  {
    DiffusionImageDICOMHeaderInformation header = retrievedHeader.at(idx);

    if( max_bvalue < header.b_value )
      max_bvalue = header.b_value;
  }

  // normalize the retrieved gradient directions according to the set b-value (maximal one)
  for( int idx = 0; idx < numberOfDWImages; idx++ )
  {
    DiffusionImageDICOMHeaderInformation header = retrievedHeader.at(idx);
    mitk::DiffusionPropertyHelper::GradientDirectionType grad = header.g_vector;

    grad.normalize();
    grad *= sqrt( header.b_value / max_bvalue );

    directions->push_back( grad );
  }

  // initialize the output image
  output_image->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( directions ) );
  output_image->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( max_bvalue ) );

  if( is_mosaic && this->m_ResolveMosaic )
  {
    mitk::DiffusionHeaderSiemensMosaicDICOMFileReader::Pointer mosaic_reader =
        mitk::DiffusionHeaderSiemensMosaicDICOMFileReader::New();

    // retrieve the remaining meta-information needed for mosaic reconstruction
    // it suffices to get it exemplatory from the first file in the file list
    mosaic_reader->RetrieveMosaicInformation( filenames.at(0).at(0) );

    mitk::MosaicDescriptor mdesc = mosaic_reader->GetMosaicDescriptor();
    mitk::CastToMitkImage( helper.LoadMosaicToVector<short, 3>( filenames, mdesc ), output_image );

  }
  else
  {
    mitk::CastToMitkImage( helper.LoadToVector<short, 3>( filenames ), output_image );
  }

  mitk::DiffusionPropertyHelper propertyHelper( output_image );
  propertyHelper.InitializeImage();

  output_image->SetProperty("diffusion.dicom.importname", mitk::StringProperty::New( helper.GetOutputName(filenames) ) );
  block.SetMitkImage( (mitk::Image::Pointer) output_image );

  return block.GetMitkImage().IsNotNull();

}
Example #4
0
/*!
\brief Fits the tractogram to the input peak image by assigning a weight to each fiber (similar to https://doi.org/10.1016/j.neuroimage.2015.06.092).
*/
int main(int argc, char* argv[])
{
  mitkCommandLineParser parser;

  parser.setTitle("Fit Fibers To Image");
  parser.setCategory("Fiber Tracking and Processing Methods");
  parser.setDescription("Assigns a weight to each fiber in order to optimally explain the input peak image");
  parser.setContributor("MIC");

  parser.setArgumentPrefix("--", "-");
  parser.addArgument("", "i1", mitkCommandLineParser::StringList, "Input tractograms:", "input tractograms (.fib, vtk ascii file format)", us::Any(), false);
  parser.addArgument("", "i2", mitkCommandLineParser::InputFile, "Input image:", "input image", us::Any(), false);
  parser.addArgument("", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false);

  parser.addArgument("max_iter", "", mitkCommandLineParser::Int, "Max. iterations:", "maximum number of optimizer iterations", 20);
  parser.addArgument("bundle_based", "", mitkCommandLineParser::Bool, "Bundle based fit:", "fit one weight per input tractogram/bundle, not for each fiber", false);
  parser.addArgument("min_g", "", mitkCommandLineParser::Float, "Min. g:", "lower termination threshold for gradient magnitude", 1e-5);
  parser.addArgument("lambda", "", mitkCommandLineParser::Float, "Lambda:", "modifier for regularization", 0.1);
  parser.addArgument("save_res", "", mitkCommandLineParser::Bool, "Save Residuals:", "save residual images", false);
  parser.addArgument("save_weights", "", mitkCommandLineParser::Bool, "Save Weights:", "save fiber weights in a separate text file", false);
  parser.addArgument("filter_outliers", "", mitkCommandLineParser::Bool, "Filter outliers:", "perform second optimization run with an upper weight bound based on the first weight estimation (99% quantile)", false);
  parser.addArgument("join_tracts", "", mitkCommandLineParser::Bool, "Join output tracts:", "outout tracts are merged into a single tractogram", false);
  parser.addArgument("regu", "", mitkCommandLineParser::String, "Regularization:", "MSM, Variance, VoxelVariance (default), Lasso, GroupLasso, GroupVariance, NONE");

  std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
  if (parsedArgs.size()==0)
    return EXIT_FAILURE;

  mitkCommandLineParser::StringContainerType fib_files = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["i1"]);
  std::string input_image_name = us::any_cast<std::string>(parsedArgs["i2"]);
  std::string outRoot = us::any_cast<std::string>(parsedArgs["o"]);

  bool single_fib = true;
  if (parsedArgs.count("bundle_based"))
    single_fib = !us::any_cast<bool>(parsedArgs["bundle_based"]);

  bool save_residuals = false;
  if (parsedArgs.count("save_res"))
    save_residuals = us::any_cast<bool>(parsedArgs["save_res"]);

  bool save_weights = false;
  if (parsedArgs.count("save_weights"))
    save_weights = us::any_cast<bool>(parsedArgs["save_weights"]);

  std::string regu = "VoxelVariance";
  if (parsedArgs.count("regu"))
    regu = us::any_cast<std::string>(parsedArgs["regu"]);

  bool join_tracts = false;
  if (parsedArgs.count("join_tracts"))
    join_tracts = us::any_cast<bool>(parsedArgs["join_tracts"]);

  int max_iter = 20;
  if (parsedArgs.count("max_iter"))
    max_iter = us::any_cast<int>(parsedArgs["max_iter"]);

  float g_tol = 1e-5;
  if (parsedArgs.count("min_g"))
    g_tol = us::any_cast<float>(parsedArgs["min_g"]);

  float lambda = 0.1;
  if (parsedArgs.count("lambda"))
    lambda = us::any_cast<float>(parsedArgs["lambda"]);

  bool filter_outliers = false;
  if (parsedArgs.count("filter_outliers"))
    filter_outliers = us::any_cast<bool>(parsedArgs["filter_outliers"]);

  try
  {
    MITK_INFO << "Loading data";
    std::streambuf *old = cout.rdbuf(); // <-- save
    std::stringstream ss;
    std::cout.rdbuf (ss.rdbuf());       // <-- redirect
    std::vector< mitk::FiberBundle::Pointer > input_tracts;

    mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Peak Image", "Fiberbundles"}, {});

    std::vector< std::string > fib_names;
    for (auto item : fib_files)
    {
      if ( ist::FileIsDirectory(item) )
      {
        for ( auto fibFile : get_file_list(item) )
        {
          mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load<mitk::FiberBundle>(fibFile);
          if (inputTractogram.IsNull())
            continue;
          input_tracts.push_back(inputTractogram);
          fib_names.push_back(fibFile);
        }
      }
      else
      {
        mitk::FiberBundle::Pointer inputTractogram = mitk::IOUtil::Load<mitk::FiberBundle>(item);
        if (inputTractogram.IsNull())
          continue;
        input_tracts.push_back(inputTractogram);
        fib_names.push_back(item);
      }
    }
    std::cout.rdbuf (old);              // <-- restore

    itk::FitFibersToImageFilter::Pointer fitter = itk::FitFibersToImageFilter::New();

    mitk::BaseData::Pointer inputData = mitk::IOUtil::Load(input_image_name, &functor)[0].GetPointer();
    mitk::Image::Pointer mitk_image = dynamic_cast<mitk::Image*>(inputData.GetPointer());
    mitk::PeakImage::Pointer mitk_peak_image = dynamic_cast<mitk::PeakImage*>(inputData.GetPointer());
    if (mitk_peak_image.IsNotNull())
    {
      typedef mitk::ImageToItk< mitk::PeakImage::ItkPeakImageType > CasterType;
      CasterType::Pointer caster = CasterType::New();
      caster->SetInput(mitk_peak_image);
      caster->Update();
      mitk::PeakImage::ItkPeakImageType::Pointer peak_image = caster->GetOutput();
      fitter->SetPeakImage(peak_image);
    }
    else if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(mitk_image))
    {
      fitter->SetDiffImage(mitk::DiffusionPropertyHelper::GetItkVectorImage(mitk_image));
      mitk::TensorModel<>* model = new mitk::TensorModel<>();
      model->SetBvalue(1000);
      model->SetDiffusivity1(0.0010);
      model->SetDiffusivity2(0.00015);
      model->SetDiffusivity3(0.00015);
      model->SetGradientList(mitk::DiffusionPropertyHelper::GetGradientContainer(mitk_image));
      fitter->SetSignalModel(model);
    }
    else if (mitk_image->GetDimension()==3)
    {
      itk::FitFibersToImageFilter::DoubleImgType::Pointer scalar_image = itk::FitFibersToImageFilter::DoubleImgType::New();
      mitk::CastToItkImage(mitk_image, scalar_image);
      fitter->SetScalarImage(scalar_image);
    }
    else
    {
      MITK_INFO << "Input image invalid. Valid options are peak image, 3D scalar image or raw diffusion-weighted image.";
      return EXIT_FAILURE;
    }

    fitter->SetTractograms(input_tracts);
    fitter->SetFitIndividualFibers(single_fib);
    fitter->SetMaxIterations(max_iter);
    fitter->SetGradientTolerance(g_tol);
    fitter->SetLambda(lambda);
    fitter->SetFilterOutliers(filter_outliers);

    if (regu=="MSM")
      fitter->SetRegularization(VnlCostFunction::REGU::MSM);
    else if (regu=="Variance")
      fitter->SetRegularization(VnlCostFunction::REGU::VARIANCE);
    else if (regu=="Lasso")
      fitter->SetRegularization(VnlCostFunction::REGU::LASSO);
    else if (regu=="VoxelVariance")
      fitter->SetRegularization(VnlCostFunction::REGU::VOXEL_VARIANCE);
    else if (regu=="GroupLasso")
      fitter->SetRegularization(VnlCostFunction::REGU::GROUP_LASSO);
    else if (regu=="GroupVariance")
      fitter->SetRegularization(VnlCostFunction::REGU::GROUP_VARIANCE);
    else if (regu=="NONE")
      fitter->SetRegularization(VnlCostFunction::REGU::NONE);

    fitter->Update();

    if (save_residuals && mitk_peak_image.IsNotNull())
    {
      itk::ImageFileWriter< PeakImgType >::Pointer writer = itk::ImageFileWriter< PeakImgType >::New();
      writer->SetInput(fitter->GetFittedImage());
      writer->SetFileName(outRoot + "_fitted.nii.gz");
      writer->Update();

      writer->SetInput(fitter->GetResidualImage());
      writer->SetFileName(outRoot + "_residual.nii.gz");
      writer->Update();

      writer->SetInput(fitter->GetOverexplainedImage());
      writer->SetFileName(outRoot + "_overexplained.nii.gz");
      writer->Update();

      writer->SetInput(fitter->GetUnderexplainedImage());
      writer->SetFileName(outRoot + "_underexplained.nii.gz");
      writer->Update();
    }
    else if (save_residuals && mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(mitk_image))
    {
      {
        mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetFittedImageDiff().GetPointer() );
        mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true);
        mitk::DiffusionPropertyHelper propertyHelper( outImage );
        propertyHelper.InitializeImage();
        mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_fitted_image.nii.gz");
      }

      {
        mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetResidualImageDiff().GetPointer() );
        mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true);
        mitk::DiffusionPropertyHelper propertyHelper( outImage );
        propertyHelper.InitializeImage();
        mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_residual_image.nii.gz");
      }

      {
        mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetOverexplainedImageDiff().GetPointer() );
        mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true);
        mitk::DiffusionPropertyHelper propertyHelper( outImage );
        propertyHelper.InitializeImage();
        mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_overexplained_image.nii.gz");
      }

      {
        mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( fitter->GetUnderexplainedImageDiff().GetPointer() );
        mitk::DiffusionPropertyHelper::CopyProperties(mitk_image, outImage, true);
        mitk::DiffusionPropertyHelper propertyHelper( outImage );
        propertyHelper.InitializeImage();
        mitk::IOUtil::Save(outImage, "application/vnd.mitk.nii.gz", outRoot + "_underexplained_image.nii.gz");
      }
    }
    else if (save_residuals)
    {
      itk::ImageFileWriter< itk::FitFibersToImageFilter::DoubleImgType >::Pointer writer = itk::ImageFileWriter< itk::FitFibersToImageFilter::DoubleImgType >::New();
      writer->SetInput(fitter->GetFittedImageScalar());
      writer->SetFileName(outRoot + "_fitted_image.nii.gz");
      writer->Update();

      writer->SetInput(fitter->GetResidualImageScalar());
      writer->SetFileName(outRoot + "_residual_image.nii.gz");
      writer->Update();

      writer->SetInput(fitter->GetOverexplainedImageScalar());
      writer->SetFileName(outRoot + "_overexplained_image.nii.gz");
      writer->Update();

      writer->SetInput(fitter->GetUnderexplainedImageScalar());
      writer->SetFileName(outRoot + "_underexplained_image.nii.gz");
      writer->Update();
    }

    std::vector< mitk::FiberBundle::Pointer > output_tracts = fitter->GetTractograms();

    if (!join_tracts)
    {
      for (unsigned int bundle=0; bundle<output_tracts.size(); bundle++)
      {
        std::string name = fib_names.at(bundle);
        name = ist::GetFilenameWithoutExtension(name);
        mitk::IOUtil::Save(output_tracts.at(bundle), outRoot + name + "_fitted.fib");

        if (save_weights)
        {
          ofstream logfile;
          logfile.open (outRoot + name + "_weights.txt");
          for (int f=0; f<output_tracts.at(bundle)->GetNumFibers(); ++f)
            logfile << output_tracts.at(bundle)->GetFiberWeight(f) << "\n";
          logfile.close();
        }
      }
    }
    else
    {
      mitk::FiberBundle::Pointer out = mitk::FiberBundle::New();
      out = out->AddBundles(output_tracts);
      out->ColorFibersByFiberWeights(false, true);
      mitk::IOUtil::Save(out, outRoot + "_fitted.fib");

      if (save_weights)
      {
        ofstream logfile;
        logfile.open (outRoot + "_weights.txt");
        for (int f=0; f<out->GetNumFibers(); ++f)
          logfile << out->GetFiberWeight(f) << "\n";
        logfile.close();
      }
    }
  }
  catch (itk::ExceptionObject e)
  {
    std::cout << e;
    return EXIT_FAILURE;
  }
  catch (std::exception e)
  {
    std::cout << e.what();
    return EXIT_FAILURE;
  }
  catch (...)
  {
    std::cout << "ERROR!?!";
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}
int mitkExtractSingleShellTest( int argc, char* argv[] )
{
  MITK_TEST_BEGIN("mitkExtractSingleShellTest");

  MITK_TEST_CONDITION_REQUIRED( argc > 3, "Specify input and output and the shell to be extracted");

  /*
    1. Get input data
    */
  mitk::Image::Pointer dwimage = dynamic_cast<mitk::Image*>(mitk::IOUtil::Load( argv[1] )[0].GetPointer());

  mitk::GradientDirectionsProperty::Pointer gradientsProperty = static_cast<mitk::GradientDirectionsProperty *>( dwimage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() );

  MITK_TEST_CONDITION_REQUIRED( gradientsProperty.IsNotNull(), "Input is a dw-image");

  unsigned int extract_value = 0;
  std::istringstream input(argv[3]);

  input >> extract_value;

  typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter<DiffusionPixelType, DiffusionPixelType> FilterType;
  typedef mitk::DiffusionPropertyHelper::BValueMapType BValueMap;

  // GetShellSelection from GUI
  BValueMap shellSelectionMap;
  BValueMap originalShellMap = static_cast<mitk::BValueMapProperty*>(dwimage->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap();
  std::vector<unsigned int> newNumGradientDirections;

  shellSelectionMap[extract_value] = originalShellMap[extract_value];
  newNumGradientDirections.push_back( originalShellMap[extract_value].size() ) ;

  itk::VectorImage< short, 3 >::Pointer itkVectorImagePointer = itk::VectorImage< short, 3 >::New();
  mitk::CastToItkImage(dwimage, itkVectorImagePointer);
  itk::VectorImage< short, 3 > *vectorImage = itkVectorImagePointer.GetPointer();

  mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer gradientContainer = static_cast<mitk::GradientDirectionsProperty*>( dwimage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer();
  FilterType::Pointer filter = FilterType::New();
  filter->SetInput(vectorImage);
  filter->SetOriginalGradientDirections(gradientContainer);
  filter->SetNumGradientDirections(newNumGradientDirections);
  filter->SetOriginalBValueMap(originalShellMap);
  filter->SetShellSelectionBValueMap(shellSelectionMap);

  try
  {
    filter->Update();
  }
  catch( const itk::ExceptionObject& e)
  {
    MITK_TEST_FAILED_MSG( << "Failed due to ITK exception: " << e.what() );
  }

  mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() );
  mitk::DiffusionPropertyHelper::CopyProperties(dwimage, outImage, true);
  outImage->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetGradientDirections() ) );
  mitk::DiffusionPropertyHelper propertyHelper( outImage );
  propertyHelper.InitializeImage();

  /*
   * 3. Write output data
   **/
  try
  {
    mitk::IOUtil::Save(outImage, argv[2]);
  }
  catch( const itk::ExceptionObject& e)
  {
    MITK_ERROR << "Catched exception: " << e.what();
    mitkThrow() << "Failed with exception from subprocess!";
  }

  MITK_TEST_END();
}