classdef Display_Abstract < handle

    properties (Access = protected)
        handle
        iterationArray
        valueArray
        style
    end

    properties (Access = private)
        figTitle
    end

    methods (Access = protected, Abstract)

        setChartType(obj)

    end

    methods (Access = public)

        function obj = Display_Abstract(figTitle)
            obj.figTitle = figTitle;
        end

        function show(obj,nRows,nCols,i,margins)
            obj.setStyle(nRows,nCols,i,margins);
            obj.setChartType();
            title(obj.figTitle);
            grid on
        end

        function updateParams(obj,it,value,monitor)
            obj.iterationArray(end+1) = it;
            if ~isempty(value)
                obj.valueArray(end+1,:) = value;
            end
            monitor.increaseRefreshIterator();
        end

        function refresh(obj)
            if ~isempty(obj.valueArray) && ~isempty(obj.iterationArray)
                set(obj.handle,'XData',obj.iterationArray,'YData',obj.valueArray);
                set(obj.style,'XLim',[0 obj.iterationArray(end)])
                drawnow
            end
        end

    end

    methods (Access = private)

        function setStyle(obj,nRows,nCols,i,margins)
            obj.style = subplot_tight(nRows,nCols,i,margins);
        end

    end

end


%% Copyright (C) 2016 Abhinav Tripathi
%% Copyright (C) 2016, 2017, 2022 Colin B. Macdonald
%% Copyright (C) 2020 Tianyu Chen (billchenchina)
%%
%% This file is part of OctSymPy.
%%
%% OctSymPy is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published
%% by the Free Software Foundation; either version 3 of the License,
%% or (at your option) any later version.
%%
%% This software is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty
%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
%% the GNU General Public License for more details.
%%
%% You should have received a copy of the GNU General Public
%% License along with this software; see the file COPYING.
%% If not, see <http://www.gnu.org/licenses/>.

function obj = check_and_convert(var_pyobj)
  persistent builtins
  persistent sp
  persistent list_or_tuple
  persistent _sym
  if isempty(builtins)
    builtins = pyeval("__builtins__");
    list_or_tuple = py.tuple({builtins.list, builtins.tuple});

    sp = py.sympy;
    _sym = py.tuple({sp.Basic, sp.MatrixBase});
  end

  if (~ py.isinstance(var_pyobj, list_or_tuple))
    var_pyobj = {var_pyobj};
  end

  obj = {};
  for i = 1:length(var_pyobj)
    x = var_pyobj{i};

    if (~ isa (x, 'pyobject'))
      obj{i} = x;
    elseif (py.isinstance(x, _sym) || isequal(x, py.None))
      obj{i} = get_sym_from_python(x);
    elseif (py.isinstance(x, list_or_tuple))
      obj{i} = check_and_convert(x);
    elseif (isa (x, 'py.str'))
      obj{i} = char (x);
    elseif (py.isinstance(x, builtins.dict))
      make_str_keys = pyeval ('lambda x: {str(k): v for k, v in x.items()}');
      x = pycall (make_str_keys, x);
      s = struct (x);
      % make sure values are converted to sym
      s = structfun (@(t) check_and_convert (t){:}, s, 'UniformOutput', false);
      obj{i} = s;
    elseif (isa (x, 'py.int'))
      if (py.isinstance(x, pyeval('bool')))
        error ('unexpected python bool')
      end
      if (abs (double (x)) > intmax ('int64'))
        error ('precision would be lost converting integer larger than %ld', ...
               intmax ('int64'))
      end
      obj{i} = int64 (x);
    else
      warning ('OctSymPy:pythonic_no_convert',
               sprintf ('something was not converted from pyobject: %s',
                       char (x)))
      obj{i} = x;
    end
  end
end


function [out] = read_tmsi_poly5(filename, varargin)

% READ_TMSI_POLY5
%
% Use as
%   hdr = read_tmri_poly5(filename)
%   dat = read_tmsi_poly5(filename, hdr, begblock, endblock)
%
% This implementation is as closely as possible based on the original "tms_read",
% which contains the comments
%
%   Changed on 08-10-2014 by TL, TMSi
%   - Now supports loading a file from different directory than the script file
%   - Feedback on the validity of arguments and whether a file could be found or not.
%   - Dialogue is opened when no argument was given.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

needhdr = (nargin==1);
needdat = (nargin>1);

if needdat
  signal = varargin{1};
  begblock = varargin{2};
  endblock = varargin{3};
end

fid = fopen_or_error(filename, 'rb');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% read the header
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if needhdr
  pos = 31;
  fseek(fid,pos,'bof');
  version = fread(fid,1,'int16');
  if version == 203
    frewind(fid);
    signal.header.FID                   = fread(fid,31,'uchar');
    signal.header.VersionNumber         = fread(fid, 1,'int16');
  else % version 204
    frewind(fid);
    signal.header.FID                   = fread(fid,32,'uchar');
    signal.header.VersionNumber         = fread(fid, 1,'int16');
  end
  signal.header.MeasurementName       = fread(fid,81,'uchar');
  signal.header.FS                    = fread(fid, 1,'int16');
  signal.header.StorageRate           = fread(fid, 1,'int16');
  signal.header.StorageType           = fread(fid, 1,'uchar');
  signal.header.NumberOfSignals       = fread(fid, 1,'int16');
  signal.header.NumberOfSamplePeriods = fread(fid, 1,'int32');
  signal.header.EMPTYBYTES            = fread(fid, 4,'uchar');
  signal.header.StartMeasurement      = fread(fid,14,'uchar');
  signal.header.NumberSampleBlocks    = fread(fid, 1,'int32');
  signal.header.SamplePeriodsPerBlock = fread(fid, 1,'uint16');
  signal.header.SizeSignalDataBlock   = fread(fid, 1,'uint16');
  signal.header.DeltaCompressionFlag  = fread(fid, 1,'int16');
  signal.header.TrailingZeros         = fread(fid,64,'uchar');

  %conversion to char of text values
  signal.header.FID               = char(signal.header.FID);
  signal.header.MeasurementName   = char(signal.header.MeasurementName(2:signal.header.MeasurementName(1)+1));
  %    signal.header.StartMeasurement  = typecast(int8(signal.header.StartMeasurement),'int16'); % commented by RS 1feb11

  signal.fs = signal.header.FS;

  %check for right fileversion
  % if signal.header.VersionNumber ~= 203
  %    disp('Wrong file version! Imput file must be a Poly5/TMS version 2.03 file!');
  %    return;
  % end;

  % Signal description
  for g=1:signal.header.NumberOfSignals,
    signal.description(g).SignalName        = fread(fid,41,'uchar');
    signal.description(g).Reserved          = fread(fid, 4,'uchar');
    signal.description(g).UnitName          = fread(fid,11,'uchar');
    signal.description(g).UnitLow           = fread(fid, 1,'float32');
    signal.description(g).UnitHigh          = fread(fid, 1,'float32');
    signal.description(g).ADCLow            = fread(fid, 1,'float32');
    signal.description(g).ADCHigh           = fread(fid, 1,'float32');
    signal.description(g).IndexSignalList   = fread(fid, 1,'int16');
    signal.description(g).CacheOffset       = fread(fid, 1,'int16');
    signal.description(g).Reserved2         = fread(fid,60,'uchar');

    % conversion of char values (to right format)
    signal.description(g).SignalName = char(signal.description(g).SignalName(2:signal.description(g).SignalName(1)+1));
    signal.description(g).UnitName   = char(signal.description(g).UnitName(2:signal.description(g).UnitName(1)+1));
  end

  % return the header details
  out = signal;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% read the data
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%read data blocks
NB = signal.header.NumberSampleBlocks;
SD = signal.header.SizeSignalDataBlock;
NS = signal.header.NumberOfSignals;
NS_32bit = NS/2;

if needdat

  for g=begblock:endblock

    % jump to right position in file
    if signal.header.VersionNumber == 203
      pos = 217 + NS*136 + (g-1) *(86+SD);
    else
      pos = 218 + NS*136 + (g-1) *(86+SD);
    end
    fseek(fid,pos,'bof');

    signal.block(g).PI = fread(fid,1,'int32'); %period index
    fread(fid,4,'uchar'); %reserved for extension of previous field to 8 bytes
    signal.block(g).BT = fread(fid,14/2,'int16'); %dostime
    fread(fid,64,'uchar'); %reserved
    data = single(fread(fid,SD/4,'float32'));

    % Convert data to 32bit values.
    % In case also 16bit values have to be measured, these values are typecasted below:
    % data = fread(fid,SD/2,'int16'); %read data
    % data = int16(data);
    % data = typecast(data,'int32');
    % signal.block(g).DATA = data;
    signal.data{g} = reshape(data,NS_32bit,SD/(NS_32bit*4));
  end % for

  % Converting data to a usable format
  dat = double(cell2mat(signal.data(begblock:endblock)));

  for g = 1:NS_32bit  % represent data in [uV]
    dat(g,:) = (dat(g,:) - signal.description(g*2).ADCLow)./(signal.description(g*2).ADCHigh - signal.description(g*2).ADCLow)  .* (signal.description(g*2).UnitHigh - signal.description(g*2).UnitLow) + signal.description(g*2).UnitLow ; %correction for uV
  end

  % return the data
  out = dat;
end

fclose(fid);


function disp(A)
%DISP   Display a CHEBOP by converting it to a pretty-printed string.
%
% See also DISPLAY.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

loose = strcmp(get(0, 'FormatSpacing'), 'loose');

if ( isempty(A) )
    fprintf('   (empty chebop)\n');
    if ( loose )
        fprintf('\n')
    end

else
    % Store the name of the variable(s) to the operator
    args = [];

    % Check whether the chebop is linear in order to be able to display
    % linearity information.
    if ( isempty(A.op) )
        fprintf('   Empty operator');
    elseif ( islinear(A) )
        fprintf('   Linear operator');
    else
        fprintf('   Nonlinear operator');
    end
    if ( ~isempty(A.op) )
        fprintf(':\n')
        [str, args] = formatOperator(A.op);
        if ( ~isempty(A.opShow) )
            str = A.opShow;
        end
        fprintf('      %s\n', str);
        if ( loose )
            fprintf('\n')
        end
        fprintf('  ');
    end
    fprintf(' operating on chebfun objects defined on:\n')
    Adom = A.domain;
    dom = strtrim(sprintf('%g ', Adom));
    % Replace ' ' with commas in the domain for printing. If the numbers are not
    % all integers, we also want to keep whitespace between the numbers.
    if ( all(floor(Adom) == ceil(Adom)) )
        dom = strrep(dom, ' ', ',');
    else
        dom = strrep(dom, ' ', ', ');
    end
    % Print the domain
    fprintf('      [%s]\n', dom);
    if ( loose )
        fprintf('\n')
    end

    if ( ~isempty(A.lbc) || ~isempty(A.rbc) || ~isempty(A.bc) )
        fprintf('   with\n');
        if ( loose )
            fprintf('\n')
        end
    end

    if ( ~isempty(A.lbc) )
        fprintf('    left boundary condition(s):\n');
        printLRbc(A.lbc, A.lbcShow, args, loose);
    end

    if ( ~isempty(A.rbc) )
        fprintf('    right boundary condition(s):\n');
        printLRbc(A.rbc, A.rbcShow, args, loose);
    end

    if ( ~isempty(A.bc) )
        if ( strcmpi(A.bc, 'periodic') )
            fprintf('    periodic boundary conditions.\n');
        else
            fprintf('    constraints:\n');
            if ( ischar(A.lbc) )
                fprintf('      %s\n', A.bc);
            else
                str = stripHandle(func2str(A.bc));
                fprintf('      %s = 0\n', str);
            end
        end
        if ( loose )
            fprintf('\n')
        end
    end

    if ( ~isempty(A.maxnorm) )
        mn = A.maxnorm;
        mn = mn(:)'; % Ensure row vector for printing
        if ( length(mn) > 1 )
            maxnormString = ['[' num2str(mn) ']'];
        else
            maxnormString = num2str(mn);
        end
        fprintf('   enforcing a maximum norm of solution: %s\n', maxnormString);
    end

end

end  % End of function DISP().

function str = stripHandle(op)
idx = strfind(op, ')');
str = op(idx(1)+1:end);

end

function printLRbc(bc, bcShow, args, loose)
% Print left or right boundary condition(s)
if ( ischar(bcShow) )
    % We had an assignment such as N.lbc = 'neumann';
    fprintf('      %s\n', bcShow);
elseif ( isnumeric(bcShow) )
    % We had an assignment such as N.lbc = [2; 3];
    if ( ~isempty(args) )
        % How many conditions are we dealing with?
        numBC = length(bcShow);

        % Check if we're dealing with a scalar case (e.g. u=2, u'=3) or system
        % case (e.g. u=2, v=3):
        if ( isempty(strfind(args, ',')) )  % Scalar case

            % Extra whitespace to make things align
            if ( numBC < 4)
                extraWS = repmat(' ', 1, numBC - 1);
            else
                extraWS = '    ';
            end

            % We always need to print the first condition:
            fprintf('      %s%s = %s\n', args, extraWS, num2str(bcShow(1)));
            % If we got more conditions, print them as well:
            if ( numBC >= 2 )
                fprintf('      %s''%s = %s\n', args, ...
                    extraWS(1:end-1), num2str(bcShow(2)));
            end
            if ( numBC >= 3 )
                fprintf('      %s''''%s = %s\n', args, ...
                    extraWS(1:end-2), num2str(bcShow(3)));
            end
            % Print all remaining conditions:
            for bcCounter = 4:numBC
                fprintf('      %s^(%i) = %s\n', args, ...
                    bcCounter-1, num2str(bcShow(bcCounter)));
            end
        else
           % Vector case. Split args back into individual variables before so we
           % can print them one per line
           args = strsplit(args,',');

           for bcCounter = 1:numBC
               fprintf('      %s = %s\n', args{bcCounter}, num2str(bcShow(bcCounter)));
           end
        end
    else
        fprintf('      %s\n', num2str(bcShow));
    end
else
    str = stripHandle(func2str(bc));
    fprintf('      %s = 0\n', str);
end
if ( loose )
    fprintf('\n')
end
end

function [str, args] = formatOperator(op)
% What type of a function did we get passed?
opFunc = functions(op);

% Convert the function to a string:
op = func2str(op);

if ( strcmp(opFunc.type, 'simple') )
    % If the function passed was of the simple type, we simply return the
    % results of func2str above
    str = op;

else
    % We got passed an anonymous function. Return a string to print on a nice
    % form.
    idx = strfind(op, ')');
    args = op(3:idx(1)-1);
    % If we have any commas in args, the independent variable (e.g. x) must be
    % included. For nicer output, don't print it
    idxCommas = strfind(args, ',');
    if ( ~isempty(idxCommas) )
        args = args(idxCommas(1)+1:end);
    end

    % Isolate the actual operator part from the string
    op = op(idx(1)+1:end);

    % If we're dealing with a system, throw away the end [ and ]. Also, split up
    % components into lines.
    if ( op(1) == '[' && op(end) == ']' )
        op = op(2:end-1);

        % Replace ; with the ASCII character for new line. Add indentation to
        % make it look nice
        wSpace = repmat(' ', 1, length(args) + 12);
        op = strrep(op, ';', [sprintf('\n'), wSpace]);
    end

    % Output string
    str = [args, ' |--> ', op];
end

end

function s = mat2char(V)
% MAT2CHAR  Convert the varmat to pretty-print string (incl. BCs)

print_bc = true;       % Print BCs or not
defreal = 6;           % Size of matrix to display
dom = get(V,'domain');
numints = numel(dom.endsandbreaks);

if numints == 1 && isempty(V,'bcs')
    print_bc = false;
end

defreal = max(2,ceil(defreal/(numints-1)));
s1 = ['   with n = ',int2str(defreal),' realization:'];

% Evaluate the linop
if print_bc && ~isempty(V,'bcs')
    Vmat = feval(V,defreal,'bc',dom);
else
    Vmat = feval(V,defreal,'nobc',dom);
end

% Some pretty scaling for large/small numbers
M = max(max(abs(Vmat)));
if ( (M > 1e2 || M < 1) && M ~= 0 )
    M = 10^round(log10(M)-1);
    Vmat = Vmat/M;
    s1 = [s1 sprintf('\n    %2.1e * ',M)];
end

if isreal(Vmat)
    s2 = num2str(Vmat,'  %8.4f');
    for k = 1:size(s2,1)
        s2(k,:) = strrep(s2(k,:),' 0.0000','      0');
        if numel(s2(k,:)) > 5,
            s2(k,1:6) = strrep(s2(k,1:6),'0.0000','     0');
        end
        s2(k,:) = strrep(s2(k,:),'-0.0000','      0');
    end
else
    s2 = num2str(Vmat,'%8.2f');
    for k = 1:size(s2,1)
        s2(k,:) = strrep(s2(k,:),'0.00 ','   0 ');
    end
end

% Pad with appropriate spaces
s2 = [ repmat(' ',size(s2,1),5) s2 ];
s = char(s1,'',s2);
end


function Dstep = extractD(Dout)
Dstep = zeros(145,145,3,size(Dout,3));
for i = 1:size(Dout,3)
    I = displayDictionaryElementsAsImage(Dout(:,:,i), floor(sqrt(256)), floor(size(Dout(:,:,i),2)/floor(sqrt(256))),8,8,0);
    I = I-min(min(min(I)));
    I = I./max(max(max(I)));
    Dstep(:,:,:,i) = I;
end
figure;
for i = 1:size(Dout,3)
    subplot(3,5,i);
    imshow(Dstep(:,:,:,i),[]);
end
end


function show_match(Ig1, Ig2, loc1, loc2);
n = size(loc1,1);
im3 = appendimages(Ig1,Ig2);
figure('Position', [100 100 size(im3,2) size(im3,1)]);
colormap('gray');
imagesc(im3);
hold on;
cols1 = size(Ig1,2);
for i = 1: n
  %if (match(i) > 0)
    line([loc1(i,2) loc2(i,2)+cols1], ...
         [loc1(i,1) loc2(i,1)], 'Color', 'c', 'LineWidth', 2);
  %end
end
hold off;


%This Progra, develop by Renoald Tang
%University Teknologi Malaysia, Photogrammetry and Laser scanning group
%for academic purpose
%Email:renoald@live.com
%***For Cocone(cocone.exe) and Tight Cocone(tcocone.exe) software
%***please request download from http://www.cse.ohio-state.edu/~tamaldey/cocone.html
function varargout = Reconstruction(varargin)
% RECONSTRUCTION M-file for Reconstruction.fig
%      RECONSTRUCTION, by itself, creates a new RECONSTRUCTION or raises the existing
%      singleton*.
%
%      H = RECONSTRUCTION returns the handle to a new RECONSTRUCTION or the handle to
%      the existing singleton*.
%
%      RECONSTRUCTION('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in RECONSTRUCTION.M with the given input arguments.
%
%      RECONSTRUCTION('Property','Value',...) creates a new RECONSTRUCTION or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before Reconstruction_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to Reconstruction_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help Reconstruction

% Last Modified by GUIDE v2.5 10-Jan-2012 16:15:16

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @Reconstruction_OpeningFcn, ...
                   'gui_OutputFcn',  @Reconstruction_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before Reconstruction is made visible.
function Reconstruction_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to Reconstruction (see VARARGIN)

% Choose default command line output for Reconstruction
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes Reconstruction wait for user response (see UIRESUME)
% uiwait(handles.figure1);
axes(handles.axes1)
%axis off
view(3)
grid on
axes(handles.axes2)
view(3)
grid on

% --- Outputs from this function are returned to the command line.
function varargout = Reconstruction_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes on button press in importbutton.
function importbutton_Callback(hObject, eventdata, handles)
% hObject    handle to importbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%Let the user select the file
[FileName,PathName] = uigetfile({'*.xyz'},'Select the Point clouds');
%combine the filename and pathname
directory=strcat(PathName ,FileName);
%.xyz check file extension
ext=findstr(FileName,'.xyz');
n=isempty(ext);
if n==0
    point=dlmread(directory);

end
dlmwrite('point', point, 'delimiter', '\t','precision', 6);
n2=length(point);
num=num2str(n2);
set(handles.text2,'String',num)
 setappdata(Reconstruction,'point1',point);
 axes(handles.axes1)
plot3(point(:,1),point(:,2),point(:,3),'r.')
grid on

% --- Executes on button press in DVbutton.
function DVbutton_Callback(hObject, eventdata, handles)
% hObject    handle to DVbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
p=getappdata(Reconstruction,'point1');
 [t,tnorm]=Crust(p);
 n=length(t);
 x=ones(n,1);

 num1=num2str(n);
axes(handles.axes2);
trisurf(t,p(:,1),p(:,2),p(:,3));
axis on
grid on
set(handles.text4,'String',num1);
 for i=1 : n
     x(i,1)=x(i,1)*3;
     t(i,1)=t(i,1)-1;
     t(i,2)=t(i,2)-1;
     t(i,3)=t(i,3)-1;
 end
t=[x t];
dlmwrite('face', t, 'delimiter', '\t','precision', 6);

% --- Executes on button press in Cbutton.
function Cbutton_Callback(hObject, eventdata, handles)
% hObject    handle to Cbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
a1 = get(handles.C_edit,'String');
C=str2num(a1);
R1=isempty(C);
if R1==1
    C=0.393;
end
b=get(handles.S_edit,'String');
S=str2num(b);
R1=isempty(S);
if R1==1
    S=1.571;
end
d=get(handles.f_edit,'String');
f=str2num(d);
R1=isempty(f);
if R1==1
    f=1.047;
end
ee=get(handles.r_edit,'String');
r=str2num(ee);
R1=isempty(r);
if R1==1
    r=1.2;
end
command=sprintf('cocone.exe -c %2f -s %2f -f %2f -r %2f  point \n',C,S,f,r);
h = waitbar(0,'Please wait , the surface is compute......','name','surface computation');
system(command);
waitbar(1/3,h,'30 % finish');
readJV('point.jv');
waitbar(2/3,h,'60 % finish');
 readOFF('point.off');
 axes(handles.axes2);
 N=dlmread('face');
 nn=length(N);
 num1=num2str(nn);
 set(handles.text4,'String',num1);

myview(0,0,0,0)
axis on
grid on
waitbar(3/3,h,'100 % finish');
close(h);
delete('point.dl');
delete('point.jv');
delete('point.wrl');
delete('point.off');
function C_edit_Callback(hObject, eventdata, handles)
% hObject    handle to C_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of C_edit as text
%        str2double(get(hObject,'String')) returns contents of C_edit as a double
%store the contents of input1_editText as a string. if the string
%is not a number then input will be empty
input = str2num(get(hObject,'String'));

%checks to see if input is empty. if so, default input1_editText to zero
if (isempty(input))
     set(hObject,'String','0.393')
end
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function C_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to C_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function S_edit_Callback(hObject, eventdata, handles)
% hObject    handle to S_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of S_edit as text
%        str2double(get(hObject,'String')) returns contents of S_edit as a double
input = str2num(get(hObject,'String'));

%checks to see if input is empty. if so, default input1_editText to zero
if (isempty(input))
     set(hObject,'String','1.571')
end
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function S_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to S_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function f_edit_Callback(hObject, eventdata, handles)
% hObject    handle to f_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of f_edit as text
%        str2double(get(hObject,'String')) returns contents of f_edit as a double
input = str2num(get(hObject,'String'));

%checks to see if input is empty. if so, default input1_editText to zero
if (isempty(input))
     set(hObject,'String','1.047')
end
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function f_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to f_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function r_edit_Callback(hObject, eventdata, handles)
% hObject    handle to r_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of r_edit as text
%        str2double(get(hObject,'String')) returns contents of r_edit as a double
if (isempty(input))
     set(hObject,'String','1.2')
end
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function r_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to r_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function re_edit_Callback(hObject, eventdata, handles)
% hObject    handle to re_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of re_edit as text
%        str2double(get(hObject,'String')) returns contents of re_edit as a double
input = str2num(get(hObject,'String'));

%checks to see if input is empty. if so, default input1_editText to zero
if (isempty(input))
     set(hObject,'String','1.1')
end
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function re_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to re_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in Tbutton.
function Tbutton_Callback(hObject, eventdata, handles)
% hObject    handle to Tbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
aa = get(handles.re_edit,'String');
CK=str2num(aa);
R1=isempty(CK);
if R1==1
    CK=1.1;
end
command=sprintf('tcocone.exe -m -r %2f point surface\n',CK);
h = waitbar(0,'Please wait , the surface is compute......','name','surface computation');
system(command);
waitbar(1/4,h,'25 % finish');

change('surface_surf.off')
waitbar(2/4,h,'50 % finish');
     readOFF('OFF');
     waitbar(3/4,h,'75 % finish');
     axes(handles.axes2);
     N=dlmread('face');
 nn=length(N);
 num1=num2str(nn);
 set(handles.text4,'String',num1);
      myview(0,0,0,0);
      axis on
grid on
  waitbar(4/4,h,'100 % finish');
  close(h);
delete('surface_axis.off');
delete('surface_axis.wrl');
delete('surface_surf.wrl');
delete('surface_surf.off');
delete('OFF');

% --- Executes on button press in pushbutton5.
function pushbutton5_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
rotate3d on

% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
rotate3d off

% --- Executes on button press in expbutton.
function expbutton_Callback(hObject, eventdata, handles)
% hObject    handle to expbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[file1,path1] = uiputfile({'*.ply';'*.off';},'Save file name');
File2=strcat(path1,file1);
ext=findstr(File2,'.ply');
nn1=isempty(ext);
if nn1==0
    WritePly(File2);
end
ext1=findstr(File2,'.off');
nn2=isempty(ext1);
if nn2==0
     WriteOFF(File2);
end

% --- Executes on button press in clearbutton.
function clearbutton_Callback(hObject, eventdata, handles)
% hObject    handle to clearbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
arrayfun(@cla,findall(0,'type','axes'));
 set(handles.text2,'String','');
 set(handles.text4,'String','');
delete('face');
delete('point');


function display(t)
%DISPLAY Command window display of a tensor.
%
%   DISPLAY(X) displays a tensor with its name.
%
%   See also TENSOR, TENSOR/DISP.
%
%MATLAB Tensor Toolbox.
%Copyright 2015, Sandia Corporation.

% This is the MATLAB Tensor Toolbox by T. Kolda, B. Bader, and others.
% http://www.sandia.gov/~tgkolda/TensorToolbox.
% Copyright (2015) Sandia Corporation. Under the terms of Contract
% DE-AC04-94AL85000, there is a non-exclusive license for use of this
% work by or on behalf of the U.S. Government. Export of this data may
% require a license from the United States Government.
% The full license terms can be found in the file LICENSE.txt

disp(t,inputname(1));


function D=import_FBG(loadName)
%-------------------------------------------------------------------------
%
%function D=import_FBG(loadName)
%
%A simple function to import FBG data from text file (specified by
%loadName) and output the data fields (columns) in a structure array D.
%
%
%Kevin Mattheus Moerman
%kevinmoerman@hotmail.com
%2014/01/07 - Created function
%-------------------------------------------------------------------------

%% PARSE TEXT FILE

fid=fopen(loadName);
[cell_out] = textscan(fid,'%s %f %f %f %f %f %f\n', 'delimiter', ',');
fclose(fid);

%% FORMULATE OUTPUT

D.test_date=cell_out{1};
D.cycle_no=cell_out{2};
D.FBG_temp=cell_out{3};
D.FBG_strain=cell_out{4};
D.ind_speed=cell_out{5};
D.ind_depth=cell_out{6};
D.TTL_logic=cell_out{7};

%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function SaveImToTiffStack(IM,tiffdir)
% IM: 1-d cell array containing all image planes

% display each plane and save as tif
h = figure;
for i_plane = 1:length(IM)
    im = IM{i_plane};
    image(im);axis equal; axis off
    drawnow;
    % save tiff
    if (i_plane == 1)
        imwrite(im, tiffdir, 'compression','none','writemode','overwrite')
    else
        imwrite(im, tiffdir, 'compression','none','writemode','append')
    end
    %     pause(0.2)
end
close(h)


function tutorial_hcp(tutorial_dir)
% TUTORIAL_HCP: Script that reproduces the results of the online tutorial "Human Connectome Project: Resting-state MEG".
%
% CORRESPONDING ONLINE TUTORIALS:
%     https://neuroimage.usc.edu/brainstorm/Tutorials/HCP-MEG
%
% INPUTS:
%     tutorial_dir: Directory where the HCP files have been unzipped

% @=============================================================================
% This function is part of the Brainstorm software:
% https://neuroimage.usc.edu/brainstorm
%
% Copyright (c) University of Southern California & McGill University
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPLv3
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Author: Francois Tadel, 2017

%% ===== FILES TO IMPORT =====
% You have to specify the folder in which the tutorial dataset is unzipped
if (nargin == 0) || isempty(tutorial_dir) || ~file_exist(tutorial_dir)
    error('The first argument must be the full path to the tutorial dataset folder.');
end
% Subject name
SubjectName = '175237';
% Build the path of the files to import
AnatDir    = fullfile(tutorial_dir, SubjectName, 'MEG', 'anatomy');
Run1File   = fullfile(tutorial_dir, SubjectName, 'unprocessed', 'MEG', '3-Restin', '4D', 'c,rfDC');
NoiseFile  = fullfile(tutorial_dir, SubjectName, 'unprocessed', 'MEG', '1-Rnoise', '4D', 'c,rfDC');
% Check if the folder contains the required files
if ~file_exist(AnatDir) || ~file_exist(Run1File) || ~file_exist(NoiseFile)
    error(['The folder ' tutorial_dir ' does not contain subject #175237 from the HCP-MEG distribution.']);
end

%% ===== CREATE PROTOCOL =====
% The protocol name has to be a valid folder name (no spaces, no weird characters...)
ProtocolName = 'TutorialHcp';
% Start brainstorm without the GUI
if ~brainstorm('status')
    brainstorm nogui
end
% Delete existing protocol
gui_brainstorm('DeleteProtocol', ProtocolName);
% Create new protocol
gui_brainstorm('CreateProtocol', ProtocolName, 0, 0);
% Start a new report
bst_report('Start');

%% ===== IMPORT DATA =====
% Process: Import anatomy folder
bst_process('CallProcess', 'process_import_anatomy', [], [], ...
    'subjectname', SubjectName, ...
    'mrifile',     {AnatDir, 'HCPv3'}, ...
    'nvertices',   15000);

% Process: Create link to raw files
sFilesRun1 = bst_process('CallProcess', 'process_import_data_raw', [], [], ...
    'subjectname',  SubjectName, ...
    'datafile',     {Run1File, '4D'}, ...
    'channelalign', 1);
sFilesNoise = bst_process('CallProcess', 'process_import_data_raw', [], [], ...
    'subjectname',  SubjectName, ...
    'datafile',     {NoiseFile, '4D'}, ...
    'channelalign', 1);
sFilesRaw = [sFilesRun1, sFilesNoise];

%% ===== PRE-PROCESSING =====
% Process: Notch filter: 60Hz 120Hz 180Hz 240Hz 300Hz
sFilesNotch = bst_process('CallProcess', 'process_notch', sFilesRaw, [], ...
    'freqlist',    [60, 120, 180, 240, 300], ...
    'sensortypes', 'MEG, EEG', ...
    'read_all',    1);

% Process: High-pass:0.3Hz
sFilesBand = bst_process('CallProcess', 'process_bandpass', sFilesNotch, [], ...
    'sensortypes', 'MEG, EEG', ...
    'highpass',    0.3, ...
    'lowpass',     0, ...
    'attenuation', 'strict', ...  % 60dB
    'mirror',      0, ...
    'useold',      0, ...
    'read_all',    1);

% Process: Power spectrum density (Welch)
sFilesPsdAfter = bst_process('CallProcess', 'process_psd', sFilesBand, [], ...
    'timewindow',  [0 100], ...
    'win_length',  4, ...
    'win_overlap', 50, ...
    'sensortypes', 'MEG, EEG', ...
    'edit',        struct(...
         'Comment',         'Power', ...
         'TimeBands',       [], ...
         'Freqs',           [], ...
         'ClusterFuncTime', 'none', ...
         'Measure',         'power', ...
         'Output',          'all', ...
         'SaveKernel',      0));

% Mark bad channels
bst_process('CallProcess', 'process_channel_setbad', sFilesBand, [], ...
            'sensortypes', 'A227, A244, A246, A248');

% Process: Snapshot: Frequency spectrum
bst_process('CallProcess', 'process_snapshot', sFilesPsdAfter, [], ...
    'target',         10, ...  % Frequency spectrum
    'modality',       1);      % MEG (All)

% Process: Delete folders
bst_process('CallProcess', 'process_delete', [sFilesRaw, sFilesNotch], [], ...
    'target', 2);  % Delete folders

%% ===== ARTIFACT CLEANING =====
% Process: Select data files in: */*
sFilesBand = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname', 'All');

% Process: Select file names with tag: 3-Restin
sFilesRest = bst_process('CallProcess', 'process_select_tag', sFilesBand, [], ...
    'tag',    '3-Restin', ...
    'search', 1, ...  % Search the file names
    'select', 1);  % Select only the files with the tag

% Process: Detect heartbeats
bst_process('CallProcess', 'process_evt_detect_ecg', sFilesRest, [], ...
    'channelname', 'ECG+, -ECG-', ...
    'timewindow',  [], ...
    'eventname',   'cardiac');

% Process: SSP ECG: cardiac
bst_process('CallProcess', 'process_ssp_ecg', sFilesRest, [], ...
    'eventname',   'cardiac', ...
    'sensortypes', 'MEG', ...
    'usessp',      1, ...
    'select',      1);

% Process: Snapshot: Sensors/MRI registration
bst_process('CallProcess', 'process_snapshot', sFilesRest, [], ...
    'target',         1, ...  % Sensors/MRI registration
    'modality',       1, ...  % MEG (All)
    'orient',         1);  % left

% Process: Snapshot: SSP projectors
bst_process('CallProcess', 'process_snapshot', sFilesRest, [], ...
    'target',         2, ...  % SSP projectors
    'modality',       1);     % MEG (All)

%% ===== SOURCE ESTIMATION =====
% Process: Select file names with tag: task-rest
sFilesNoise = bst_process('CallProcess', 'process_select_tag', sFilesBand, [], ...
    'tag',    '1-Rnoise', ...
    'search', 1, ...  % Search the file names
    'select', 1);  % Select only the files with the tag

% Process: Compute covariance (noise or data)
bst_process('CallProcess', 'process_noisecov', sFilesNoise, [], ...
    'baseline',       [], ...
    'sensortypes',    'MEG', ...
    'target',         1, ...  % Noise covariance     (covariance over baseline time window)
    'dcoffset',       1, ...  % Block by block, to avoid effects of slow shifts in data
    'identity',       0, ...
    'copycond',       1, ...
    'copysubj',       0, ...
    'replacefile',    1);  % Replace

% Process: Compute head model
bst_process('CallProcess', 'process_headmodel', sFilesRest, [], ...
    'sourcespace', 1, ...  % Cortex surface
    'meg',         3);     % Overlapping spheres

% Process: Compute sources [2018]
sSrcRest = bst_process('CallProcess', 'process_inverse_2018', sFilesRest, [], ...
    'output',  2, ...  % Kernel only: one per file
    'inverse', struct(...
         'Comment',        'dSPM: MEG', ...
         'InverseMethod',  'minnorm', ...
         'InverseMeasure', 'dspm2018', ...
         'SourceOrient',   {{'fixed'}}, ...
         'Loose',          0.2, ...
         'UseDepth',       1, ...
         'WeightExp',      0.5, ...
         'WeightLimit',    10, ...
         'NoiseMethod',    'reg', ...
         'NoiseReg',       0.1, ...
         'SnrMethod',      'fixed', ...
         'SnrRms',         1e-06, ...
         'SnrFixed',       3, ...
         'ComputeKernel',  1, ...
         'DataTypes',      {{'MEG'}}));

%% ===== POWER MAPS =====
% Process: Power spectrum density (Welch)
sSrcPsd = bst_process('CallProcess', 'process_psd', sSrcRest, [], ...
    'timewindow',  [0, 100], ...
    'win_length',  4, ...
    'win_overlap', 50, ...
    'clusters',    {}, ...
    'scoutfunc',   1, ...  % Mean
    'edit',        struct(...
         'Comment',         'Power,FreqBands', ...
         'TimeBands',       [], ...
         'Freqs',           {{'delta', '2, 4', 'mean'; 'theta', '5, 7', 'mean'; 'alpha', '8, 12', 'mean'; 'beta', '15, 29', 'mean'; 'gamma1', '30, 59', 'mean'; 'gamma2', '60, 90', 'mean'}}, ...
         'ClusterFuncTime', 'none', ...
         'Measure',         'power', ...
         'Output',          'all', ...
         'SaveKernel',      0));

% Process: Spectrum normalization
sSrcPsdNorm = bst_process('CallProcess', 'process_tf_norm', sSrcPsd, [], ...
    'normalize', 'relative', ...  % Relative power (divide by total power)
    'overwrite', 0);

% Process: Spatial smoothing (3.00)
sSrcPsdNorm = bst_process('CallProcess', 'process_ssmooth_surfstat', sSrcPsdNorm, [], ...
    'fwhm',      3, ...
    'overwrite', 1);

% Screen capture of final result
hFig = view_surface_data([], sSrcPsdNorm.FileName);
set(hFig, 'Position', [200 200 200 200]);
hFigContact = view_contactsheet(hFig, 'freq', 'fig');
bst_report('Snapshot', hFigContact, sSrcPsdNorm.FileName, 'Power');
close([hFig, hFigContact]);

% Save and display report
ReportFile = bst_report('Save', []);
bst_report('Open', ReportFile);


function dispsig(signalMatrix, range, titlestr);
%DISPSIG - deprecated!
%
% Please use icaplot instead.
%
%   See also ICAPLOT

% @(#)$Id$

fprintf('\nNote: DISPSIG is now deprecated! Please use ICAPLOT.\n');

if nargin < 3, titlestr = ''; end
if nargin < 2, range = 1:size(signalMatrix, 1); end

icaplot('dispsig',signalMatrix',0,range,range,titlestr);


% EEG_INTERP - interpolate data channels
%
% Usage: EEGOUT = eeg_interp(EEG, badchans, method, t_range);
%
% Inputs:
%     EEG      - EEGLAB dataset
%     badchans - [integer array] indices of channels to interpolate.
%                For instance, these channels might be bad.
%                [chanlocs structure] channel location structure containing
%                either locations of channels to interpolate or a full
%                channel structure (missing channels in the current
%                dataset are interpolated).
%     method   - [string] method used for interpolation (default is 'spherical').
%                'invdist'/'v4' uses inverse distance on the scalp
%                'spherical' uses superfast spherical interpolation.
%                'spacetime' uses griddata3 to interpolate both in space
%                and time (very slow and cannot be interrupted).
%     t_range  - [integer array with just two elements] time interval of the
%                badchans which should be interpolated. First element is
%                the start time and the second element is the end time.
% Output:
%     EEGOUT   - data set with bad electrode data replaced by
%                interpolated data
%
% Author: Arnaud Delorme, CERCO, CNRS, Mai 2006-

% Copyright (C) Arnaud Delorme, CERCO, 2006, arno@salk.edu
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

function EEG = eeg_interp(ORIEEG, bad_elec, method, t_range)

    if nargin < 2
        help eeg_interp;
        return;
    end
    EEG = ORIEEG;

    if nargin < 3
        disp('Using spherical interpolation');
        method = 'spherical';
    end

    if nargin < 4
        t_range = [ORIEEG.xmin ORIEEG.xmax];
    end

    % check channel structure
    tmplocs = ORIEEG.chanlocs;
    if isempty(tmplocs) || isempty([tmplocs.X])
        error('Interpolation require channel location');
    end

    if isstruct(bad_elec)

        % remove duplicate channel labels
        % -------------------------------
        allLabels = { bad_elec.labels };
        if length(unique(allLabels)) ~= length(allLabels)
            [~,uniqueInd] = unique(allLabels);
            bad_elec = bad_elec(uniqueInd);
        end

        % add missing channels in interpolation structure
        % -----------------------------------------------
        lab1 = { bad_elec.labels };
        tmpchanlocs = EEG.chanlocs;
        lab2 = { tmpchanlocs.labels };
        [~, tmpchan] = setdiff_bc( lab2, lab1);
        tmpchan = sort(tmpchan);

        % From 'bad_elec' using only fields present on EEG.chanlocs
        fields = fieldnames(bad_elec);
        [~, indx1] = setxor(fields,fieldnames(EEG.chanlocs)); clear tmp;
        if ~isempty(indx1)
            bad_elec = rmfield(bad_elec,fields(indx1));
            fields = fieldnames(bad_elec);
        end

        if ~isempty(tmpchan)
            newchanlocs = [];
            for index = 1:length(fields)
                if isfield(bad_elec, fields{index})
                    for cind = 1:length(tmpchan)
                        fieldval = getfield( EEG.chanlocs, { tmpchan(cind) },  fields{index});
                        newchanlocs = setfield(newchanlocs, { cind }, fields{index}, fieldval);
                    end
                end
            end
            newchanlocs(end+1:end+length(bad_elec)) = bad_elec;
            bad_elec = newchanlocs;
        end
        if length(EEG.chanlocs) == length(bad_elec), return; end

        lab1 = { bad_elec.labels };
        tmpchanlocs = EEG.chanlocs;
        lab2 = { tmpchanlocs.labels };
        [~, badchans] = setdiff_bc( lab1, lab2);
        fprintf('Interpolating %d channels...\n', length(badchans));
        if isempty(badchans), return; end
        goodchans      = sort(setdiff(1:length(bad_elec), badchans));

        % re-order good channels
        % ----------------------
        [~, tmp2, neworder] = intersect_bc( lab1, lab2 );
        [~, ordertmp2] = sort(tmp2);
        neworder = neworder(ordertmp2);
        EEG.data = EEG.data(neworder, :, :);

        % looking at channels for ICA
        % ---------------------------
        %[tmp sorti] = sort(neworder);
        %{ EEG.chanlocs(EEG.icachansind).labels; bad_elec(goodchans(sorti(EEG.icachansind))).labels }

        % update EEG dataset (add blank channels)
        % ---------------------------------------
        if ~isempty(EEG.icasphere)

            [~, sorti] = sort(neworder);
            EEG.icachansind = sorti(EEG.icachansind);
            EEG.icachansind = goodchans(EEG.icachansind);
            EEG.chaninfo.icachansind = EEG.icachansind;

            % TESTING SORTING
            %icachansind = [ 3 4 5 7 8]
            %data = round(rand(8,10)*10)
            %neworder = shuffle(1:8)
            %data2 = data(neworder,:)
            %icachansind2 = sorti(icachansind)
            %data(icachansind,:)
            %data2(icachansind2,:)
        end
        % { EEG.chanlocs(neworder).labels; bad_elec(sort(goodchans)).labels }
        %tmpdata                  = zeros(length(bad_elec), size(EEG.data,2), size(EEG.data,3));
        %tmpdata(goodchans, :, :) = EEG.data;

        % looking at the data
        % -------------------
        %tmp1 = mattocell(EEG.data(sorti,1));
        %tmp2 = mattocell(tmpdata(goodchans,1));
        %{ EEG.chanlocs.labels; bad_elec(goodchans).labels; tmp1{:}; tmp2{:} }
        %EEG.data      = tmpdata;

        EEG.chanlocs  = bad_elec;

    else
        badchans  = bad_elec;
        goodchans = setdiff_bc(1:EEG.nbchan, badchans);
        if strcmpi(method, 'sphericalfast')
            EEG.data(badchans,:) = [];
            EEG.nbchan = length(goodchans);
        else
            oldelocs  = EEG.chanlocs;
            EEG       = pop_select(EEG, 'nochannel', badchans);
            EEG.chanlocs = oldelocs;
            disp('Interpolating missing channels...');
        end
    end

    % find non-empty good channels
    % ----------------------------
    origoodchans = goodchans;
    chanlocs     = EEG.chanlocs;
    nonemptychans = find(~cellfun('isempty', { chanlocs.theta }));
    [tmp indgood ] = intersect_bc(goodchans, nonemptychans);
    goodchans = goodchans( sort(indgood) );
    datachans = getdatachans(goodchans,badchans);
    badchans  = intersect_bc(badchans, nonemptychans);
    if isempty(badchans), return; end

    % scan data points
    % ----------------
    if strcmpi(method, 'spherical') || strcmpi(method, 'sphericalfast')
        % get theta, rad of electrodes
        % ----------------------------
        tmpgoodlocs = EEG.chanlocs(goodchans);
        xelec = [ tmpgoodlocs.X ];
        yelec = [ tmpgoodlocs.Y ];
        zelec = [ tmpgoodlocs.Z ];
        rad = sqrt(xelec.^2+yelec.^2+zelec.^2);
        xelec = xelec./rad;
        yelec = yelec./rad;
        zelec = zelec./rad;
        tmpbadlocs = EEG.chanlocs(badchans);
        xbad = [ tmpbadlocs.X ];
        ybad = [ tmpbadlocs.Y ];
        zbad = [ tmpbadlocs.Z ];
        rad = sqrt(xbad.^2+ybad.^2+zbad.^2);
        xbad = xbad./rad;
        ybad = ybad./rad;
        zbad = zbad./rad;
        if isempty(xbad)
            error('Trying to interpolate a channel without coordinates assigned to it');
        end

        EEG.data = reshape(EEG.data, EEG.nbchan, EEG.pnts*EEG.trials);
        %[tmp1 tmp2 tmp3 tmpchans] = spheric_spline_old( xelec, yelec, zelec, EEG.data(goodchans,1));
        %max(tmpchans(:,1)), std(tmpchans(:,1)),
        %[tmp1 tmp2 tmp3 EEG.data(badchans,:)] = spheric_spline( xelec, yelec, zelec, xbad, ybad, zbad, EEG.data(goodchans,:));
        [tmp1 tmp2 tmp3 badchansdata] = spheric_spline( xelec, yelec, zelec, xbad, ybad, zbad, EEG.data(datachans,:));
        %max(EEG.data(goodchans,1)), std(EEG.data(goodchans,1))
        %max(EEG.data(badchans,1)), std(EEG.data(badchans,1))
        EEG.data = reshape(EEG.data, EEG.nbchan, EEG.pnts, EEG.trials);
    elseif strcmpi(method, 'spacetime') % 3D interpolation, works but x10 times slower
        disp('Warning: if processing epoch data, epoch boundary are ignored...');
        disp('3-D interpolation, this can take a long (long) time...');
        tmpgoodlocs = EEG.chanlocs(goodchans);
        tmpbadlocs = EEG.chanlocs(badchans);
        [xbad ,ybad]  = pol2cart([tmpbadlocs.theta],[tmpbadlocs.radius]);
        [xgood,ygood] = pol2cart([tmpgoodlocs.theta],[tmpgoodlocs.radius]);
        pnts = size(EEG.data,2)*size(EEG.data,3);
        zgood = [1:pnts];
        zgood = repmat(zgood, [length(xgood) 1]);
        zgood = reshape(zgood,prod(size(zgood)),1);
        xgood = repmat(xgood, [1 pnts]); xgood = reshape(xgood,prod(size(xgood)),1);
        ygood = repmat(ygood, [1 pnts]); ygood = reshape(ygood,prod(size(ygood)),1);
        tmpdata = reshape(EEG.data, prod(size(EEG.data)),1);
        zbad = 1:pnts;
        zbad = repmat(zbad, [length(xbad) 1]);
        zbad = reshape(zbad,prod(size(zbad)),1);
        xbad = repmat(xbad, [1 pnts]); xbad = reshape(xbad,prod(size(xbad)),1);
        ybad = repmat(ybad, [1 pnts]); ybad = reshape(ybad,prod(size(ybad)),1);
        badchansdata = griddata3(ygood, xgood, zgood, tmpdata,...
                                              ybad, xbad, zbad, 'nearest'); % interpolate data
    else
        % get theta, rad of electrodes
        % ----------------------------
        tmpchanlocs = EEG.chanlocs;
        [xbad ,ybad]  = pol2cart([tmpchanlocs( badchans).theta],[tmpchanlocs( badchans).radius]);
        [xgood,ygood] = pol2cart([tmpchanlocs(goodchans).theta],[tmpchanlocs(goodchans).radius]);

        fprintf('Points (/%d):', size(EEG.data,2)*size(EEG.data,3));
        badchansdata = zeros(length(badchans), size(EEG.data,2)*size(EEG.data,3));

        for t=1:(size(EEG.data,2)*size(EEG.data,3)) % scan data points
            if mod(t,100) == 0, fprintf('%d ', t); end
            if mod(t,1000) == 0, fprintf('\n'); end;

            %for c = 1:length(badchans)
            %   [h EEG.data(badchans(c),t)]= topoplot(EEG.data(goodchans,t),EEG.chanlocs(goodchans),'noplot', ...
            %        [EEG.chanlocs( badchans(c)).radius EEG.chanlocs( badchans(c)).theta]);
            %end
            tmpdata = reshape(EEG.data, size(EEG.data,1), size(EEG.data,2)*size(EEG.data,3) );
            if strcmpi(method, 'invdist'), method = 'v4'; end
            [Xi,Yi,badchansdata(:,t)] = griddata(ygood, xgood , double(tmpdata(datachans,t)'),...
                                                    ybad, xbad, method); % interpolate data
        end
        fprintf('\n');
    end

    tmpdata               = zeros(length(bad_elec), EEG.pnts, EEG.trials);
    tmpdata(origoodchans, :,:) = EEG.data;
    %if input data are epoched reshape badchansdata for Octave compatibility...
    if length(size(tmpdata))==3
        badchansdata = reshape(badchansdata,length(badchans),size(tmpdata,2),size(tmpdata,3));
    end

    if ~isempty(t_range)
        t_start = t_range(1);
        t_end   = t_range(2);
        if t_start~=ORIEEG.xmin || t_end~=ORIEEG.xmax
            if length(size(tmpdata))==2
                times_2b_ignored = [1:floor(t_start*ORIEEG.srate), floor(t_end*ORIEEG.srate):floor(ORIEEG.xmax*ORIEEG.srate)];
                badchansdata(:, times_2b_ignored) = ORIEEG.data(badchans, times_2b_ignored);
            end
        end
    end

    tmpdata(badchans,:,:) = badchansdata;
    EEG.data = tmpdata;
    EEG.nbchan = size(EEG.data,1);
    if ~strcmpi(method, 'sphericalfast')
        EEG = eeg_checkset(EEG);
    end

% get data channels
% -----------------
function datachans = getdatachans(goodchans, badchans);
      datachans = goodchans;
      badchans  = sort(badchans);
      for index = length(badchans):-1:1
          datachans(find(datachans > badchans(index))) = datachans(find(datachans > badchans(index)))-1;
      end

% -----------------
% spherical splines
% -----------------
function [x, y, z, Res] = spheric_spline_old( xelec, yelec, zelec, values);

SPHERERES = 20;
[x,y,z] = sphere(SPHERERES);
x(1:(length(x)-1)/2,:) = []; x = [ x(:)' ];
y(1:(length(y)-1)/2,:) = []; y = [ y(:)' ];
z(1:(length(z)-1)/2,:) = []; z = [ z(:)' ];

Gelec = computeg(xelec,yelec,zelec,xelec,yelec,zelec);
Gsph  = computeg(x,y,z,xelec,yelec,zelec);

% equations are
% Gelec*C + C0  = Potential (C unknown)
% Sum(c_i) = 0
% so
%             [c_1]
%      *      [c_2]
%             [c_ ]
%    xelec    [c_n]
% [x x x x x]         [potential_1]
% [x x x x x]         [potential_ ]
% [x x x x x]       = [potential_ ]
% [x x x x x]         [potential_4]
% [1 1 1 1 1]         [0]

% compute solution for parameters C
% ---------------------------------
meanvalues = mean(values);
values = values - meanvalues; % make mean zero
C = pinv([Gelec;ones(1,length(Gelec))]) * [values(:);0];

% apply results
% -------------
Res = zeros(1,size(Gsph,1));
for j = 1:size(Gsph,1)
    Res(j) = sum(C .* Gsph(j,:)');
end
Res = Res + meanvalues;
Res = reshape(Res, length(x(:)),1);

function [xbad, ybad, zbad, allres] = spheric_spline( xelec, yelec, zelec, xbad, ybad, zbad, values);

newchans = length(xbad);
numpoints = size(values,2);

%SPHERERES = 20;
%[x,y,z] = sphere(SPHERERES);
%x(1:(length(x)-1)/2,:) = []; xbad = [ x(:)'];
%y(1:(length(x)-1)/2,:) = []; ybad = [ y(:)'];
%z(1:(length(x)-1)/2,:) = []; zbad = [ z(:)'];

Gelec = computeg(xelec,yelec,zelec,xelec,yelec,zelec);
Gsph  = computeg(xbad,ybad,zbad,xelec,yelec,zelec);

% compute solution for parameters C
% ---------------------------------
meanvalues = mean(values);
values = values - repmat(meanvalues, [size(values,1) 1]); % make mean zero

values = [values;zeros(1,numpoints)];
C = pinv([Gelec;ones(1,length(Gelec))]) * values;
clear values;
allres = zeros(newchans, numpoints);

% apply results
% -------------
for j = 1:size(Gsph,1)
    allres(j,:) = sum(C .* repmat(Gsph(j,:)', [1 size(C,2)]));
end
allres = allres + repmat(meanvalues, [size(allres,1) 1]);

% compute G function
% ------------------
function g = computeg(x,y,z,xelec,yelec,zelec)

unitmat = ones(length(x(:)),length(xelec));
EI = unitmat - sqrt((repmat(x(:),1,length(xelec)) - repmat(xelec,length(x(:)),1)).^2 +...
                (repmat(y(:),1,length(xelec)) - repmat(yelec,length(x(:)),1)).^2 +...
                (repmat(z(:),1,length(xelec)) - repmat(zelec,length(x(:)),1)).^2);

g = zeros(length(x(:)),length(xelec));
%dsafds
m = 4; % 3 is linear, 4 is best according to Perrin's curve
for n = 1:7
    if ismatlab
        L = legendre(n,EI);
    else % Octave legendre function cannot process 2-D matrices
        for icol = 1:size(EI,2)
            tmpL = legendre(n,EI(:,icol));
            if icol == 1, L = zeros([ size(tmpL) size(EI,2)]); end
            L(:,:,icol) = tmpL;
        end
    end
    g = g + ((2*n+1)/(n^m*(n+1)^m))*squeeze(L(1,:,:));
end
g = g/(4*pi);


function a = ge( x, y )

evalin( 'caller', 'cvx_verify' );
b = cvx_pushcnstr( x, y, '>=' );
if nargout, a = b; end

% Copyright 2005-2014 CVX Research, Inc.
% See the file LICENSE.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function [lab]=vadlabel(data)

l=abs(data)>0;
n=find(l==0);
for i=2:length(n)-1
if data(n(i)-1)~=0 || data(n(i)+1)~=0
l(n(i))=1;
end
end
lab = l;


function tests = test_spm_dcm_fmri_check
% Unit Tests for spm_dcm_fmri_check
%__________________________________________________________________________
% Copyright (C) 2016 Wellcome Trust Centre for Neuroimaging

% $Id: test_spm_dcm_fmri_check.m 6790 2016-04-28 14:30:27Z guillaume $

tests = functiontests(localfunctions);

% -------------------------------------------------------------------------
function test_DCM(testCase)
% Simply tests the function doesn't crash with one DCM

import matlab.unittest.constraints.*

data_path = get_data_path();
dcm_file  = fullfile(data_path,'DCM_s1_m1.mat');

DCM = spm_dcm_fmri_check(dcm_file, true);

testCase.fatalAssertThat(DCM, HasField('diagnostics'));
testCase.verifyThat(DCM.diagnostics, HasElementCount(3));

% -------------------------------------------------------------------------
function test_GCM(testCase)
% Simply tests the function doesn't crash with a GCM array

import matlab.unittest.constraints.*

data_path = get_data_path();
gcm_file  = fullfile(data_path,'GCM_simulated.mat');

GCM = spm_dcm_fmri_check(gcm_file, true);

testCase.verifyThat(GCM, IsOfClass('cell'));
testCase.fatalAssertThat(GCM{1}, HasField('diagnostics'));
testCase.verifyThat(GCM{1}.diagnostics, HasElementCount(3));

% -------------------------------------------------------------------------
function data_path = get_data_path()
data_path = fullfile( spm('Dir'), 'tests', ...
    'data', 'fMRI', 'simulated_2region', 'models');


function [im] = im_pad(im)

[w,h,~] = size(im);

if mod(w,2)==1
    im = cat(1,im, im(end,:,:)) ;
end
if mod(h,2)==1
    im = cat(2,im, im(:,end,:)) ;
end

end


function calSave1 (~, ~, A, B)
    % save data to an interactively chosen file

    msg.infodisp('  ','Save Data');

    [file1,path1] = uiputfile(fullfile(ZmapGlobal.Data.Directories.output, '*.dat'), 'Filename ');
    if file1 && path1
        if ~iscolumn(A)
            A = A';
        end
        if ~iscolumn(B)
            B = B';
        end
        data = [A, B]';
        fid = fopen([path1 file1],'w') ;
        fprintf(fid, '%12.5f  %12.5f\n' , data);
        fclose(fid) ;
    else
        msg.dbdisp('  ','cancelled save');
    end

end


function [] = latex2pdf3d(fname, latex_compiler)
%LATEX2PDF3D    Compile LaTeX code to PDF.
%
% usage
%   LATEX2PDF3D
%   LATEX2PDF3D(fname, latex_compiler)
%
% optional input
%   fname = file name string
%   latex_compiler = 'pdflatex' | 'xelatex'
%
% output
%   If compilation succeeds, then a PDF file is produced.
%
% dependency
%   pdflatex or xelatex should be available in the system path
%
% See also FIG2PDF3D, FIG2LATEX, U3D_IN_LATEX.
%
% File:      latex2pdf3d.m
% Author:    Ioannis Filippidis, jfilippidis@gmail.com
% Date:      2012.06.21
% Language:  MATLAB R2012a
% Purpose:   compile LaTeX file to a PDF
%
% acknowledgment
%   Based on demo_mesh2pdf by Alexandre Gramfort.
%   This can be found on the MATLAb Central File Exchange:
%       http://www.mathworks.com/matlabcentral/fileexchange/25383-matlab-mesh-to-pdf-with-3d-interactive-object
%   and is covered by the BSD License.

% depends
%   {pdflatex | xelatex}, {media9 | movie15}

%% input
if nargin < 1
    fname = 'matfig';
end

if nargin < 2
    latex_compiler = 'xelatex';
end

%% Use pdflatex to generate the pdf
switch latex_compiler
    case 'pdflatex'
        cmd = ['pdflatex --interaction=nonstopmode ', fname, '.tex'];
    case 'xelatex'
        cmd = ['xelatex --interaction=nonstopmode ', fname, '.tex'];
    otherwise
        error('latex:compiler', 'Unknown LaTeX compiler.')
end

status = system(cmd);
if status ~= 0
    error('latex:compile', 'LaTeX compilation failed.')
end


function [fhdr,chdr,ename,cnames,fcom,ftext] = read_egis_header(filename)

% READ_EGIS_HEADER reads the header information from an EGI EGIS format file
%
% Use as
%   [fhdr chdr] = read_egia_header(filename)
% with
%   fhdr        - the file header information
%   chdr        - the cell header information
%   ename       - experiment name
%   cnames      - cell names
%   fcom        - comments
%   ftext       - general text
% and
%   filename    - the name of the data file
%_______________________________________________________________________
%
%
% Modified from EGI's EGI Toolbox with permission 2007-06-28 Joseph Dien

% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

fh=fopen_or_error([filename],'r');

%Prep file for reading
fhdr=zeros(1,23);
status=fseek(fh,0,'bof');

%Read in fhdr fields.
fhdr(1)=fread(fh,1,'int32'); %BytOrd
[str,maxsize,cEndian]=computer;
if fhdr(1)==16909060
  if cEndian == 'B'
    endian = 'ieee-be';
  elseif cEndian == 'L'
    endian = 'ieee-le';
  end
elseif fhdr(1)==67305985
  if cEndian == 'B'
    endian = 'ieee-le';
  elseif cEndian == 'L'
    endian = 'ieee-be';
  end
else
  ft_error('This is not an EGIS average file.');
end

fhdr(2)=fread(fh,1,'int16',endian); %HdrVer

if (fhdr(2) ~= -1) && (fhdr(2) ~= 3)
  ft_error('This is not an EGIS average file.');
end

fhdr(3)=fread(fh,1,'uint16',endian); %LHeader
fhdr(4)=fread(fh,1,'uint32',endian); %LData
status=fseek(fh,80,'cof'); %Skip ExptNam
fhdr(5:10)=fread(fh,6,'int16',endian); %RunDate and RunTime

fhdr(11:23)=fread(fh,13,'int16',endian); %Everything else up to LCellHdr

fhdr(24:(24+fhdr(18)-1))=fread(fh,fhdr(18),'uint16',endian); %LCellHdr for each cell

%Read in chdr
chdr=zeros(fhdr(18),5);
status=fseek(fh,(4*fhdr(19)),'cof');
for loop=1:fhdr(18)
  chdr(loop,1)=fread(fh,1,'int16',endian);
  status=fseek(fh,80,'cof');
  chdr(loop, 2:5)=(fread(fh,4,'int16',endian))';
  lspectot=(chdr(loop,2)*(chdr(loop,5)/2));
  lastcol=(6+lspectot-1);
  if lastcol >= 6
    chdr(loop,lastcol)=0;
    chdr(loop,6:lastcol)=(fread(fh,lspectot,'int16',endian))';
  end
end

%Read experiment name
status=fseek(fh,12,'bof');
tempstr=fread(fh,80,'char');
ename=char(tempstr);

%Read cellnames
status=fseek(fh,(130+(2*fhdr(18))+(4*fhdr(19))),'bof');
status=fseek(fh,2,'cof');
for loop=1:fhdr(18)
  temp=fread(fh,80,'char');
  theName=strtok(temp,0);
  cnames{loop}=deblank(char(theName))';
  status=fseek(fh,fhdr(24+(loop-1))-80,'cof');
end

%Read comment
%status=fseek(fh,fhdr(3),'bof');
%status=fseek(fh,-(fhdr(22)+fhdr(21)+fhdr(20)),'cof');
fcom=fread(fh,fhdr(20),'char');

%Read text
%status=fseek(fh,fhdr(3),'bof');
%status=fseek(fh,-(fhdr(22)+fhdr(21)),'cof');
ftext=fread(fh,fhdr(21),'char');

fclose(fh);


function spm_dcm_create(syn_model,source_model,SNR)
% Create a DCM with simulated data (specified via GUI or an existing model)
% FORMAT spm_dcm_create(syn_model,source_model,SNR)
%
% syn_model     - name of the synthetic DCM to be created
% source_model  - define new model ('GUI')
%                 or import existing model via file selector ('import')
%                 or import existing model (directly specified by directory
%                 and name)
%                 [default: 'GUI']
% SNR           - signal-to-noise ratio [default: 1]
%
% This function allows to create DCM networks with known connectivity
% parameters from which synthetic data are then generated by calling
% spm_dcm_generate.
%
% This function is very much like spm_dcm_specify_ui but inputs etc. are
% specified either via the user interface or from an existing model.
% Currently, the interface provided by this function does not allow for
% manual specification of nonlinear DCMs; however, these can be imported
% from existing files.
%__________________________________________________________________________
% Copyright (C) 2002-2014 Wellcome Trust Centre for Neuroimaging

% Will Penny & Klaas Enno Stephan & Peter Zeidman
% $Id: spm_dcm_create.m 7654 2019-08-25 20:09:35Z karl $

Finter = spm_figure('GetWin','Interactive');
header = get(Finter,'Name');
set(Finter,'Name','Dynamic Causal Modelling')

%-Check parameters and insert default values, if necessary
%==========================================================================
if nargin == 0
    syn_model    = spm_input('Name for target DCM_???.mat','+1','s');
    SNR          = spm_input('Signal-to-noise ratio (SNR)? ','+1','r',[],1);
    source_model = 'GUI';
else
    try, source_model; catch, source_model = 'GUI'; end
    try, SNR;          catch, SNR = 1;              end
end

%-Outputs
%==========================================================================
switch upper(source_model)

    case 'GUI'

        %-Define model by GUI
        %==================================================================

        % Load SPM for experimental timing
        %------------------------------------------------------------------
        [spm_file, sts] = spm_select(1,'^SPM\.mat$','Select SPM.mat');
        if ~sts, return; end
        try
            SPM = load(spm_file);
            SPM = SPM.SPM;
        catch
            error('Cannot read %s.',spm_file);
        end

        % Check for which session to create the DCM
        %------------------------------------------------------------------
        session = length(SPM.Sess);
        if session > 1
            session   = spm_input('which session','!+1','n1',1,session);
            if isempty(session) || ~isnumeric(session)
                error('A session number is required');
            end
        end

        % Get cell array of region structures
        %------------------------------------------------------------------
        n = spm_input('Enter number of regions',1,'r',[],1);
        for i=1:n
            str         = sprintf('Region %d',i);
            xY(i).name  = spm_input(['Name for ',str],'+1','s');
            % Make up spurious VOI info
            % for compatibility with spm_dcm_display
            xY(i).xyz   = [i i i]'*10;
            xY(i).XYZmm = [i i i]'*10;
            xY(i).s     = 1;
            xY(i).spec  = 1;
            % for compatibility with spm_dcm_specify
            xY(i).Sess  = session;
            xY(i).u     = 1;
            xY(i).X0    = [];
        end

        % Run through standard specification questions
        %------------------------------------------------------------------
        DCM   = spm_dcm_specify_ui(SPM,xY);

        % Get desired number of scans
        %------------------------------------------------------------------
        DCM.v = SPM.nscan(session);

        % Set default connection strengths to reasonable values
        %------------------------------------------------------------------
        DEFAULT_SELF    = 0;
        DEFAULT_BETWEEN = 0.3;
        DEFAULT_DRIVING = 0.8;

        def   = struct();
        def.A = DEFAULT_BETWEEN .* DCM.a;
        def.A = def.A - diag(diag(def.A));
        def.A = def.A + diag(repmat(DEFAULT_SELF,n,1));
        def.B = DEFAULT_BETWEEN .* DCM.b;
        def.C = DEFAULT_DRIVING .* DCM.c;

        % Build A-matrix
        %------------------------------------------------------------------

        % Initialize DCM.Ep with prior values
        DCM.Ep  = spm_dcm_fmri_priors(DCM.a,DCM.b,DCM.c,DCM.d);

        enabled = struct('A',DCM.a,'B',DCM.b,'C',DCM.c);

        entry_accepted = false;
        while ~entry_accepted
            % Prompt for A-matrix
            str = 'Connectivity for';
            con = spm_dcm_connectivity_ui(DCM,'A', str, def, enabled);
            DCM.Ep.A = con.A;

            % Check stability
            if spm_dcm_check_stability(DCM)
                entry_accepted = true;
            else
                % Query for another attempt
                qtext = ...
                    'Parameters may lead to an unstable estimate. Edit your selection?';
                options = struct('Default','Yes','Interpreter','none');
                choice = questdlg(qtext,'Stability','Yes','No',options);
                entry_accepted = ~strcmp(choice,'Yes');

                % Ensure any new values are re-populated
                def = struct('A',DCM.Ep.A,'B',DCM.Ep.B,'C',DCM.Ep.C);
            end
        end

        % Build B-matrix and C-matrix
        %------------------------------------------------------------------
        con = spm_dcm_connectivity_ui(DCM,'B', str, def, enabled);
        DCM.Ep.B = con.B;
        con = spm_dcm_connectivity_ui(DCM,'C', str, def, enabled);
        DCM.Ep.C = con.C;

    case 'IMPORT'

        % Import existing model - prompt user to choose it
        %==================================================================
        P     = spm_select(1,'^DCM.*\.mat$','Select source DCM_???.mat');
        load(P)

    otherwise

        % Import existing model (directly specified by directory & name)
        %==================================================================
        try
            load(source_model)
        catch
            error('Cannot load source model');
        end

end

% Now set up output structure
%--------------------------------------------------------------------------
X0    = ones(DCM.v,1);
switch upper(source_model)
    case 'GUI'
        Y              = DCM.Y;
        DCM.Ep.decay   = sparse(DCM.n,1);
        DCM.Ep.transit = sparse(DCM.n,1);
        DCM.Ep.epsilon = sparse(1,1);
    otherwise
        try
            Y.dt = DCM.Y.dt;
        catch
            Y.dt = DCM.delays(1);
        end
end
Y.X0  = X0;
for i = 1:DCM.n
    Y.name{i} = DCM.xY(i).name;
end
Y.Q   = spm_Ce(ones(1,DCM.n)*DCM.v);
DCM.Y = Y;

%-Save
%--------------------------------------------------------------------------
dcm_filename = ['DCM_' syn_model '.mat'];
save(dcm_filename,'DCM', spm_get_defaults('mat.format'));

% Generate synthetic output data
%==========================================================================
spm_dcm_generate(dcm_filename,SNR);

spm('FigName',header);


function [Nm] = J2Nm(J)
% Convert energy or work from joules to newton-meters.
% Chad A. Greene 2012
Nm = J;
% You say tomatermort, I say tomato.


function [version released] = manopt_version()
% Returns the version of the Manopt package you are running, as a vector.
%
% function [version released] = manopt_version()
%
% version(1) is the primary version number.
% released is the date this version was released, in the same format as the
% date() function in Matlab.

    version = [1, 0, 6];
    released = '25-Jun-2014';


function value = l4_to_i4 ( l )

%*****************************************************************************80
%
%% L4_TO_I4 converts an L4 to an I4.
%
%  Discussion:
%
%    0 is FALSE, and anything else if TRUE.
%
%    An I4 is an integer value.
%    An L4 is a logical value.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    10 January 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, logical L, a logical value.
%
%    Output, integer VALUE, the integer value of L.
%
  if ( l )
    value = 1;
  else
    value = 0;
  end

  return
end


function figbolden(pos,pv,m)
% embolden the current figure
% Inputs: pos = [xmin ymin width height] gives the lower left corner position and the window size in pixels
%               [width height] leaves the lower left corner alone
%               [width] has a standard aspect ratio of 4:3
%               [-width/height] leaves the area unchanged but fixes the aspect ratio
%         pv is a cell name containing attribute-value pairs.
%            default = {'FontName' 'Ariel'; 'FontSize' 16; 'LineWidth' 2; 'MarkerSize' 8}
%         m is a mode string:
%                'l' lists the changes made
%                'd' uses default pv settings
%                'x' suppresses changes

%      Copyright (C) Mike Brookes 2003
%      Version: $Id: figbolden.m,v 1.10 2011/02/28 12:52:10 dmb Exp $
%
%   VOICEBOX is a MATLAB toolbox for speech processing.
%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   This program is free software; you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation; either version 2 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You can obtain a copy of the GNU General Public License from
%   http://www.gnu.org/copyleft/gpl.html or by writing to
%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

ps={'Title' 'XLabel' 'YLabel' 'Children'};
if nargin<3
    m='';
end
if nargin<2 || any(m=='d')
    pv={'FontName' 'Arial'; 'FontSize' 16; 'LineWidth' 2; 'MarkerSize' 8};
end
pp={'Symbol';'Wingdings'};      % protected fonts
if nargin<1
    pos=[];
end
mlist=any(m=='l');  % list changes
mnotx=~any(m=='x'); % do changes
scsz=get(0,'screensize');
if length(pos)
    po=get(gcf,'position');
    if length(pos)>2            % position is specified
        po(1:2)=pos(1:2);
        pos(1:2)=[];      % remove xmin,ymin
    end
    if length(pos)>1
        po(3:4)=pos(1:2);
    else
        if pos(1)>0
            po(3:4)=[1 0.75]*pos(1);
        else
            po(3:4)=[-pos(1) 1]*sqrt(-po(3)*po(4)/pos(1)); % preserve area
        end
    end
    set(gcf,'position',po);
end
hlist=get(gcf,'children');
while length(hlist)
    pl=get(hlist(1));
    %fprintf('list length = %d, handle = %f\n',length(hlist),hlist(1));
    for i=1:size(pv,1)
        if isfield(pl,pv{i,1})
            if i>1 || all(~strcmp(get(hlist(1),pv{i,1}),pp))
                pval=get(hlist(1),pv{i,1});
                if ~all(size(pval)==size(pv{i,2})) || ~all(pval(:) == pv{i,2}(:))
                    if mnotx
                        set(hlist(1),pv{i,1},pv{i,2})
                    end
                    if mlist
                        if ischar(pval)
                            fch='s';
                        else
                            fch='g';
                        end
                        fprintf(['change %f %s: %' fch ' -> %' fch '\n'],hlist(1),pv{i,1},pval,pv{i,2});
                    end
                end
            end
        end
    end
    for i=1:length(ps)
        if isfield(pl,ps{i})
            hlist=[hlist; get(hlist(1),ps{i})];
            %fprintf('add %f:%s\n',hlist(1),ps{i});
        end
    end
    hlist(1)=[];
end


function cMap=gjet(varargin)

switch nargin
    case 0
        n=250;
    case 1
        n=varargin{1};
end

cMap=[51  105 232;... %Blue
      0   153 37;... %Green
      238 178 17;... %Yelow
      213 15  37;... %red
    ];
cMap=cMap./255;

[cMap]=resampleColormap(cMap,n);

%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function Cpp_Params = Flatten_Cpp_Params(P_Cpp,Data)

%FUNCTION:
%   This function takes a state struct S, and collapses it to a column
%   vector s. It relies on information about the struct format that is
%   stored in P.StateStruct, which is created by the
%   Define_StateStruct_Data.m function.
%
%INPUTS:
%   P = the struct the is being used ito pass parameters
%   Data = contains information about P
%
%OUTPUTS:
%   param_vec = a column vector with all of the data in P
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Names = Data.Names;
Sizes = Data.Sizes;
Idx = Data.Idx;

Length = Idx(end,2);   %How many elements in the entire state
Cpp_Params = zeros(Length,1);   %Total size of the state struct
N = length(Names);   %total number of fields;
L = Sizes(:,1).*Sizes(:,2);   %Length of each field;

for i=1:N
   Cpp_Params(Idx(i,1):Idx(i,2)) = reshape(P_Cpp.(Names{i})',L(i),1);  %Transpose accounts for C++ array definition difference
end

end


% LFDispLawnmower - visualize a 4D light field animating a lawnmower path through two dimensions
%
% Usage:
%     FigureHandle = LFDispLawnmower( LF )
%     FigureHandle = LFDispLawnmower( LF, [RenderOptions], [ScaleFactor] )
%
%
% Inputs:
%
%     LF : a colour or single-channel light field, and can a floating point or integer format. For
%          display, it is converted to 8 bits per channel. If LF contains more than three colour
%          channels, as is the case when a weight channel is present, only the first three are used.
%
% Optional Inputs:
%
%     RenderOptions
%        .FrameDelay         : delay between frames, in seconds. Default 1/30.
%        .NumCycles          : how many times the path should repeat. Default inf.
%
%     ScaleFactor : Adjusts the size of the display -- 1 means no change, 2 means twice as
%                   big, etc. Integer values are recommended to avoid scaling artifacts.
%
% Outputs:
%
%     FigureHandle
%
%
% User guide: LFToolbox.pdf
% See also: LFDisp, LFDispMousePan, LFDispVidCirc, LFDispProj, LFDispTiles

% Copyright (c) 2013-2020 Donald G. Dansereau

% todo: smooth transition from vertical to horizontal
% todo: optional horz/vert only

function FigureHandle = LFDispLawnmower( LF, RenderOptions, ScaleFactor )

%---Defaults---
ScaleFactor = LFDefaultVal('ScaleFactor', 1);
RenderOptions = LFDefaultField( 'RenderOptions', 'FrameDelay', 1/30 );
RenderOptions = LFDefaultField( 'RenderOptions', 'NumCycles', inf );

%---Check for a light field with only one spatial dim---
if( ndims(LF) == 3 || (ndims(LF)==4 && (size(LF,4)==3 || size(LF,4)==4)) )
	LF = reshape(LF, [1, size(LF)]);
end
LFSize = size(LF);

%---Check for mono and clip off the weight channel if present---
HasWeight = (ndims(LF)>2 && (LFSize(end)==2 || LFSize(end)==4));
if( HasWeight )
	LF = LF(:,:,:,:,1:end-1);
end

%---Rescale for 8-bit display---
if( isfloat(LF) )
	LF = uint8(LF ./ max(LF(:)) .* 255);
else
	LF = uint8(LF.*(255 / double(intmax(class(LF)))));
end

%---Setup the motion path---
[TSize,SSize, ~,~] = size(LF(:,:,:,:,1));
[tt,ss] = ndgrid(1:TSize, 1:SSize);

%---Setup the display---
TIdx = 1;
SIdx = 1;
[ImageHandle,FigureHandle] = LFDispSetup( squeeze(LF(TIdx,SIdx,:,:,:)), ScaleFactor );

while( 1 )
	CurRep = 0;

	% left/right
	TVec = tt;
	SVec = ss;
	SVec(2:2:end,:) = SVec(2:2:end,end:-1:1);
	SVec = SVec';
	TVec = TVec';

	for( PoseIdx = 1:numel(tt) )

		TIdx = TVec(PoseIdx);
		SIdx = SVec(PoseIdx);

		CurFrame =  squeeze(LF( TIdx, SIdx, :,:,: ));
		set(ImageHandle,'cdata', CurFrame );

		pause(RenderOptions.FrameDelay)

	end

	% Up/down
	TVec = tt;
	TVec(:,2:2:end) = TVec(end:-1:1, 2:2:end);
	SVec = ss;

	for( PoseIdx = 1:numel(tt) )

		TIdx = TVec(PoseIdx);
		SIdx = SVec(PoseIdx);

		CurFrame =  squeeze(LF( TIdx, SIdx, :,:,: ));
		set(ImageHandle,'cdata', CurFrame );

		pause(RenderOptions.FrameDelay)

	end
	CurRep = CurRep + 1;

	if( CurRep >= RenderOptions.NumCycles )
		break;
	end
end


% Signal Processing Toolbox check
% axs Nov 2020
function SigProcT_here = SignalProcessingToolboxCheck

% Get Toolbox list from ver
tbxs = ver;
[a, tbxs_n] = size(tbxs);
tbx_cell = cell(1,tbxs_n);
tbx_cell = {tbxs.Name};

SigProcT_here = any(ismember(tbx_cell,'Signal Processing Toolbox'));

if SigProcT_here == 0
    % if the Signal Processing Toolbox is not found
    warning_text = 'Matlab Signal Processing Toolbox has not been found.';
    warning_text2= 'This is required for many ERPLAB functions, especially filters';
    warning(warning_text)
    warning(warning_text2)
    disp('See Signal Processing Toolbox help here')

end


% loaddat() - loading neuroscan format data file into matlab.
%
% Usage:
%   >> [typeeeg, rt, response, n] = loaddat( filename );
%
% Inputs:
%   filename     - input Neuroscan .dat file
%
% Outputs:
% 	typeeeg	 - type of the sweeps
%	rt	 - reaction time of the subject
%	response - response of the subject
%	n	 - number of sweeps
%
% See also: loadeeg()

% Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 2 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

function [tmptypeeeg, tmprt, tmpresponseeeg, n] = loaddat( FILENAME)

if nargin<1
	fprintf('Not enought arguments\n');
	help loaddat
	return;
end;

BOOL='int16';
ULONG='int32';
FLOAT='float32';

fid=fopen(FILENAME,'r','ieee-le');
if fid<0
	fprintf(2,['Error LOADEEG: File ' FILENAME ' not found\n']);
	return;
end;

% skip the first 20 lines
% -----------------------
for index=1:20	fgetl(fid); end;

% read the matrix
% ---------------
tmpMat 		    = fscanf(fid, '%f', [5, inf]);
tmptypeeeg  	= tmpMat(3,:);
tmpresponseeeg  = tmpMat(4,:);
tmprt       	= tmpMat(5,:);
n        	    = size( tmpMat, 2);

fclose(fid);
return;


function f = cumsum(f, dim)
%CUMSUM   Indefinite integral of a SPHEREFUN.
%
%  F = CUMSUM(F) or F = CUMSUM(F, DIM) is not defined on a spherefun.
%
%   This is not allowed and returns an error.  This function exists so that the
%   error message is meaningful to a SPHEREFUN user.
%
% See also SPHEREFUN/CUMSUM2.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

error('CHEBFUN:SPHEREFUN:CUMSUM:fail',...
      'The indefinite integral is not defined for a spherefun.');

end


function [ meta ] = read_sicd01_meta( filename )
%READ_SICD01_META Read metadata from Sensor Independent Complex Data (SICD)
%file, version 0.1
%
% Written by: Wade Schwartzkopf, NGA/IDT
%
% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////

% Open file
fid=fopen(filename,'r','b');
if(fid<0)
    error('READ_SICD01_META:InvalidFile','Unable to open file.');
end
% Read in non-xml header data
meta.format=fgetl(fid);
if(~strcmp(meta.format,'SICD-E/0.1'))
    error('READ_SICD01_META:UnrecognizedVersion','Unrecognized version of SICD format.  Only version 0.1 supported.');
end
for i=1:10
    [fieldname,value]=strtok(fgetl(fid),':=');
    fieldname=regexprep(fieldname,'-','_'); % Make sure field is valid Matlab variable name
    meta.header.(fieldname)=value(3:end);
    doubval=str2double(meta.header.(fieldname));
    if(~isnan(doubval)) % If value is numeric, store as such
        meta.header.(fieldname)=doubval;
    end
end
meta.header_length_in_bytes=ftell(fid);
fread(fid,2,'uchar'); % Blank line (/12/10) in between header and xml
% Read XML
SICD_xml_string = fread(fid,meta.header.xml_content_length,'uchar=>char',0)';
meta.xmldata = xml2simplestruct( xmlread( java.io.StringBufferInputStream( SICD_xml_string ) ) );
fclose(fid);

end

% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////


function title = p19_title ( title )

%*****************************************************************************80
%
%% P19_TITLE returns the title of problem 19.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    15 January 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string TITLE, the title of the problem.
%
  title = 'The jumping cosine';

  return
end


%==============================================================================
% This code is part of the Matlab-based toolbox
% FAIR - Flexible Algorithms for Image Registration.
% For details see
% - https://github.com/C4IR and
% - http://www.siam.org/books/fa06/
%==============================================================================
% This is a testing environment for the files in the folder kernel/viewer
% 1. Based on data/contents, a list of required files is generated and it
%    is verified, that all files are present; additional files are listed.
% 2. All c-files are compiled.
% 3. All files are executed.
%==============================================================================

FAIRcheckFiles(mfilename);

viewImage('reset','viewImage','viewImage2D','colormap','gray(256)');
viewImage('disp');
[scheme,parameter] = viewImage
viewImage('clear');
viewImage('disp');
testEnd

%==============================================================================


function [newModel, modelChanges] = addMetabolicNetwork(model,rxnsToAdd,metsToAdd)
%addMetabolicNetwork  Integrate a new metabolic network into a model
%
% NOTE: The function is to incorporate a subnetwork that is provided by two
%       arrays, rxnsToAdd and metsToAdd, which should be in defined
%       structure as below，and with reactions and metabolites that are
%       NOT included in the model
%
% Usage:
%   [newModel, modelChanges] = addMetabolicNetwork(model,rxnsToAdd,metsToAdd)
%
%
% Inputs:
%   model        A model structure
%
%   rxnsToAdd    the reaction structure can have the following fields:
%            rxns               cell array with unique strings that
%                               identifies each reaction
%            equations          cell array with equation strings. Decimal
%                               coefficients are expressed as "1.2".
%                               Reversibility is indicated by "<=>" or "=>"
%                               The metabolites have to be written as
%                               "metNames[comps]". Only compartments in
%                               model.comps are allowed. New metabolites to
%                               the model should be added to metsToAdd array
%            rxnNames           cell array with the names of each reaction
%                               (opt, default '')
%            lb                 vector with the lower bounds (opt, default
%                               to model.annotations.defaultLB or -inf for
%                               reversible reactions and 0 for irreversible
%                               when "equations" is used. When "mets" and
%                               "stoichCoeffs" are used it defaults for all
%                               reactions to model.annotations.defaultLB or
%                               -inf)
%            ub                 vector with the upper bounds (opt, default
%                               to model.annotations.defaultUB or inf)
%            eccodes            cell array with the EC-numbers for each
%                               reactions. Delimit several EC-numbers with
%                               ";" (opt, default '')
%            subSystems         cell array with the subsystems for each
%                               reaction (opt, default '')
%            grRules            cell array with the gene-reaction
%                               relationship for each reaction. For example
%                               "(A and B) or (C)" means that the reaction
%                               could be catalyzed by a complex between
%                               A & B or by C on its own. All the genes
%                               have to be present in model.genes. Add
%                               genes with addGenesRaven before calling
%                               this function if needed (opt, default '')
%            rxnReferences      cell array with reaction references (opt,
%                               default '')
%            rxnConfidenceScores   vector with reaction confidence scores
%                               (opt, default NaN)
%
%   metsToAdd   the metabolite structure can have the following fields:
%            mets              cell array with unique strings that
%                              identifies each metabolite (opt, default IDs
%                              of new metabolites are numbered with the
%                              prefix defined below)
%            metNames          cell array with the names of each
%                              metabolite
%            compartments      cell array with the compartment of each
%                              metabolite. Should match model.comps.
%                              If this is a string rather than a cell
%                              array it is assumed that all mets are in
%                              that compartment
%            inchis            cell array with InChI strings for each
%                              metabolite (opt, default '')
%            metFormulas       cell array with the formulas for each of
%                              the metabolites (opt, default '')
%            metCharges        metabolite charge (opt, default NaN)
%
%
% Outputs:
%   newModel      a new model with the added reactons and metabolites
%
%   modelChanges  a cell structure containing the original and new reaction
%                 and/or metabolite properties. Reaction-related changes
%                 are reported in the modelChanges.rxns field, whereas
%                 metabolite-related changes are reported in the
%                 modelChanges.mets field
%

if nargin<2
    error('Missing input!');
end

if nargin<3
    metsToAdd = [];
end

%% Add new metabolites

if isempty(metsToAdd)
    newModel = model;
else
    % the following metabolite fields are required to be included
    requiredMetFields = {'mets','metNames','metFormulas','metCharges','compartments'};
    if ~all(ismember(requiredMetFields, fieldnames(metsToAdd)))
        error('There is missing fields in the metabolite structure to be added.');
    end

    % verify that none of the metabolites exist in the current model
    if any(ismember(metsToAdd.mets, model.mets))
        error('One or more metabolite IDs to be added already exist in the model.');
    end

    % add metabolites to the model
    newModel = addMets(model,metsToAdd);
end

%% Check new reactions

% the following reaction fields are required to be included
requiredRxnFields = {'rxns','equations','subSystems','grRules'};
if ~all(ismember(requiredRxnFields, fieldnames(rxnsToAdd)))
    error('There is missing fields in the metabolite structure to be added.');
end

% verify that none of the reactions exist in the current model
if any(ismember(rxnsToAdd.rxns, model.rxns))
    error('One or more reactions to be added already exist in the model.');
end

% make sure all equations have metabolites in a format of "metNames[comps]"
if ~all(contains(rxnsToAdd.equations, '[') & contains(rxnsToAdd.equations, ']'))
    error('The metabolites in equations should be in a format of "metNames[comps]".');
end

%% Add new genes

% extract genes from grRules
newGenes = getGenesFromGrRules(rxnsToAdd.grRules);

% remove genes that are already existed in model
if any(ismember(newGenes, newModel.genes))
    fprintf('One or more genes to be added already exist in the model，therefore they will be merged.\n');
    newGenes = setdiff(newGenes, newModel.genes);
end

% append new genes to list of model genes
newModel.genes = [newModel.genes; newGenes];

% add new columns to rxnGeneMat will be updated after the new reactions are added below.
newModel.rxnGeneMat(:, end+1:end+numel(newGenes)) = 0;

%% Integrate new subnetwork to the model
newModel = addRxns(newModel, rxnsToAdd, 3);

% update genes and rxnGeneMat with new grRules
[newModel.genes, newModel.rxnGeneMat] = getGenesFromGrRules(newModel.grRules);

%% Document model changes
modelChanges = docModelChanges(model, newModel);