function [Nvoxels]=calc_vfs2(anat_fbase,ecc_fname_mag,ecc_fbase,...
	pol_fname_mag,pol_fbase, ...
	grad_thresh,fft_mag_thresh,fname_out,save_grad,DoCalc)
%function [Nvoxels]=calc_vfs2(anat_fbase,ecc_fname_mag,ecc_fbase,...
%	pol_fname_mag,pol_fbase, ...
%	grad_thresh,fft_mag_thresh,fname_out,_save_grad,DoCalc)

% ---------------------------------
% Copyright (c) 2003 Rick Hoge and Serge Dumoulin
% This program is free software; you can redistribute it and/or
% modify it under the terms of the GNU General Public License version 2
% as published by the Free Software Foundation.
% ---------------------------------

if nargin < 10,
   DoCalc=[]; %do complete vfs calculation
end;
if nargin < 9 | save_grad == 0,
   save_grad=[];
end;
if nargin < 8,
   fname_out=[];
end;
if isempty(fname_out),
   save_grad=[];
end;


tic

% open the minc files
dx_anat_handle = openimage([anat_fbase 'dx.mnc']);
dy_anat_handle = openimage([anat_fbase 'dy.mnc']);
dz_anat_handle = openimage([anat_fbase 'dz.mnc']);

mod_ecc_handle = openimage(ecc_fname_mag);
dx_ecc_handle = openimage([ecc_fbase 'dx.mnc']);
dy_ecc_handle = openimage([ecc_fbase 'dy.mnc']);
dz_ecc_handle = openimage([ecc_fbase 'dz.mnc']);

mod_pol_handle = openimage(pol_fname_mag);
dx_pol_handle = openimage([pol_fbase 'dx.mnc']);
dy_pol_handle = openimage([pol_fbase 'dy.mnc']);
dz_pol_handle = openimage([pol_fbase 'dz.mnc']);

sizes=getimageinfo(dx_anat_handle,'ImageSize');
ImageHeight=sizes(1);
ImageWidth=sizes(2);
len = sizes(1).*sizes(2);
size_ = sizes(1);
ns=getimageinfo(dx_anat_handle,'NumSlices');

if ~isempty(fname_out),
   org_fname_out=fname_out;
   fname_out = [ fname_out '_VFS.mnc'];
   new_handle = newimage(fname_out,[0 ns],[pol_fbase 'dx.mnc']);
   if ~isempty(save_grad),
      fname_out_a = [ org_fname_out '_grada.mnc'];
      new_handle_a = newimage(fname_out_a,[0 ns],[pol_fbase 'dx.mnc']);
      fname_out_e = [ org_fname_out '_grade.mnc'];
      new_handle_e = newimage(fname_out_e,[0 ns],[pol_fbase 'dx.mnc']);
      fname_out_p = [ org_fname_out '_gradp.mnc'];
      new_handle_p = newimage(fname_out_p,[0 ns],[pol_fbase 'dx.mnc']);
      
   end;
end;

% compute VFS, slice by slice, row by row:
% write results to MINC file

% create vectors for activation map:

vfs = zeros(len,ns);
Nvoxels=0;

fprintf('[%s]: Processing:',mfilename);
for slice=1:ns
   fprintf('.');drawnow;
   dx_anat = [];
   dy_anat = [];
   dz_anat = [];

   mod_ecc = [];
   dx_ecc = [];
   dy_ecc = [];
   dz_ecc = [];

   mod_pol = [];
   dx_pol = [];
   dy_pol = [];
   dz_pol = [];
 
   dx_anat = getimages(dx_anat_handle,slice,[],dx_anat).';
   dy_anat = getimages(dy_anat_handle,slice,[],dy_anat).';
   dz_anat = getimages(dz_anat_handle,slice,[],dz_anat).';

   grad_anat = [ dx_anat ; dy_anat ; dz_anat ];

   mod_ecc = getimages(mod_ecc_handle,slice,[],mod_ecc).';
   dx_ecc = getimages(dx_ecc_handle,slice,[],dx_ecc).';
   dy_ecc = getimages(dy_ecc_handle,slice,[],dy_ecc).';
   dz_ecc = getimages(dz_ecc_handle,slice,[],dz_ecc).';

   grad_ecc = [ dx_ecc ; dy_ecc ; dz_ecc ];

   mod_pol = getimages(mod_pol_handle,slice,[],mod_pol).';
   dx_pol = getimages(dx_pol_handle,slice,[],dx_pol).';
   dy_pol = getimages(dy_pol_handle,slice,[],dy_pol).';
   dz_pol = getimages(dz_pol_handle,slice,[],dz_pol).';

   grad_pol = [ dx_pol ; dy_pol ; dz_pol ];


   % THRESHOLDS:

   grad_anat_mags = sqrt( sum(grad_anat.*grad_anat) ); %mean value
   grad_pol_mags  = sqrt( sum(grad_pol.*grad_pol) );
   grad_ecc_mags  = sqrt( sum(grad_ecc.*grad_ecc) );

   vfs = zeros(size(grad_anat_mags));

   above=find(mod_pol+mod_ecc > ones(size(mod_pol)).*fft_mag_thresh.*2 & ...
               grad_anat_mags > ones(size(mod_pol)).*grad_thresh );
   Nvoxels=Nvoxels+length(above);

   % normalize anatomy gradient vectors:

   grad_anat = grad_anat ./ [grad_anat_mags;grad_anat_mags;grad_anat_mags];
      
   
   % compute gradient vectors on cortex:

   if isempty(DoCalc),
    if length(above) > 0

      grad_anat2 = grad_anat(:,above);
      grad_ecc2 = grad_ecc(:,above);
      grad_pol2 = grad_pol(:,above);
  
      dots = sum(grad_anat2 .* grad_ecc2) ;
      weights = [dots;dots;dots];
      norm_proj_ecc = weights .* grad_anat2;
      surf_grad_ecc = grad_ecc2 - norm_proj_ecc ;
      surf_grad_ecc_mag = sqrt( sum(surf_grad_ecc.*surf_grad_ecc) );
      surf_grad_ecc_mag_vec = [ surf_grad_ecc_mag ; ...
				surf_grad_ecc_mag ; ...
				surf_grad_ecc_mag ];

      dots = sum(grad_anat2 .* grad_pol2) ;
      weights = [dots;dots;dots];
      norm_proj_pol = weights .* grad_anat2;
      surf_grad_pol = grad_pol2 - norm_proj_pol ;
      surf_grad_pol_mag = sqrt( sum(surf_grad_pol.*surf_grad_pol) );
      surf_grad_pol_mag_vec = [ surf_grad_pol_mag ; ...
				surf_grad_pol_mag ; ...
				surf_grad_pol_mag ];

      ecc_pol_angle = asin(sum((cross(surf_grad_ecc , surf_grad_pol)./ ...
                         (surf_grad_ecc_mag_vec.*surf_grad_pol_mag_vec)).* ...
			  grad_anat2));

%      disp(['Angles = ' num2str(ecc_pol_angle)]);

      vfs(above) = sign(ecc_pol_angle);

    elseif length(above) == 0,
       disp(sprintf('no values above thresholds'));
%---       return;
    end; % for if length(above) > 0

    % write maps to file, if requested
 
    if ~isempty(fname_out)
       putimages(new_handle,vfs.',slice);
       if ~isempty(save_grad),
          putimages(new_handle_a,grad_anat_mags.',slice);
          putimages(new_handle_e,grad_ecc_mags.',slice);
          putimages(new_handle_p,grad_pol_mags.',slice);
       end;
    end
  end; % end for DoCalc
 %disp(['Done slice # ' num2str(slice) ' of ' num2str(ns)]);
end; % for slices

if ~isempty(fname_out),
   closeimage(new_handle);
   if ~isempty(save_grad),
      closeimage(new_handle_a);
      closeimage(new_handle_e);
      closeimage(new_handle_p);
   end;
end;

fprintf('Done[%d minutes].\n',round(toc/60));









