classdef RGBIPR < matlab.mixin.Copyable
    properties
        setup       = struct();     % structure with camera models etc.
        opts        = struct();     % options for reconstruction
        
		riter		= 1;			% current reconstruction iteration
        n_cameras   = 0;            % number of cameras
        img_meas    = cell(1, 0);   % 1 x n_cameras, camera images
        img_proj    = cell(1, 0);   % 1 x n_cameras, internal model of camera images
        img_res     = cell(1, 0);   % 1 x n_cameras, residual images
        img_size    = zeros(2,0);   % 2 x n_cameras, size of camera images
        
        pprops      = {'re_part','dx_part','d_part','lambda',...
			're_part_lb','re_part_ub', 'dx_part_lb', 'dx_part_ub',...
			'pimg_res','pimg_norm','pimg_snr',...
			'n_views'};
        re_part     = zeros(3,0);   % 3 x n_part, particle position in object space 
        dx_part     = zeros(3,0);   % 3 x n_part, particle displacement
        d_part      = zeros(3,0);   % 1 x n_part, particle diameter (brightness~d^2)
        lambda      = zeros(3,0);   % 1 x n_part, relaxation factor
        re_part_lb  = zeros(3,0);   % 3 x n_part, lower bound on particle position
        re_part_ub  = zeros(3,0);   % 3 x n_part, upper bound on particle position
		dx_part_lb  = zeros(3,0);   % 3 x n_part, lower bound on displacement
		dx_part_ub  = zeros(3,0);   % 3 x n_part, upper bound on displacement
        pimg_res    = zeros(1,0);   % 1 x n_part, mean image residual
        pimg_norm   = zeros(1,0);   % 1 x n_part, norm of particle images
        pimg_snr    = zeros(1,0);   % 1 x n_part, signal to noise ratio
        n_views     = zeros(3,0);   % 3 x n_part, number of views particle is visible in
		n_part_start= zeros(1,0);   % number of particles at start of iteration
		n_part_remove=zeros(5,0);	% number of particles removed after shake
		n_part_found= zeros(1,0);   % number of particles found at end of iteration
		n_part_merge= zeros(1,0);   % number of particles after merge
    end
    
    methods
        % constructor
        function obj = RGBIPR(setup, opts)
            if nargin >= 2
                obj.setup       = setup;
                obj.opts        = opts;
                obj.n_cameras   = length(setup.camera);
            end
        end
        
        % append particles from another reconstruction to this one
        append(obj, obj1);
        % count number of particles
        n = count(obj);
        % initialisation from first guess of particle positions/displacements
        initialise(obj, img_ary, re_fg, dx_fg);
		initialise_mart(obj, img_ary, re_fg, dx_fg);
		initialise_art(obj, img_ary, re_fg, dx_fg);
        % merge particles within a given tolerance
        merge(obj, tol)
		% plot residuals from reconstruction
		plotresiduals(obj, tracks, c_range);
        % project images and evaluate residual
        pimg = project(obj);
        % perform iterative particle reconstruction
        reconstruct(obj, img_ary, re_fg, dx_fg);
        % retriangulate
        frames = retriangulate(obj);
        % select/re order particles internally
        select(obj, index);
        % shake
        shake(obj);
		shake_mart(obj);
        % sort particles along spatial direction
        sort(obj, e_sort);
		% validate particles
		b_reason = validate(obj);
    end
end