WeightedLeastSquares::TensorImageType::Pointer WeightedLeastSquares::ConvertGammaVector2DT(VectorialImageTensorType::Pointer vecTensorImage)
{
	ScalarImageIterator itMask(m_HRmask, m_HRmask->GetLargestPossibleRegion());
	VecTensorImageIterator itVec(vecTensorImage , vecTensorImage->GetLargestPossibleRegion());

	TensorImageType::Pointer tempTensorImage = TensorImageType::New();
	CopyImage  cpImage;
	cpImage.CopyTensorImage(m_tensorImage_init, tempTensorImage);
	
	TensorImageIterator itTensor(tempTensorImage, tempTensorImage->GetLargestPossibleRegion());
	
	for (itMask.GoToBegin(), itTensor.GoToBegin() ; !itMask.IsAtEnd(), !itTensor.IsAtEnd(); 
		++itMask, ++itTensor)
	{
	  if (itMask.Get() != 0)
	  {
		VectorialTensorType gamma;
	   	gamma  = vecTensorImage->GetPixel(itMask.GetIndex());
		
		DiffusionTensorType D;
		D(0,0) = gamma[1];
		D(1,1) = gamma[2];
		D(2,2) = gamma[3];
		D(0,1) = gamma[4];
		D(1,2) = gamma[5];
		D(0,2) = gamma[6]; 
		
		itTensor.Set(D);		     
	  }
	}

	return tempTensorImage;
}
WeightedLeastSquares::ImageListType WeightedLeastSquares::ComputePredictedImage(TensorImageType::Pointer tensorImage)
{

//Compute Predicted Imge
	CopyImage cpImage;
	TensorUtilities utilsTensor;
	
	int numOfImages = m_DWIListHR.size();
// Evaluate W

	
	ScalarImageIterator itHRMask(m_HRmask, m_HRmask->GetLargestPossibleRegion());
	ScalarImageIterator itB0(m_B0Image_HR, m_B0Image_HR->GetLargestPossibleRegion());
	TensorImageIterator itTens(tensorImage, tensorImage->GetLargestPossibleRegion());

	ImageListType PredImageList;

	for (int i=0; i < numOfImages; i++)
	{
		ScalarImageType::Pointer predImage_HR_i = ScalarImageType::New();
		cpImage.CopyScalarImage(m_B0Image_HR, predImage_HR_i);
		ScalarImageIterator itPredHR(predImage_HR_i, predImage_HR_i->GetLargestPossibleRegion());
		

		for (itHRMask.GoToBegin(), itPredHR.GoToBegin(), itB0.GoToBegin(), itTens.GoToBegin(); 
		     !itPredHR.IsAtEnd(), !itHRMask.IsAtEnd(), !itB0.IsAtEnd(), !itTens.IsAtEnd();
		    ++itPredHR, ++itHRMask, ++itB0, ++itTens)
		{
		  	
		if (itHRMask.Get() != 0)
			{
			vnl_vector<double> g_i_temp = m_GradList[i]->GetPixel(itHRMask.GetIndex()).GetVnlVector();
			vnl_vector<RealType> g_i; g_i.set_size(3);
			vnl_copy(g_i_temp, g_i);

			vnl_matrix<RealType> g_mat_i;
 			 g_mat_i.set_size(3,1);
                  	 g_mat_i.set_column(0,g_i);
 			
			
			DiffusionTensorType D = itTens.Get();
			MatrixType D_mat;
			D_mat.set_size(3,3);
			D_mat = utilsTensor.ConvertDT2Mat(D);
			MatrixType temp; temp.set_size(1,1);
			temp = g_mat_i.transpose()*D_mat*g_mat_i;

			RealType atten_i = exp(temp(0,0)*(-1)*m_BVal)*itB0.Get();
			
			itPredHR.Set(atten_i);
			}

		}

		PredImageList.push_back(predImage_HR_i);

	}
// Compute the difference
	return PredImageList;
}
WeightedLeastSquares::VectorialImageTensorType::Pointer WeightedLeastSquares::ConvertDT2Vector(TensorImageType::Pointer tensorImage)
{
	
	ScalarImageIterator itMask(m_HRmask, m_HRmask->GetLargestPossibleRegion());
	TensorImageIterator itTensor(tensorImage, tensorImage->GetLargestPossibleRegion());

	VectorialImageTensorType::Pointer vecImageTensor = VectorialImageTensorType::New();
        vecImageTensor->SetOrigin(m_HRmask->GetOrigin());
        vecImageTensor->SetDirection(m_HRmask->GetDirection());
        vecImageTensor->SetSpacing(m_HRmask->GetSpacing());
        vecImageTensor->SetRegions(m_HRmask->GetLargestPossibleRegion());
        vecImageTensor->Allocate();

        VectorialTensorType  ZeroVecTensor; ZeroVecTensor.Fill(0);

	vecImageTensor->FillBuffer(ZeroVecTensor);

	TensorUtilities utils;	

	for (itMask.GoToBegin(), itTensor.GoToBegin(); !itMask.IsAtEnd(); ++itTensor, ++itMask)
	{
		if (itMask.Get() != 0)
		{
		  DiffusionTensorType D = itTensor.Get();
		  vnl_matrix<double> P = utils.CholeskyDecomposition(D);

	   vnl_vector<double> Rho_vec;
	    Rho_vec.set_size(7);
	    Rho_vec[0] = log(m_B0Image_HR->GetPixel(itMask.GetIndex()));
	 /*   Rho_vec[1] = P(0,0);  // rho 2
	    Rho_vec[2] = P(1,1); // rho 3
	    Rho_vec[3] = P(2,2); // rho 4
	    Rho_vec[4] = P(0,1); // rho 5
	    Rho_vec[5] = P(1,2); // rho 6
	    Rho_vec[6] = P(0,2); // rho 7		 
	*/

             Rho_vec[1] = D(0,0);
	     Rho_vec[2] = D(1,1);
	     Rho_vec[3] = D(2,2);
		Rho_vec[4] = D(0,1);
		Rho_vec[5] = D(1,2);
		Rho_vec[6] = D(0,2);	    
	    VectorialTensorType tempVec; tempVec.SetVnlVector(Rho_vec);	
		
	    vecImageTensor->SetPixel(itMask.GetIndex(), tempVec);
						
		}
	}
	
	return vecImageTensor;
}
WeightedLeastSquares::VectorialImageTensorType::Pointer WeightedLeastSquares::MakeGammaImage(TensorImageType::Pointer tensorImage)
{

	ScalarImageIterator itMask(m_HRmask, m_HRmask->GetLargestPossibleRegion());
	TensorImageIterator itTens(tensorImage, tensorImage->GetLargestPossibleRegion());

	VectorialImageTensorType::Pointer GammaImage = VectorialImageTensorType::New();
	GammaImage->SetOrigin(m_HRmask->GetOrigin());
	GammaImage->SetDirection(m_HRmask->GetDirection());
	GammaImage->SetSpacing(m_HRmask->GetSpacing());
	GammaImage->SetRegions(m_HRmask->GetLargestPossibleRegion());
	GammaImage->Allocate();
	

	VectorialTensorType  ZeroVecTensor; ZeroVecTensor.Fill(0);
	GammaImage->FillBuffer(ZeroVecTensor);



	for (itMask.GoToBegin(), itTens.GoToBegin(); !itMask.IsAtEnd(), !itTens.IsAtEnd(); ++itMask, ++itTens)
	{
	if (itMask.Get() != 0)
	{
		VectorialTensorType temp;
		DiffusionTensorType D = itTens.Get();
		temp[0] = log(m_B0Image_HR->GetPixel(itMask.GetIndex()));
		temp[1] = D(0,0);
		temp[2] = D(1,1);
		temp[3] = D(2,2);
		temp[4] = D(0,1);
		temp[5] = D(1,2);
		temp[6] = D(0,2);	
		
		GammaImage->SetPixel(itMask.GetIndex(), temp);
	}
		
	}
	
	return GammaImage;
}
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::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());
    }
}
int main(int argc, char* *argv)
{


	     GetPot   cl(argc, argv);
	     if( cl.size() == 1 || cl.search(2, "--help", "-h") )
	      {
	          std::cout << "Not enough arguments" << std::endl;
	          return -1;
	      }

	const string image_n = cl.follow("NoFile", 1, "-i");
	const string maskImage_n  =  cl.follow("NoFile", 1, "-m");

	typedef itk::Image<float, 3> ImageType;
	typedef itk::ImageFileReader<ImageType> ReaderType;

	ReaderType::Pointer reader = ReaderType::New();

	reader->SetFileName(maskImage_n.c_str());
	reader-> Update();
	ImageType::Pointer maskimage = reader->GetOutput();

 	typedef itk::ImageRegionIterator<ImageType> ImageIterator;
	ImageIterator it(maskimage, maskimage->GetLargestPossibleRegion());

	typedef itk::DiffusionTensor3D<float> DiffusionTensorType;
	typedef itk::Image<DiffusionTensorType, 3> TensorImageType;
	typedef itk::ImageFileReader<TensorImageType> TensorImageReaderType;
	TensorImageReaderType::Pointer tensorReader = TensorImageReaderType::New();

	tensorReader->SetFileName(image_n.c_str());
	tensorReader->Update();
	TensorImageType::Pointer tensorImage = tensorReader->GetOutput();

	typedef itk::ImageRegionIterator<TensorImageType> TensorIterator;
	TensorIterator itT(tensorImage, tensorImage->GetLargestPossibleRegion());
	
	typedef DiffusionTensorType::EigenValuesArrayType EigenArrayType;

	ImageType::Pointer Eig1 = ImageType::New();
	ImageType::Pointer Eig2 = ImageType::New();
	ImageType::Pointer Eig3 = ImageType::New();

	CopyImage cpImage;
	cpImage.CopyScalarImage(maskimage, Eig1);
	cpImage.CopyScalarImage(maskimage, Eig2);
	cpImage.CopyScalarImage(maskimage, Eig3);

	TensorImageType::Pointer tensorProb = TensorImageType::New();
	cpImage.CopyTensorImage(tensorImage, tensorProb);

	DiffusionTensorType D_Identity;
	
	vnl_matrix<float> ZeroD_mat; ZeroD_mat.set_size(3,3);
 	ZeroD_mat.set_identity();

	TensorUtilities utils;
	D_Identity = utils.ConvertMat2DT(ZeroD_mat);

	//tensorProb->FillBuffer(D_Identity);
	
	for (it.GoToBegin(), itT.GoToBegin(); !it.IsAtEnd(), !itT.IsAtEnd(); ++it, ++itT)
	{
		if (it.Get() != 0)
		{
			EigenArrayType eig;
			DiffusionTensorType D = itT.Get();
			D.ComputeEigenValues(eig);
			
			if ( (eig[0] < 0) || (eig[1] < 0 ) || (eig[2] < 0) || eig[0] > 5 || (eig[1] > 5) || (eig[2] > 5))
			{
				tensorProb->SetPixel(itT.GetIndex(), D);	
				std::cout << eig << std::endl;	
			}			
			
		
		}
	}	

	typedef itk::ImageFileWriter<TensorImageType> TensorImageWriter;
	TensorImageWriter::Pointer tensorWriter = TensorImageWriter::New();
	tensorWriter->SetFileName("TensorImage_Prob.nii.gz");
	tensorWriter->SetInput(tensorProb);
	tensorWriter->Update();
	
	return 0;
}
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();

}
WeightedLeastSquares::VectorialImageTensorType::Pointer  WeightedLeastSquares::ComputeDelSim(TensorImageType::Pointer tensorImage)
{
	ScalarImageIterator itHRMask(m_HRmask, m_HRmask->GetLargestPossibleRegion());
	
	TensorImageType::Pointer delSim = TensorImageType::New();
	CopyImage cpImage;
	cpImage.CopyTensorImage(tensorImage, delSim);
	
	TensorImageIterator itDelSim(delSim, delSim->GetLargestPossibleRegion());

	int numOfImages = m_DWIListHR.size();

	//ComputePredictedImage;
	ImageListType PredImageList = ComputePredictedImage(tensorImage);

	//ComputeDifferenceImageList
	ImageListType DiffImageList = ComputeDifferenceImage(PredImageList);

	ScalarImageType::IndexType tempIndex;
	tempIndex[0] = 70; 
	tempIndex[1] = 109;
	tempIndex[2] = 81;

	VectorialImageTensorType::Pointer DelSim = VectorialImageTensorType::New();
	DelSim->SetOrigin(m_HRmask->GetOrigin());
	DelSim->SetDirection(m_HRmask->GetDirection());
	DelSim->SetSpacing(m_HRmask->GetSpacing());
	DelSim->SetRegions(m_HRmask->GetLargestPossibleRegion());
	DelSim->Allocate();
	
	VectorialTensorType  ZeroVecTensor; ZeroVecTensor.Fill(0);
	DelSim->FillBuffer(ZeroVecTensor);	
	
	for(itHRMask.GoToBegin(), itDelSim.GoToBegin(); !itHRMask.IsAtEnd(), !itDelSim.IsAtEnd() ; ++itHRMask, ++itDelSim)
	{
	
	 if (itHRMask.Get() != 0)
	{
		vnl_matrix<double> W; W.set_size(numOfImages, 7);
		vnl_vector<double> S_vec; S_vec.set_size(numOfImages);
		vnl_diag_matrix<double> S;
		vnl_vector<double> r;
		r.set_size(numOfImages);	
		DiffusionTensorType D = tensorImage->GetPixel(itHRMask.GetIndex());
		vnl_matrix<double> J = ComputeJacobian(D);		

		 for(int i=0; i < numOfImages; i++)
		{
			
			//Create W 
			vnl_vector<double> W_row_i = ComputeWeightMatrixRow(m_GradList[i]->GetPixel(itHRMask.GetIndex()));
			W.set_row(i, W_row_i);		
		
			// Create S
			S_vec[i] = PredImageList[i]->GetPixel(itHRMask.GetIndex());
			//Create r
			r[i] = DiffImageList[i]->GetPixel(itHRMask.GetIndex());	
				
		}
			vnl_vector<double> delF; 
			S.set(S_vec);
			delF = W.transpose()*S*r;
			VectorialTensorType tempDelF;
			tempDelF.SetVnlVector(delF);
			DelSim->SetPixel(itHRMask.GetIndex(), tempDelF);
	
	}
	}
	
	return DelSim;
}
bool itkDataTensorImageReaderBase::read (const QString &path)
{
    if (this->io.IsNull())
        return false;
	
    this->readInformation ( path );
	
    qDebug() << "Read with: " << this->identifier();

    if (medAbstractData *medData = dynamic_cast<medAbstractData*>(this->data()) ) {
      
        if (medData->identifier()=="itkDataTensorImageDouble3") {

	  if (this->io->GetNumberOfComponents()==6) {

	    typedef itk::Tensor<double, 3>    TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<double, 6>    VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for( unsigned int j=0; j<6; j++) {
		tensor[j] = vec[j];
	      }
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }

	    medData->setData (tensors);
	    
	  }
	  else if (this->io->GetNumberOfComponents()==9) {

	    typedef itk::Tensor<double, 3>    TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<double, 9>    VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for (unsigned int i=0; i<3; i++)
		for (unsigned int j=0; j<3; j++)
		  tensor.SetComponent (i, j, vec[i*3+j]);
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }

	    medData->setData (tensors);
	  }
	  else {
	      qDebug() << "Unsupported number of components";
	      return false;
	  } 
	}

	else if (medData->identifier()=="itkDataTensorImageFloat3") {

	  if (this->io->GetNumberOfComponents()==6) {

	    typedef itk::Tensor<float, 3>     TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<float, 6>     VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for( unsigned int j=0; j<6; j++) {
		tensor[j] = vec[j];
	      }
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }
	    
	    medData->setData (tensors);
	  }
	  else if (this->io->GetNumberOfComponents()==9) {

	    typedef itk::Tensor<float, 3>     TensorType;
	    typedef itk::Image<TensorType, 3> TensorImageType;

	    typedef itk::Vector<float, 9>     VectorType;
	    typedef itk::Image<VectorType, 3> VectorImageType;

	    typedef itk::ImageFileReader<VectorImageType> ReaderType;
	    
	    VectorImageType::Pointer image = 0;
	    {
	      ReaderType::Pointer reader = ReaderType::New();
	      reader->SetImageIO (this->io);
	      reader->SetFileName ( path.toAscii().constData() );
	      try {
		reader->Update();
	      }
	      catch (itk::ExceptionObject &e) {
		qDebug() << e.GetDescription();
		return false;
	      }
	      image = reader->GetOutput(); 
	    }

	    TensorImageType::Pointer tensors = TensorImageType::New();
	    TensorImageType::RegionType region = image->GetLargestPossibleRegion();
	    tensors->SetRegions   (region);
	    tensors->SetSpacing   (image->GetSpacing());
	    tensors->SetOrigin    (image->GetOrigin());
	    tensors->SetDirection (image->GetDirection());

	    try {
	        tensors->Allocate();
	    }
	    catch (itk::ExceptionObject &e) {
	        qDebug() << e.GetDescription();
		return false;
	    }

	    itk::ImageRegionConstIteratorWithIndex<VectorImageType>  itIn (image,
									   image->GetLargestPossibleRegion());
	    itk::ImageRegionIteratorWithIndex<TensorImageType> itOut(tensors,
								     tensors->GetLargestPossibleRegion());

	    while(!itOut.IsAtEnd()) {
      
	      VectorType vec = itIn.Get();
	      TensorType tensor;
	      
	      for (unsigned int i=0; i<3; i++)
		for (unsigned int j=0; j<3; j++)
		  tensor.SetComponent (i, j, vec[i*3+j]);
      
	      itOut.Set (tensor);
	      
	      ++itOut;
	      ++itIn;
	    }

	    medData->setData (tensors);
	  }
	  else {
	      qDebug() << "Unsupported number of components";
	      return false;
	  } 
	}
	else {
	  qDebug() << "Unsupported data type";
	  return false;
	}
    }
    else {
      qDebug() << "No data set or could not create one";
      return false;
    }

    return true;
    
}
int main (int argc, char *argv[])
	{
	const unsigned int ImageDimension = 2;
	    GetPot cl (argc, const_cast<char**>(argv));
	    if( cl.size() == 1 || cl.search (2,"--help","-h") )
	    {
	        std::cout << "Not Enough Arguments" << std::endl;
	        std::cout << "Generate the Gradient Table" << std::endl;
	        std::cout << "Usage:  return -1" << std::endl;
	    }

	   const string image_n = cl.follow("NoFile",1, "-i");
	   const string mask_n = cl.follow("NoFile", 1, "-m");	 
	   const string out_n   = cl.follow("NoFile",1, "-o");

	    typedef itk::DiffusionTensor3D<float> DiffusionTensorType;
	    typedef itk::Image<DiffusionTensorType, 3> TensorImageType;
	    typedef itk::ImageFileReader<TensorImageType> TensorReaderType;
	    TensorReaderType::Pointer reader = TensorReaderType::New();

	    reader->SetFileName(image_n.c_str());
	    reader->Update();

	    TensorImageType::Pointer image = reader->GetOutput();


	    typedef itk::Image<float, 3> ScalarImageType;
	    typedef itk::ImageFileReader<ScalarImageType> ScalarReaderType;

	    ScalarReaderType::Pointer scalarReader = ScalarReaderType::New();
	    scalarReader->SetFileName(mask_n.c_str());
	    scalarReader->Update();
	    ScalarImageType::Pointer maskImage = scalarReader->GetOutput();
	
	    typedef itk::ImageRegionIterator<TensorImageType> TensorIterator;

	    typedef itk::ImageRegionIterator<ScalarImageType> ScalarIterator;
	    ScalarIterator itMask(maskImage, maskImage->GetLargestPossibleRegion());
	

	    TensorUtilities  utilsTensor;
	    TensorImageType::Pointer logTensorImage = utilsTensor.LogTensorImageFilter(image, maskImage);


	    typedef itk::ImageFileWriter<TensorImageType> TensorImageWriterType;
	    TensorImageWriterType::Pointer tensorImageWriter = TensorImageWriterType::New();

            tensorImageWriter->SetFileName("LogTensorImage_stupid.nii.gz");
	    tensorImageWriter->SetInput(logTensorImage);
	    tensorImageWriter->Update();
	
	    std::ofstream  file;
	    file.open(out_n);

	 	ScalarImageType::Pointer TraceImage = ScalarImageType::New();
	    CopyImage	cpImage;
	    cpImage.CopyScalarImage(maskImage, TraceImage);

	    ScalarIterator itTr(TraceImage, TraceImage->GetLargestPossibleRegion());



	    TensorIterator itImg(logTensorImage, logTensorImage->GetLargestPossibleRegion());
	    for(itImg.GoToBegin(), itMask.GoToBegin(), itTr.GoToBegin(); !itTr.IsAtEnd(), !itImg.IsAtEnd(), !itMask.IsAtEnd(); ++itTr, ++itImg, ++itMask)
	    {
	    		file << itImg.Get().GetTrace() << std::endl;
	    		itTr.Set(itImg.Get().GetTrace()) ;
		

	   }


		typedef itk::ImageFileWriter<ScalarImageType> WriterType;
		WriterType::Pointer writer = WriterType::New();
	
		writer->SetFileName("LogTense_Trace.nii.gz");
		writer->SetInput(TraceImage);
		writer->Update();


	    file.close();


		return 0;
	}