function meqgsave(G,P,opts,fname,verbosity)
%MEQGSAVE Save meq geometry quantities for easy re-loading with MEQGLOAD
%
% meqgsave(G,P,opts)
%   G   : Geometry structure
%   P   : Parameter structure
%   opts: string of objects to save
%            all possible options: 'auxzvwfm'. 
%            default='auvxzfm' allows to change vessel mode easily
%            'auxfm' is fastest when vessel mode is fixed
%
% [+MEQ MatlabEQuilibrium Toolbox+] Swiss Plasma Center EPFL Lausanne 2022. All rights reserved.

% Input handling
allopts = 'auxzvwfm';
if nargin<3 || isempty(opts)
  opts = 'auvxzfm';
  if (~P.izgrid), opts(opts == 'z') = [];end % Remove z if P.izgrid is false
end
if nargin<4 || isempty(fname)
  fname = fullfile(pwd,'meqG.mat');
end
if nargin<5 || isempty(verbosity)
  verbosity = 1;
end

% Checks
assert(ischar(opts),'opts must be a string');
assert(all(contains(num2cell(opts),num2cell(allopts))),...
  'opts must contain only characters from the set ''%s''',allopts)
assert(~contains(opts,'z') || P.izgrid , 'must set izgrid=true to store z')
%%
% list of all potential things to save and compute
fulllist = {...
  'Mvv',            'Mxv','Mzv','Mbv','dzMvx','Brxv','Bzxv','Brzv','Bzzv',...
  'Mwv','Mww',      'Mxw','Mzw','Mbw','dzMwx','Brxw','Bzxw','Brzw','Bzzw',...
  'Mav',      'Maa','Mxa','Mza',      'dzMax','Brxa','Bzxa','Brza','Bzza',...
  'Mau',      'Muu','Mxu','Mzu',      'dzMux','Brxu','Bzxu','Brzu','Bzzu',...
  'Mfv','Mfw','Mfa','Mfx',            'dzMfx',                            ...
  'Bmv','Bmw','Bmx','Bma',            'dzBmx',                            ...
                          'Mzy',                                          ...
  };

excludeopts = setdiff(num2cell(allopts),num2cell(opts)); % excluded options
yy = cellfun(@(x) x(end-1:end),fulllist,'UniformOutput',false); % last two letters of each in fulllist
savelist = fulllist(~contains(yy,excludeopts)); % save those not being excluded

if isempty(savelist), warning('MEQGSAVE:emptylist','empty savelist, not saving anything'); return; end

%% Compute geometry quantities including from list of objects to be saved
if verbosity, fprintf('computing geometry information to be saved... '); tic; end
G = meqg(G,P,savelist{:});
if verbosity, fprintf('done in %fs\n',toc); end
fields = fieldnames(G)';

% remove *u,*m,*f,*.s fields from structure to be saved, as well as excluded ones
rmfields = fields(endsWith(fields,excludeopts)|endsWith(fields,{'s','c','W'})); 
G = rmfield(G,rmfields);

%% Save to file
if verbosity, fprintf('saving to %s...%',fname); tic; end
save(fname,'-struct','G');
if verbosity,  fprintf('done in %fs \n',toc); end

end
