void StartSimulation(FiberfoxParameters<double> parameters, FiberBundleX::Pointer fiberBundle, mitk::DiffusionImage<short>::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::DiffusionImage<short>::Pointer testImage = mitk::DiffusionImage<short>::New();
    testImage->SetVectorImage( tractsToDwiFilter->GetOutput() );
    testImage->SetB_Value(parameters.m_Bvalue);
    testImage->SetDirections(parameters.GetGradientDirections());
    testImage->InitializeFromVectorImage();

    if (refImage.IsNotNull())
    {
        bool cond = CompareDwi(testImage->GetVectorImage(), refImage->GetVectorImage());
        if (!cond)
        {
            mitk::IOUtil::SaveBaseData(testImage, "/tmp/testImage.dwi");
            mitk::IOUtil::SaveBaseData(refImage, "/tmp/refImage.dwi");
        }
        MITK_TEST_CONDITION_REQUIRED(cond, message);
    }
    else
    {
        MITK_INFO << "Saving test image to " << message;
        mitk::IOUtil::SaveBaseData(testImage, message);
    }
}
    void StartSimulation(string testFileName)
    {
        mitk::DiffusionImage<short>::Pointer refImage = NULL;
        if (!testFileName.empty())
            CPPUNIT_ASSERT(refImage = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(testFileName)->GetData()));

        itk::AddArtifactsToDwiImageFilter< short >::Pointer artifactsToDwiFilter = itk::AddArtifactsToDwiImageFilter< short >::New();
        artifactsToDwiFilter->SetUseConstantRandSeed(true);
        artifactsToDwiFilter->SetInput(m_InputDwi->GetVectorImage());
        artifactsToDwiFilter->SetParameters(m_Parameters);
        CPPUNIT_ASSERT_NO_THROW(artifactsToDwiFilter->Update());

        mitk::DiffusionImage<short>::Pointer testImage = mitk::DiffusionImage<short>::New();
        testImage->SetVectorImage( artifactsToDwiFilter->GetOutput() );
        testImage->SetB_Value(m_Parameters.m_Bvalue);
        testImage->SetDirections(m_Parameters.GetGradientDirections());
        testImage->InitializeFromVectorImage();

        if (refImage.IsNotNull())
        {
            bool ok = CompareDwi(testImage->GetVectorImage(), refImage->GetVectorImage());
            if (!ok)
            {
                mitk::IOUtil::SaveBaseData(testImage, "/tmp/test2.dwi");
                mitk::IOUtil::SaveBaseData(refImage, "/tmp/ref2.dwi");
            }
            CPPUNIT_ASSERT_MESSAGE(testFileName, ok);
        }
        else
        {
            mitk::IOUtil::SaveBaseData(testImage, "/local/distortions2.dwi");
        }
    }
    void setUp()
    {
        // reference files
        m_InputDwi = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(GetTestDataFilePath("DiffusionImaging/Fiberfox/StickBall_RELAX.dwi"))->GetData());

        // parameter setup
        m_Parameters = FiberfoxParameters<short>();
        m_Parameters.m_ImageRegion = m_InputDwi->GetVectorImage()->GetLargestPossibleRegion();
        m_Parameters.m_ImageSpacing = m_InputDwi->GetVectorImage()->GetSpacing();
        m_Parameters.m_ImageOrigin = m_InputDwi->GetVectorImage()->GetOrigin();
        m_Parameters.m_ImageDirection = m_InputDwi->GetVectorImage()->GetDirection();
        m_Parameters.m_Bvalue = m_InputDwi->GetB_Value();
        m_Parameters.SetGradienDirections(m_InputDwi->GetDirections());
    }
int mitkFiberfoxSignalGenerationTest(int argc, char* argv[])
{
    MITK_TEST_BEGIN("mitkFiberfoxSignalGenerationTest");

    // input fiber bundle
    FiberBundle::Pointer fiberBundle = dynamic_cast<FiberBundle*>(mitk::IOUtil::Load(argv[1])[0].GetPointer());

    for (int i=2; i<argc; i++)
    {
        // Load parameter file
        FiberfoxParameters<double> parameters;
        string file = argv[i];
        MITK_INFO << "Starting test: " << file;
        parameters.LoadParameters(file+".ffp");

        // Load reference diffusion weighted image
        mitk::Image::Pointer mitkRef = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(file+".dwi")->GetData());

        StartSimulation(parameters, fiberBundle, mitkRef, file);
    }

    // always end with this!
    MITK_TEST_END();
}
int mitkFiberfoxSignalGenerationTest(int argc, char* argv[])
{
    MITK_TEST_BEGIN("mitkFiberfoxSignalGenerationTest");

    MITK_TEST_CONDITION_REQUIRED(argc>=19,"check for input data");

    // input fiber bundle
    FiberBundleXReader::Pointer fibReader = FiberBundleXReader::New();
    fibReader->SetFileName(argv[1]);
    fibReader->Update();
    FiberBundleX::Pointer fiberBundle = dynamic_cast<FiberBundleX*>(fibReader->GetOutput());

    // reference diffusion weighted images
    mitk::DiffusionImage<short>::Pointer stickBall = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[2])->GetData());
    mitk::DiffusionImage<short>::Pointer stickAstrosticks = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[3])->GetData());
    mitk::DiffusionImage<short>::Pointer stickDot = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[4])->GetData());
    mitk::DiffusionImage<short>::Pointer tensorBall = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[5])->GetData());
    mitk::DiffusionImage<short>::Pointer stickTensorBall = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[6])->GetData());
    mitk::DiffusionImage<short>::Pointer stickTensorBallAstrosticks = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[7])->GetData());
    mitk::DiffusionImage<short>::Pointer gibbsringing = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[8])->GetData());
    mitk::DiffusionImage<short>::Pointer ghost = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[9])->GetData());
    mitk::DiffusionImage<short>::Pointer aliasing = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[10])->GetData());
    mitk::DiffusionImage<short>::Pointer eddy = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[11])->GetData());
    mitk::DiffusionImage<short>::Pointer linearmotion = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[12])->GetData());
    mitk::DiffusionImage<short>::Pointer randommotion = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[13])->GetData());
    mitk::DiffusionImage<short>::Pointer spikes = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[14])->GetData());
    mitk::DiffusionImage<short>::Pointer riciannoise = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[15])->GetData());
    mitk::DiffusionImage<short>::Pointer chisquarenoise = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[16])->GetData());
    mitk::DiffusionImage<short>::Pointer distortions = dynamic_cast<mitk::DiffusionImage<short>*>(mitk::IOUtil::LoadDataNode(argv[17])->GetData());
    mitk::Image::Pointer mitkFMap = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(argv[18])->GetData());
    typedef itk::Image<double, 3> ItkDoubleImgType;
    ItkDoubleImgType::Pointer fMap = ItkDoubleImgType::New();
    mitk::CastToItkImage<ItkDoubleImgType>(mitkFMap, fMap);

    FiberfoxParameters<double> parameters;
    parameters.m_DoSimulateRelaxation = true;
    parameters.m_SignalScale = 10000;
    parameters.m_ImageRegion = stickBall->GetVectorImage()->GetLargestPossibleRegion();
    parameters.m_ImageSpacing = stickBall->GetVectorImage()->GetSpacing();
    parameters.m_ImageOrigin = stickBall->GetVectorImage()->GetOrigin();
    parameters.m_ImageDirection = stickBall->GetVectorImage()->GetDirection();
    parameters.m_Bvalue = stickBall->GetB_Value();
    parameters.SetGradienDirections(stickBall->GetDirections());

    // intra and inter axonal compartments
    mitk::StickModel<double> stickModel;
    stickModel.SetBvalue(parameters.m_Bvalue);
    stickModel.SetT2(110);
    stickModel.SetDiffusivity(0.001);
    stickModel.SetGradientList(parameters.GetGradientDirections());

    mitk::TensorModel<double> tensorModel;
    tensorModel.SetT2(110);
    stickModel.SetBvalue(parameters.m_Bvalue);
    tensorModel.SetDiffusivity1(0.001);
    tensorModel.SetDiffusivity2(0.00025);
    tensorModel.SetDiffusivity3(0.00025);
    tensorModel.SetGradientList(parameters.GetGradientDirections());

    // extra axonal compartment models
    mitk::BallModel<double> ballModel;
    ballModel.SetT2(80);
    ballModel.SetBvalue(parameters.m_Bvalue);
    ballModel.SetDiffusivity(0.001);
    ballModel.SetGradientList(parameters.GetGradientDirections());

    mitk::AstroStickModel<double> astrosticksModel;
    astrosticksModel.SetT2(80);
    astrosticksModel.SetBvalue(parameters.m_Bvalue);
    astrosticksModel.SetDiffusivity(0.001);
    astrosticksModel.SetRandomizeSticks(true);
    astrosticksModel.SetSeed(0);
    astrosticksModel.SetGradientList(parameters.GetGradientDirections());

    mitk::DotModel<double> dotModel;
    dotModel.SetT2(80);
    dotModel.SetGradientList(parameters.GetGradientDirections());

    // noise models
    mitk::RicianNoiseModel<double>* ricianNoiseModel = new mitk::RicianNoiseModel<double>();
    ricianNoiseModel->SetNoiseVariance(1000000);
    ricianNoiseModel->SetSeed(0);

    // Rician noise
    mitk::ChiSquareNoiseModel<double>* chiSquareNoiseModel = new mitk::ChiSquareNoiseModel<double>();
    chiSquareNoiseModel->SetNoiseVariance(1000000);
    chiSquareNoiseModel->SetSeed(0);

    try {
        // Stick-Ball
        parameters.m_FiberModelList.push_back(&stickModel);
        parameters.m_NonFiberModelList.push_back(&ballModel);
        StartSimulation(parameters, fiberBundle, stickBall, argv[2]);

        // Srick-Astrosticks
        parameters.m_NonFiberModelList.clear();
        parameters.m_NonFiberModelList.push_back(&astrosticksModel);
        StartSimulation(parameters, fiberBundle, stickAstrosticks, argv[3]);

        // Stick-Dot
        parameters.m_NonFiberModelList.clear();
        parameters.m_NonFiberModelList.push_back(&dotModel);
        StartSimulation(parameters, fiberBundle, stickDot, argv[4]);

        // Tensor-Ball
        parameters.m_FiberModelList.clear();
        parameters.m_FiberModelList.push_back(&tensorModel);
        parameters.m_NonFiberModelList.clear();
        parameters.m_NonFiberModelList.push_back(&ballModel);
        StartSimulation(parameters, fiberBundle, tensorBall, argv[5]);

        // Stick-Tensor-Ball
        parameters.m_FiberModelList.clear();
        parameters.m_FiberModelList.push_back(&stickModel);
        parameters.m_FiberModelList.push_back(&tensorModel);
        parameters.m_NonFiberModelList.clear();
        parameters.m_NonFiberModelList.push_back(&ballModel);
        StartSimulation(parameters, fiberBundle, stickTensorBall, argv[6]);

        // Stick-Tensor-Ball-Astrosticks
        parameters.m_NonFiberModelList.push_back(&astrosticksModel);
        StartSimulation(parameters, fiberBundle, stickTensorBallAstrosticks, argv[7]);

        // Gibbs ringing
        parameters.m_FiberModelList.clear();
        parameters.m_FiberModelList.push_back(&stickModel);
        parameters.m_NonFiberModelList.clear();
        parameters.m_NonFiberModelList.push_back(&ballModel);
        parameters.m_DoAddGibbsRinging = true;
        StartSimulation(parameters, fiberBundle, gibbsringing, argv[8]);

        // Ghost
        parameters.m_DoAddGibbsRinging = false;
        parameters.m_KspaceLineOffset = 0.25;
        StartSimulation(parameters, fiberBundle, ghost, argv[9]);

        // Aliasing
        parameters.m_KspaceLineOffset = 0;
        parameters.m_CroppingFactor = 0.4;
        parameters.m_SignalScale = 1000;
        StartSimulation(parameters, fiberBundle, aliasing, argv[10]);

        // Eddy currents
        parameters.m_CroppingFactor = 1;
        parameters.m_SignalScale = 10000;
        parameters.m_EddyStrength = 0.05;
        StartSimulation(parameters, fiberBundle, eddy, argv[11]);

        // Motion (linear)
        parameters.m_EddyStrength = 0.0;
        parameters.m_DoAddMotion = true;
        parameters.m_DoRandomizeMotion = false;
        parameters.m_Translation[1] = 10;
        parameters.m_Rotation[2] = 90;
        StartSimulation(parameters, fiberBundle, linearmotion, argv[12]);

        // Motion (random)
        parameters.m_DoRandomizeMotion = true;
        parameters.m_Translation[1] = 5;
        parameters.m_Rotation[2] = 45;
        StartSimulation(parameters, fiberBundle, randommotion, argv[13]);

        // Spikes
        parameters.m_DoAddMotion = false;
        parameters.m_Spikes = 5;
        parameters.m_SpikeAmplitude = 1;
        StartSimulation(parameters, fiberBundle, spikes, argv[14]);

        // Rician noise
        parameters.m_Spikes = 0;
        parameters.m_NoiseModel = ricianNoiseModel;
        StartSimulation(parameters, fiberBundle, riciannoise, argv[15]);
        delete parameters.m_NoiseModel;

        // Chi-square noise
        parameters.m_NoiseModel = chiSquareNoiseModel;
        StartSimulation(parameters, fiberBundle, chisquarenoise, argv[16]);
        delete parameters.m_NoiseModel;

        // Distortions
        parameters.m_NoiseModel = NULL;
        parameters.m_FrequencyMap = fMap;
        StartSimulation(parameters, fiberBundle, distortions, argv[17]);
    }
    catch (std::exception &e)
    {
        MITK_TEST_CONDITION_REQUIRED(false, e.what());
    }

    // always end with this!
    MITK_TEST_END();
}
Exemplo n.º 6
0
/*!
* \brief Command line interface to Fiberfox.
* Simulate a diffusion-weighted image from a tractogram using the specified parameter file.
*/
int main(int argc, char* argv[])
{
  mitkCommandLineParser parser;
  parser.setTitle("Fiberfox");
  parser.setCategory("Diffusion Simulation Tools");
  parser.setContributor("MIC");
  parser.setDescription("Command line interface to Fiberfox." " Simulate a diffusion-weighted image from a tractogram using the specified parameter file.");
  parser.setArgumentPrefix("--", "-");
  parser.addArgument("", "o", mitkCommandLineParser::String, "Output root:", "output folder and file prefix", us::Any(), false, false, false, mitkCommandLineParser::Output);
  parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input tractogram or diffusion-weighted image", us::Any(), false, false, false, mitkCommandLineParser::Input);
  parser.addArgument("parameters", "p", mitkCommandLineParser::String, "Parameter file:", "fiberfox parameter file (.ffp)", us::Any(), false, false, false, mitkCommandLineParser::Input);
  parser.addArgument("template", "t", mitkCommandLineParser::String, "Template image:", "use parameters of the template image", us::Any(), true, false, false, mitkCommandLineParser::Input);
  parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Output additional images:", "output volume fraction images etc.", us::Any());
  parser.addArgument("dont_apply_direction_matrix", "", mitkCommandLineParser::Bool, "Don't apply direction matrix:", "don't rotate gradients by image direction matrix", us::Any());
  parser.addArgument("fix_seed", "", mitkCommandLineParser::Bool, "Use fix random seed:", "always use same sequence of random numbers", us::Any());

  std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
  if (parsedArgs.size()==0)
  {
    return EXIT_FAILURE;
  }
  std::string outName = us::any_cast<std::string>(parsedArgs["o"]);
  std::string paramName = us::any_cast<std::string>(parsedArgs["parameters"]);

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

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

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

  bool apply_direction_matrix = true;
  if (parsedArgs.count("dont_apply_direction_matrix"))
    apply_direction_matrix = false;

  FiberfoxParameters parameters;
  parameters.LoadParameters(paramName, fix_seed);

  // Test if /path/dir is an existing directory:
  std::string file_extension = "";
  if( itksys::SystemTools::FileIsDirectory( outName ) )
  {
    while( *(--(outName.cend())) == '/')
    {
      outName.pop_back();
    }
    outName = outName + '/';
    parameters.m_Misc.m_OutputPath = outName;
    outName = outName + parameters.m_Misc.m_OutputPrefix; // using default m_OutputPrefix as initialized.
  }
  else
  {
    // outName is NOT an existing directory, so we need to remove all trailing slashes:
    while( *(--(outName.cend())) == '/')
    {
      outName.pop_back();
    }

    // now split up the given outName into directory and (prefix of) filename:
    if( ! itksys::SystemTools::GetFilenamePath( outName ).empty()
        && itksys::SystemTools::FileIsDirectory(itksys::SystemTools::GetFilenamePath( outName ) ) )
    {
      parameters.m_Misc.m_OutputPath = itksys::SystemTools::GetFilenamePath( outName ) + '/';
    }
    else
    {
      parameters.m_Misc.m_OutputPath = itksys::SystemTools::GetCurrentWorkingDirectory() + '/';
    }

    file_extension = itksys::SystemTools::GetFilenameExtension(outName);
    if( ! itksys::SystemTools::GetFilenameWithoutExtension( outName ).empty() )
    {
      parameters.m_Misc.m_OutputPrefix = itksys::SystemTools::GetFilenameWithoutExtension( outName );
    }
    else
    {
      parameters.m_Misc.m_OutputPrefix = "fiberfox";
    }

    outName = parameters.m_Misc.m_OutputPath + parameters.m_Misc.m_OutputPrefix;
  }

  mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images", "Fiberbundles"}, {});
  mitk::BaseData::Pointer inputData = mitk::IOUtil::Load(input, &functor)[0];

  itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New();

  if ( dynamic_cast<mitk::FiberBundle*>(inputData.GetPointer()) )   // simulate dataset from fibers
  {
    tractsToDwiFilter->SetFiberBundle(dynamic_cast<mitk::FiberBundle*>(inputData.GetPointer()));

    if (parsedArgs.count("template"))
    {
      MITK_INFO << "Loading template image";
      typedef itk::VectorImage< short, 3 >    ItkDwiType;
      typedef itk::Image< short, 3 >    ItkImageType;
      mitk::BaseData::Pointer templateData = mitk::IOUtil::Load(us::any_cast<std::string>(parsedArgs["template"]), &functor)[0];
      mitk::Image::Pointer template_image = dynamic_cast<mitk::Image*>(templateData.GetPointer());

      if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(template_image))
      {
        ItkDwiType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::GetItkVectorImage(template_image);
        parameters.m_SignalGen.m_ImageRegion = itkVectorImagePointer->GetLargestPossibleRegion();
        parameters.m_SignalGen.m_ImageSpacing = itkVectorImagePointer->GetSpacing();
        parameters.m_SignalGen.m_ImageOrigin = itkVectorImagePointer->GetOrigin();
        parameters.m_SignalGen.m_ImageDirection = itkVectorImagePointer->GetDirection();
        parameters.SetBvalue(mitk::DiffusionPropertyHelper::GetReferenceBValue(template_image));
        parameters.SetGradienDirections(mitk::DiffusionPropertyHelper::GetOriginalGradientContainer(template_image));
      }
      else
      {
        ItkImageType::Pointer itkImagePointer = ItkImageType::New();
        mitk::CastToItkImage(template_image, itkImagePointer);
        parameters.m_SignalGen.m_ImageRegion = itkImagePointer->GetLargestPossibleRegion();
        parameters.m_SignalGen.m_ImageSpacing = itkImagePointer->GetSpacing();
        parameters.m_SignalGen.m_ImageOrigin = itkImagePointer->GetOrigin();
        parameters.m_SignalGen.m_ImageDirection = itkImagePointer->GetDirection();
      }
    }
  }
  else if ( dynamic_cast<mitk::Image*>(inputData.GetPointer()) )  // add artifacts to existing image
  {
    typedef itk::VectorImage< short, 3 >    ItkDwiType;
    mitk::Image::Pointer diffImg = dynamic_cast<mitk::Image*>(inputData.GetPointer());
    ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New();
    mitk::CastToItkImage(diffImg, itkVectorImagePointer);

    parameters.m_SignalGen.m_SignalScale = 1;
    parameters.m_SignalGen.m_ImageRegion = itkVectorImagePointer->GetLargestPossibleRegion();
    parameters.m_SignalGen.m_ImageSpacing = itkVectorImagePointer->GetSpacing();
    parameters.m_SignalGen.m_ImageOrigin = itkVectorImagePointer->GetOrigin();
    parameters.m_SignalGen.m_ImageDirection = itkVectorImagePointer->GetDirection();
    parameters.SetBvalue(mitk::DiffusionPropertyHelper::GetReferenceBValue(diffImg));
    parameters.SetGradienDirections(mitk::DiffusionPropertyHelper::GetOriginalGradientContainer(diffImg));

    tractsToDwiFilter->SetInputImage(itkVectorImagePointer);
  }

  if (verbose)
  {
    MITK_DEBUG << outName << ".ffp";
    parameters.m_Misc.m_OutputAdditionalImages = true;
    parameters.SaveParameters(outName+".ffp");
  }
  else
    parameters.m_Misc.m_OutputAdditionalImages = false;
  
  if (apply_direction_matrix)
  {
    MITK_INFO << "Applying direction matrix to gradient directions.";
    parameters.ApplyDirectionMatrix();
  }
  tractsToDwiFilter->SetParameters(parameters);
  tractsToDwiFilter->SetUseConstantRandSeed(fix_seed);
  tractsToDwiFilter->Update();

  mitk::Image::Pointer image = mitk::GrabItkImageMemory(tractsToDwiFilter->GetOutput());

  if (parameters.m_SignalGen.GetNumWeightedVolumes()>0)
  {
    if (apply_direction_matrix)
      mitk::DiffusionPropertyHelper::SetGradientContainer(image, parameters.m_SignalGen.GetItkGradientContainer());
    else
      mitk::DiffusionPropertyHelper::SetOriginalGradientContainer(image, parameters.m_SignalGen.GetItkGradientContainer());
    mitk::DiffusionPropertyHelper::SetReferenceBValue(image, parameters.m_SignalGen.GetBvalue());
    mitk::DiffusionPropertyHelper::InitializeImage(image);

    if (file_extension=="")
      mitk::IOUtil::Save(image, "DWI_NIFTI", outName+".nii.gz");
    else if (file_extension==".nii" || file_extension==".nii.gz")
      mitk::IOUtil::Save(image, "DWI_NIFTI", outName+file_extension);
    else
      mitk::IOUtil::Save(image, outName+file_extension);
  }
  else
    mitk::IOUtil::Save(image, outName+".nii.gz");

  if (verbose)
  {
    if (tractsToDwiFilter->GetTickImage().IsNotNull())
    {
      mitk::Image::Pointer mitkImage = mitk::Image::New();
      itk::TractsToDWIImageFilter< short >::Float2DImageType::Pointer itkImage = tractsToDwiFilter->GetTickImage();
      mitkImage = mitk::GrabItkImageMemory( itkImage.GetPointer() );
      mitk::IOUtil::Save(mitkImage, outName+"_Ticks.nii.gz");
    }

    if (tractsToDwiFilter->GetRfImage().IsNotNull())
    {
      mitk::Image::Pointer mitkImage = mitk::Image::New();
      itk::TractsToDWIImageFilter< short >::Float2DImageType::Pointer itkImage = tractsToDwiFilter->GetRfImage();
      mitkImage = mitk::GrabItkImageMemory( itkImage.GetPointer() );
      mitk::IOUtil::Save(mitkImage, outName+"_TimeFromRf.nii.gz");
    }

    std::vector< itk::TractsToDWIImageFilter< short >::ItkDoubleImgType::Pointer > volumeFractions = tractsToDwiFilter->GetVolumeFractions();
    for (unsigned int k=0; k<volumeFractions.size(); k++)
    {
      mitk::Image::Pointer image = mitk::Image::New();
      image->InitializeByItk(volumeFractions.at(k).GetPointer());
      image->SetVolume(volumeFractions.at(k)->GetBufferPointer());
      mitk::IOUtil::Save(image, outName+"_Compartment"+boost::lexical_cast<std::string>(k+1)+".nii.gz");
    }

    if (tractsToDwiFilter->GetPhaseImage().IsNotNull())
    {
      mitk::Image::Pointer image = mitk::Image::New();
      itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer itkPhase = tractsToDwiFilter->GetPhaseImage();
      image = mitk::GrabItkImageMemory( itkPhase.GetPointer() );
      mitk::IOUtil::Save(image, outName+"_Phase.nii.gz");
    }

    if (tractsToDwiFilter->GetKspaceImage().IsNotNull())
    {
      mitk::Image::Pointer image = mitk::Image::New();
      itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer itkImage = tractsToDwiFilter->GetKspaceImage();
      image = mitk::GrabItkImageMemory( itkImage.GetPointer() );
      mitk::IOUtil::Save(image, outName+"_kSpace.nii.gz");
    }

    int c = 1;
    std::vector< itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer > output_real = tractsToDwiFilter->GetOutputImagesReal();
    for (auto real : output_real)
    {
      mitk::Image::Pointer image = mitk::Image::New();
      image->InitializeByItk(real.GetPointer());
      image->SetVolume(real->GetBufferPointer());
      mitk::IOUtil::Save(image, outName+"_Coil-"+boost::lexical_cast<std::string>(c)+"-real.nii.gz");
      ++c;
    }

    c = 1;
    std::vector< itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer > output_imag = tractsToDwiFilter->GetOutputImagesImag();
    for (auto imag : output_imag)
    {
      mitk::Image::Pointer image = mitk::Image::New();
      image->InitializeByItk(imag.GetPointer());
      image->SetVolume(imag->GetBufferPointer());
      mitk::IOUtil::Save(image, outName+"_Coil-"+boost::lexical_cast<std::string>(c)+"-imag.nii.gz");
      ++c;
    }
  }

  return EXIT_SUCCESS;
}