function [ shape_space_model ] = train_diffeomorphic_model(param)
%Main wrapper for Taraz's LDDMM shapespace training function
%default parameters take from test_shape_space_construction_synthesis
%

% Aug 30, 2013 G. Johnson    Changed they way files are input into the
%                            diffeomorphic model function
% Nov 4, 2013 G. Johnson     Set aspect ratio to [1,1,1] by default

    if ~isfield(param.model, 'diffeomorphic') 
        param.model.diffeomorphic = true;
    end
    
    param.model.diffeomorphic = ml_initparam(param.model.diffeomorphic, ...
        struct( 'use_distance_matrix_completion', true, ...
                'minimum_relative_semidiameter', 1 / 4, ...
                'maximum_relative_semidiameter', 2 / 3, ...
                'generate_cycle', true, ...
                'useCurrentResults', false, ...
                'tempdir', [param.tempparent filesep 'diffeomorphic'], ...
                'downsample', max(param.model.resolution)./param.model.resolution, ...
                'com_align', true, ...
                'z_align', 'com', ... %can be 'bottom', 'com' or 'largest_slice'
                'number_windows', 1, ...
                'regfunc', @(x,y) cellfile2registeredimg([param.preprocessingFolder filesep 'cell' num2str(x) '.mat'], y), ...
                'relative_filter_radius', 0.10, ...
                'scale_z_kernel', false ... %flag to scale the z kernel to be imsize(1)/imsize(3);
                ));
    
    param.model.diffeomorphic.resolution = param.model.diffeomorphic.downsample .* param.model.resolution;
        


            
    if ~exist(param.model.diffeomorphic.tempdir, 'dir')
        mkdir(param.model.diffeomorphic.tempdir)
    end
            
    options = struct();
    
    options.tempparent = param.tempparent;
    options.save_location = [param.model.diffeomorphic.tempdir];
    
    [imfunc_return_aligned_images, min_im_size, maxdims, image_output_size] = get_diffeo_image_function(param);
        
    image_width = min(min_im_size(1:2));
    
    options.number_images = param.documentation.numimgs;
     
    options.voxel_size = param.model.resolution;
    options.shape_aspect_ratio = [1, 1, 1];   
    
    %use filter that is 1/10 the size of the image
    options.filter_radius = ceil(image_output_size(1)*param.model.diffeomorphic.relative_filter_radius);
    
    %if the window radius is not set, we just use one window
    options.window_radius = ceil(image_output_size(1)/param.model.diffeomorphic.number_windows);
%   options.window_radius = max(min_im_size(1:2)); %old code

    
    %use z_radius kernel that is 1/5 the size of the z dimension
    if(maxdims(3) > 1)
        
        if param.model.diffeomorphic.scale_z_kernel
            options.kernel_z_radius = options.filter_radius;
        else
            options.kernel_z_radius = ceil(min_im_size(3)/5);
        end
    else
        options.kernel_z_radius = 0;
    end
 
    options.convergence_absolute_error = (mean([param.model.diffeomorphic.minimum_relative_semidiameter, param.model.diffeomorphic.maximum_relative_semidiameter]) * image_width * 2 * pi) / 10;
    options.maximum_deformation_per_step = ones(1, 3) .* [1,1,0.5]; 
%     options.maximum_deformation_per_step = ones(1, 3) * .25; 
    options.convergence_absolute_error_difference = 25;
    options.useCurrentResults = param.model.diffeomorphic.useCurrentResults;
    
    if param.model.diffeomorphic.use_distance_matrix_completion
        options.desired_shape_space_dimensionality = 2;
        % shape_space_options.desired_shape_space_dimensionality = 5;
    end
    
    %Resize the images to be divisible by the window_raidus
    options.image_function = @(x) pad_imfunc_to_window_size(x, imfunc_return_aligned_images, options.window_radius);
    options.imsize = min_im_size;
    
    
    options = ml_initparam(param.model.diffeomorphic, options);
    
    shape_space_model = train_shape_space_model(options);

    
%     shape_space_model.imfunc = imfunc_return_aligned_images;
%     shape_space_model.numimgs = param.documentation.numimgs;
%     shape_space_model.imsize = min_im_size;
%     shape_space_model.name = 'diffeomorphic model of the cell';
%     shape_space_model.type = 'diffeomorphic';
% %     shape_space_model.matCompletionFunctionString = options.matCompletionFunctionString;
%     shape_space_model.version = 1.0;

end


