function varargout = DiffTool(varargin)
%DiffTool.m
%Jamie Near, McGill University 2014.
%
% USAGE:
% DiffTool(in1,in2,ppmmin,ppmmax);
%
% DESCRIPTION:
% Graphical User Interface for Subtraction of two spectra, with manual
% adjustment of the relative phase and frequency of the two spectra.
% Difference spectrum is shown in real time.
%
% INPUTS:
% in1        = first input dataset in matlab structure format.
% in2        = second input dataset in matlab structure format.
% ppmmin     = minimum of ppm frequency range.
% ppmmax     = maximum of ppm frequency range.
%
%DIFFTOOL M-file for DiffTool.fig
%      DIFFTOOL, by itself, creates a new DIFFTOOL or raises the existing
%      singleton*.
%
%      H = DIFFTOOL returns the handle to a new DIFFTOOL or the handle to
%      the existing singleton*.
%
%      DIFFTOOL('Property','Value',...) creates a new DIFFTOOL using the
%      given property value pairs. Unrecognized properties are passed via
%      varargin to DiffTool_OpeningFcn.  This calling syntax produces a
%      warning when there is an existing singleton*.
%
%      DIFFTOOL('CALLBACK') and DIFFTOOL('CALLBACK',hObject,...) call the
%      local function named CALLBACK in DIFFTOOL.M with the given input
%      arguments.
%
%      *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 DiffTool

% Last Modified by GUIDE v2.5 16-Jul-2014 12:48:29

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @DiffTool_OpeningFcn, ...
                   'gui_OutputFcn',  @DiffTool_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 DiffTool is made visible.
function DiffTool_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   unrecognized PropertyName/PropertyValue pairs from the
%            command line (see VARARGIN)

%JAMIE NEAR ADDED SPECTROSCOPY DATA CODE

handles.in1=varargin{1};
handles.in2=varargin{2};
handles.ppmmin=varargin{3};
handles.ppmmax=varargin{4};

%Magnetic field 3 Tesla
Bo=handles.in1.Bo;

n=length(handles.in1.t);

handles.orig_Specs1=handles.in1.specs;
handles.orig_Specs2=handles.in2.specs;
handles.current_Specs2=handles.in2.specs;
handles.diff=op_subtractScans(handles.in1,handles.in2);
handles.orig_diffSpecs=handles.diff.specs;
handles.current_diffSpecs=handles.diff.specs;

%obtains the zero order phase value from the phas0Slider component
phas0Value = 0;
phas1Value = 0;
freqValue = 0;
ampValue = 100;
DCValue = 0;

handles.phas0Value=phas0Value;
handles.phas1Value=phas1Value;
handles.freqValue=freqValue;
handles.ampValue=ampValue;
handles.DCValue=DCValue;

labsiz=14;
handles.labsiz=labsiz;
tiksiz=12;
handles.tiksiz=tiksiz;
%linwidth=1.5;
%mksiz=12;

% %MAKE SUBSPECS PLOTS
axes(handles.axes2);
plot(handles.in1.ppm,real(handles.orig_Specs1),'b-',handles.in2.ppm,real(handles.current_Specs2),'r-',handles.diff.ppm,real(handles.current_diffSpecs)*5,'g-');
xlim([handles.ppmmin handles.ppmmax]);
%set(gca,'FontSize',handles.tiksiz)
%set(gcf,'Color','w');
%box off;
%xlabel('Time (s)','FontSize',handles.labsiz);
%ylabel('Signal Intensity','FontSize',handles.labsiz);

%END OF SECTION ADDED BY JAMIE NEAR

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

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes DiffTool wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = DiffTool_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 during object creation, after setting all properties.
function axes2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to axes2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: place code in OpeningFcn to populate axes2

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

% Hint: place code in OpeningFcn to populate axes3

% --- Executes on slider movement.
function phas0Slider_Callback(hObject, eventdata, handles)
% hObject    handle to phas0Slider (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,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

%obtains the zero order phase value from the phas0Slider component
phas0Value = get(handles.phas0Slider,'Value');
phas1Value = get(handles.phas1Slider,'Value');
freqValue = get(handles.freqSlider,'Value');
ampValue = get(handles.ampSlider,'Value');
DCValue = get(handles.DCSlider,'Value');

%puts the slider value into the edit text component
set(handles.phas0Slider_editText,'String', num2str(phas0Value));

handles.phas0Value=phas0Value;
handles.phas1Value=phas1Value;
handles.freqValue=freqValue;
handles.ampValue=ampValue;
handles.DCValue=DCValue;

%Create current_timeDomainData and current freqDomainData
in2_phas=op_addphase(handles.in2,handles.phas0Value,handles.phas1Value);
in2_phas_freq=op_freqshift(in2_phas,handles.freqValue);
in2_phas_freq_amp=op_ampScale(in2_phas_freq,handles.ampValue/100);
%in2_phas_freq_amp_dc=op_dccorr(in2_phas_freq_amp,'v',handles.DCValue*max(real(handles.in1.specs))/5000);
in2_phas_freq_amp_dc=op_filter2(in2_phas_freq_amp,'g',handles.DCValue);
handles.current_Specs2=in2_phas_freq_amp_dc.specs;
handles.diff=op_subtractScans(handles.in1,in2_phas_freq_amp_dc);
handles.current_diffSpecs=handles.diff.specs;

% %MAKE SUBSPECS PLOTS
axes(handles.axes2);
plot(handles.in1.ppm,real(handles.orig_Specs1),'b-',handles.in2.ppm,real(handles.current_Specs2),'r-',handles.diff.ppm,real(handles.current_diffSpecs)*5,'g-');
xlim([handles.ppmmin handles.ppmmax]);
%set(gca,'FontSize',handles.tiksiz)
%set(gcf,'Color','w');
%box off;
%xlabel('Time (s)','FontSize',handles.labsiz);
%ylabel('Signal Intensity','FontSize',handles.labsiz);

% Update handles structure
guidata(hObject, handles);

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

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

% --- Executes on key press with focus on phas0Slider and none of its controls.
function phas0Slider_KeyPressFcn(hObject, eventdata, handles)
% hObject    handle to phas0Slider (see GCBO)
% eventdata  structure with the following fields (see UICONTROL)
%	Key: name of the key that was pressed, in lower case
%	Character: character interpretation of the key(s) that was pressed
%	Modifier: name(s) of the modifier key(s) (i.e., control, shift) pressed
% handles    structure with handles and user data (see GUIDATA)

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

function phas0Slider_editText_Callback(hObject, eventdata, handles)
% hObject    handle to phas0Slider_editText (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 phas0Slider_editText as text
%        str2double(get(hObject,'String')) returns contents of phas0Slider_editText as a double

%get the string for the editText component
phas0Value = get(handles.phas0Slider_editText,'String');
phas1Value = get(handles.phas1Slider,'String');
freqValue = get(handles.freqSlider,'Value');
ampValue = get(handles.ampSlider,'Value');
DCValue = get(handles.DCSlider,'Value');

%convert from string to number if possible, otherwise returns empty
phas0Value = str2num(phas0Value);

%if user inputs something is not a number, or if the input is less than 0
%then the slider value defaults to 0
if (isempty(phas0Value) || phas0Value < -180 || phas0Value > 180)
    set(handles.phas0Slider,'Value',0);
    set(handles.phas0Slider_editText,'String','0');
else
    set(handles.phas0Slider,'Value',phas0Value);
end
handles.phas0Value=phas0Value;
handles.phas1Value=phas1Value;
handles.freqValue=freqValue;
handles.ampValue=ampValue;
handles.DCValue=DCValue;

%Create current_timeDomainData and current freqDomainData
in2_phas=op_addphase(handles.in2,handles.phas0Value,handles.phas1Value);
in2_phas_freq=op_freqshift(in2_phas,handles.freqValue);
in2_phas_freq_amp=op_ampScale(in2_phas_freq,handles.ampValue/100);
%in2_phas_freq_amp_dc=op_dccorr(in2_phas_freq_amp,'v',handles.DCValue*max(real(handles.in1.specs))/5000);
in2_phas_freq_amp_dc=op_filter2(in2_phas_freq_amp,'g',handles.DCValue);
handles.current_Specs2=in2_phas_freq_amp_dc.specs;
handles.diff=op_subtractScans(handles.in1,in2_phas_freq_amp_dc);
handles.current_diffSpecs=handles.diff.specs;

% %MAKE SUBSPECS PLOTS
axes(handles.axes2);
plot(handles.in1.ppm,real(handles.orig_Specs1),'b-',handles.in2.ppm,real(handles.current_Specs2),'r-',handles.diff.ppm,real(handles.current_diffSpecs)*5,'g-');
xlim([handles.ppmmin handles.ppmmax]);
%set(gca,'FontSize',handles.tiksiz)
%set(gcf,'Color','w');
%box off;
%xlabel('Time (s)','FontSize',handles.labsiz);
%ylabel('Signal Intensity','FontSize',handles.labsiz);

% Update handles structure
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function phas0Slider_editText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to phas0Slider_editText (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 slider movement.
function freqSlider_Callback(hObject, eventdata, handles)
% hObject    handle to freqSlider (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,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

%obtains the slider value from the slider component
phas0Value = get(handles.phas0Slider,'Value');
phas1Value = get(handles.phas1Slider,'Value');
freqValue = get(handles.freqSlider,'Value');
ampValue = get(handles.ampSlider,'Value');
DCValue = get(handles.DCSlider,'Value');

%puts the slider value into the edit text component
set(handles.freqSlider_editText,'String', num2str(freqValue));

% Update handles structure
guidata(hObject, handles);

handles.phas0Value=phas0Value;
handles.phas1Value=phas1Value;
handles.freqValue=freqValue;
handles.ampValue=ampValue;
handles.DCValue=DCValue;

%Create current_timeDomainData and current freqDomainData
in2_phas=op_addphase(handles.in2,handles.phas0Value,handles.phas1Value);
in2_phas_freq=op_freqshift(in2_phas,handles.freqValue);
in2_phas_freq_amp=op_ampScale(in2_phas_freq,handles.ampValue/100);
%in2_phas_freq_amp_dc=op_dccorr(in2_phas_freq_amp,'v',handles.DCValue*max(real(handles.in1.specs))/5000);
in2_phas_freq_amp_dc=op_filter2(in2_phas_freq_amp,'g',handles.DCValue);
handles.current_Specs2=in2_phas_freq_amp_dc.specs;
handles.diff=op_subtractScans(handles.in1,in2_phas_freq_amp_dc);
handles.current_diffSpecs=handles.diff.specs;

% %MAKE SUBSPECS PLOTS
axes(handles.axes2);
plot(handles.in1.ppm,real(handles.orig_Specs1),'b-',handles.in2.ppm,real(handles.current_Specs2),'r-',handles.diff.ppm,real(handles.current_diffSpecs)*5,'g-');
xlim([handles.ppmmin handles.ppmmax]);
%set(gca,'FontSize',handles.tiksiz)
%set(gcf,'Color','w');
%box off;
%xlabel('Time (s)','FontSize',handles.labsiz);
%ylabel('Signal Intensity','FontSize',handles.labsiz);

% Update handles structure
guidata(hObject, handles);

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

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

function freqSlider_editText_Callback(hObject, eventdata, handles)
% hObject    handle to freqSlider_editText (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 freqSlider_editText as text
%        str2double(get(hObject,'String')) returns contents of freqSlider_editText as a double

%get the string for the editText component
phas0Value = get(handles.phas0Slider,'Value');
phas1Value = get(handles.phas1Slider,'Value');
freqValue = get(handles.freqSlider_editText,'String');
ampValue = get(handles.ampSlider,'Value');
DCValue = get(handles.DCSlider,'Value');

%convert from string to number if possible, otherwise returns empty
freqValue = str2num(freqValue);

%if user inputs something is not a number, or if the input is less than
%-100 or greater than 100, then the slider value defaults to 0
if (isempty(freqValue) || freqValue < -100 || freqValue > 100   )
    freqValue=0;
    set(handles.freqSlider,'Value',0);
    set(handles.freqSlider_editText,'String','0');
else
    set(handles.freqSlider,'Value',freqValue);
end

handles.phas0Value=phas0Value;
handles.phas1Value=phas1Value;
handles.freqValue=freqValue;
handles.ampValue=ampValue;
handles.DCValue=DCValue;

%Create current_timeDomainData and current freqDomainData
in2_phas=op_addphase(handles.in2,handles.phas0Value,handles.phas1Value);
in2_phas_freq=op_freqshift(in2_phas,handles.freqValue);
in2_phas_freq_amp=op_ampScale(in2_phas_freq,handles.ampValue/100);
%in2_phas_freq_amp_dc=op_dccorr(in2_phas_freq_amp,'v',handles.DCValue*max(real(handles.in1.specs))/5000);
in2_phas_freq_amp_dc=op_filter2(in2_phas_freq_amp,'g',handles.DCValue);
handles.current_Specs2=in2_phas_freq_amp_dc.specs;
handles.diff=op_subtractScans(handles.in1,in2_phas_freq_amp_dc);
handles.current_diffSpecs=handles.diff.specs;

% %MAKE SUBSPECS PLOTS
axes(handles.axes2);
plot(handles.in1.ppm,real(handles.orig_Specs1),'b-',handles.in2.ppm,real(handles.current_Specs2),'r-',handles.diff.ppm,real(handles.current_diffSpecs)*5,'g-');
xlim([handles.ppmmin handles.ppmmax]);
%set(gca,'FontSize',handles.tiksiz)
%set(gcf,'Color','w');
%box off;
%xlabel('Time (s)','FontSize',handles.labsiz);
%ylabel('Signal Intensity','FontSize',handles.labsiz);

% Update handles structure
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function freqSlider_editText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to freqSlider_editText (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 key press with focus on phas0Slider_editText and none of its controls.
function phas0Slider_editText_KeyPressFcn(hObject, eventdata, handles)
% hObject    handle to phas0Slider_editText (see GCBO)
% eventdata  structure with the following fields (see UICONTROL)
%	Key: name of the key that was pressed, in lower case
%	Character: character interpretation of the key(s) that was pressed
%	Modifier: name(s) of the modifier key(s) (i.e., control, shift) pressed
% handles    structure with handles and user data (see GUIDATA)

% --- Executes on slider movement.
function phas1Slider_Callback(hObject, eventdata, handles)
% hObject    handle to phas1Slider (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,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

%obtains the zero order phase value from the phas0Slider component
phas0Value = get(handles.phas0Slider,'Value');
phas1Value = get(handles.phas1Slider,'Value');
freqValue = get(handles.freqSlider,'Value');
ampValue = get(handles.ampSlider,'Value');
DCValue = get(handles.DCSlider,'Value');

%puts the slider value into the edit text component
set(handles.phas1Slider_editText,'String', num2str(phas1Value));

handles.phas0Value=phas0Value;
handles.phas1Value=phas1Value;
handles.freqValue=freqValue;
handles.ampValue=ampValue;
handles.DCValue=DCValue;

%Create current_timeDomainData and current freqDomainData
in2_phas=op_addphase(handles.in2,handles.phas0Value,handles.phas1Value);
in2_phas_freq=op_freqshift(in2_phas,handles.freqValue);
in2_phas_freq_amp=op_ampScale(in2_phas_freq,handles.ampValue/100);
%in2_phas_freq_amp_dc=op_dccorr(in2_phas_freq_amp,'v',handles.DCValue*max(real(handles.in1.specs))/5000);
in2_phas_freq_amp_dc=op_filter2(in2_phas_freq_amp,'g',handles.DCValue);
handles.current_Specs2=in2_phas_freq_amp_dc.specs;
handles.diff=op_subtractScans(handles.in1,in2_phas_freq_amp_dc);
handles.current_diffSpecs=handles.diff.specs;

% %MAKE SUBSPECS PLOTS
axes(handles.axes2);
plot(handles.in1.ppm,real(handles.orig_Specs1),'b-',handles.in2.ppm,real(handles.current_Specs2),'r-',handles.diff.ppm,real(handles.current_diffSpecs)*5,'g-');
xlim([handles.ppmmin handles.ppmmax]);
%set(gca,'FontSize',handles.tiksiz)
%set(gcf,'Color','w');
%box off;
%xlabel('Time (s)','FontSize',handles.labsiz);
%ylabel('Signal Intensity','FontSize',handles.labsiz);

% Update handles structure
guidata(hObject, handles);

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

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

function phas1Slider_editText_Callback(hObject, eventdata, handles)
% hObject    handle to phas1Slider_editText (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 phas1Slider_editText as text
%        str2double(get(hObject,'String')) returns contents of phas1Slider_editText as a double

%get the string for the editText component
phas0Value = get(handles.phas0Slider,'String');
phas1Value = get(handles.phas1Slider_editText,'String');
freqValue = get(handles.freqSlider,'Value');
ampValue = get(handles.ampSlider,'Value');
DCValue = get(handles.DCSlider,'Value');

%convert from string to number if possible, otherwise returns empty
phas1Value = str2num(phas1Value);

%if user inputs something is not a number, or if the input is less than 0
%then the slider value defaults to 0
if (isempty(phas1Value) || phas1Value < -1 || phas1Value > 1)
    set(handles.phas1Slider,'Value',0);
    set(handles.phas1Slider_editText,'String','0');
else
    set(handles.phas1Slider,'Value',phas1Value);
end
handles.phas0Value=phas0Value;
handles.phas1Value=phas1Value;
handles.freqValue=freqValue;
handles.ampValue=ampValue;
handles.DCValue=DCValue;

%Create current_timeDomainData and current freqDomainData
in2_phas=op_addphase(handles.in2,handles.phas0Value,handles.phas1Value);
in2_phas_freq=op_freqshift(in2_phas,handles.freqValue);
in2_phas_freq_amp=op_ampScale(in2_phas_freq,handles.ampValue/100);
%in2_phas_freq_amp_dc=op_dccorr(in2_phas_freq_amp,'v',handles.DCValue*max(real(handles.in1.specs))/5000);
in2_phas_freq_amp_dc=op_filter2(in2_phas_freq_amp,'g',handles.DCValue);
handles.current_Specs2=in2_phas_freq_amp_dc.specs;
handles.diff=op_subtractScans(handles.in1,in2_phas_freq_amp_dc);
handles.current_diffSpecs=handles.diff.specs;

% %MAKE SUBSPECS PLOTS
axes(handles.axes2);
plot(handles.in1.ppm,real(handles.orig_Specs1),'b-',handles.in2.ppm,real(handles.current_Specs2),'r-',handles.diff.ppm,real(handles.current_diffSpecs)*5,'g-');
xlim([handles.ppmmin handles.ppmmax]);
%set(gca,'FontSize',handles.tiksiz)
%set(gcf,'Color','w');
%box off;
%xlabel('Time (s)','FontSize',handles.labsiz);
%ylabel('Signal Intensity','FontSize',handles.labsiz);

% Update handles structure
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function phas1Slider_editText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to phas1Slider_editText (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 slider movement.
function ampSlider_Callback(hObject, eventdata, handles)
% hObject    handle to ampSlider (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,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

%obtains the zero order phase value from the phas0Slider component
phas0Value = get(handles.phas0Slider,'Value');
phas1Value = get(handles.phas1Slider,'Value');
freqValue = get(handles.freqSlider,'Value');
ampValue = get(handles.ampSlider,'Value');
DCValue = get(handles.DCSlider,'Value');

%puts the slider value into the edit text component
set(handles.ampSlider_editText,'String', num2str(ampValue));

handles.phas0Value=phas0Value;
handles.phas1Value=phas1Value;
handles.freqValue=freqValue;
handles.ampValue=ampValue;
handles.DCValue=DCValue;

%Create current_timeDomainData and current freqDomainData
in2_phas=op_addphase(handles.in2,handles.phas0Value,handles.phas1Value);
in2_phas_freq=op_freqshift(in2_phas,handles.freqValue);
in2_phas_freq_amp=op_ampScale(in2_phas_freq,handles.ampValue/100);
%in2_phas_freq_amp_dc=op_dccorr(in2_phas_freq_amp,'v',handles.DCValue*max(real(handles.in1.specs))/5000);
in2_phas_freq_amp_dc=op_filter2(in2_phas_freq_amp,'g',handles.DCValue);
handles.current_Specs2=in2_phas_freq_amp_dc.specs;
handles.diff=op_subtractScans(handles.in1,in2_phas_freq_amp_dc);
handles.current_diffSpecs=handles.diff.specs;

% %MAKE SUBSPECS PLOTS
axes(handles.axes2);
plot(handles.in1.ppm,real(handles.orig_Specs1),'b-',handles.in2.ppm,real(handles.current_Specs2),'r-',handles.diff.ppm,real(handles.current_diffSpecs)*5,'g-');
xlim([handles.ppmmin handles.ppmmax]);
%set(gca,'FontSize',handles.tiksiz)
%set(gcf,'Color','w');
%box off;
%xlabel('Time (s)','FontSize',handles.labsiz);
%ylabel('Signal Intensity','FontSize',handles.labsiz);

% Update handles structure
guidata(hObject, handles);

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

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

function ampSlider_editText_Callback(hObject, eventdata, handles)
% hObject    handle to ampSlider_editText (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 ampSlider_editText as text
%        str2double(get(hObject,'String')) returns contents of ampSlider_editText as a double

%get the string for the editText component
phas0Value = get(handles.phas0Slider,'String');
phas1Value = get(handles.phas1Slider,'String');
freqValue = get(handles.freqSlider,'Value');
ampValue = get(handles.ampSlider_editText,'Value');
DCValue = get(handles.DCSlider,'Value');

%convert from string to number if possible, otherwise returns empty
ampValue = str2num(ampValue);

%if user inputs something is not a number, or if the input is less than 0
%then the slider value defaults to 0
if (isempty(ampValue) || ampValue < 0 || ampValue > 200)
    set(handles.ampSlider,'Value',100);
    set(handles.ampSlider_editText,'String','100');
else
    set(handles.ampSlider,'Value',ampValue);
end
handles.phas0Value=phas0Value;
handles.phas1Value=phas1Value;
handles.freqValue=freqValue;
handles.ampValue=ampValue;
handles.DCValue=DCValue;

%Create current_timeDomainData and current freqDomainData
in2_phas=op_addphase(handles.in2,handles.phas0Value,handles.phas1Value);
in2_phas_freq=op_freqshift(in2_phas,handles.freqValue);
in2_phas_freq_amp=op_ampScale(in2_phas_freq,handles.ampValue/100);
%in2_phas_freq_amp_dc=op_dccorr(in2_phas_freq_amp,'v',handles.DCValue*max(real(handles.in1.specs))/5000);
in2_phas_freq_amp_dc=op_filter2(in2_phas_freq_amp,'g',handles.DCValue);
handles.current_Specs2=in2_phas_freq_amp_dc.specs;
handles.diff=op_subtractScans(handles.in1,in2_phas_freq_amp_dc);
handles.current_diffSpecs=handles.diff.specs;

% %MAKE SUBSPECS PLOTS
axes(handles.axes2);
plot(handles.in1.ppm,real(handles.orig_Specs1),'b-',handles.in2.ppm,real(handles.current_Specs2),'r-',handles.diff.ppm,real(handles.current_diffSpecs)*5,'g-');
xlim([handles.ppmmin handles.ppmmax]);
%set(gca,'FontSize',handles.tiksiz)
%set(gcf,'Color','w');
%box off;
%xlabel('Time (s)','FontSize',handles.labsiz);
%ylabel('Signal Intensity','FontSize',handles.labsiz);

% Update handles structure
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function ampSlider_editText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to ampSlider_editText (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 slider movement.
function DCSlider_Callback(hObject, eventdata, handles)
% hObject    handle to DCSlider (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,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

%obtains the zero order phase value from the phas0Slider component
phas0Value = get(handles.phas0Slider,'Value');
phas1Value = get(handles.phas1Slider,'Value');
freqValue = get(handles.freqSlider,'Value');
ampValue = get(handles.ampSlider,'Value');
DCValue = get(handles.DCSlider,'Value');

%puts the slider value into the edit text component
set(handles.DCSlider_editText,'String', num2str(DCValue));

handles.phas0Value=phas0Value;
handles.phas1Value=phas1Value;
handles.freqValue=freqValue;
handles.ampValue=ampValue;
handles.DCValue=DCValue;

%Create current_timeDomainData and current freqDomainData
in2_phas=op_addphase(handles.in2,handles.phas0Value,handles.phas1Value);
in2_phas_freq=op_freqshift(in2_phas,handles.freqValue);
in2_phas_freq_amp=op_ampScale(in2_phas_freq,handles.ampValue/100);
%in2_phas_freq_amp_dc=op_dccorr(in2_phas_freq_amp,'v',handles.DCValue*max(real(handles.in1.specs))/5000);
in2_phas_freq_amp_dc=op_filter2(in2_phas_freq_amp,'g',handles.DCValue);
handles.current_Specs2=in2_phas_freq_amp_dc.specs;
handles.diff=op_subtractScans(handles.in1,in2_phas_freq_amp_dc);
handles.current_diffSpecs=handles.diff.specs;

% %MAKE SUBSPECS PLOTS
axes(handles.axes2);
plot(handles.in1.ppm,real(handles.orig_Specs1),'b-',handles.in2.ppm,real(handles.current_Specs2),'r-',handles.diff.ppm,real(handles.current_diffSpecs)*5,'g-');
xlim([handles.ppmmin handles.ppmmax]);
%set(gca,'FontSize',handles.tiksiz)
%set(gcf,'Color','w');
%box off;
%xlabel('Time (s)','FontSize',handles.labsiz);
%ylabel('Signal Intensity','FontSize',handles.labsiz);

% Update handles structure
guidata(hObject, handles);

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

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

function DCSlider_editText_Callback(hObject, eventdata, handles)
% hObject    handle to DCSlider_editText (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 DCSlider_editText as text
%        str2double(get(hObject,'String')) returns contents of DCSlider_editText as a double

%get the string for the editText component
phas0Value = get(handles.phas0Slider,'String');
phas1Value = get(handles.phas1Slider,'String');
freqValue = get(handles.freqSlider,'Value');
ampValue = get(handles.ampSlider,'Value');
DCValue = get(handles.DCSlider_editText,'Value');

%convert from string to number if possible, otherwise returns empty
DCValue = str2num(DCValue);

%if user inputs something is not a number, or if the input is less than 0
%then the slider value defaults to 0
if (isempty(DCValue) || DCValue < -500 || DCValue > 500)
    set(handles.DCSlider,'Value',0);
    set(handles.DCSlider_editText,'String','0');
else
    set(handles.DCSlider,'Value',DCValue);
end
handles.phas0Value=phas0Value;
handles.phas1Value=phas1Value;
handles.freqValue=freqValue;
handles.ampValue=ampValue;
handles.DCValue=DCValue;

%Create current_timeDomainData and current freqDomainData
in2_phas=op_addphase(handles.in2,handles.phas0Value,handles.phas1Value);
in2_phas_freq=op_freqshift(in2_phas,handles.freqValue);
in2_phas_freq_amp=op_ampScale(in2_phas_freq,handles.ampValue/100);
%in2_phas_freq_amp_dc=op_dccorr(in2_phas_freq_amp,'v',handles.DCValue*max(real(handles.in1.specs))/5000);
in2_phas_freq_amp_dc=op_filter2(in2_phas_freq_amp,'g',handles.DCValue);
handles.current_Specs2=in2_phas_freq_amp_dc.specs;
handles.diff=op_subtractScans(handles.in1,in2_phas_freq_amp_dc);
handles.current_diffSpecs=handles.diff.specs;

% %MAKE SUBSPECS PLOTS
axes(handles.axes2);
plot(handles.in1.ppm,real(handles.orig_Specs1),'b-',handles.in2.ppm,real(handles.current_Specs2),'r-',handles.diff.ppm,real(handles.current_diffSpecs)*5,'g-');
xlim([handles.ppmmin handles.ppmmax]);
%set(gca,'FontSize',handles.tiksiz)
%set(gcf,'Color','w');
%box off;
%xlabel('Time (s)','FontSize',handles.labsiz);
%ylabel('Signal Intensity','FontSize',handles.labsiz);

% Update handles structure
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function DCSlider_editText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to DCSlider_editText (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 blas1_z_test ( )

%*****************************************************************************80
%
%% BLAS1_Z_TEST tests the BLAS1_Z library.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 May 2006
%
%  Author:
%
%    John Burkardt
%
  addpath ( '../blas0' );

  timestamp ( );
  fprintf ( 1, '\n' );
  fprintf ( 1, 'BLAS1_Z_PRB:\n' );
  fprintf ( 1, '  MATLAB version\n' );
  fprintf ( 1, '  Test the BLAS1_Z library.\n' );

  blas1_z_test01 ( );
  blas1_z_test02 ( );
  blas1_z_test03 ( );
  blas1_z_test04 ( );
  blas1_z_test05 ( );
  blas1_z_test06 ( );
  blas1_z_test07 ( );
  blas1_z_test08 ( );
  blas1_z_test09 ( );

  blas1_z_test10 ( );
  blas1_z_test11 ( );
  blas1_z_test12 ( );
  blas1_z_test13 ( );
  blas1_z_test14 ( );
  blas1_z_test15 ( );
  blas1_z_test16 ( );
  blas1_z_test17 ( );
%
%  Terminate.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'BLAS1_Z_PRB:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );
  fprintf ( 1, '\n' );
  timestamp ( );

  rmpath ( '../blas0' );

  return
end


function nVars = numVars(N)
%NUMVARS   Detect how many unknown variables a CHEBOP operates on.
%   NVARS = NUMVARS(N), where N is a CHEBOP, returns the integer NVARS which is
%   equal to the number of variables that N operates on.

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

% NUMVARS indicate how many unknown function we seek. This can be tricky of the
% operator is specified on CHEBMATRIX syntax, e.g. via
%   N.op = @(x, u) [diff(u{1}) + u{2}; u{1} + diff(u{2})];
% is in this case, nargin(N.op) does not match the number of variables we need.
% If nargin(N.op) is greater than two, we can however safely assume that N.op is
% specified on the form
%   N.op = @(x, u, v) [diff(u) + v; u + diff(v)];

% We begin by looking at whether we have the easy case!
narginN = nargin(N);
if ( narginN > 2 )
    % Need to subtract 1 since x is the first argument:
    nVars = narginN - 1;

elseif ( ~isempty(N.numVars) )
    % Now we know we're dealing with
    %   N.op = @(x, u) ...
    % But we don't know yet whether this is a system or not. In an ideal world,
    % the user has passed this information through the numVars property of the
    % CHEBOP.

    nVars = N.numVars; % Lucky us!

else
    % If that field is empty, we try to inspect the string representation of
    % N.op, and look for the highest index appearing inside {} -- this will only
    % work if N.op is specified as an anonymous function, not if it is a handle
    % to another function.

    % Obtain the function string:
    NopString = func2str(N.op);

    % Try to find out what the unknown function is. But first, we must check
    % whether we actually have the argument list available to us...
    firstRightPar = min(strfind(NopString, ')'));
    if ( isempty(firstRightPar) )
        % Don't have a list of arguments available. Take numVars == 1, and hope
        % for the best...
        warning('CHEBFUN:CHEBOP:numVars:numberOfArguments', ...
            ['Unable to determine the number of variable that the ', ...
            'chebop\noperates on. Assuming problem is a scalar problem,',...
            ' results might be\nunreliable. Please specify the number', ...
            ' of variables that the operator\n', ...
            'operates on via CHEBOP.numVars.'])
        nVars = 1;

    else
        % If nargin(N) == 2, the first variable appearing will be the
        % independent space variable, but if nargin(N) == 1, we only have the
        % unknown function in the argument list.
        if ( narginN == 1 )
            % The unknown variable appears between @( and the first ).
            firstLeftPar = min(strfind(NopString, '('));
            variableName = NopString(firstLeftPar+1 : firstRightPar - 1);

        else
            % The unknown variable appears between the first , and the first ),
            % e.g. @(x, ___ ).
            firstLeftComma = min(strfind(NopString, ','));
            variableName = NopString(firstLeftComma+1 : firstRightPar - 1);
        end

        % The regular expression we seek must include the variable name:
        expression = [variableName, '{[1-9]+}'];

        % Obtain all matches:
        match = regexp(NopString, expression, 'match');

        % If we don't have any matches, problem can't have been specified using
        % CHEBMATRIX syntax. But nargin(N) == 2, and we did indeed have the
        % argument list to the anonymous function passed, so we must be dealing
        % with a scalar problem!
        if ( isempty(match) )
            nVars = 1;
        else
            % Throw away the variable name and the { }, e.g. convert 'u{1}' to
            % '1':
            match = strrep(match, [variableName, '{'], '');
            match = strrep(match, '}', '');

            % We are now left with cell-array of strings that only contain
            % numbers. So convert to doubles!
            indx = str2double(match);

            % The number of variables that the CHEBOP operates on is the
            % greatest index that appears:
            nVars = max(indx);
        end

    end

end


classdef TestBlur
    %TestBlur

    properties (Constant)
        img = 255*uint8([...
            0 0 0 0 0 0 0 0 0 0;...
            0 0 0 0 0 0 0 0 0 0;...
            0 0 0 0 0 0 0 0 0 0;...
            0 0 0 1 1 1 0 0 0 0;...
            0 0 0 1 1 1 0 0 0 0;...
            0 0 0 1 1 1 0 0 0 0;...
            0 0 0 0 0 0 0 0 0 0;...
            0 0 0 0 0 0 0 0 0 0;...
            0 0 0 0 0 0 0 0 0 0;...
            0 0 0 0 0 0 0 0 0 0;...
        ]);
    end

    methods (Static)
        function test_1
            result = cv.blur(TestBlur.img);
            validateattributes(result, {class(TestBlur.img)}, ...
                {'size',size(TestBlur.img)});
        end

        function test_2
            result = cv.blur(TestBlur.img, 'KSize', [3,7]);
            validateattributes(result, {class(TestBlur.img)}, ...
                {'size',size(TestBlur.img)});
        end

        function test_3
            result = cv.blur(TestBlur.img, 'Anchor', [0,1]);
            validateattributes(result, {class(TestBlur.img)}, ...
                {'size',size(TestBlur.img)});
        end

        function test_4
            result = cv.blur(TestBlur.img, 'BorderType', 'Constant');
            validateattributes(result, {class(TestBlur.img)}, ...
                {'size',size(TestBlur.img)});
        end

        function test_5
            img = imread(fullfile(mexopencv.root(),'test','fruits.jpg'));
            result = cv.blur(img);
            validateattributes(result, {class(img)}, {'size',size(img)});
        end

        function test_error_argnum
            try
                cv.blur();
                throw('UnitTest:Fail');
            catch e
                assert(strcmp(e.identifier,'mexopencv:error'));
            end
        end
    end

end


function scn_export_papersetup(minsize)
% :Usage:
% ::
%
%    scn_export_papersetup([opt: min size in pixels, default = 400])
%
% set paper size for current figure so that print to png or tiff looks as
% it should (as it does on-screen)
%
% ..
%    tor wager, aug. 06
% ..

if nargin < 1, minsize = 400; end

% make sure that min size of fig. is 400 pixels
sz = get(gcf,'Position');
sz = sz(3:4);   % width and height
szratio = max(sz) ./ min(sz);   % max to min size
wh = find(sz == min(sz));
sz(wh) = minsize;
wh = find(sz == max(sz));
sz(wh) = minsize * szratio;

% set paper size using current screen
set(gcf,'PaperUnits','points','PaperPosition',[0 0 sz],'PaperType','usletter');
return


function f = conj(f)
%CONJ   Complex conjugate of a SPHEREFUN.
%   CONJ(F) returns the complex conjugate of F.  For a complex F, CONJ(F) =
%   REAL(F) - i*IMAG(F).
%
%   Since only real-valued SPHEREFUNS are presently supported, this
%   function is trivial.
%
% See also SPHEREFUN/REAL, SPHEREFUN/IMAG.

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

end


function varargout = process_evt_detect_ecg( varargin )
% PROCESS_EVT_DETECT_ECG: Detect heartbeats in a continuous file, and create set of events called "cardiac"

% @=============================================================================
% 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.
% =============================================================================@
%
% Authors: Francois Tadel, Elizabeth Bock, 2011-2016

eval(macro_method);
end

%% ===== GET DESCRIPTION =====
function sProcess = GetDescription() %#ok<DEFNU>
    % Description the process
    sProcess.Comment     = 'Detect heartbeats';
    sProcess.Category    = 'Custom';
    sProcess.SubGroup    = 'Events';
    sProcess.Index       = 43;
    sProcess.Description = 'https://neuroimage.usc.edu/brainstorm/Tutorials/ArtifactsDetect#Detection:_Heartbeats';
    % Definition of the input accepted by this process
    sProcess.InputTypes  = {'raw', 'data'};
    sProcess.OutputTypes = {'raw', 'data'};
    sProcess.nInputs     = 1;
    sProcess.nMinFiles   = 1;
    % Channel name
    sProcess.options.channelname.Comment = 'Channel name: ';
    sProcess.options.channelname.Type    = 'channelname';
    sProcess.options.channelname.Value   = '';
    % Channel name comment
    sProcess.options.channelhelp.Comment = 'You can use the montage syntax here: "ch1, -ch2"';
    sProcess.options.channelhelp.Type    = 'label';
    % Channel name comment
    sProcess.options.channelhelp.Comment = 'You can use the montage syntax here: "ch1, -ch2"';
    sProcess.options.channelhelp.Type    = 'label';
    % Time window
    sProcess.options.timewindow.Comment = 'Time window:';
    sProcess.options.timewindow.Type    = 'timewindow';
    sProcess.options.timewindow.Value   = [];
    % Event name
    sProcess.options.eventname.Comment = 'Event name: ';
    sProcess.options.eventname.Type    = 'text';
    sProcess.options.eventname.Value   = 'cardiac';
end

%% ===== FORMAT COMMENT =====
function Comment = FormatComment(sProcess) %#ok<DEFNU>
    Comment = sProcess.Comment;
end

%% ===== RUN =====
function OutputFiles = Run(sProcess, sInputs) %#ok<DEFNU>
    % Pre-defined set of properties
    %sProcess.options.eventname.Value = 'cardiac';
    sProcess.options.threshold.Value = {4, 'x std', 2};
    sProcess.options.bandpass.Value  = {[10 40], 'Hz', 2};
    sProcess.options.blanking.Value  = {0.5, 'ms', []};
    sProcess.options.isnoisecheck.Value = 1;
    sProcess.options.isclassify.Value   = 1;
    % Call the generic version of the event detection
    OutputFiles = process_evt_detect('Run', sProcess, sInputs);
end


function J = cell2Image(I)

    numChannels = numel(I);
    for channelIdx = 1:numChannels
        J(:,:,channelIdx) = I{channelIdx};
    end


function posinpu()
    %[lat1 lon1 lat2,  lon2] =posinpu
    % Position input of two coordinates to build a crossection
    %
    % Alexander Allmann
    % updated: 20.10.2004
    % j.woessner@sed.ethz.ch

    ZG=ZmapGlobal.Data; % used by get_zmap_globals

    report_this_filefun();

    %...

    hInpuCoord = figure_w_normalized_uicontrolunits( ...
        'Name','Cross-section Input Coordinates',...
        'tag','InpuCoordX','Position',[260 504 300 300],...
        'NumberTitle','off', ...
        'backingstore','on',...
        'Visible','on');
    set(gca,'Box','off','visible','off')

    txt1 = text(...
        'Position',[0. 0.65 0 ],...
        'FontSize',12,...
        'String','Point 1: ');
    txt2 = text(...
        'Position',[0. 0.45 0 ],...
        'FontSize',12,...
        'String','Point 2: ');

    txt3 = text(...
        'Position',[0.35 0.8 0 ],...
        'FontSize',12,...
        'String','Longitude:');
    txt4 = text(...
        'Position',[0.75 0.8 0 ],...
        'FontSize',12,...
        'String','Latitude:');

    inp1_field=uicontrol('Style','edit',...
        'Position',[.70 .60 .25 .10],...
        'Units','normalized','String',num2str(lat1,5),...
        'callback',@callbackfun_001);

    inp2_field=uicontrol('Style','edit',...
        'Position',[.70 .40 .25 .10],...
        'Units','normalized','String',num2str(lat2,5),...
        'callback',@callbackfun_002);

    inp3_field=uicontrol('Style','edit',...
        'Position',[.40 .60 .25 .10],...
        'Units','normalized','String',num2str(lon1,6),...
        'callback',@callbackfun_003);

    inp4_field=uicontrol('Style','edit',...
        'Position',[.40 .40 .25 .10],...
        'Units','normalized','String',num2str(lon2,6),...
        'callback',@callbackfun_004);
    go_button=uicontrol('Style','Pushbutton',...
        'Position',[.40 .05 .15 .15],...
        'Units','normalized',...
        'callback',@callbackfun_005,...
        'String','Go');

    cancel_button=uicontrol('Style','Pushbutton',...
        'Position',[.20 .05 .15 .15],...
        'Units','normalized',...
        'callback',@callbackfun_006,...
        'String','Cancel');

    function callbackfun_001(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lat1=str2double(inp1_field.String);
        inp1_field.String=num2str(lat1);
    end

    function callbackfun_002(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lat2=str2double(inp2_field.String);
        inp2_field.String=num2str(lat2);
    end

    function callbackfun_003(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lon1=str2double(inp3_field.String);
        inp3_field.String=num2str(lon1);
    end

    function callbackfun_004(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        lon2=str2double(inp4_field.String);
        inp4_field.String=num2str(lon2);
    end

    function callbackfun_005(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        [xsecx xsecy,  inde] =mysect(tmp1,tmp2,ZG.primeCatalog.Depth,ZG.xsec_defaults.WidthKm,0,lat1,lon1,lat2,lon2);
        nlammap2;
        close(hInpuCoord);
    end

    function callbackfun_006(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        figure(mapl);
    end

end


function varargout = anaglyph(varargin)
% ANAGLYPH - displays an anaglyph obtained by two stereoscopical images
%
% anaglyph with no arguments, opens a dialog to pick an image which contains
% two stereoscopical images in a single image file.
%
% anaglyph('filename') displays an anaglyph of the image "filename"
% (with extension), which contains two stereoscopical images in a single
% image file (bmp, jpg, or other supported image type).
%
% anaglyph('filename1', 'filename2') displays an anaglyph from the two images
% "filename1", "filename2" (with extension) one for the right eye and one for
% the left one.
%
% anaglyph(A) displays an anaglyph of the image A, in memory,
% which contains two stereoscopical images in a single image
% file (bmp, jpg, or other supported image type).
%
% anaglyph(A,B) displays an anaglyph from the two images A and B, in memory,
% (with extension) one for the right eye and one for the left one.
%
% Inputs: one or two names of image files or of matlab variables
%
% Outputs (optional):
%    the figure handle to the anaglyph
%
% Notes:
% One can swap the two images during the visualization.
%
% Version 2.0 NEWS
% - now plots also images in memory
% - with no args, opens a dialog to choose the image
% - zoom function
%
% Example:
%    anaglyph('foto3d.bmp')
%
% Other m-files required: none
% Subfunctions: plotAnaglyph, swap
% MAT-files required: none
%
% See also: stereoview
%
% Author: Iari-Gabriel Marino, Ph.D., nonlinear optics
% University of Parma, Dept. of Physics, ITALY
% email address: iarigabriel.marino@fis.unipr.it
% Website: http://www.fis.unipr.it/raman/index2.htm
% Personal: http://www.fis.unipr.it/home/marino/
% November 2006; Last revision: 6-Nov-2006
%
%------------- BEGIN CODE --------------

switch nargin
    case 0
        [imageName, pathname] = uigetfile({'*.*'}, 'Pick a stereo image..');
        m = imread([pathname imageName(1:end-4)],imageName(end-2:end));
        [x,y,z] = size(m);
        if rem(y,2) == 0,
            dx = m(:,1:y/2,:);
            sx = m(:,y/2+1:end,:);
        elseif rem(y,2) == 1,
            dx = m(:,1:fix(y/2),:);
            sx = m(:,fix(y/2)+1:end-1,:);
        end
    case 1
        % cuts the image in two
        imageName = varargin{1};
        if isstr(imageName) % if it is a string, I load it
            m = imread(imageName(1:end-4),imageName(end-2:end));
        else % else it is a variable yet in memory:
            m = imageName;
        end
        [x,y,z] = size(m);
        if rem(y,2) == 0,
            dx = m(:,1:y/2,:);
            sx = m(:,y/2+1:end,:);
        elseif rem(y,2) == 1,
            dx = m(:,1:fix(y/2),:);
            sx = m(:,fix(y/2)+1:end-1,:);
        end
    case 2
        % assign each image
        namedx = varargin{1};
        namesx = varargin{2};
        if and(isstr(namedx),isstr(namesx)) % if they are strings, I load them
            dx = imread(namedx(1:end-4),namedx(end-2:end));
            sx = imread(namesx(1:end-4),namesx(end-2:end));
        else % else they should be variable yet in memory
            dx = namedx;
            sx = namesx;
        end
end

figH = figure;
set(figH,'userdata',0);

swapButt = uicontrol(figH,'style','pushbutton','String','Swap RL','value',0,'pos',[20 10 58 20]);
zoomInButt = uicontrol(figH,'style','pushbutton','String','Zoom +','pos',[80 10 58 20]);
zoomOutButt = uicontrol(figH,'style','pushbutton','String','Zoom -','pos',[140 10 58 20]);

set(swapButt,'callback',{@swap,dx,sx,figH});
set(zoomInButt,'callback',{@zoomCLB,-0.1})
set(zoomOutButt,'callback',{@zoomCLB,+0.1})

plotAnaglyph(dx,sx);

if nargout == 1,
    varargout = {figH};
end

% -------------------------------------------------------
% Plots the anaglyphic image
function plotAnaglyph(A,B);

r = zeros(size(A));
gb = zeros(size(B));

r(:,:,1) = double(A(:,:,1));
gb(:,:,2:3) = double(B(:,:,2:3));

% subplot(1,2,1)
% image(uint8(r)); axis equal
%
% subplot(1,2,2)
% image(uint8(gb)); axis equal

image(uint8(r+gb));
axis equal
set(gca,'YTickLabel',[])
set(gca,'XTickLabel',[])
set(gca,'XTick',[])
set(gca,'YTick',[])
set(gca,'color',[0 0 0])
set(gcf,'color',[0 0 0])
shg

% -------------------------------------------------------
% Swaps right/left
function swap(UiHandle,action,A,B,figH)
flag = get(figH,'userdata');
switch flag
case 1
    plotAnaglyph(A,B);
    set(figH,'userdata',0);
case 0
    plotAnaglyph(B,A);
    set(figH,'userdata',1);
end
% -------------------------------------------------------
% Zoom
function zoomCLB(UiHandle,action,D)
origCVA = get(gca,'CameraViewAngle');
set(gca,'CameraViewAngle',origCVA+D)
%------------- END OF CODE --------------


%SerialLink.plot3d Graphical display and animation of solid model robot
%
% R.plot3d(Q, options) displays and animates a solid model of the robot.
% The robot is displayed at the joint angle Q (1xN), or
% if a matrix (MxN) it is animated as the robot moves along the M-point trajectory.
%
% Options::
%
% 'color',C         A cell array of color names, one per link.  These are
%                   mapped to RGB using colorname().  If not given, colors
%                   come from the axis ColorOrder property.
% 'alpha',A         Set alpha for all links, 0 is transparant, 1 is opaque
%                   (default 1)
% 'path',P          Overide path to folder containing STL model files
% 'workspace', W    Size of robot 3D workspace, W = [xmn, xmx ymn ymx zmn zmx]
% 'floorlevel',L    Z-coordinate of floor (default -1)
%-
% 'delay',D         Delay betwen frames for animation (s)
% 'fps',fps         Number of frames per second for display, inverse of 'delay' option
% '[no]loop'        Loop over the trajectory forever
% '[no]raise'       Autoraise the figure
% 'movie',M         Save frames as files in the folder M
%-
% 'scale',S         Annotation scale factor
% 'ortho'           Orthographic view (default)
% 'perspective'     Perspective view
% 'view',V          Specify view V='x', 'y', 'top' or [az el] for side elevations,
%                   plan view, or general view by azimuth and elevation
%                   angle.
%-
% '[no]wrist'       Enable display of wrist coordinate frame
% 'xyz'             Wrist axis label is XYZ
% 'noa'             Wrist axis label is NOA
% '[no]arrow'       Display wrist frame with 3D arrows
%-
% '[no]tiles'       Enable tiled floor (default true)
% 'tilesize',S      Side length of square tiles on the floor (default 0.2)
% 'tile1color',C   Color of even tiles [r g b] (default [0.5 1 0.5]  light green)
% 'tile2color',C   Color of odd tiles [r g b] (default [1 1 1] white)
%-
% '[no]jaxes'       Enable display of joint axes (default true)
% '[no]joints'      Enable display of joints
%-
% '[no]base'        Enable display of base shape
%
% Notes::
% - Solid models of the robot links are required as STL ascii format files,
%   with extensions .stl
% - Suitable STL files can be found in the package ARTE: A ROBOTICS TOOLBOX
%   FOR EDUCATION by Arturo Gil, https://arvc.umh.es/arte
% - The root of the solid models is an installation of ARTE with an empty
%   file called arte.m at the top level
% - Each STL model is called 'linkN'.stl where N is the link number 0 to N
% - The specific folder to use comes from the SerialLink.model3d property
% - The path of the folder containing the STL files can be specified using
%   the 'path' option
% - The height of the floor is set in decreasing priority order by:
%   - 'workspace' option, the fifth element of the passed vector
%   - 'floorlevel' option
%   - the lowest z-coordinate in the link1.stl object
%
% Authors::
% - Peter Corke, based on existing code for plot()
% - Bryan Moutrie, demo code on the Google Group for connecting ARTE and RTB
% - Don Riley, function rndread() extracted from cad2matdemo (MATLAB
%   File Exchange)
%
% See also SerialLink.plot, plotbotopt3d, SerialLink.animate, SerialLink.teach, SerialLink.fkine.

% Copyright (C) 1993-2015, by Peter I. Corke
%
% This file is part of The Robotics Toolbox for MATLAB (RTB).
%
% RTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% RTB 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 Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com

function plot3d(robot, q, varargin)

    if robot.mdh
        error('RTB:plot3d:badmodel', '3D models are defined for standard, not modified, DH parameters');
    end

    clf
    opt = plot_options(robot, varargin);

    %-- load the shape if need be

    nshapes = robot.n+1;

    if isempty(robot.faces)
        % no 3d model defined, let's try to load one

        if isempty(opt.path)
            % first find the path to the models
            pth = which('arte.m');
            if ~pth
                error('RTB:plot3d:nomodel', 'no 3D model found, install the RTB contrib zip file');
            end

            % find the path to this specific model
            pth = fullfile(fileparts(pth), 'robots', robot.model3d);
        else
            pth = opt.path;
        end

        % now load the STL files
        robot.points = cell(1, robot.n+1);
        robot.faces = cell(1, robot.n+1);
        for i=1:nshapes
            [F,P] = rndread( fullfile(pth, sprintf('link%d.stl', i-1)) );
            robot.points{i} = P;
            robot.faces{i} = F;
        end
    end

    % if a base is specified set the floor height to this
    if isempty(opt.workspace)
        % workspace not provided, fall through the options for setting floor level
        if ~isempty(opt.floorlevel)
            opt.ws(5) = opt.floorlevel;
        elseif opt.base
            mn = min( robot.points{1} );
            opt.ws(5) = mn(3);
        end
    end
    opt.floorlevel = opt.ws(5);

% TODO
% should test if the plot exists, pinch the logic from plot()

    %-- set up to plot
    % create an axis
    ish = ishold();
    if ~ishold
        % if hold is off, set the axis dimensions
        axis(opt.ws);
        set(gca, 'ZLimMode', 'manual');
        axis(opt.ws);
        hold on
    end

    if opt.raise
        % note this is a very time consuming operation
        figure(gcf);
    end

    if strcmp(opt.projection, 'perspective')
        set(gca, 'Projection', 'perspective');
    end

    grid on
    xlabel('X'); ylabel('Y'); zlabel('Z');

    %--- create floor if required
    if opt.tiles
        create_tiled_floor(opt);
    end

    %--- configure view and lighting
    if isstr(opt.view)
        switch opt.view
            case 'top'
                view(0, 90);
            case 'x'
                view(0, 0);
            case 'y'
                view(90, 0)
            otherwise
                error('rtb:plot3d:badarg', 'view must be: x, y, top')
        end
    elseif isnumeric(opt.view) && length(opt.view) == 2
        view(opt.view)
    else
        campos([2 2 1]);
    end

    daspect([1 1 1]);
    light('Position', [0 0 opt.reach*2]);
    light('Position', [1 0.5 1]);

    %-- figure the colors for each shape
    if isempty(opt.color)
        % if not given, use the axis color order
        C = get(gca,'ColorOrder');
    else
        C = [];
        for c=opt.color
            C = [C; colorname(c{1})];
        end
    end

    %--- create the robot
    %  one patch per shape, use hgtransform to animate them later
    group = hggroup('Tag', robot.name);
    ncolors = numrows(C);

    h = [];
    for link=0:robot.n
        if link == 0
            if ~opt.base
                continue;
            end

            patch('Faces', robot.faces{link+1}, 'Vertices', robot.points{link+1}, ...
                'FaceColor', C(mod(link,ncolors)+1,:), 'EdgeAlpha', 0, 'FaceAlpha', opt.alpha);
        else
            h.link(link) = hgtransform('Tag', sprintf('link%d', link), 'Parent', group);

            patch('Faces', robot.faces{link+1}, 'Vertices', robot.points{link+1}, ...
                'FaceColor', C(mod(link,ncolors)+1,:), 'EdgeAlpha', 0, 'FaceAlpha', opt.alpha, ...
            'Parent', h.link(link));
        end
    end

    % enable mouse-based 3D rotation
    rotate3d on

    h.wrist = [];  % HACK, should be trplot
    h.robot = robot;
    h.link = [0 h.link];
    set(group, 'UserData', h);

    robot.animate(q);

    if ~ish
        hold off
    end
end

function opt = plot_options(robot, optin)
    opt.color = [];
    opt.path = [];  % override path
    opt.alpha = 1;

        % timing/looping
    opt.delay = 0.1;
    opt.fps = [];
    opt.loop = false;

    opt.raise = false;

    % general appearance
    opt.scale = 1;

    opt.workspace = [];
    opt.floorlevel = [];

    opt.name = true;
    opt.projection = {'ortho', 'perspective'};
    opt.view = [];

    % tiled floor
    opt.tiles = true;
    opt.tile1color = [0.5 1 0.5];  % light green
    opt.tile2color = [1 1 1];  % white
    opt.tilesize = 0.2;

    % the base or pedestal
    opt.base = true;

    % wrist
    opt.wrist = true;
    opt.wristlabel = {'xyz', 'noa'};
    opt.arrow = true;

    % joint rotation axes
    opt.jaxes = false;

    % misc
    opt.movie = [];

    % build a list of options from all sources
    %   1. the M-file plotbotopt if it exists
    %   2. robot.plotopt
    %   3. command line arguments
    if exist('plotbotopt3d', 'file') == 2
        options = [plotbotopt3d robot.plotopt3d optin];
    else
        options = [robot.plotopt3d optin];
    end

    % parse the options
    [opt,args] = tb_optparse(opt, options);
    if ~isempty(args)
        error(['unknown option: ' args{1}]);
    end

    if ~isempty(opt.fps)
        opt.delay = 1/opt.fps;
    end
    % figure the size of the figure

    if isempty(opt.workspace)
        %
        % simple heuristic to figure the maximum reach of the robot
        %
        L = robot.links;
        if any(L.isprismatic)
            error('Prismatic joint(s) present: requires the ''workspace'' option');
        end
        reach = 0;
        for i=1:robot.n
            reach = reach + abs(L(i).a) + abs(L(i).d);
        end

        % if we have a floor, quantize the reach to a tile size
        if opt.tiles
            reach = opt.tilesize * ceil(reach/opt.tilesize);
        end

        % now create a 3D volume based on this reach
        opt.ws = [-reach reach -reach reach -reach reach];

        % if a floorlevel has been given, ammend the 3D volume
        if ~isempty(opt.floorlevel)
            opt.ws(5) = opt.floorlevel;
        end
    else
        % workspace is provided
        reach = min(abs(opt.workspace));
        if opt.tiles
            % set xy limits to be integer multiple of tilesize
            opt.ws(1:4) = opt.tilesize * round(opt.workspace(1:4)/opt.tilesize);
            opt.ws(5:6) = opt.workspace(5:6);
        end
    end

    opt.reach = reach;

    % update the fundamental scale factor (given by the user as a multiplier) by a length derived from
    % the overall workspace dimension
    %  we need that a lot when creating the robot model
    opt.scale = opt.scale * reach/40;

    % deal with a few options that need to be stashed in the SerialLink object
    % movie mode has not already been flagged
    if opt.movie
        robot.framenum = 0;
        robot.moviepath = opt.movie;
    else
        robot.framenum = [];
    end

    if ~isempty(opt.movie)
        mkdir(opt.movie);
        framenum = 1;
    end

    robot.delay = opt.delay;
    robot.loop = opt.loop;
end

% Extracted from cad2matdemo
% http://www.mathworks.com/matlabcentral/fileexchange/3642-cad2matdemo-m/content/cad2matR2.zip
%
% Copyright (c) 2003, Don Riley
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
%     * Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%     * 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
%     * Neither the name of the Walla Walla University nor the names
%       of its contributors may be used to endorse or promote products derived
%       from this software without specific prior written permission.
%
% 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 OWNER 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 [fout, vout, cout] = rndread(filename)

    % Reads CAD STL ASCII files, which most CAD programs can export.
    % Used to create Matlab patches of CAD 3D data.
    % Returns a vertex list and face list, for Matlab patch command.
    %
    % filename = 'hook.stl';  % Example file.
    %
    fid=fopen(filename, 'r'); %Open the file, assumes STL ASCII format.
    if fid == -1
        error('File could not be opened, check name or path.')
    end
    %
    % Render files take the form:
    %
    %solid BLOCK
    %  color 1.000 1.000 1.000
    %  facet
    %      normal 0.000000e+00 0.000000e+00 -1.000000e+00
    %      normal 0.000000e+00 0.000000e+00 -1.000000e+00
    %      normal 0.000000e+00 0.000000e+00 -1.000000e+00
    %    outer loop
    %      vertex 5.000000e-01 -5.000000e-01 -5.000000e-01
    %      vertex -5.000000e-01 -5.000000e-01 -5.000000e-01
    %      vertex -5.000000e-01 5.000000e-01 -5.000000e-01
    %    endloop
    % endfacet
    %
    % The first line is object name, then comes multiple facet and vertex lines.
    % A color specifier is next, followed by those faces of that color, until
    % next color line.
    %
    CAD_object_name = sscanf(fgetl(fid), '%*s %s');  %CAD object name, if needed.
    %                                                %Some STLs have it, some don't.
    vnum=0;       %Vertex number counter.
    report_num=0; %Report the status as we go.
    VColor = 0;
    %
    while feof(fid) == 0                    % test for end of file, if not then do stuff
        tline = fgetl(fid);                 % reads a line of data from file.
        fword = sscanf(tline, '%s ');       % make the line a character string
        % Check for color
        if strncmpi(fword, 'c',1) == 1;    % Checking if a "C"olor line, as "C" is 1st char.
            VColor = sscanf(tline, '%*s %f %f %f'); % & if a C, get the RGB color data of the face.
        end                                % Keep this color, until the next color is used.
        if strncmpi(fword, 'v',1) == 1;    % Checking if a "V"ertex line, as "V" is 1st char.
            vnum = vnum + 1;                % If a V we count the # of V's
            report_num = report_num + 1;    % Report a counter, so long files show status
            if report_num > 249;
                %disp(sprintf('Reading vertix num: %d.',vnum));
                report_num = 0;
            end
            v(:,vnum) = sscanf(tline, '%*s %f %f %f'); % & if a V, get the XYZ data of it.
            c(:,vnum) = VColor;              % A color for each vertex, which will color the faces.
        end                                 % we "*s" skip the name "color" and get the data.
    end
    %   Build face list; The vertices are in order, so just number them.
    %
    fnum = vnum/3;      %Number of faces, vnum is number of vertices.  STL is triangles.
    flist = 1:vnum;     %Face list of vertices, all in order.
    F = reshape(flist, 3,fnum); %Make a "3 by fnum" matrix of face list data.
    %
    %   Return the faces and vertexs.
    %
    fout = F';  %Orients the array for direct use in patch.
    vout = v';  % "
    cout = c';
    %
    fclose(fid);
end

% draw a tiled floor in the current axes
function create_tiled_floor(opt)

    xmin = opt.ws(1);
    xmax = opt.ws(2);
    ymin = opt.ws(3);
    ymax = opt.ws(4);

    % create a colored tiled floor
    xt = xmin:opt.tilesize:xmax;
    yt = ymin:opt.tilesize:ymax;
    Z = opt.floorlevel*ones( numel(yt), numel(xt));
    C = zeros(size(Z));
    [r,c] = ind2sub(size(C), 1:numel(C));
    C = bitand(r+c,1);
    C = reshape(C, size(Z));
    C = cat(3, opt.tile1color(1)*C+opt.tile2color(1)*(1-C), ...
        opt.tile1color(2)*C+opt.tile2color(2)*(1-C), ...
        opt.tile1color(3)*C+opt.tile2color(3)*(1-C));
    [X,Y] = meshgrid(xt, yt);
    surface(X, Y, Z, C, ...
        'FaceColor','texturemap',...
        'EdgeColor','none',...
        'CDataMapping','direct');
end


% std_chaninds() - look up channel indices in a EEG structure
%
% Usage:
%         >> inds = std_chaninds(EEG, channames);
% Inputs:
%         EEG   - EEG structure containing a chanlocs substructure.
%                 the chanlocs structure may also be used as input.
%     channames - [cell] channel names. May also be a string containing
%                 one or several channel names.
%
% Outputs:
%       inds - [integer array] channel indices
%
% Author: Arnaud Delorme, CERCO, 2009-

% Copyright (C) Arnaud Delorme, 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 finalinds = eeg_chaninds(EEG, channames, errorifnotfound);

    if nargin < 2
        help eeg_chaninds;
        return;
    end;
    if nargin < 3
        errorifnotfound = 1;
    end;

    if isfield(EEG, 'chanlocs')
         chanlocs = EEG.chanlocs;
    else chanlocs = EEG;
    end;

    % decode string if necessary
    % --------------------------
    if isstr(channames)
        channames = parsetxt( channames );
    end;

    finalinds   = [];
    if isempty(chanlocs)
         tmpallchans = [];
    else tmpallchans = lower({ chanlocs.labels });
    end;
    if isempty(channames), finalinds = [1:length(chanlocs)]; return; end;
    for c = 1:length(channames)
        chanind = strmatch( lower(channames{c}), tmpallchans, 'exact');
        if isempty(chanind),
            chanind = str2double(channames{c});
            if isnan(chanind), chanind = []; end;
            if errorifnotfound && isempty(chanind)
                error(sprintf('Channel %s not found', channames{c}));
            end;
        end;
        finalinds   = [ finalinds chanind ];
    end;
    finalinds = sort(finalinds);


function region = p17_region ( )

%*****************************************************************************80
%
%% P17_REGION returns the name of the integration region for problem 17.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 March 2007
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string REGION, the name of the integration region.
%
  region = 'box';

  return
end


function [Alpha, Trf] = bSSFP_GetSeq( VaryAlpha, FixTrf, VaryTrf, FixAlpha )

Alpha =  zeros(length(VaryTrf)+length(VaryAlpha), 1);
Trf   =  Alpha;

kk=1;
for ii = 1:length(VaryAlpha)
    Alpha(kk) = VaryAlpha(ii);
    Trf(kk) = FixTrf;
    kk = kk+1;
end

for jj = 1:length(VaryTrf)
    Alpha(kk) = FixAlpha;
    Trf(kk) = VaryTrf(jj);
    kk = kk+1;
end

end


function [uOutput] = yourfilterimp(nFunction, sFilename)
% Import filter template -- copy and modify to import your own delimted ascii files
%
% To use this:
%   - Copy it into an appropriate new name (still in the importfilters directory)
%   - Change it

% Assume this function is to convert a comma-separated file formatted thusly:
%
%  ID, La, Lo, Dp, Yr, Mo, Dy, Tm, Ma, MagT, cm
%  01, 46.0, 10.3, 4.0, 2015, 12, 3, 3.1, 12:00:03, Mb, comment
%  02, 45.2, 6.4, 6.0, 2015, 12, 4, 3.2, 03:00:03, Mb, comment
%  03, 45.8, 9.1, 8.0, 2015, 12, 3, 2.0, 12:00:03, Mb, comment
%   ... etc ...
%
%  The goal is to turn this into a ZmapCatalog.
%

% if the file did not have a header, you would specify the column names here:
%
% ColumnNamesInFile = {'ID','Latitude','Longitude','Depth','Year','Month','Day','Time','Magnitude','MagnitudeType', 'Comment'}

% if the names need to be remapped, create the mapping here:
%   - note, if a column is not mentioned, it will be unchanged
%   - note, if a column is mapped to [], it will be removed
fileCols2catalogCols = {'La', 'Latitude';...
                        'Lo', 'Longitude';...
                        'Dp', 'Depth';...
                        'Ma', 'Magnitude';...
                        'MagT', 'MagnitudeType';...
                        'cm', []...
                        };

% Filter function switchyard
switch nFunction
    case FilterOp.getDescription
        % return a short description which will appear in the drop-down list
        uOutput = 'Your data format - adjust the file yourfilterimp.m';
    case FilterOp.getWebpage
        % return a web-page detailing your format
        uOutput = 'yourfilterimp.html';
    case FilterOp.importCatalog

        opts = detectImportOptions(sFilename);
        tb = readtable(sFilename, opts);

        % now add or change column names, thesemay not map directly to ZmapCatalog yet
        if exist('ColumnNamesInFile','var')
            tb.Properties.VariableNames = ColumnNamesInFile;
        end

        % now calculate any columns as necessary.
        tb.Date = datetime(tb.Yr, tb.Mo, tb.Dy) + tb.Tm;  % in this case, tm was automatically converted to a duration

        % now rename and delete columns as desired
        if exist('fileCols2catalogCols','var')
            remapper = containers.Map(fileCols2catalogCols(:,1),fileCols2catalogCols(:,2));
            for idx = numel(tb.Properties.VariableNames) : -1 : 1 % going backwards avoids trouble deleting
                fcolname = tb.Properties.VariableNames{idx};
                if ismember(fcolname, remapper.keys())
                    if isempty(remapper(fcolname))
                        tb.(fcolname) = [];
                    else
                        tb.Properties.VariableNames{idx} = remapper(fcolname);
                    end
                end
            end
        end
        uOutput = ZmapCatalog.from(tb);
        return

end


function [proj,geo,angles]=NikonDataLoader(filepath,varargin)
%NikonDataLoader(filepath) Loads Nikon uCT datasets into TIGRE standard
%
%   NikonDataLoader(filepath OPT,VAL,...) uses options and values.
%      These are options in case you don't want to load the entire
%      dataset, but only particular sets of projections.
%      The possible options in OPT are:
%           'sampling': type of sampling. default 'equidistant' Can be:
%                  'equidistant': equidistantly sample the entire set
%                       of angles. 'num_angles' should be set for partial
%                       loading of the data.
%                  'step': sample the entire set of projections every
%                         'sampling_step' angles.
%                  'continous': Load the first 'num_angles' amount of
%                             angles only.
%
%           'num_angles': Number of total angles to load. Default all of
%                    them. Useful for 'equidistant' and 'continous' loading
%
%           'sampling_step': step to load when loading projections.
%                   Default=1. Useful for 'step' loading.
%%

[geo,angles]=readXtekctGeometry(filepath);
[proj,geo,angles]=loadNikonProjections(filepath,geo,angles,varargin{:});

end


function CPT = CPD_to_CPT(CPD)
% CPD_TO_CPT Convert the tabular_decision_node to a CPT
% CPT = CPD_to_CPT(CPD)

CPT = CPD.CPT;


function r8mat_print_some ( m, n, a, ilo, jlo, ihi, jhi, title )

%*****************************************************************************80
%
%% R8MAT_PRINT_SOME prints out a portion of an R8MAT.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 February 2010
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer M, N, the number of rows and columns of the matrix.
%
%    Input, real A(M,N), an M by N matrix to be printed.
%
%    Input, integer ILO, JLO, the first row and column to print.
%
%    Input, integer IHI, JHI, the last row and column to print.
%
%    Input, string TITLE, a title.
%
  incx = 5;

  fprintf ( 1, '\n' );
  fprintf ( 1, '%s\n', title );

  for j2lo = max ( jlo, 1 ): incx : min ( jhi, n )

    j2hi = j2lo + incx - 1;
    j2hi = min ( j2hi, n );
    j2hi = min ( j2hi, jhi );

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Col: ' );

    for j = j2lo : j2hi
      fprintf ( 1, '%7d       ', j );
    end

    fprintf ( 1, '\n' );
    fprintf ( 1, '  Row\n' );

    i2lo = max ( ilo, 1 );
    i2hi = min ( ihi, m );

    for i = i2lo : i2hi

      fprintf ( 1, '%7d  ', i );

      for j = j2lo : j2hi
        fprintf ( 1, '%12g  ', a(i,j) );
      end

      fprintf ( 1, '\n' );

    end

  end

  return
end


function [sFile, ChannelMat] = in_fopen_eyelink(DataFile)
% IN_FOPEN_EYELINK: Open EyeLink eye tracker recordings (.edf).
%
% USAGE:  [sFile, ChannelMat] = in_fopen_eyelink(DataFile)

% @=============================================================================
% 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.
% =============================================================================@
%
% Authors: Francois Tadel & Martin Voelker, 2015

%% ===== READ HEADER =====
% Windows only
if ~ispc
    error('This format is only supported on Windows systems.');
end
% Read header and events
Trials = edfImport(DataFile, [0 1 1]);
% Get events of interest
Trials = edfExtractInterestingEvents(Trials, '^TRIALID');
Trials = edfExtractMicrosaccades(Trials);
hdr.Headers = [Trials.Header];
% Split filename
[fPath, fBase, fExt] = bst_fileparts(DataFile);
% Cannot handled multiple sampling frequencies
nEpochs = length(hdr.Headers);
allRec = [hdr.Headers.rec];
if (nEpochs > 1) && ~all([allRec.sample_rate] == hdr.Headers(1).rec.sample_rate)
    error('This function cannot handle different sampling frequencies between trials.');
end
% Sampling frequency
sfreq = double(hdr.Headers(1).rec.sample_rate);

%% ===== CREATE CHANNEL FILE =====
% List of data types
chnames = {'flags','px','py','hx','hy','pa','gx','gy','rx','ry','input','buttons','htype','hdata','errors', ...
           'gxvel','gyvel','hxvel','hyvel','rxvel','ryvel','fgxvel','fgyvel','fhxvel','fhyvel','frxvel','fryvel'};
chtypes = {'STATUS','EYE','EYE','EYE','EYE','EYE','EYE','EYE','EYE','EYE','STATUS','STATUS','STATUS','STATUS','STATUS', ...
           'EYE','EYE','EYE','EYE','EYE','EYE','EYE','EYE','EYE','EYE','EYE','EYE'};
% Convert to channels
hdr.chnames = {};
hdr.chtypes = {};
% hdr.chgain  = [];
for i = 1:length(chnames)
    % Channel is not available
    if ~isfield(Trials(1).Samples, chnames{i})
        continue;
    end
%     % Compute channel maximum (as a deviant from the mean)
%     chsamples = double(Trials(1).Samples.(chnames{i}));
%     champ     = max(abs(chsamples),[],2) - abs(mean(chsamples,2));
%     % Channel gain: 1/amplitude (or 0 if the value is constant)
%     chgain = zeros(size(champ));
%     chgain(champ ~= 0) = 1 ./ champ(champ ~= 0);
    % One channel of data per entry
    if (size(Trials(1).Samples.(chnames{i}),1) == 1)
        hdr.chnames{end+1} = chnames{i};
        hdr.chtypes{end+1} = chtypes{i};
%         hdr.chgain(end+1)  = chgain(1);
    % Two channels of data per entry
    else
        % Left eye only OR both eyes
        if (Trials(1).Header.rec.eye == 1) || (Trials(1).Header.rec.eye == 3)
            hdr.chnames{end+1} = [chnames{i}, '_l'];
            hdr.chtypes{end+1} = chtypes{i};
%             hdr.chgain(end+1)  = chgain(1);
        end
        % Right eye only OR both eyes
        if (Trials(1).Header.rec.eye == 2) || (Trials(1).Header.rec.eye == 3)
            hdr.chnames{end+1} = [chnames{i}, '_r'];
            hdr.chtypes{end+1} = chtypes{i};
%             hdr.chgain(end+1)  = chgain(2);
        end
    end
end
nChannels = length(hdr.chnames);
% Create structure
ChannelMat = db_template('channelmat');
ChannelMat.Comment = 'EyeLink channels';
ChannelMat.Channel = repmat(db_template('channeldesc'), [1, nChannels]);
% For each channel
for i = 1:nChannels
    ChannelMat.Channel(i).Name    = hdr.chnames{i};
    ChannelMat.Channel(i).Type    = hdr.chtypes{i};
    ChannelMat.Channel(i).Loc     = [0; 0; 0];
    ChannelMat.Channel(i).Orient  = [];
    ChannelMat.Channel(i).Weight  = 1;
    ChannelMat.Channel(i).Comment = [];
end

%% ===== CREATE BRAINSTORM SFILE STRUCTURE =====
% Initialize returned file structure
sFile = db_template('sfile');
% Add information read from header
sFile.byteorder = 'l';
sFile.filename  = DataFile;
sFile.format    = 'EYELINK';
sFile.device    = 'EyeLink';
sFile.header    = hdr;
sFile.comment   = fBase;
sFile.condition = [];
% Epochs
sFile.epochs = repmat(db_template('epoch'), 1, nEpochs);
for i = 1:nEpochs
    % 1 timestamp = 1 millisecond
    sFile.epochs(i).times   = round((double(hdr.Headers(i).starttime) + [0, double(hdr.Headers(i).duration)-1]) ./ 1000 .* sfreq)  ./ sfreq;
    sFile.epochs(i).label   = sprintf('Trial #%d', i);
    sFile.epochs(i).nAvg    = 1;
    sFile.epochs(i).select  = 1;
    sFile.epochs(i).bad     = 0;
end
% Consider that the sampling rate of the file is the sampling rate of the first signal
sFile.prop.sfreq   = sfreq;
sFile.prop.times   = [min([sFile.epochs.times]), max([sFile.epochs.times])];
sFile.prop.nAvg    = 1;
% No info about bad channels
sFile.channelflag = ones(nChannels, 1);

%% ===== EVENT MARKERS =====
% Initialize structure of events
events = repmat(db_template('event'), 1, 6);
iFixL = 1;  events(iFixL).label = 'fixation L';   % eye=0
iFixR = 2;  events(iFixR).label = 'fixation R';   % eye=1
iBliL = 3;  events(iBliL).label = 'blink L';
iBliR = 4;  events(iBliR).label = 'blink R';
iSacL = 5;  events(iSacL).label = 'saccade L';
iSacR = 6;  events(iSacR).label = 'saccade R';
iUsa  = 7;  events(iUsa).label = 'microsaccade';
iBut  = 8;  events(iBut).label  = 'button';
iMessList = {}; % for storing of event numbers of message events

% Create events
for i = 1:nEpochs
    % Fixation
    if isfield(Trials, 'Fixations') && ~isempty(Trials(i).Fixations)
        Ltime = unique(double(Trials(i).StartTime + Trials(i).Fixations.sttime(Trials(i).Fixations.eye == 0)) ./ 1000);
        Rtime = unique(double(Trials(i).StartTime + Trials(i).Fixations.sttime(Trials(i).Fixations.eye == 1)) ./ 1000);
        events(iFixL).times  = [events(iFixL).times, Ltime];
        events(iFixR).times  = [events(iFixR).times, Rtime];
        events(iFixL).epochs = [events(iFixL).epochs, repmat(i, 1, length(Ltime))];
        events(iFixR).epochs = [events(iFixR).epochs, repmat(i, 1, length(Rtime))];
    end
    % Blinks
    if isfield(Trials, 'Blinks') && ~isempty(Trials(i).Blinks)
        Ltime = unique(double(Trials(i).StartTime + Trials(i).Blinks.sttime(Trials(i).Blinks.eye == 0)) ./ 1000);
        Rtime = unique(double(Trials(i).StartTime + Trials(i).Blinks.sttime(Trials(i).Blinks.eye == 1)) ./ 1000);
        events(iBliL).times  = [events(iBliL).times, Ltime];
        events(iBliR).times  = [events(iBliR).times, Rtime];
        events(iBliL).epochs = [events(iBliL).epochs, repmat(i, 1, length(Ltime))];
        events(iBliR).epochs = [events(iBliR).epochs, repmat(i, 1, length(Rtime))];
    end
    % Saccade
    if isfield(Trials, 'Saccades') && ~isempty(Trials(i).Saccades)
        Ltime = unique(double(Trials(i).StartTime + Trials(i).Saccades.sttime(Trials(i).Saccades.eye == 0)) ./ 1000);
        Rtime = unique(double(Trials(i).StartTime + Trials(i).Saccades.sttime(Trials(i).Saccades.eye == 1)) ./ 1000);
        events(iSacL).times  = [events(iSacL).times, Ltime];
        events(iSacR).times  = [events(iSacR).times, Rtime];
        events(iSacL).epochs = [events(iSacL).epochs, repmat(i, 1, length(Ltime))];
        events(iSacR).epochs = [events(iSacR).epochs, repmat(i, 1, length(Rtime))];
    end
    % Button
    if isfield(Trials, 'Buttons') && ~isempty(Trials(i).Buttons)
        Time = unique(double(Trials(i).StartTime + Trials(i).Buttons.time) ./ 1000);
        events(iBut).times  = [events(iBut).times, Time];
        events(iBut).epochs = [events(iBut).epochs, repmat(i, 1, length(Time))];
    end
    % Micro-saccade (separate detection)
    if isfield(Trials, 'Microsaccades') && ~isempty(Trials(i).Microsaccades)
        Time = unique(double(Trials(i).Microsaccades.StartTime) ./ 1000);
        events(iUsa).times  = [events(iUsa).times, Time];
        events(iUsa).epochs = [events(iUsa).epochs, repmat(i, 1, length(Time))];
    end

    % Messages send by user (e.g. as sync triggers)
    if isfield(Trials, 'Events') && ~isempty(Trials(i).Events.message)
        messageType = unique(Trials(i).Events.message);
        % Exclude "TRIALID" and empty markers
        for iMess = numel(messageType):-1:1
            if strncmpi(messageType{iMess}, 'TRIALID', 6) || isempty(messageType{iMess})
                messageType(iMess) = [];
            end
        end
        % Store messages into 'event' struct
        for iMess = 1:numel(messageType)
            if ~isempty(find(strcmp([iMessList{:}], messageType{iMess}), 1)) % if 1, the event type has already a slot in 'events'
                iEvent = find(strcmp([iMessList{:}], messageType{iMess}));
            else                                                % new event type, define index for 'events' struct and label
                iMessList{numel(iMessList)+1} = messageType{iMess};
                iEvent = numel(events)+1;
                events(iEvent).label = messageType{iMess};
            end

            Time = double(Trials(i).Events.sttime(ismember(Trials(i).Events.message, messageType{iMess})==1)) ./ 1000;
            events(iEvent).times  = [events(iEvent).times, Time];
            events(iEvent).epochs = [events(iEvent).epochs, repmat(i, 1, length(Time))];
        end
    end
end
% Additional fixes
for i = 1:length(events)
    % Rounding the times to the nearest sample
    if ~isempty(events(i).times)
        events(i).times = round(events(i).times .* sFile.prop.sfreq) ./ sFile.prop.sfreq;
    end
    % Add channels and notes fields
    events(i).channels = [];
    events(i).notes    = [];
end

% Import this list
sFile = import_events(sFile, [], events);


function [params, names] = diagKernExtractParam(kern)

% DIAGKERNEXTRACTPARAM Extract parameters from the DIAG kernel structure.
% FORMAT
% DESC extracts parameters from the diagonal noise covariance function
% kernel structure into a vector of parameters for optimisation.
% ARG kern : the kernel structure containing the parameters to be
% extracted.
% RETURN param : vector of parameters extracted from the kernel. If
% the field 'transforms' is not empty in the kernel structure, the
% parameters will be transformed before optimisation (for example
% positive only parameters could be logged before being returned).
%
% FORMAT
% DESC extracts parameters and parameter names from the diagonal noise covariance function
% kernel structure.
% ARG kern : the kernel structure containing the parameters to be
% extracted.
% RETURN param : vector of parameters extracted from the kernel. If
% the field 'transforms' is not empty in the kernel structure, the
% parameters will be transformed before optimisation (for example
% positive only parameters could be logged before being returned).
% RETURN names : cell array of strings containing names for each
% parameter.
%
% SEEALSO diagKernParamInit, diagKernExpandParam, kernExtractParam, scg, conjgrad
%
% COPYRIGHT : Neil D. Lawrence, 2011
%
% KERN

params = kern.variance;
if nargout > 1
  names = {'variance'};
end