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 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 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();

}