function [L,LX,LY] = liu(tok,shot,t,varargin)
%LIU  LIUQE top level equilibrium reconstuction
%
% [L,LX,LY] = LIU('TOK',SHOT,T,'PAR',VAL,...) performs the LIUQE
% reconstruction for TOK SHOT at times T, optionally replacing or adding
% parameters with specified values.
% L = LIU('TOK',SHOT,[],...) returns only the pre-computed quantities as provided by 
% LIUP<TOK>, LIUG<TOK> and LIUC
% [L,LX] = LIU('TOK',SHOT,T,...) also returns the diagnostic measurements
% as provided by LIUX<TOK> for later use.
%
% For general help,see README.MD and MEQHELP
% For help on LY,  see MEQT and LIUT
% For help on LX,  see LIUX and LIUX<TOK>
% For help on L.P, see MEQP, MEQP<TOK>, LIUP and LIUP<TOK> 
% For help on L.G, see MEQG, MEQG<TOK>, LIUG and LIUG<TOK> 
%
% [+MEQ MatlabEQuilibrium Toolbox+] Swiss Plasma Center EPFL Lausanne 2022. All rights reserved.

% Check inputs
assert(ischar(tok),'tok must be a string');
assert(isnumeric(shot)||ischar(shot)||iscell(shot),'shot must be numeric (for database) or string (for file)');
if ischar(shot), shot = {shot};end
if nargin>=4, assert(~mod(numel(varargin),2),'varargs must come in ''parameter'',value pairs'); end

% Tokamak specific functions
tok = lower(tok);
liuptok = str2func(['liup' tok]);
liugtok = str2func(['liug' tok]);
liuxtok = str2func(['liux' tok]);

% Algorithm configuration parameters, geometry and anciliary data
P = liuptok(shot(1),varargin{:}); % parameters
G = liugtok(shot(1),P);  % geometry
P = liup(P);
G = liug(G,P);
L = liuc(P,G); % Final assembly of all parameters

if nargout > 1
  assert(~isnumeric(shot) || all(shot > 0),'shot must be non-numeric or an array of positive numbers')
  
  assert(isnumeric(t),'time must be numeric');
  
  % LIUQE measurements
  LX = liuxtok(shot,t,L);
  LX = liux(L,LX);
  if nargout > 2
    % LIUQE reconstruction
    if L.P.slx
      LY = liutsim(L,LX, varargin{:}); % Simulink version
    elseif strcmp(L.P.algoNL, 'jfnk')
      LY = liutnwt(L,LX);
    elseif strcmp(L.P.algoNL, 'picard')
      LY = liut(L,LX); % Matlab version
    end
  end
end
end

