int main(int argc,char ** argv){

	typedef itk::Image<float,3> ImageType;
	typedef itk::Image<float,2> SliceType;

	typedef itk::ImageFileReader<ImageType> ReaderType;
	typedef itk::ImageFileWriter<SliceType> WriterType;

	typedef itk::BoundedReciprocalImageFilter<ImageType,ImageType> BoundedReciprocalType;
	BoundedReciprocalType::Pointer boundedReciprocal = BoundedReciprocalType::New();


	typedef ttt::AdvectiveDiffusion2DIterationImageFilter<SliceType,SliceType> AdvectionDiffusion2DIterationType;

	ReaderType::Pointer reader = ReaderType::New();
	reader->SetFileName(argv[1]);
	reader->UpdateOutputInformation();


	typedef itk::ExtractImageFilter<ImageType,SliceType> ExtractorType;

	ExtractorType::Pointer extractor = ExtractorType::New();

	ImageType::RegionType extractionRegion = reader->GetOutput()->GetLargestPossibleRegion();
	extractionRegion.SetSize(2,0);

	boundedReciprocal->SetInput(reader->GetOutput());
	extractor->SetInput(boundedReciprocal->GetOutput());
	extractor->SetExtractionRegion(extractionRegion);
	extractor->SetDirectionCollapseToIdentity();

	AdvectionDiffusion2DIterationType::Pointer advectionDiffusionIteration =AdvectionDiffusion2DIterationType::New();

	advectionDiffusionIteration->SetInput(extractor->GetOutput());
	advectionDiffusionIteration->SetNumberOfThreads(1.0);


	WriterType::Pointer sliceWriter = WriterType::New();
	sliceWriter->SetInput(extractor->GetOutput());
	sliceWriter->SetFileName(argv[2]);
	sliceWriter->Update();


	WriterType::Pointer writer = WriterType::New();
	writer->SetFileName(argv[3]);

	writer->SetInput(advectionDiffusionIteration->GetOutput());
	writer->Update();

}
int AffineTransformCentered2NotCentered( int argc , char* argv[] )
{
  if( argc != 6 )
  {
    std::cout<< argv[ 0 ] << " " << argv[ 1 ] << " inputTransform Source Target outputTransform" << std::endl ;
    return 1 ;
  }
  std::string inputTransform ;
  inputTransform.assign( argv[ 2 ] ) ;
  std::string source ;
  source.assign( argv[ 3 ] ) ;
  std::string target ;
  target.assign( argv[ 4 ] ) ;
  std::string outputTransform ;
  outputTransform.assign( argv[ 5 ] ) ;
  //Read transform files
  itk::TransformFileReader::Pointer transformFile ;
  transformFile = itk::TransformFileReader::New() ;
  transformFile->SetFileName( inputTransform ) ;
  transformFile->Update() ;
  //Check that transform file contains only one transform
  if( transformFile->GetTransformList()->size() != 1
    )
  {
     std::cout<< "Transform file must contain only 1 transform" << std::endl ;
     return 1 ;
  }
  typedef itk::AffineTransform< double , 3 > AffineTransformType ;
  AffineTransformType::Pointer affineTransform
            = dynamic_cast< AffineTransformType* > ( transformFile->GetTransformList()->front().GetPointer() ) ;
          if( !affineTransform )
            {
            std::cout << "Transform must be of type AffineTransform_double_3_3" << std::endl ;
            return 1 ;
            }
  typedef itk::Image< unsigned short , 3 > ImageType ;
  typedef itk::ImageFileReader< ImageType > ReaderType ;
  ReaderType::Pointer reader = ReaderType::New() ;
  reader->SetFileName( source.c_str() ) ;
  reader->UpdateOutputInformation() ;
  itk::Vector< double , 3 > tSource ;
  tSource = ComputeTranslationToCenter( reader->GetOutput() ) ;
  reader->SetFileName( target.c_str() ) ;
  reader->UpdateOutputInformation() ;
  itk::Vector< double , 3 > tTarget ;
  tTarget = - ComputeTranslationToCenter( reader->GetOutput() ) ;
//  std::cout<<"Target: "<< tTarget<<std::endl;
//  std::cout<<"Source: "<< tSource<<std::endl;
//  itk::Vector< double , 3 > tSourceTransform ;
//  tSourceTransform = affineTransform->TransformVector( tSource ) ;
  itk::Vector< double , 3 > tTargetTransform ;
  tTargetTransform = affineTransform->TransformVector( tTarget ) ;
  itk::Vector< double , 3 > translation ;
  translation = affineTransform->GetTranslation() ;
//std::cout<<translation<<std::endl;
//  std::cout<<translation<<std::endl;
//  translation += tSourceTransform ;
  translation += tTargetTransform ;
//  std::cout<<"Transformed Ttarget: "<<tTargetTransform<<std::endl;
//  std::cout<<translation<<std::endl;
//  translation += tTarget ;
  translation += tSource ;
//  std::cout<<translation<<std::endl;
  affineTransform->SetTranslation( translation ) ;
  
  //Compose transforms
  //Save transform
  itk::TransformFileWriter::Pointer outputTransformFile ;
  outputTransformFile = itk::TransformFileWriter::New() ;
  outputTransformFile->SetFileName( outputTransform.c_str() ) ;
  outputTransformFile->SetInput( affineTransform ) ;
  outputTransformFile->Update() ;
  return 0 ;
}