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 out_n   = cl.follow("NoFile",1, "-o");

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

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

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

	    typedef itk::ImageRegionIterator<ImageType> TensorIterator;
	    TensorIterator itImg(image, image->GetLargestPossibleRegion());

	    std::ofstream  file;
	    file.open(out_n);

	    for(itImg.GoToBegin(); !itImg.IsAtEnd(); ++itImg)
	    {
	    	file << itImg.Get() << std::endl;
	    }

	    file.close();



		return 0;
	}
int main (int argc, char *argv[])
{

    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 << "Scales the tensors with a scalar factor" << std::endl;
        std::cout << "Usage: -trueB0 <true B0> -m <MaskImage> -true <True Tensors> -f <flag for extended gradient> -t <initial tensor estimate> -g <gradient> -o <Output File> -s <Sigma> -nm <Noise Model> -Sim <intelligent COnvergence>" << std::endl;
      return -1;
    }

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

    const int idx = cl.follow(0, 1, "-ix");
    const int idy = cl.follow(0, 1, "-iy");
    const int idz = cl.follow(0, 1, "-iz");

    const int sx = cl.follow(0, 1, "-sx");
    const int sy = cl.follow(0, 1, "-sy");
    const int sz = cl.follow(0, 1, "-sz");



    typedef itk::Image< float, 3> ImageType;
    typedef itk::ImageFileReader<ImageType> ReaderType;
    ReaderType::Pointer reader = ReaderType::New();

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

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

    ImageType::SizeType size;
    ImageType::IndexType id;

    id[0] = idx; id[1] = idy; id[2] = idz;

    size[0] = sx; size[1] = sy; size[2] =sz;

    ImageType::RegionType region(id, size);

    typedef itk::ExtractImageFilter<ImageType, ImageType> FilterType;
    FilterType::Pointer filter = FilterType::New();

    filter->SetExtractionRegion(region);
    filter->SetInput(image);
    filter->SetDirectionCollapseToIdentity();

    filter->Update();

    ImageType::Pointer exImage = filter ->GetOutput();

    typedef itk::ImageFileWriter<ImageType> WriterType;
    WriterType::Pointer writer = WriterType::New();

    writer->SetFileName(out_n);
    writer->SetInput(exImage);
    writer->Update();






    return 0;
}
int main(int argc, char *argv[])
{
    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;
	    }

    // One idea is to apply the rotation matrix
    const string Linear_trans_n = cl.follow("NoFile",1,"-t");
    const string ref_Image_n = cl.follow("NoFile",1, "-r");
    const string out_n = cl.follow("NoFile",1,"-o");
    const string B0_n =cl.follow("NoFile",1,"-B0");
    const string T1_n =cl.follow("NoFile",1,"-T1");

    typedef itk::Image<float, 3> ImageType;
    typedef itk::ImageFileReader<ImageType> ImageReaderType;
    ImageReaderType::Pointer imageReaderB0 = ImageReaderType::New();
    imageReaderB0->SetFileName(B0_n);
    imageReaderB0->Update();

    std::cout << imageReaderB0->GetOutput()->GetDirection() << std::endl;


    ImageReaderType::Pointer imageReaderT1 = ImageReaderType::New();

    imageReaderT1->SetFileName(B0_n);
        imageReaderT1->Update();


        std::cout << imageReaderT1->GetOutput()->GetDirection() << std::endl;


//    typedef itk::TransformFileReader TransformFileReaderType;
//    typedef TransformFileReaderType::TransformListType TransformListType;
//    typedef itk::TransformBase TransformBaseType;
//    typedef itk::AffineTransform<double, 3> AffineTransformType;
//
//    typedef itk::Image<float, 3> ImageType;
//    typedef itk::ImageFileReader<ImageType> ImageReaderType;
//    ImageReaderType::Pointer imageReader = ImageReaderType::New();
//
//    imageReader->SetFileName(ref_Image_n);
//    imageReader->Update();
//    ImageType::Pointer refImage = imageReader->GetOutput();
//
//
//
//	TransformFileReaderType::Pointer readerTransform = TransformFileReaderType::New();
//	readerTransform->SetFileName(Linear_trans_n);
//	readerTransform -> Update();
//	TransformListType *list = readerTransform->GetTransformList();
//	TransformBaseType * transform = list->front().GetPointer();
//	TransformBaseType::ParametersType parameters = transform->GetParameters();
//	AffineTransformType::Pointer transform_fwd = AffineTransformType::New();
//	transform_fwd->SetParameters(parameters);
//
//	std::cout << transform_fwd->GetParameters() << std::endl;

//    typedef itk::Vector< float, 3 >          VectorPixelType;
//    typedef itk::Image< VectorPixelType, 3 > DisplacementFieldImageType;
//
//
//    typedef itk::TransformToDisplacementFieldFilter<DisplacementFieldImageType, double> DisplacementFieldGeneratorType;
//    DisplacementFieldGeneratorType::Pointer dispfieldGenerator = DisplacementFieldGeneratorType::New();
//
//    dispfieldGenerator->UseReferenceImageOn();
//    dispfieldGenerator->SetReferenceImage( refImage );
//    dispfieldGenerator->SetTransform( transform_fwd );
//    dispfieldGenerator->Update();
//    DisplacementFieldImageType::Pointer dispField = dispfieldGenerator->GetOutput();
//
//    typedef itk::ImageFileWriter<DisplacementFieldImageType> DispFieldWriterType;
//    DispFieldWriterType::Pointer writer = DispFieldWriterType::New();
//    writer->SetFileName(out_n);
//    writer->SetInput(dispField);
//    writer->Update();

    return 0;
}
int main (int argc, char *argv[])
{

    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 << "Scales the tensors with a scalar factor" << std::endl;
        std::cout << "Usage: -trueB0 <true B0> -m <MaskImage> -true <True Tensors> -f <flag for extended gradient> -t <initial tensor estimate> -g <gradient> -o <Output File> -s <Sigma> -nm <Noise Model> -Sim <intelligent COnvergence>" << std::endl;
      return -1;
    }




     const string file_g_n = cl.follow("NoFile",1, "-g");
     const string fileIn  = cl.follow("NoFile",1,"-i");
     const string fileIn_HR  = cl.follow("NoFile",1,"-iHR");
     const string B0_n     =  cl.follow("NoFile", 1, "-B0");
     const string mask_LR_n   = cl.follow("NoFile",1, "-mLR");
     const int numOfIter   = cl.follow(1,1, "-n");
     const float kappa_L   = cl.follow(0.05, 1, "-k");
     const float lambda_L  = cl.follow(0.25, 1, "-lamb_L");
     const string B0Image_HR_n = cl.follow("NoFile", 1, "-B0HR");
     const string dispField_n = cl.follow("NoFile",1,"-d");
     const string T1Image_n   = cl.follow("NoFile",1,"-T1");
     const string mask_HR_n = cl.follow("NoFile", 1, "-mHR");
    // Usual Typedefs
    typedef float RealType;
    const int ImageDim  =3;

    typedef itk::Image<RealType, ImageDim> ScalarImageType;
    typedef itk::Vector<double, ImageDim> VectorType;
    typedef itk::Image<VectorType, ImageDim> DeformationFieldType;
    typedef itk::Image<VectorType, ImageDim> VectorImageType;

    typedef itk::ImageFileReader<ScalarImageType> ScalarImageReaderType;
    typedef itk::ImageFileWriter<ScalarImageType> ScalarImageWriterType;

    //Read T1 image
	ScalarImageReaderType::Pointer scalarReader = ScalarImageReaderType::New();
	scalarReader->SetFileName(T1Image_n.c_str());
	scalarReader->Update();
	
	ScalarImageType::Pointer T1_image = scalarReader->GetOutput();

    // Read LR ImageList
	typedef std::vector<ScalarImageType::Pointer> ImageListType;
	ImageListType DWIList;
	
	std::ifstream file(fileIn.c_str());
        int numOfImages = 0;
        file >> numOfImages;	
    
	for (int i=0; i < numOfImages  ; i++) // change of numOfImages
         {
             char filename[256];
             file >> filename;
             ScalarImageReaderType::Pointer myReader=ScalarImageReaderType::New();
             myReader->SetFileName(filename);
             std::cout << "Reading.." << filename << std::endl; // add a try catch block
             myReader->Update();
             DWIList.push_back( myReader->GetOutput() ); //using push back to create a stack of diffusion images
         }

	// Read deformation field
	typedef itk::ImageFileReader<DeformationFieldType> DeformationFieldReaderType;
	DeformationFieldReaderType::Pointer deformationFieldReader = DeformationFieldReaderType::New();

	deformationFieldReader->SetFileName(dispField_n.c_str());
	deformationFieldReader->Update();
	
	DeformationFieldType::Pointer defField = deformationFieldReader->GetOutput();
	

	// Read Mask Image Spatial
	typedef itk::ImageMaskSpatialObject<ImageDim> MaskSpatialObjectType;
	typedef MaskSpatialObjectType::ImageType MaskSpatialImageType;
	typedef itk::ImageFileReader<MaskSpatialImageType> MaskSpatialImageReaderType;	

	MaskSpatialImageReaderType::Pointer spatialReader = MaskSpatialImageReaderType::New();
	spatialReader->SetFileName(mask_LR_n.c_str());
	spatialReader->Update();
	
	MaskSpatialImageType::Pointer maskSpatialImage_LR = spatialReader->GetOutput();

	//Read Mask Image Normal
	ScalarImageReaderType::Pointer maskImageReader = ScalarImageReaderType::New();
	maskImageReader->SetFileName(mask_LR_n.c_str());
	maskImageReader->Update();
	
	ScalarImageType::Pointer maskImage_LR = maskImageReader->GetOutput();

		
	// Resample diffusion Images	
/*	typedef itk::WarpImageFilter<ScalarImageType, ScalarImageType, DeformationFieldType> WarpImageFilterType;
	typedef itk::ImageFileWriter<ScalarImageType> ScalarImageWriterType;
	
	

	for (int i =0; i < numOfImages; i++)
	{
		WarpImageFilterType::Pointer warpImageFilter = WarpImageFilterType::New();
		warpImageFilter->SetOutputSpacing(T1_image->GetSpacing());
		warpImageFilter->SetOutputOrigin(T1_image->GetOrigin());
		warpImageFilter->SetDisplacementField(defField);
		warpImageFilter->SetInput(DWIList[i]);
		warpImageFilter->Update();		
		
		ScalarImageType::Pointer imageDWI = warpImageFilter->GetOutput();	
		
		std::ostringstream num_con;
		num_con << i ;
		std::string result = num_con.str() + ".nii.gz";
		
		ScalarImageWriterType::Pointer writer = ScalarImageWriterType::New();
		writer->SetFileName(result);
		writer->SetInput(imageDWI);
		writer->Update();
		std::cout<< i << "Done" << std::endl;
	}*/

	// Read Gradient List ScalarValues
		typedef itk::Vector<double, 3> VectorDoubleType;
		typedef std::vector<VectorDoubleType> GradientListType;
		GradientListType GradientList;
		std::ifstream fileg(file_g_n.c_str());
		
		int numOfGrads =0;
		fileg >> numOfGrads;
		for (int i=0; i < numOfGrads ; i++)
		{
		VectorType g;
		fileg >> g[0]; fileg >> g[1]; fileg >> g[2];
		GradientList.push_back(g);
		}	

	// Transform gradients
	

	// Read the HR diffusion images, 
	
	typedef std::vector<ScalarImageType::Pointer> ImageListType;
	ImageListType DWIList_HR;
	
	std::ifstream fileHR(fileIn_HR.c_str());
        int numOfImagesHR = 0;
        fileHR >> numOfImagesHR;	
    
/*	for (int i=0; i < numOfImagesHR  ; i++) // change of numOfImages
         {
             char filename[256];
             fileHR >> filename;
             ScalarImageReaderType::Pointer myReader=ScalarImageReaderType::New();
             myReader->SetFileName(filename);
	     myReader->Update();
             std::cout << "Reading.." << filename << std::endl; // add a try catch block
	    DWIList_HR.push_back(myReader->GetOutput());
	}
*/
		// Read HR mask image spatial
	MaskSpatialImageReaderType::Pointer spatialReader_HR = MaskSpatialImageReaderType::New();
	spatialReader_HR->SetFileName(mask_HR_n.c_str());
	spatialReader_HR->Update();
    MaskSpatialImageType::Pointer maskSpatial_HR = spatialReader_HR->GetOutput();

		//Read HR mask image Normal
	ScalarImageReaderType::Pointer maskImage_HR_reader = ScalarImageReaderType::New();
	maskImage_HR_reader->SetFileName(mask_HR_n.c_str());
	maskImage_HR_reader->Update();
	ScalarImageType::Pointer maskImage_HR = maskImage_HR_reader->GetOutput();
		// Read B0 HR image
	ScalarImageReaderType::Pointer B0Image_HR_reader = ScalarImageReaderType::New();
	B0Image_HR_reader->SetFileName(B0Image_HR_n.c_str());
	B0Image_HR_reader->Update();
	ScalarImageType::Pointer B0Image_HR = B0Image_HR_reader->GetOutput();	

		//Read B0 LR image
	ScalarImageReaderType::Pointer B0_image_LR_reader = ScalarImageReaderType::New();
	B0_image_LR_reader->SetFileName(B0_n.c_str());
	B0_image_LR_reader->Update();
	ScalarImageType::Pointer B0_image_LR = B0_image_LR_reader->GetOutput();

	// ComputeGradientImages
/*	 TransformGradients transformGradients;
	 transformGradients.ReadMaskImage(maskImage_HR);
	 transformGradients.ReadDeformationField(defField);
	 transformGradients.ReadGradients(GradientList);
	 transformGradients.ComputeGradients();
	 
	typedef std::vector<VectorImageType::Pointer> GradientImageListType;
	GradientImageListType GradientImageList;
	GradientImageList = transformGradients.GetGradientImages();

	std::cout << "Transformed all Gradients... Done." << std::endl;
	
	typedef itk::ImageFileWriter<VectorImageType> GradientImageWriterType;
	for (int i=0; i < numOfGrads; i++)
	{
	GradientImageWriterType::Pointer gradientImageWriter = GradientImageWriterType::New();
	
		std::ostringstream c; 
		c << i; 	
		std::string tempName;
		tempName = "Gradient_" + c.str()  + ".nii.gz";
		
		gradientImageWriter->SetFileName(tempName);
		gradientImageWriter->SetInput(GradientImageList[i]);
		gradientImageWriter->Update();

	}
*/

	//Read GradientImages
	const string file_gradImage_n = cl.follow("NoFile", 1, "-fG");
	std::ifstream fileGImg(file_gradImage_n.c_str());
	
	int numOfGradImages = 0;
	fileGImg >> numOfGradImages;
	
	typedef itk::ImageFileReader<VectorImageType> GradientImageReaderType;
	typedef std::vector<VectorImageType::Pointer> GradientImageListType;
	GradientImageListType gradientImageList;	

/*	for (int i=0; i < numOfGradImages; i++)
	{
		char filename[25];
		fileGImg >> filename;
		VectorImageType::Pointer gradientImage = VectorImageType::New();
		GradientImageReaderType::Pointer gradientImageReader = GradientImageReaderType::New();
		gradientImageReader->SetFileName(filename);
		gradientImageReader->Update();
		gradientImageList.push_back(gradientImageReader->GetOutput()) ;

		std::cout << "Reading...." << filename << std::endl;		
	
	}*/

	// Compute the matrix
	MapFilterLR2HRDisp filter;
	filter.ReadFixedImage(T1_image); //	
	filter.ReadMovingImage(B0_image_LR); 
	filter.ReadDeformationField(defField);
	filter.ReadMaskImage(maskSpatial_HR);
	filter.ComputeMapWithDefField();

	vnl_sparse_matrix<float> MapLR2HR, MapHR2LR;
	
	MapLR2HR = filter.GetLR2HRMatrix();
	MapHR2LR = filter.GetHR2LRMatrix();

	std::cout << "Computing Map done " << std::endl;

	std::cout << B0_image_LR->GetLargestPossibleRegion().GetSize() << std::endl;
//
//	ComposeImageFilter composeFilter;
//	composeFilter.GetHRImage(T1_image);
//	composeFilter.GetLRImage(B0_image_LR);
//	composeFilter.ReadMatrix(MapLR2HR);
//
//	ScalarImageType::Pointer tempImage1 = composeFilter.ComposeIt();
	
//	std::cout << "Composing done " << std::endl;
//
//	typedef itk::ImageFileWriter<ScalarImageType> ScalarWriterType;
//	ScalarWriterType::Pointer scalarWriter = ScalarWriterType::New();
//	scalarWriter->SetFileName("TempImage.nii.gz");
//	scalarWriter->SetInput(tempImage1);
//	scalarWriter->Update();

/*	UnweightedLeastSquaresTensorEstimation UnWeightedTensorEstimator;
	UnWeightedTensorEstimator.ReadDWIList(DWIList_HR);
	UnWeightedTensorEstimator.ReadMask(maskImage_HR);
	UnWeightedTensorEstimator.ReadBVal(1.0);
        UnWeightedTensorEstimator.ReadGradientList(gradientImageList);
	UnWeightedTensorEstimator.ReadB0Image(B0Image_HR);	

	typedef itk::DiffusionTensor3D<RealType> DiffusionTensorType;
	typedef itk::Image<DiffusionTensorType, ImageDim> TensorImageType;
	TensorImageType::Pointer tensorImage_init = UnWeightedTensorEstimator.Compute();

	typedef itk::ImageFileWriter<TensorImageType> TensorWriterType;	
	TensorWriterType::Pointer tensorWriter = TensorWriterType::New();
	tensorWriter->SetFileName("TensorImage.nii.gz");
	tensorWriter->SetInput(tensorImage_init);
	tensorWriter->Update();
	
	//Compute Sigma 
		vnl_vector<RealType> Sigma; 
		 
	
	// Compute Joint Estimation 
//	JointTensorEstimation jTestimation;
//	jTestimation.ReadBVal(1.0);
//	jTestimation.ReadDWIList(DWIList_HR);
//	jTestimation.ReadMaskImage(maskImage_HR);
//	jTestimation.ReadB0Image(B0Image_HR);
//	jTestimation.ReadGradientList(gradientImageList);
//	jTestimation.ReadInitialTensorImage(tensorImage_init);
//	jTestimation.ReadKappa(kappa_L);
*/	
		
	
   return 0;

}
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;
	}