clear;
vt_keep=1000; % keep every

% 2D-Golgi model
% units: length in micrometers, time in seconds

% SETTINGS:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 6 cisternae:
nC=6;                    % number of cisternae
dC=1.5;                  % diameter

% diameter of tubules:
dT=.03;                  % diameter
lT=.10;                  % length

% box:
box_res=.03;             % um resolution

% simulation

t_end=20000*10^-3;             % duration

t_dt=10^-5;              % time step:  r = Cdiff * t_dt / box_res^2 < 1/2 !!

t_keep=1000;               % keep every

% initial concentration
conc_0=10;               % uM

% diffusion constant
Cdiff=10;                % um^2/s albumin

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% generation of box and geometry
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

box_Sx=nC*dC+(nC-1)*lT+2*box_res; % length of simulation box in x-direction
box_Sy=dC+2*box_res;              % length of simulation box in y-direction
% number of pixels
box_Nx=ceil(box_Sx/box_res)+1;    % box is a 2D-matrix defining the system boundaries
box_Ny=ceil(box_Sy/box_res)+1;    % box has value 1 inside and value 0 outside
box=0*newim(box_Nx,box_Ny);
for nx=0:box_Nx-1
    for ny=0:box_Ny-1
        co_x=nx*box_res;
        co_y=ny*box_res-dC/2-box_res;
        % cisternae
        for n=1:nC
            if sqrt((co_x-box_res-dC/2-(n-1)*(dC+lT))^2+co_y^2)<=dC/2
                box(nx,ny)=1; 
            end
        end
        % tubules
        if co_x>dC/2 & co_x<box_Sx-dC/2 & abs(co_y)<=dT/2
            box(nx,ny)=1; 
        end
    end
end
box=box>.5;                        % sets all box entries with value > 0.5 to integeger 1

M_Nx=box_Nx;
M_Ny=box_Ny;
M_Nt=ceil(t_end/t_dt/t_keep)+1;
M=0*newim(M_Nx,M_Ny,M_Nt);
Mzeros=0*newim(M_Nx,M_Ny);
Mtmp0=Mzeros;
Mtmp1=newim(M_Nx,M_Ny);

% count neighbors in box
Cbox1=0*newim(M_Nx,M_Ny,4); 
Cbox1(0:M_Nx-2,:,0)=box(1:M_Nx-1,:);
Cbox1(1:M_Nx-1,:,1)=box(0:M_Nx-2,:);
Cbox1(:,0:M_Ny-2,2)=box(:,1:M_Ny-1);
Cbox1(:,1:M_Ny-1,3)=box(:,0:M_Ny-2);
CboxA=dip_image(sum(double(Cbox1),3)); % CboxA contains the sum of neighbors for each pixel
 
% initial condition: first cisternae filled
for nx=0:box_Nx-1
    for ny=0:box_Ny-1
        co_x=nx*box_res;
        co_y=ny*box_res-dC/2-box_res;
        if sqrt((co_x-box_res-dC/2)^2+co_y^2)<=dC/2+box_res & box(nx,ny)==1 % first pixel in first tubule set to half concentration
            Mtmp0(nx,ny)=conc_0/2;
        end
        if sqrt((co_x-box_res-dC/2)^2+co_y^2)<=dC/2 & box(nx,ny)==1 % if particle in first cisternae
            Mtmp0(nx,ny)=conc_0;
        end
    end
end
M(:,:,0)=Mtmp0;
Ntot(1)=sum(Mtmp0);
Ntot2(1)=sum(Mtmp0);
Mlast(1)=double(Mtmp0(round((5*(dC+lT)+dC/2)/box_res+1),round(dC/2/box_res+1))); % concentration in the last cisterna

tic
% simulation
for nt=1:ceil(t_end/t_dt)
    t=nt*t_dt;
    Mtmp1=Mzeros;
    % diffusion ; computes difference between central pixel and 4 neighbor pixels -> gives second derivative of concentration  
    Mlap1=0*newim(M_Nx,M_Ny,4);
    Mlap1(0:M_Nx-2,:,0)=Mtmp0(1:M_Nx-1,:); % shift matrix to the left
    Mlap1(1:M_Nx-1,:,1)=Mtmp0(0:M_Nx-2,:); % shift matrix to the right
    Mlap1(:,0:M_Ny-2,2)=Mtmp0(:,1:M_Ny-1); % shift matrix down
    Mlap1(:,1:M_Ny-1,3)=Mtmp0(:,0:M_Ny-2); % shift matrix up
    MlapA=dip_image(sum(double(Mlap1),3)); % sum of 4 neighbor concentrations
    Mtmp1=box*(Mtmp0+t_dt*Cdiff*(MlapA-CboxA.*Mtmp0)/box_res^2); % solves diffusion equation
    Ntot(nt)=round(sum(Mtmp1)); % Ntot : total concentration of proteins in the full system
   
    % save frame
    if nt/t_keep==round(nt/t_keep)
          Ntot2(nt/t_keep+1)=sum(Mtmp1);
          Mlast(nt/t_keep+1)=Mtmp1(round((5*(dC+lT)+dC/2)/box_res+1),round(dC/2/box_res+1));
        M(:,:,nt/t_keep)=Mtmp1;
        disp(['time: t = ' num2str(t) ' sec']); 
        disp(['total number of particles: ' num2str(Ntot(nt))]); 
        toc; tic
    end
    Mtmp0=Mtmp1; 
end
M

% analysis
tim=(0:t_dt:t_end);
figure; plot(tim,Ntot)

tim2=(0:t_dt*t_keep:t_end)';

% figures
figure; plot(tim2,Ntot2) 
figure; plot(tim2,Mlast)

savemat=[tim2 Mlast'];
save('Mlast_flick2_2_1.5min.dat','savemat','-ascii') % saves concentration in last cisternae to file

                
