void QmitkTensorReconstructionView::ItkTensorReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages)
{
    try
    {
        itk::TimeProbe clock;

        int nrFiles = inImages->size();
        if (!nrFiles) return;

        QString status;
        mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles);

        mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
        mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );

        std::vector<mitk::DataNode::Pointer> nodes;
        while ( itemiter != itemiterend ) // for all items
        {

            mitk::DiffusionImage<DiffusionPixelType>* vols =
                    static_cast<mitk::DiffusionImage<DiffusionPixelType>*>(
                        (*itemiter)->GetData());

            std::string nodename;
            (*itemiter)->GetStringProperty("name", nodename);
            ++itemiter;

            // TENSOR RECONSTRUCTION
            clock.Start();
            MITK_DEBUG << "Tensor reconstruction ";
            mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toAscii());
            typedef itk::DiffusionTensor3DReconstructionImageFilter<
                    DiffusionPixelType, DiffusionPixelType, TTensorPixelType > TensorReconstructionImageFilterType;
            TensorReconstructionImageFilterType::Pointer tensorReconstructionFilter =
                    TensorReconstructionImageFilterType::New();
            tensorReconstructionFilter->SetGradientImage( vols->GetDirections(), vols->GetVectorImage() );
            tensorReconstructionFilter->SetBValue(vols->GetB_Value());
            tensorReconstructionFilter->SetThreshold( m_Controls->m_TensorReconstructionThreshold->value() );
            tensorReconstructionFilter->Update();
            clock.Stop();
            MITK_DEBUG << "took " << clock.GetMeanTime() << "s.";

            // TENSORS TO DATATREE
            mitk::TensorImage::Pointer image = mitk::TensorImage::New();

            typedef itk::Image<itk::DiffusionTensor3D<TTensorPixelType>, 3> TensorImageType;
            TensorImageType::Pointer tensorImage;
            tensorImage = tensorReconstructionFilter->GetOutput();

            // Check the tensor for negative eigenvalues
            if(m_Controls->m_CheckNegativeEigenvalues->isChecked())
            {
                typedef itk::ImageRegionIterator<TensorImageType> TensorImageIteratorType;
                TensorImageIteratorType tensorIt(tensorImage, tensorImage->GetRequestedRegion());
                tensorIt.GoToBegin();

                while(!tensorIt.IsAtEnd())
                {

                    typedef itk::DiffusionTensor3D<TTensorPixelType> TensorType;
                    //typedef itk::Tensor<TTensorPixelType, 3> TensorType2;

                    TensorType tensor = tensorIt.Get();

                    TensorType::EigenValuesArrayType ev;
                    tensor.ComputeEigenValues(ev);
                    for(unsigned int i=0; i<ev.Size(); i++)
                    {
                        if(ev[i] < 0.0)
                        {
                            tensor.Fill(0.0);
                            tensorIt.Set(tensor);
                            break;
                        }
                    }
                    ++tensorIt;
                }
            }

            tensorImage->SetDirection( vols->GetVectorImage()->GetDirection() );
            image->InitializeByItk( tensorImage.GetPointer() );
            image->SetVolume( tensorReconstructionFilter->GetOutput()->GetBufferPointer() );
            mitk::DataNode::Pointer node=mitk::DataNode::New();
            node->SetData( image );

            QString newname;
            newname = newname.append(nodename.c_str());
            newname = newname.append("_dti");

            SetDefaultNodeProperties(node, newname.toStdString());
            nodes.push_back(node);

            mitk::ProgressBar::GetInstance()->Progress();
        }

        std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
        for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
            GetDefaultDataStorage()->Add(*nodeIt);

        mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii());
        m_MultiWidget->RequestUpdate();

    }
    catch (itk::ExceptionObject &ex)
    {
        MITK_INFO << ex ;
        QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription());
        return;
    }
}
void QmitkTensorReconstructionView::DoTensorsToDWI(mitk::DataStorage::SetOfObjects::Pointer inImages)
{
    try
    {
        itk::TimeProbe clock;

        int nrFiles = inImages->size();
        if (!nrFiles) return;

        QString status;
        mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles);

        mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
        mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );

        std::vector<mitk::DataNode::Pointer> nodes;
        while ( itemiter != itemiterend ) // for all items
        {

            std::string nodename;
            (*itemiter)->GetStringProperty("name", nodename);

            mitk::TensorImage* vol =
                    static_cast<mitk::TensorImage*>((*itemiter)->GetData());

            ++itemiter;

            typedef float                                       TTensorPixelType;
            typedef itk::DiffusionTensor3D< TTensorPixelType >  TensorPixelType;
            typedef itk::Image< TensorPixelType, 3 >            TensorImageType;


            TensorImageType::Pointer itkvol = TensorImageType::New();
            mitk::CastToItkImage<TensorImageType>(vol, itkvol);

            typedef itk::TensorImageToDiffusionImageFilter<
                    TTensorPixelType, DiffusionPixelType > FilterType;

            FilterType::GradientListType gradientList;

            switch(m_Controls->m_TensorsToDWINumDirsSelect->currentIndex())
            {
            case 0:
                gradientList = MakeGradientList<12>();
                break;
            case 1:
                gradientList = MakeGradientList<42>();
                break;
            case 2:
                gradientList = MakeGradientList<92>();
                break;
            case 3:
                gradientList = MakeGradientList<162>();
                break;
            case 4:
                gradientList = MakeGradientList<252>();
                break;
            case 5:
                gradientList = MakeGradientList<362>();
                break;
            case 6:
                gradientList = MakeGradientList<492>();
                break;
            case 7:
                gradientList = MakeGradientList<642>();
                break;
            case 8:
                gradientList = MakeGradientList<812>();
                break;
            case 9:
                gradientList = MakeGradientList<1002>();
                break;
            default:
                gradientList = MakeGradientList<92>();

            }

            double bVal = m_Controls->m_TensorsToDWIBValueEdit->text().toDouble();

            // DWI ESTIMATION
            clock.Start();
            MBI_INFO << "DWI Estimation ";
            mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
                                                            "DWI Estimation for %s", nodename.c_str()).toAscii());
            FilterType::Pointer filter = FilterType::New();
            filter->SetInput( itkvol );
            filter->SetBValue(bVal);
            filter->SetGradientList(gradientList);
            //filter->SetNumberOfThreads(1);
            filter->Update();
            clock.Stop();
            MBI_DEBUG << "took " << clock.GetMeanTime() << "s.";

            // TENSORS TO DATATREE
            mitk::DiffusionImage<DiffusionPixelType>::Pointer image = mitk::DiffusionImage<DiffusionPixelType>::New();
            image->SetVectorImage( filter->GetOutput() );
            image->SetB_Value(bVal);
            image->SetDirections(gradientList);
            image->InitializeFromVectorImage();
            mitk::DataNode::Pointer node=mitk::DataNode::New();
            node->SetData( image );

            mitk::DiffusionImageMapper<short>::SetDefaultProperties(node);

            QString newname;
            newname = newname.append(nodename.c_str());
            newname = newname.append("_dwi");
            node->SetName(newname.toAscii());

            nodes.push_back(node);

            mitk::ProgressBar::GetInstance()->Progress();

        }

        std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
        for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
            GetDefaultDataStorage()->Add(*nodeIt);

        mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii());
        m_MultiWidget->RequestUpdate();

    }
    catch (itk::ExceptionObject &ex)
    {
        MITK_INFO << ex ;
        QMessageBox::information(0, "DWI estimation failed:", ex.GetDescription());
        return ;
    }
}
void QmitkTensorReconstructionView::TensorReconstructionWithCorr
(mitk::DataStorage::SetOfObjects::Pointer inImages)
{
    try
    {
        itk::TimeProbe clock;
        int nrFiles = inImages->size();
        if (!nrFiles) return;

        QString status;
        mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles);

        mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
        mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );

        std::vector<mitk::DataNode::Pointer> nodes;
        while ( itemiter != itemiterend ) // for all items
        {

            typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;

            DiffusionImageType* vols = static_cast<DiffusionImageType*>((*itemiter)->GetData());

            std::string nodename;
            (*itemiter)->GetStringProperty("name", nodename);
            ++itemiter;

            // TENSOR RECONSTRUCTION
            clock.Start();
            MITK_INFO << "Tensor reconstruction with correction for negative eigenvalues";
            mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toAscii());

            typedef itk::TensorReconstructionWithEigenvalueCorrectionFilter< DiffusionPixelType, TTensorPixelType > ReconstructionFilter;

            float b0Threshold = m_Controls->m_TensorReconstructionThreshold->value();

            ReconstructionFilter::Pointer reconFilter = ReconstructionFilter::New();
            reconFilter->SetGradientImage( vols->GetDirections(), vols->GetVectorImage() );
            reconFilter->SetBValue(vols->GetB_Value());
            reconFilter->SetB0Threshold(b0Threshold);
            reconFilter->Update();

            typedef itk::Image<itk::DiffusionTensor3D<TTensorPixelType>, 3> TensorImageType;
            TensorImageType::Pointer outputTensorImg = reconFilter->GetOutput();

            typedef itk::ImageRegionIterator<TensorImageType> TensorImageIteratorType;
            TensorImageIteratorType tensorIt(outputTensorImg, outputTensorImg->GetRequestedRegion());
            tensorIt.GoToBegin();

            int negatives = 0;
            while(!tensorIt.IsAtEnd())
            {
                typedef itk::DiffusionTensor3D<TTensorPixelType> TensorType;
                TensorType tensor = tensorIt.Get();

                TensorType::EigenValuesArrayType ev;
                tensor.ComputeEigenValues(ev);

                for(unsigned int i=0; i<ev.Size(); i++)
                {
                    if(ev[i] < 0.0)
                    {
                        tensor.Fill(0.0);
                        tensorIt.Set(tensor);
                        negatives++;
                        break;
                    }
                }
                ++tensorIt;
            }
            MITK_INFO << negatives << " tensors with negative eigenvalues" << std::endl;

            mitk::TensorImage::Pointer image = mitk::TensorImage::New();
            image->InitializeByItk( outputTensorImg.GetPointer() );
            image->SetVolume( outputTensorImg->GetBufferPointer() );
            mitk::DataNode::Pointer node=mitk::DataNode::New();
            node->SetData( image );

            QString newname;
            newname = newname.append(nodename.c_str());
            newname = newname.append("_dti_corrected");

            SetDefaultNodeProperties(node, newname.toStdString());
            nodes.push_back(node);

            // Corrected diffusion image
//            typedef itk::VectorImage<short, 3>  ImageType;
//            ImageType::Pointer correctedVols = reconFilter->GetVectorImage();
//            DiffusionImageType::Pointer correctedDiffusion = DiffusionImageType::New();
//            correctedDiffusion->SetVectorImage(correctedVols);
//            correctedDiffusion->SetDirections(vols->GetDirections());
//            correctedDiffusion->SetB_Value(vols->GetB_Value());
//            correctedDiffusion->InitializeFromVectorImage();
//            mitk::DataNode::Pointer diffNode = mitk::DataNode::New();
//            diffNode->SetData( correctedDiffusion );
//            QString diffname;
//            diffname = diffname.append(nodename.c_str());
//            diffname = diffname.append("corrDiff");
//            SetDefaultNodeProperties(diffNode, diffname.toStdString());
//            nodes.push_back(diffNode);

            mitk::ProgressBar::GetInstance()->Progress();
        }

        std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
        for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
            GetDefaultDataStorage()->Add(*nodeIt);

        mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii());
        m_MultiWidget->RequestUpdate();
    }
    catch (itk::ExceptionObject &ex)
    {
        MITK_INFO << ex ;
        QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription());
    }
}
void QmitkDiffusionQuantificationView::TensorQuantification(
        mitk::DataStorage::SetOfObjects::Pointer inImages, int method)
{
    itk::TimeProbe clock;
    QString status;

    int nrFiles = inImages->size();
    if (!nrFiles) return;

    mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
    mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );

    std::vector<mitk::DataNode::Pointer> nodes;
    while ( itemiter != itemiterend ) // for all items
    {

        typedef float                                       TTensorPixelType;
        typedef itk::DiffusionTensor3D< TTensorPixelType >  TensorPixelType;
        typedef itk::Image< TensorPixelType, 3 >            TensorImageType;

        mitk::Image* vol =
                static_cast<mitk::Image*>((*itemiter)->GetData());
        TensorImageType::Pointer itkvol = TensorImageType::New();
        mitk::CastToItkImage<TensorImageType>(vol, itkvol);

        std::string nodename;
        (*itemiter)->GetStringProperty("name", nodename);
        ++itemiter;

        // COMPUTE FA
        clock.Start();
        MBI_INFO << "Computing FA ";
        mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
                                                        "Computing FA for %s", nodename.c_str()).toAscii());
        typedef itk::Image< TTensorPixelType, 3 >              FAImageType;

        typedef itk::ShiftScaleImageFilter<FAImageType, FAImageType>
                ShiftScaleFilterType;
        ShiftScaleFilterType::Pointer multi =
                ShiftScaleFilterType::New();
        multi->SetShift(0.0);
        multi->SetScale(m_Controls->m_ScaleImageValuesBox->value());//itk::NumericTraits<RealValueType>::max()

        typedef itk::TensorDerivedMeasurementsFilter<TTensorPixelType> MeasurementsType;

        if(method == 0) //FA
        {
            /* typedef itk::TensorFractionalAnisotropyImageFilter<
        TensorImageType, FAImageType >                       FilterType;
      FilterType::Pointer anisotropyFilter = FilterType::New();
      anisotropyFilter->SetInput( itkvol.GetPointer() );
      anisotropyFilter->Update();
      multi->SetInput(anisotropyFilter->GetOutput());
      nodename = QString(nodename.c_str()).append("_FA").toStdString();*/


            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::FA);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_FA").toStdString();

        }
        else if(method == 1) //RA
        {
            /*typedef itk::TensorRelativeAnisotropyImageFilter<
        TensorImageType, FAImageType >                       FilterType;
      FilterType::Pointer anisotropyFilter = FilterType::New();
      anisotropyFilter->SetInput( itkvol.GetPointer() );
      anisotropyFilter->Update();
      multi->SetInput(anisotropyFilter->GetOutput());
      nodename = QString(nodename.c_str()).append("_RA").toStdString();*/

            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::RA);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_RA").toStdString();

        }
        else if(method == 2) // AD (Axial diffusivity)
        {
            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::AD);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_AD").toStdString();
        }
        else if(method == 3) // RD (Radial diffusivity, (Lambda2+Lambda3)/2
        {
            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::RD);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_RD").toStdString();
        }
        else if(method == 4) // 1-(Lambda2+Lambda3)/(2*Lambda1)
        {
            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::CA);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_CA").toStdString();
        }
        else if(method == 5) // MD (Mean Diffusivity, (Lambda1+Lambda2+Lambda3)/3 )
        {
            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::MD);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_MD").toStdString();
        }

        multi->Update();
        clock.Stop();
        MBI_DEBUG << "took " << clock.GetMeanTime() << "s.";

        // FA TO DATATREE
        mitk::Image::Pointer image = mitk::Image::New();
        image->InitializeByItk( multi->GetOutput() );
        image->SetVolume( multi->GetOutput()->GetBufferPointer() );
        mitk::DataNode::Pointer node=mitk::DataNode::New();
        node->SetData( image );
        node->SetProperty( "name", mitk::StringProperty::New(nodename) );
        nodes.push_back(node);

        mitk::StatusBar::GetInstance()->DisplayText("Computation complete.");

    }

    std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
    for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
        GetDefaultDataStorage()->Add(*nodeIt);

    m_MultiWidget->RequestUpdate();

}
void QmitkDiffusionQuantificationView::QBIQuantification(
        mitk::DataStorage::SetOfObjects::Pointer inImages, int method)
{
    itk::TimeProbe clock;
    QString status;

    int nrFiles = inImages->size();
    if (!nrFiles) return;

    mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
    mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );

    std::vector<mitk::DataNode::Pointer> nodes;
    while ( itemiter != itemiterend ) // for all items
    {

        typedef float TOdfPixelType;
        const int odfsize = QBALL_ODFSIZE;
        typedef itk::Vector<TOdfPixelType,odfsize> OdfVectorType;
        typedef itk::Image<OdfVectorType,3> OdfVectorImgType;
        mitk::Image* vol =
                static_cast<mitk::Image*>((*itemiter)->GetData());
        OdfVectorImgType::Pointer itkvol = OdfVectorImgType::New();
        mitk::CastToItkImage<OdfVectorImgType>(vol, itkvol);

        std::string nodename;
        (*itemiter)->GetStringProperty("name", nodename);
        ++itemiter;

        float p1 = m_Controls->m_ParamKEdit->text().toFloat();
        float p2 = m_Controls->m_ParamPEdit->text().toFloat();

        // COMPUTE RA
        clock.Start();
        MBI_INFO << "Computing GFA ";
        mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
                                                        "Computing GFA for %s", nodename.c_str()).toAscii());
        typedef OdfVectorType::ValueType                 RealValueType;
        typedef itk::Image< RealValueType, 3 >                 RAImageType;
        typedef itk::DiffusionQballGeneralizedFaImageFilter<TOdfPixelType,TOdfPixelType,odfsize>
                GfaFilterType;
        GfaFilterType::Pointer gfaFilter = GfaFilterType::New();
        gfaFilter->SetInput(itkvol);

        double scale = 1;
        std::string newname;
        newname.append(nodename);
        switch(method)
        {
        case 0:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD);
            newname.append("GFA");
            break;
        }
        case 1:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_HIGH_LOW);
            newname.append("01");
            break;
        }
        case 2:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_HIGH);
            newname.append("02");
            break;
        }
        case 3:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_MAX_ODF_VALUE);
            newname.append("03");
            break;
        }
        case 4:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_DECONVOLUTION_COEFFS);
            newname.append("04");
            break;
        }
        case 5:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_MAX_NORMALIZED_STANDARD);
            newname.append("05");
            break;
        }
        case 6:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_NORMALIZED_ENTROPY);
            newname.append("06");
            break;
        }
        case 7:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_NEMATIC_ORDER_PARAMETER);
            newname.append("07");
            break;
        }
        case 8:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_LOW_HIGH);
            newname.append("08");
            break;
        }
        case 9:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_LOW);
            newname.append("09");
            break;
        }
        case 10:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_ODF_VALUE);
            newname.append("10");
            break;
        }
        case 11:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_STD_BY_MAX);
            newname.append("11");
            break;
        }
        case 12:
        {
            p1 = m_Controls->MinAngle->text().toFloat();
            p2 = m_Controls->MaxAngle->text().toFloat();
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_PRINCIPLE_CURVATURE);
            QString paramString;
            paramString = paramString.append("PC%1-%2").arg(p1).arg(p2);
            newname.append(paramString.toAscii());
            gfaFilter->SetParam1(p1);
            gfaFilter->SetParam2(p2);
            break;
        }
        case 13:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_GENERALIZED_GFA);
            QString paramString;
            paramString = paramString.append("GFAK%1P%2").arg(p1).arg(p2);
            newname.append(paramString.toAscii());
            gfaFilter->SetParam1(p1);
            gfaFilter->SetParam2(p2);
            break;
        }
        default:
        {
            newname.append("0");
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD);
        }
        }
        gfaFilter->Update();
        clock.Stop();
        MBI_DEBUG << "took " << clock.GetMeanTime() << "s.";

        typedef itk::Image<TOdfPixelType, 3> ImgType;
        ImgType::Pointer img = ImgType::New();
        img->SetSpacing( gfaFilter->GetOutput()->GetSpacing() );   // Set the image spacing
        img->SetOrigin( gfaFilter->GetOutput()->GetOrigin() );     // Set the image origin
        img->SetDirection( gfaFilter->GetOutput()->GetDirection() );  // Set the image direction
        img->SetLargestPossibleRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion());
        img->SetBufferedRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion() );
        img->Allocate();
        itk::ImageRegionIterator<ImgType> ot (img, img->GetLargestPossibleRegion() );
        ot = ot.Begin();
        itk::ImageRegionConstIterator<GfaFilterType::OutputImageType> it
                (gfaFilter->GetOutput(), gfaFilter->GetOutput()->GetLargestPossibleRegion() );
        it = it.Begin();

        for (it = it.Begin(); !it.IsAtEnd(); ++it)
        {
            GfaFilterType::OutputImageType::PixelType val = it.Get();
            ot.Set(val * m_Controls->m_ScaleImageValuesBox->value());
            ++ot;
        }


        // GFA TO DATATREE
        mitk::Image::Pointer image = mitk::Image::New();
        image->InitializeByItk( img.GetPointer() );
        image->SetVolume( img->GetBufferPointer() );
        mitk::DataNode::Pointer node=mitk::DataNode::New();
        node->SetData( image );
        node->SetProperty( "name", mitk::StringProperty::New(newname) );
        nodes.push_back(node);

        mitk::StatusBar::GetInstance()->DisplayText("Computation complete.");

    }

    std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
    for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
        GetDefaultDataStorage()->Add(*nodeIt);

    m_MultiWidget->RequestUpdate();

}
void QmitkQBallReconstructionView::AnalyticalQBallReconstruction(
  mitk::DataStorage::SetOfObjects::Pointer inImages,
  int normalization)
{
  try
  {
    itk::TimeProbe clock;

    int nrFiles = inImages->size();
    if (!nrFiles) return;

    std::vector<float> lambdas;
    float minLambda  = m_Controls->m_QBallReconstructionLambdaLineEdit->text().toFloat();
    lambdas.push_back(minLambda);
    int nLambdas = lambdas.size();


    QString status;
    mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles*nLambdas);

    mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
    mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );

    std::vector<mitk::DataNode::Pointer>* nodes
      = new std::vector<mitk::DataNode::Pointer>();
    while ( itemiter != itemiterend ) // for all items
    {

      mitk::DiffusionImage<DiffusionPixelType>* vols =
        static_cast<mitk::DiffusionImage<DiffusionPixelType>*>(
        (*itemiter)->GetData());

      std::string nodename;
      (*itemiter)->GetStringProperty("name",nodename);
      itemiter++;

      // QBALL RECONSTRUCTION
      clock.Start();
      MBI_INFO << "QBall reconstruction ";
      mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
        "QBall reconstruction for %s", nodename.c_str()).toAscii());

      for(int i=0; i<nLambdas; i++)
      {

        float currentLambda = lambdas[i];

        switch(m_Controls->m_QBallReconstructionMaxLLevelComboBox->currentIndex())
        {
        case 0:
          {
            TemplatedAnalyticalQBallReconstruction<2>(vols, currentLambda, nodename, nodes, normalization);
            break;
          }
        case 1:
          {
            TemplatedAnalyticalQBallReconstruction<4>(vols, currentLambda, nodename, nodes, normalization);
            break;
          }
        case 2:
          {
            TemplatedAnalyticalQBallReconstruction<6>(vols, currentLambda, nodename, nodes, normalization);
            break;
          }
        case 3:
          {
            TemplatedAnalyticalQBallReconstruction<8>(vols, currentLambda, nodename, nodes, normalization);
            break;
          }
        }

        clock.Stop();
        MBI_DEBUG << "took " << clock.GetMeanTime() << "s." ;
        mitk::ProgressBar::GetInstance()->Progress();

      }
    }

    std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
    for(nodeIt = nodes->begin(); nodeIt != nodes->end(); ++nodeIt)
      GetDefaultDataStorage()->Add(*nodeIt);

    m_MultiWidget->RequestUpdate();

    mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii());

  }
  catch (itk::ExceptionObject &ex)
  {
    MBI_INFO << ex ;
    return ;
  }
}
void QmitkQBallReconstructionView::NumericalQBallReconstruction
  (mitk::DataStorage::SetOfObjects::Pointer inImages, int normalization)
{
  try
  {
    itk::TimeProbe clock;

    int nrFiles = inImages->size();
    if (!nrFiles) return;

    QString status;
    mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles);

    mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
    mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );

    std::vector<mitk::DataNode::Pointer> nodes;
    while ( itemiter != itemiterend ) // for all items
    {

      mitk::DiffusionImage<DiffusionPixelType>* vols =
        static_cast<mitk::DiffusionImage<DiffusionPixelType>*>(
        (*itemiter)->GetData());

      std::string nodename;
      (*itemiter)->GetStringProperty("name", nodename);
      ++itemiter;

      // QBALL RECONSTRUCTION
      clock.Start();
      MBI_INFO << "QBall reconstruction ";
      mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
        "QBall reconstruction for %s", nodename.c_str()).toAscii());

      typedef itk::DiffusionQballReconstructionImageFilter
        <DiffusionPixelType, DiffusionPixelType, TTensorPixelType, QBALL_ODFSIZE>
        QballReconstructionImageFilterType;

      QballReconstructionImageFilterType::Pointer filter =
        QballReconstructionImageFilterType::New();
      filter->SetGradientImage( vols->GetDirections(), vols->GetVectorImage() );
      filter->SetNumberOfThreads( m_Controls->m_QBallReconstructionNumberThreadsSpinbox->value() );
      filter->SetBValue(vols->GetB_Value());
      filter->SetThreshold( m_Controls->m_QBallReconstructionThreasholdEdit->text().toFloat() );

      switch(normalization)
      {
      case 0:
        {
          filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_STANDARD);
          break;
        }
      case 1:
        {
          filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_B_ZERO_B_VALUE);
          break;
        }
      case 2:
        {
          filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_B_ZERO);
          break;
        }
      case 3:
        {
          filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_NONE);
          break;
        }
      default:
        {
          filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_STANDARD);
        }
      }

      filter->Update();
      clock.Stop();
      MBI_DEBUG << "took " << clock.GetMeanTime() << "s." ;

      // ODFs TO DATATREE
      mitk::QBallImage::Pointer image = mitk::QBallImage::New();
      image->InitializeByItk( filter->GetOutput() );
      //image->SetImportVolume( filter->GetOutput()->GetBufferPointer(), 0, 0, mitk::Image::ImportMemoryManagementType::ManageMemory );
      image->SetVolume( filter->GetOutput()->GetBufferPointer() );
      mitk::DataNode::Pointer node=mitk::DataNode::New();
      node->SetData( image );
      QString newname;
      newname = newname.append(nodename.c_str());
      newname = newname.append("_QN%1").arg(normalization);
      SetDefaultNodeProperties(node, newname.toStdString());
      nodes.push_back(node);

      // B-Zero TO DATATREE
      if(m_Controls->m_OutputB0Image->isChecked())
      {
        mitk::Image::Pointer image4 = mitk::Image::New();
        image4->InitializeByItk( filter->GetBZeroImage().GetPointer() );
        image4->SetVolume( filter->GetBZeroImage()->GetBufferPointer() );
        mitk::DataNode::Pointer node4=mitk::DataNode::New();
        node4->SetData( image4 );
        node4->SetProperty( "name", mitk::StringProperty::New(
          QString(nodename.c_str()).append("_b0").toStdString()) );
        nodes.push_back(node4);
      }
      mitk::ProgressBar::GetInstance()->Progress();

    }

    std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
    for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
      GetDefaultDataStorage()->Add(*nodeIt);

    mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii());
    m_MultiWidget->RequestUpdate();

  }
  catch (itk::ExceptionObject &ex)
  {
    MBI_INFO << ex ;
    return ;
  }
}