clear all
clc

% This programme takes Temperature from an input grid, treats it so all
% nans are replaced by interpolated or nearest neighbour values and then
% interpolates this on to the NEMO grid

% Note, interpolation around land is a dark art - this may not give a
% stable solution, but it at least works for me.

% 24/04/19 - Ashley Brereton


fname = 'initcd_vosaline.nc';    % name of output file
fname_data = 'Sal_16_0000.nc';   % name of input file
z_data = 'domain_cfg.nc';        % grid file
 
% The input data is a regular grid. The co-ordinates are 1D vectors and the
% variable is F(x,y,z,t). Later in this code, we make our co-ordinates each
% a function of F(x,y,z) with meshgrid. If your data is in NEMO format,
% replicate how (xout,yout,zout) are made for (xin,yin,zin).

% Read in input variables 

Sin=ncread(fname_data,'so');  
xin=double(ncread(fname_data,'longitude'));
yin=double(ncread(fname_data,'latitude'));
zin=double(ncread(fname_data,'depth'));
Sin=permute(Sin,[2 1 3]);


% Read output grid information 

xout=double(ncread(z_data,'nav_lon'));
yout=double(ncread(z_data,'nav_lat'));
dzout=ncread(z_data,'e3t_0');

% need all grid variables as F(x,y,z) as this is what is needed by griddata

xout=repmat(xout,1,1,size(dzout,3));
yout=repmat(yout,1,1,size(dzout,3));

% pre-allocate matrix
zout=zeros(size(dzout,1),size(dzout,2),size(dzout,3));




% Build z from dz given in grid file

for i=1:size(dzout,3)
    
    if i==1
        zout(:,:,i)=dzout(:,:,i);
    else
        zout(:,:,i)=zout(:,:,i-1)+dzout(:,:,i);
    end
        
end


% fix surface depth to 0

zin(1)=0;


% make all input grid information F(x,y,z)
[Xin,Yin,Zin]=meshgrid(xin,yin,zin);


% Remove all nan points.
Xlr=Xin(~isnan(Sin));
Ylr=Yin(~isnan(Sin));
Zlr=Zin(~isnan(Sin));
Tlr=Sin(~isnan(Sin));


% Interpolate input on to whole input grid - getting rid of nans
Sin=griddata(Xlr,Ylr,Zlr,Tlr,Xin,Yin,Zin);


% All the nans that couldn't be filled on the input grid, we replace with
% nearest neighbours.

ind_nnan=~isnan(Sin(:));
ind_nan = isnan(Sin(:));

Xlnnan=Xin(ind_nnan);
Ylnnan=Yin(ind_nnan);
Zlnnan=Zin(ind_nnan);
coordnnan=[Xlnnan Ylnnan Zlnnan];

Xlnan=Xin(ind_nan);
Ylnan=Yin(ind_nan);
Zlnan=Zin(ind_nan);
coordnan=[Xlnan Ylnan Zlnan];

ind=knnsearch(coordnnan,coordnan);

T_TEMP=Sin(ind_nnan);
T_TEMP=T_TEMP(ind);


Sin(isnan(Sin))=T_TEMP;



% Then we interpolate fully treated input grid on to our domain.

Sinterp=interp3(xin,yin,zin,Sin,xout,yout,zout);


% converts days since 1900 to seconds since 1950...
time=ncread(  fname_data , 'time');
time_counter = (time + 18262*24)*3600;  % 18262 days between 1900 and 1950



% write all the variables to file

delete(fname)
nccreate(fname,'nav_lon',...
    'Dimensions',{'x',size(xout,1),'y',size(yout,2)},...
    'Format','netcdf4_classic');
ncwrite(fname,'nav_lon',nav_lon);


nccreate(fname,'nav_lat',...
    'Dimensions',{'x',size(xout,1),'y',size(yout,2)},...
    'Format','netcdf4_classic');
ncwrite(fname,'nav_lat',nav_lat);


nccreate(fname,'time_counter',...
    'Dimensions',{'time_counter',Inf},...
    'Format','netcdf4_classic');
ncwrite(fname,'time_counter',time_counter);


nccreate(fname,'gdept',...
    'Dimensions',{'x',size(zout,1),'y',size(zout,2),'z',size(zout,3)},...
    'Format','netcdf4_classic');
ncwrite(fname,'gdept',z);


nccreate(fname,'vosaline',...
    'Dimensions',{'x',size(zout,1),'y',size(zout,2),'z',size(zout,3),'time_counter',1},...
    'Format','netcdf4_classic');
ncwrite(fname,'votemper',Sinterp);