function [ima_stack1,ima_stack2,errorCode] = pco_sdk_example_recorder_dual(imacount,exposure_time,triggermode)
% set variables and grab images with the pco.recorder from 2 cameras.
% When done copy imagedata from Recorder to a Matlab arrays
%
%   [ima_stack1,imastack2] = pco_sdk_example_recorder(imacount,exposure_time,triggermode)
%
% * Input parameters :
%    imacount                number of images to grab
%    exposure_time           camera exposure time (default=10ms)
%    triggermode             camera trigger mode (default=AUTO)
%
% * Output parameters :
%    ima_stack1              stack with grabbed images from camera 1
%    ima_stack2              stack with grabbed images from camera 2
%    errorCode               ErrorCode returned from pco.camera SDK or pco.recorder functions
%

%function workflow
%open camera1
%open camera2
%set variables
%create recorder
%initialize recorder
%grab images with recorder
%stop camera
%copy image data from recorder to matlab image stacks
%close camera
%
%%

%%initialize cameras
glvar1=struct('do_libunload',0,'do_close',0,'camera_open',0,'out_ptr',[]);
glvar2=struct('do_libunload',0,'do_close',0,'camera_open',0,'out_ptr',[]);

if(~exist('imacount','var'))
 imacount = 10;
end

if(~exist('exposure_time','var'))
 exposure_time = 10;
end

if(~exist('triggermode','var'))
 triggermode = 0;
end

pco_camera_load_defines();
subfunc=pco_camera_subfunction();

disp('Open and initialize camera 1');
[errorCode,glvar1]=pco_camera_open_close(glvar1);
pco_errdisp('pco_camera_setup',errorCode);
disp(['camera_open should be 1 is ',int2str(glvar1.camera_open)]);
if(errorCode~=PCO_NOERROR)
 glvar1.do_close=1;
 glvar1.do_libunload=1;
 pco_camera_open_close(glvar1);
 commandwindow;
 return;
end

hcam_ptr1=glvar1.out_ptr;

subfunc.fh_stop_camera(hcam_ptr1);

cam_desc1=libstruct('PCO_Description');
set(cam_desc1,'wSize',cam_desc1.structsize);
[errorCode,~,cam_desc1] = calllib('PCO_CAM_SDK', 'PCO_GetCameraDescription', hcam_ptr1,cam_desc1);
pco_errdisp('PCO_GetCameraDescription',errorCode);

if(bitand(cam_desc1.dwGeneralCapsDESC1,GENERALCAPS1_NO_TIMESTAMP)==0)
 subfunc.fh_enable_timestamp(hcam_ptr1,TIMESTAMP_MODE_BINARYANDASCII);
end

subfunc.fh_set_exposure_times(hcam_ptr1,exposure_time,2,0,2);
subfunc.fh_set_triggermode(hcam_ptr1,triggermode);
subfunc.fh_set_bitalignment(hcam_ptr1,BIT_ALIGNMENT_LSB);
subfunc.fh_set_transferparameter(hcam_ptr1);

errorCode = calllib('PCO_CAM_SDK', 'PCO_ArmCamera', hcam_ptr1);
pco_errdisp('PCO_ArmCamera',errorCode);
%if PCO_ArmCamera does fail no images can be grabbed
if(errorCode~=PCO_NOERROR)
 if(glvar1.camera_open==1)
  glvar1.do_close=1;
  glvar1.do_libunload=1;
  pco_camera_open_close(glvar1);
 end
 commandwindow;
 return;
end

subfunc.fh_get_triggermode(hcam_ptr1);
imatime1=subfunc.fh_show_frametime(hcam_ptr1);
disp('Initialize camera 1 done ');

disp('Open and initialize camera 2');
[errorCode,glvar2]=pco_camera_open_close(glvar2);
pco_errdisp('pco_camera_setup',errorCode);
disp(['camera_open should be 1 is ',int2str(glvar2.camera_open)]);
if(errorCode~=PCO_NOERROR)
 if(glvar1.camera_open==1)
  glvar1.do_close=1;
  glvar1.do_libunload=1;
  pco_camera_open_close(glvar1);
 end
 commandwindow;
 return;
end

hcam_ptr2=glvar2.out_ptr;

subfunc.fh_stop_camera(hcam_ptr2);

cam_desc2=libstruct('PCO_Description');
set(cam_desc2,'wSize',cam_desc2.structsize);
[errorCode,~,cam_desc2] = calllib('PCO_CAM_SDK', 'PCO_GetCameraDescription', hcam_ptr2,cam_desc2);
pco_errdisp('PCO_GetCameraDescription',errorCode);

if(bitand(cam_desc2.dwGeneralCapsDESC1,GENERALCAPS1_NO_TIMESTAMP)==0)
 subfunc.fh_enable_timestamp(hcam_ptr2,TIMESTAMP_MODE_BINARYANDASCII);
end

subfunc.fh_set_exposure_times(hcam_ptr2,exposure_time,2,0,2);
subfunc.fh_set_triggermode(hcam_ptr2,triggermode);
subfunc.fh_set_bitalignment(hcam_ptr2,BIT_ALIGNMENT_LSB);
subfunc.fh_set_transferparameter(hcam_ptr2);

errorCode = calllib('PCO_CAM_SDK', 'PCO_ArmCamera', hcam_ptr2);
pco_errdisp('PCO_ArmCamera',errorCode);
%if PCO_ArmCamera does fail no images can be grabbed
if(errorCode~=PCO_NOERROR)
 if(glvar2.camera_open==1)
  glvar2.do_close=1;
  pco_camera_open_close(glvar2);
 end
 if(glvar1.camera_open==1)
  glvar1.do_close=1;
  glvar1.do_libunload=1;
  pco_camera_open_close(glvar1);
 end
 commandwindow;
 return;
end

subfunc.fh_get_triggermode(hcam_ptr2);
imatime2=subfunc.fh_show_frametime(hcam_ptr2);
disp('Initialize camera 2 done ');

%%
%////////////////////////////////////////////////////////////
%     here is the startpoint of the pco.recorder part
%////////////////////////////////////////////////////////////

% Test if recorder library is loaded
if (~libisloaded('PCO_CAM_RECORDER'))
 % make sure the dll and h file specified below resides in your current folder
  loadlibrary('PCO_Recorder','SC2_CamMatlab.h' ...
              ,'addheader','PCO_Recorder_Export.h' ...
              ,'alias','PCO_CAM_RECORDER');
  disp('PCO_CAM_RECORDER library is loaded!');
else
 [errorCode] = calllib('PCO_CAM_RECORDER','PCO_RecorderResetLib',1);
 pco_errdisp('PCO_RecorderResetLib',errorCode);
 if(errorCode~=PCO_NOERROR)
  commandwindow;
  return;
 end
end

%uncomment to show functions and parameters of the recorder library
%libfunctionsview('PCO_CAM_RECORDER');

%Create and setup recorder for dual camera operation
%storing images in RAM
camcount=2;

MaxImgCountArr=zeros(1,camcount,'uint32');
pMaxImgCountArr=libpointer('uint32Ptr',MaxImgCountArr);

pImgDistributionArr=libpointer('uint32Ptr');

%fill structures according to available cameras
if camcount==1
 ml_camlist.cam_ptr1=libpointer('voidPtr',hcam_ptr1);
%uncomment if ImgDistributionArr setting is necessary
 %ImgDistributionArr=zeros(1,camcount,'uint32');
 %ImgDistributionArr(1)=imacount+10;
 %pImgDistributionArr=libpointer('uint32Ptr',ImgDistributionArr);
elseif camcount==2
 ml_camlist.cam_ptr1=libpointer('voidPtr',hcam_ptr1);
 ml_camlist.cam_ptr2=libpointer('voidPtr',hcam_ptr2);
%uncomment if ImgDistributionArr setting is necessary
 %ImgDistributionArr=zeros(1,camcount,'uint32');
 %ImgDistributionArr(1)=imacount+10;
 %ImgDistributionArr(2)=imacount+10;
 %pImgDistributionArr=libpointer('uint32Ptr',ImgDistributionArr);
end

camera_array=libstruct('PCO_cam_ptr_List',ml_camlist);

diskchar=int8(67);  %'C'

hreci_ptr = libpointer('voidPtrPtr');

[errorCode,hrec_ptr,~,ImgDistributionArr,MaxImgCountArr] = calllib('PCO_CAM_RECORDER', 'PCO_RecorderCreate' ...
                          ,hreci_ptr ...
                          ,camera_array ...
                          ,pImgDistributionArr ...
                          ,camcount ...
                          ,PCO_RECORDER_MODE_MEMORY ...
                          ,diskchar ...
                          ,pMaxImgCountArr);
pco_errdisp('PCO_RecorderCreate',errorCode);

if errorCode ~= 0
 clear camera_array;
 unloadlibrary('PCO_CAM_RECORDER');
 disp('PCO_CAM_RECORDER unloadlibrary done');

 if(glvar2.camera_open==1)
  glvar2.do_close=1;
  pco_camera_open_close(glvar2);
 end
 if(glvar1.camera_open==1)
  glvar1.do_close=1;
  glvar1.do_libunload=1;
  pco_camera_open_close(glvar1);
 end
 commandwindow;
 return;
end

if ~isNull(pImgDistributionArr)
 disp(['ImgDistribution: ',int2str(ImgDistributionArr)]);
 if imacount>min(ImgDistributionArr)
  imacount=min(ImgDistributionArr);
  disp('imacount changed to ',imacount);
 end
end

disp(['MaxImgCount:     ',int2str(MaxImgCountArr)]);

if imacount>min(MaxImgCountArr)
 imacount=min(MaxImgCountArr);
 disp('imacount changed to ',imacount);
end

ImgCountArr=zeros(1,camcount,'uint32');
ImgCountArr(1)=imacount;
if camcount==2
 ImgCountArr(2)=imacount;
end

[errorCode] = calllib('PCO_CAM_RECORDER', 'PCO_RecorderInit' ...
                      ,hrec_ptr ...
                      ,ImgCountArr,camcount ...
                      ,PCO_RECORDER_MEMORY_SEQUENCE ...
                      ,1,[],[]);
pco_errdisp('PCO_RecorderInit',errorCode);

if errorCode ~= 0
 [errorCode]=calllib('PCO_CAM_RECORDER','PCO_RecorderDelete',hrec_ptr);
 pco_errdisp('PCO_RecorderDelete',errorCode);

 clear camera_array;

 unloadlibrary('PCO_CAM_RECORDER');
 disp('PCO_CAM_RECORDER unloadlibrary done');

 if(glvar2.camera_open==1)
  glvar2.do_close=1;
  pco_camera_open_close(glvar2);
 end
 if(glvar1.camera_open==1)
  glvar1.do_close=1;
  glvar1.do_libunload=1;
  pco_camera_open_close(glvar1);
 end
 commandwindow;
 return;
end

IsRunning1    =true;
IsNotValid    =false;
ProcImgCount1 =uint32(0);
ReqImgCount1  =uint32(0);
StartTime     =uint32(0);
StopTime      =uint32(0);

[errorCode,~,~...
 ,IsRunning1,~,~...
 ,ProcImgCount1,ReqImgCount1] = calllib('PCO_CAM_RECORDER', 'PCO_RecorderGetStatus' ...
                           ,hrec_ptr,hcam_ptr1 ...
                           ,IsRunning1,IsNotValid,IsNotValid ...
                           ,ProcImgCount1,ReqImgCount1 ...
                           ,[],[] ...
                           ,StartTime,StopTime);
pco_errdisp('PCO_PCO_RecorderGetStatus',errorCode);

if IsRunning1
 s='started';
else
 s='stopped';
end
disp(['Cam1 Current runstate: ',s]);
disp(['Cam1 images done:      ',int2str(ProcImgCount1)]);
disp(['Cam1 images requested: ',int2str(ReqImgCount1)]);

IsRunning2    =true;
ProcImgCount2 =uint32(0);
ReqImgCount2  =uint32(0);

[errorCode,~,~...
 ,IsRunning2,~,~...
 ,ProcImgCount2,ReqImgCount2] = calllib('PCO_CAM_RECORDER', 'PCO_RecorderGetStatus' ...
                           ,hrec_ptr,hcam_ptr2 ...
                           ,IsRunning2,IsNotValid,IsNotValid ...
                           ,ProcImgCount2,ReqImgCount2 ...
                           ,[],[] ...
                           ,StartTime,StopTime);
pco_errdisp('PCO_PCO_RecorderGetStatus',errorCode);

if IsRunning2
 s='started';
else
 s='stopped';
end
disp(['Cam2 Current runstate: ',s]);
disp(['Cam2 images done:      ',int2str(ProcImgCount2)]);
disp(['Cam2 images requested: ',int2str(ReqImgCount2)]);

%not really necessary here
[errorCode] = calllib('PCO_CAM_RECORDER', 'PCO_RecorderCleanup',hrec_ptr,[]);
pco_errdisp('PCO_RecorderCleanup',errorCode);

imatime=max(imatime1,imatime2);
looptime=(imatime*imacount);
disp(['time for all images is:   ',int2str(looptime),' seconds']);

disp('Start Recorder');
tic;
[errorCode] = calllib('PCO_CAM_RECORDER', 'PCO_RecorderStartRecord',hrec_ptr,[]);
pco_errdisp('PCO_PCO_RecorderStartRecord',errorCode);

[errorCode,~,~,IsRunning1] = calllib('PCO_CAM_RECORDER', 'PCO_RecorderGetStatus' ...
                          ,hrec_ptr,hcam_ptr1 ...
                          ,IsRunning1,IsNotValid,IsNotValid ...
                          ,ProcImgCount1,ReqImgCount1 ...
                          ,[],[],[],[]);
pco_errdisp('PCO_PCO_RecorderGetStatus',errorCode);

if IsRunning1
 s='started';
else
 s='stopped';
end
disp(['Cam1 Current runstate: ',s]);

[errorCode,~,~,IsRunning2] = calllib('PCO_CAM_RECORDER', 'PCO_RecorderGetStatus' ...
                          ,hrec_ptr,hcam_ptr2 ...
                          ,IsRunning2,IsNotValid,IsNotValid ...
                          ,ProcImgCount2,ReqImgCount2 ...
                          ,[],[],[],[]);
pco_errdisp('PCO_PCO_RecorderGetStatus',errorCode);

if IsRunning2
 s='started';
else
 s='stopped';
end
disp(['Cam2 Current runstate: ',s]);

while( IsRunning1 || IsRunning2)
 pause(0.5);

[errorCode,~,~...
 ,IsRunning1,~,~...
 ,ProcImgCount1,ReqImgCount1] = calllib('PCO_CAM_RECORDER', 'PCO_RecorderGetStatus' ...
                          ,hrec_ptr,hcam_ptr1 ...
                          ,IsRunning1,IsNotValid,IsNotValid ...
                          ,ProcImgCount1,ReqImgCount1 ...
                          ,[],[] ...
                          ,StartTime,StopTime);
 pco_errdisp('PCO_PCO_RecorderGetStatus',errorCode);
 disp(['CAM1 images done: ',int2str(ProcImgCount1)]);

[errorCode,~,~...
 ,IsRunning2,~,~...
 ,ProcImgCount2,ReqImgCount2] = calllib('PCO_CAM_RECORDER', 'PCO_RecorderGetStatus' ...
                          ,hrec_ptr,hcam_ptr2 ...
                          ,IsRunning2,IsNotValid,IsNotValid ...
                          ,ProcImgCount2,ReqImgCount2 ...
                          ,[],[] ...
                          ,StartTime,StopTime);
 pco_errdisp('PCO_PCO_RecorderGetStatus',errorCode);
 disp(['CAM2 images done: ',int2str(ProcImgCount2)]);

 if((ProcImgCount1>=ReqImgCount1)&&(ProcImgCount2>=ReqImgCount2))
  disp('break on ImageCount');
  break;
 end

 t=toc;
 if(t>looptime+10)
  disp('break on looptime');
  break;
 end
end

[errorCode]=calllib('PCO_CAM_RECORDER','PCO_RecorderStopRecord',hrec_ptr,hcam_ptr1);
pco_errdisp('PCO_RecorderStopRecord',errorCode);
[errorCode]=calllib('PCO_CAM_RECORDER','PCO_RecorderStopRecord',hrec_ptr,hcam_ptr2);
pco_errdisp('PCO_RecorderStopRecord',errorCode);

disp(' ');
disp('Cam1 Copy images');
[errorCode,ima_stack1]=pco_recorder_copy_images(hrec_ptr,hcam_ptr1,imacount,uint16(cam_desc1.wDynResDESC));
pco_errdisp('pco_recorder_copy_images',errorCode);

disp(' ');
disp('Cam2 Copy images');
[errorCode,ima_stack2]=pco_recorder_copy_images(hrec_ptr,hcam_ptr2,imacount,uint16(cam_desc2.wDynResDESC));
pco_errdisp('pco_recorder_copy_images',errorCode);

[errorCode]=calllib('PCO_CAM_RECORDER','PCO_RecorderDelete',hrec_ptr);
pco_errdisp('PCO_RecorderDelete',errorCode);

clear camera_array;

unloadlibrary('PCO_CAM_RECORDER');
disp('PCO_CAM_RECORDER unloadlibrary done');

%////////////////////////////////////////////////////////////
%    here is the endpoint of the pco.recorder part
%////////////////////////////////////////////////////////////
%%

if(glvar2.camera_open==1)
 glvar2.do_close=1;
 pco_camera_open_close(glvar2);
end

if(glvar1.camera_open==1)
 glvar1.do_close=1;
 glvar1.do_libunload=1;
 pco_camera_open_close(glvar1);
end

%draw_images(ima_stack,1);

clear glvar2;
clear glvar1;
commandwindow;
end

%%
function [errorCode,ima_stack]=pco_recorder_copy_images(hrec_ptr,hcam_ptr,imacount,bitpix)

subfunc=pco_camera_subfunction();

act_xsize=uint16(0);
act_ysize=uint16(0);
max_xsize=uint16(0);
max_ysize=uint16(0);
%use PCO_GetSizes because this always returns accurat image size for next recording
[errorCode,~,act_xsize,act_ysize]  = calllib('PCO_CAM_SDK', 'PCO_GetSizes', hcam_ptr,act_xsize,act_ysize,max_xsize,max_ysize);
pco_errdisp('PCO_GetSizes',errorCode);

bitalign=subfunc.fh_get_bitalignment(hcam_ptr);

disp(['bitpix:   ',int2str(bitpix)]);
disp(['bitalign: ',int2str(bitalign)]);

%allocate matlab array and copy images from recorder

imasize=uint32(fix((double(bitpix)+7)/8));
imasize= imasize*uint32(act_xsize)* uint32(act_ysize);

image=zeros(act_xsize,act_ysize,'uint16');
ima_stack=zeros(act_ysize,act_xsize,imacount,'uint16');

disp(['allocated matlab memory is ',num2str((double(imasize)*imacount)/(1024*1024*1024),'%.2f'),'GByte'])

str_meta=libstruct('PCO_METADATA_STRUCT');
set(str_meta,'wSize',str_meta.structsize);
str_time=libstruct('PCO_TIMESTAMP_STRUCT');
set(str_time,'wSize',str_time.structsize);

im_ptr=libpointer('uint16Ptr',image(:,:));

%copy images
for n=1:imacount
 set(str_meta,'wSize',str_meta.structsize);
 set(str_time,'wSize',str_time.structsize);
 [errorCode]=calllib('PCO_CAM_RECORDER','PCO_RecorderCopyImage',hrec_ptr,hcam_ptr,n-1,1,1,act_xsize,act_ysize,im_ptr,[],str_meta,str_time);
 pco_errdisp('PCO_RecorderCopyImage',errorCode);
 if errorCode ~= 0
  break;
 end

 disp(['PCO_RecorderCopyImage ',int2str(n),' done']);
 ima=get(im_ptr,'Value');
 ima_stack(:,:,n)=ima';
 txt=subfunc.fh_print_timestamp_t(ima_stack(1:2,1:50,n),bitalign,bitpix);
 disp(['Timestamp data of image ',int2str(n),' ',txt]);
 tmin=['min Value: ',int2str(min(min(ima_stack(10:end-10,10:end-10,n))))];
 tmax=['max Value: ',int2str(max(max(ima_stack(10:end-10,10:end-10,n))))];
 disp([tmin,'   ',tmax]);
end

pause(0.5);
clear image;
end


% Like lvmVisualiseGeneral but for audio
function lvmRealtimeAudio(model, YLbls, ...
			visualiseFunction, visualiseModify, showVariance, varargin)

% LVMVISUALISEGENERAL Visualise the manifold.
% This is a copy of lvmVisualise where the classVisualise function depends on the
% model type. Additionally, there is a flag showVariance which, when set to
% false, does not plot the variance of the inputs in the scatter plot,
% something which saves a lot of computational time for high-dimensional
% data.
%
% SEEALSO : lvmVisualise, lvmClassVisualise, lvmScatterPlot,
% lvmScatterPlotNoVar
%

% MLTOOLS

global visualiseInfo

visualiseInfo.showVariance = showVariance;

lvmClassVisualiseFunc = [model.type 'ClassVisualise'];
if ~exist(lvmClassVisualiseFunc)
    lvmClassVisualiseFunc = 'lvmClassVisualise';
end

if isfield(model, 'vis') && isfield(model.vis, 'figHandle')
    figure(model.vis.figHandle{1});
else
    figure(1)
end

clf
if isfield(model, 'vis') && isfield(model.vis, 'startDim')
    visualiseInfo.dim1 = model.vis.startDim{1};
    visualiseInfo.dim2 = model.vis.startDim{2};
else
    visualiseInfo.dim1 = 1;
    visualiseInfo.dim2 = 2;
end
if isfield(model, 'vis') && isfield(model.vis, 'startPos')
    visualiseInfo.latentPos = model.vis.startPos;
else
    visualiseInfo.latentPos = zeros(1, model.q);
end
visualiseInfo.model = model;
visualiseInfo.lbls = YLbls;
if showVariance
    visualiseInfo.plotAxes = lvmScatterPlot(model, YLbls);
else
    visualiseInfo.plotAxes = lvmScatterPlotNoVar(model, YLbls, [], [visualiseInfo.dim1 visualiseInfo.dim2]);
end

if showVariance
    lvmSetPlot;
else
    lvmSetPlotNoVar(lvmClassVisualiseFunc);
end
visualiseInfo.latentHandle = line(visualiseInfo.latentPos(visualiseInfo.dim1), visualiseInfo.latentPos(visualiseInfo.dim2), 'markersize', 20, 'color', ...
                                  [0 0 0], 'marker', '.', 'visible', ...
                                  'on', 'erasemode', 'xor');

visualiseInfo.clicked = 0;
visualiseInfo.digitAxes = [];
visualiseInfo.digitIndex = [];

    visualiseInfo.dynamicsRadio = ...
        uicontrol('Style', 'radiobutton', ...
        'String', 'Run Dynamics', ...
        'units', 'normalized', ...
        'position', [0 0 0.2 0.05], ...
        'Callback', [lvmClassVisualiseFunc '(''toggleDynamics'')'], ...
        'value', 0);

    visualiseInfo.dynamicsSlider = ...
        uicontrol('Style', 'slider', ...
        'String', 'Time', ...
        'sliderStep', [0.01, 0.1], ...
        'units', 'normalized', ...
        'position', [0 0.95 1 0.05], ...
        'callback', [lvmClassVisualiseFunc '(''dynamicsSliderChange'')']);

    if ~isfield(model, 'dynamics') | isempty(model.dynamics)
        set(visualiseInfo.dynamicsRadio, 'visible', 'off');
        set(visualiseInfo.dynamicsSlider, 'visible', 'off');
    else
        if ~isfield(model.dynamics, 'dynamicsType')
            set(visualiseInfo.dynamicsRadio, 'visible', 'on');
            set(visualiseInfo.dynamicsSlider, 'visible', 'off');
        else
            switch model.dynamics.dynamicsType
                case 'regressive'
                    set(visualiseInfo.dynamicsRadio, 'visible', 'off');
                    set(visualiseInfo.dynamicsSlider, 'visible', 'on');
                    set(visualiseInfo.dynamicsSlider, 'min', min(model.dynamics.X), ...
                        'max', max(model.dynamics.X), ...
                        'value', model.dynamics.X(1))
                case 'auto-regressive'
                    set(visualiseInfo.dynamicsRadio, 'visible', 'on');
                    set(visualiseInfo.dynamicsSlider, 'visible', 'off');
            end
        end
    end

visualiseInfo.runDynamics = false;

% Set the callback function
set(gcf, 'WindowButtonMotionFcn', [lvmClassVisualiseFunc '(''move'')'])
set(gcf, 'WindowButtonDownFcn', [lvmClassVisualiseFunc '(''click'')'])

if isfield(model, 'vis') && isfield(model.vis, 'figHandle')
    figure(model.vis.figHandle{2});
else
    figure(2)
end
clf

%
% if length(visualiseFunction)>4 & strcmp(visualiseFunction(1:5), 'image') & length(varargin)>0
%   set(gcf, 'menubar', 'none')
%   xPixels = 115;
%   yPixels = 115;
%   set(gcf, 'position', [232 572 xPixels yPixels/varargin{1}(1)*varargin{1}(2)])
%   visualiseInfo.visualiseAxes = subplot(1, 1, 1);
%   xWidth = varargin{1}(1)/xPixels;
%   yHeight = varargin{1}(2)/yPixels;
%   set(visualiseInfo.visualiseAxes, 'position', [0.5-xWidth/2 0.5-yHeight/2 xWidth yHeight])
% else
  visualiseInfo.visualiseAxes =subplot(1, 1, 1);
% end

visData = zeros(1,model.d);
if(length(visualiseFunction)>4 & strcmp(visualiseFunction(1:5), 'image'))
  visData(1) = min(min(model.y));
  visData(end) = max(max(model.y));
else
  [void, indMax]= max(sum((model.y.*model.y), 2));
  visData = model.y(indMax, :);
end

set(get(visualiseInfo.visualiseAxes, 'title'), 'string', 'Y', 'fontsize',30);
set(visualiseInfo.visualiseAxes, 'position', [0.05 0.05 0.9 0.8]);

visualiseInfo.visualiseFunction = str2func(visualiseFunction);
visHandle = visualiseInfo.visualiseFunction(visData, varargin{:});
handleType = get(visHandle, 'type');
if ~strcmp(handleType, 'figure')
    set(visHandle, 'erasemode', 'xor');
end
% Pass the data to visualiseInfo
visualiseInfo.model = model;
visualiseInfo.varargin = varargin;
visualiseInfo.visualiseModify = str2func(visualiseModify);
visualiseInfo.visHandle = visHandle;

hold off

%hsvargplvmClassVisualise('updateLatentRepresentation')
%visualiseInfo.clicked = 1; %%%%
%hsvargplvmClassVisualise('move')
%hsvargplvmClassVisualise('click')


function s = spider_path(set)
% This function returns the path where spider is installed.
% If an arugment is provided than it adds all spider subdirectory paths
% to the Matlab search path.

subdirs=spider_subdirs;

% if nargin==0 %% can just return s and do not set paths
if nargin>0
    for i=1:length(subdirs)
        t = cellstr(subdirs{i});
        path(path,t{:});
    end
s=subdirs{1};

end

s=subdirs{1};
k = findstr(s,'spider');
s=s(1:k+5);

if nargin > 0
    path(path,s);
else
    subdirs=spider_subdirs;
% if nargin
    addpath(subdirs{:})
    addpath(s);

end

% show all default values for algorithms e.g C=Inf in svm, otherwise suppress
global display_tree_show_defaults;
display_tree_show_defaults=0;

% doesn't draw whole tree, only up to depth given
global display_tree_depth;
display_tree_depth=100;

% displays indexes e.g [1 3 4] if set to 1,
% displays last element of array e.g 4 of [1 3 4] if set to 2,
% or else displays a single integer index system for whole tree
%              (breadth-wise, leftmost is smallest value)
global display_tree_array_indexing;
display_tree_array_indexing=2;

% place index display at front or end of each line of output
global display_tree_index_at_front;
display_tree_index_at_front=1;

% draw brackets in display for object sets
global display_tree_show_brackets;
display_tree_show_brackets=1;

% number of characters of tab spacing for nested objects in tree
global display_tree_tab_step;
display_tree_tab_step=3;

% whether to allow recursive search for variables in statements
% such as:  b=algs({svm svm}); b.C=2
% (what you lose is it is much slower...)

global recursive_subsasgn_off;
recursive_subsasgn_off=0;
% else

if isunix
     s = [ s '/'];
 else
     s = [ s '\'];
 end

s(s=='\')='/';

%% Take into account weka.jar
wekajar=[matlabroot filesep 'java' filesep 'jar' filesep 'weka.jar'];
if( length(dir(wekajar))>0)
    javaaddpath(wekajar);
end


function s = y_to_s_republican ( y, s )

%*****************************************************************************80
%
%% Y_TO_S_REPUBLICAN writes a Republican year into a string.
%
%  Format:
%
%    YearNumber ER
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    20 March 2013
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer Y, the year.
%
%    Output, string S, a representation of the year.
%
  s = sprintf ( '%d ER', y );

  return
end


function status = exportTable(table, pth);
% Write out a table to a text file.
%
% status = exportTable(table, [pth=dialog]);
%
% table should be a cell array of strings (1D or 2D).
% THis function was written for tables produces by the MATLAB
% anova functions.
%
% ras, 11/2007.
if notDefined('table'), error('Need an ANOVA table .'); end
if notDefined('pth'),
	pth = mrvSelectFile('w', 'txt', 'Specify ANOVA Table file');
end

status = -1;

fid = fopen(pth, 'w');
if fid < 1
	error( sprintf('Couldn''t open file %s for writing.', pth) )
end

for i = 1:size(table, 1)
	for j = 1:size(table, 2)
		val = table{i,j};
		if isnumeric(val)
			fprintf(fid, '%s\t', num2str(val));
		else
			fprintf(fid, '%s\t', val);
		end
	end

	fprintf(fid, '\n');
end

st = fclose(fid);

if st==0  % ok flag from fclose
	status = 1;
	fprintf('Saved table as %s.\n', pth);
end

return


%% load data annotation
param.anno_pos = {'annotation/my_pos', 'annotation/renren_pos', 'annotation/newrenren_pos', 'annotation/imdb1_pos.mat', 'annotation/meta_pos.mat'};
param.anno_neg = {'annotation/my_neg', 'annotation/renren_neg', 'annotation/newrenren_neg'};
param.dataset_root = 'G:\temp\face\detection';

%% load net
param.model_name = 'ResNet_3b_s16_fm2fm_feat_deep';
param.solverfile = 'solver_train.prototxt';
param.netnolossfile = 'net_noloss.prototxt';
assert(~isempty(param.netnolossfile));
param.net_def_dir = fullfile(pwd, 'model', 'rpn_prototxts', param.model_name);
param.output_dir = fullfile(pwd, 'output', param.model_name);

%% configure training setting
param.gpu_id = 0:3;
param.pos_gpu = 0:3;
param.neg_gpu = 0;
param.batch_size_per_gpu = 1;
% param.anchor_is_stride_center = true; % always true
param.speedup = 1;
param.max_img = 1200;
param.max_pos_img = 1200;
param.min_img = 32;
param.max_target = 1024;
param.min_target = 32;
param.val_num = 128;
param.fast_valid = 1;
param.test_interval = 10000;
param.snapshot_interval = 10000;
param.display_interval = 500;
param.max_rand_offset = 5;
param.reg_points_diff = true;
param.anchor_scale = 1;
param.multishape_anchor = false;
param.pos_overlap_ratio = 0.7;
param.neg_overlap_ratio = 0.5;
param.gray_augment_ratio = 0.4;
param.validation_ratio = 0.01;
param.ignore_min_roi = 5;

%% configure init setting
%param.init_model = 'model/pre_trained_models/ResNet-101L/ResNet-101-model.caffemodel';
param.init_model = 'weight_share_feat_new_68w';
param.out_dir = fullfile(pwd, 'output', param.model_name);
param.caffe_log_dir = fullfile(param.out_dir, 'caffe_log/');


function r = struct2rowsexport(s,varargin)
% r = struct2rowsexport(s,varargin)
% Optional PVs:
%   - nansAsStrings: If true, numeric scalar NaNs are replaced with the
%   string 'NaN'. Defaults to false.

nansAsStrings = myparse(varargin,...
  'nansAsStrings',false);

assert(isstruct(s)&&isvector(s),'Expected d to be a struct vector.');
s = s(:);

r = struct2cell(s);
r = r';

% replace values in r for export
for c = 1:numel(r)
  val = r{c};
  if isscalar(val)&&isnan(val)&&nansAsStrings
    r{c} = 'NaN';
  elseif isnumeric(val)&&isscalar(val) || ...
      islogical(val)&&isscalar(val) || ...
      ischar(val)&&isrow(val) || ...
      isequal(val,[])
    % none
  else
    r{c} = '<array value>';
  end
end

hdr = fieldnames(s);
r = [hdr(:)';r];


function [seqName, seqFolder, imgFolder, frameRate, F, imWidth, imHeight, imgExt] ...
    = getSeqInfoFromFile(seq, dataDir)
% construct variables with relevant information about the sequence 'seq'
%

    seqName=char(seq);
    seqFolder= [dataDir,seqName,filesep];

    seqInfoFile = [dataDir,seqName,filesep,'seqinfo.ini'];
    ini = IniConfig();
    ini.ReadFile(seqInfoFile);

    imgFolder = ini.GetValues('Sequence','imDir');
    frameRate = ini.GetValues('Sequence','frameRate');
    F=ini.GetValues('Sequence','seqLength');
    imWidth=ini.GetValues('Sequence','imWidth');
    imHeight=ini.GetValues('Sequence','imHeight');
    imgExt = ini.GetValues('Sequence','imExt');

end


function FlyBowlJAABADetect(expdir,varargin)

version = '0.2';

[analysis_protocol,settingsdir,datalocparamsfilestr,...
  forcecompute,DEBUG] = ...
  myparse(varargin,'analysis_protocol','current',...
  'settingsdir','/groups/branson/bransonlab/projects/olympiad/FlyBowlAnalysis/settings',...
  'datalocparamsfilestr','dataloc_params.txt',...
  'forcecompute',false,...
  'debug',false);

if isunix && settingsdir(1) ~= '/',
  warning('settingsdir path must be the global path');
end

if ischar(forcecompute),
  forcecompute = str2double(forcecompute);
end
if ischar(DEBUG),
  DEBUG = str2double(DEBUG);
end

datalocparamsfile = fullfile(settingsdir,analysis_protocol,datalocparamsfilestr);
dataloc_params = ReadParams(datalocparamsfile);
paramsfile = fullfile(settingsdir,analysis_protocol,dataloc_params.jaabadetectparamsfilestr);
params = ReadParams(paramsfile);

%% log file

if isfield(dataloc_params,'jaabadetect_logfilestr') && ~DEBUG,
  logfile = fullfile(expdir,dataloc_params.jaabadetect_logfilestr);
  logfid = fopen(logfile,'a');
  if logfid < 1,
    warning('Could not open log file %s\n',logfile);
    logfid = 1;
  end
else
  logfid = 1;
end

timestamp = datestr(now,'yyyymmddTHHMMSS');
real_analysis_protocol = GetRealAnalysisProtocol(analysis_protocol,settingsdir);

jaabapath = fileparts(mfilename('fullpath'));
versionfile = fullfile(jaabapath,'version.txt');
jaaba_version = 'unknown';
if exist(versionfile,'file'),
  versionfid = fopen(versionfile,'r');
  if versionfid > 0,
    while true,
      s = fgetl(versionfid);
      if ~ischar(s),
        break;
      end
      s = strtrim(s);
      if ~isempty(s),
        jaaba_version = s;
        break;
      end
    end
    fclose(versionfid);
  end
end

fprintf(logfid,'\n\n***\nRunning FlyBowlJAABADetect version %s (JAABA version %s), analysis_protocol %s (linked to %s) at %s\n',version,jaaba_version,analysis_protocol,real_analysis_protocol,timestamp);

%% main loop

%jaabadir = fullfile(settingsdir,analysis_protocol,params.jaabadir);

%
% oldpwd = pwd;
% cd(params.jaabadir);

% loop through the classifier params files to process in order
if ~iscell(params.classifierparamsfiles),
  params.classifierparamsfiles = {params.classifierparamsfiles};
end

classifierinfo = [];
for i = 1:numel(params.classifierparamsfiles),

  classifierparamsfile = fullfile(settingsdir,analysis_protocol,params.classifierparamsfiles{i});
  classifierinfocurr = JAABADetect(expdir,'jablistfile',classifierparamsfile,...
    'forcecompute',forcecompute,...
    'debug',DEBUG);
  %'isrelativepath',true,...
  %'fnsrelative',{'featureparamfilename'});
  classifierinfo = structappend(classifierinfo,classifierinfocurr);

end
%
% cd(oldpwd);

%% save info

if ~DEBUG,

  savefile = fullfile(expdir,dataloc_params.jaabadetectinfomatfilestr);
  if exist(savefile,'file'),
    try %#ok<TRYNC>
      delete(savefile);
    end
  end
  try
    save(savefile,'classifierinfo','timestamp','analysis_protocol','real_analysis_protocol','version');
  catch ME
    warning('Could not save jaabadetect info to file %s: %s',savefile,getReport(ME));
  end

end

%% close log

fprintf(logfid,'Finished running FlyBowlJAABADetect at %s.\n',datestr(now,'yyyymmddTHHMMSS'));

if logfid > 1,
  fclose(logfid);
end


function [errorCode,glvar] = pco_camera_resetmem(glvar,segment)
%reset memory size to 0 of all or distinct segment
%
%   [errorCode,glvar] = pco_camera_resetmem(glvar,segment)
%
% * Input parameters :
%    glvar                   structure to hold status info
%    segment                 segment to reset
% * Output parameters :
%    errorCode               ErrorCode returned from pco.camera SDK-functions
%    glvar                   structure to hold status info
%
%structure glvar is used to set different modes for
%load/unload library
%open/close camera SDK
%
%glvar.do_libunload: 1 unload lib at end
%glvar.do_close:     1 close camera SDK at end
%glvar.camera_open:  open status of camera SDK
%glvar.out_ptr:      libpointer to camera SDK handle
%
%if glvar does not exist,
%the library is loaded at begin and unloaded at end
%the SDK is opened at begin and closed at end
%
%if segment does not exist all camera memory is set to segment 1
%
%function workflow
%parameters are checked
%set camera memory structure
%return

% Test if library is loaded
if (~libisloaded('PCO_CAM_SDK'))
    % make sure the dll and h file specified below resides in your current
    % folder
	loadlibrary('SC2_Cam','SC2_CamMatlab.h' ...
                ,'addheader','SC2_CamExport.h' ...
                ,'alias','PCO_CAM_SDK');
	disp('PCO_CAM_SDK library is loaded!');
end

if((exist('glvar','var'))&& ...
   (isfield(glvar,'do_libunload'))&& ...
   (isfield(glvar,'do_close'))&& ...
   (isfield(glvar,'camera_open'))&& ...
   (isfield(glvar,'out_ptr')))
 unload=glvar.do_libunload;
 cam_open=glvar.camera_open;
 do_close=glvar.do_close;
else
 unload=1;
 cam_open=0;
 do_close=1;
end

ph_ptr = libpointer('voidPtrPtr');

%libcall PCO_OpenCamera
if(cam_open==0)
 [errorCode,out_ptr] = calllib('PCO_CAM_SDK', 'PCO_OpenCamera', ph_ptr, 0);
 if(errorCode == 0)
  disp('PCO_OpenCamera done');
  cam_open=1;
  if((exist('glvar','var'))&& ...
     (isfield(glvar,'camera_open'))&& ...
     (isfield(glvar,'out_ptr')))
   glvar.camera_open=1;
   glvar.out_ptr=out_ptr;
  end
 else
   pco_errdisp('PCO_OpenCamera',errorCode);
  if(unload)
   unloadlibrary('PCO_CAM_SDK');
   disp('PCO_CAM_SDK unloadlibrary done');
  end
  return ;
 end
else
 if(isfield(glvar,'out_ptr'))
  out_ptr=glvar.out_ptr;
 end
end

pco_camera_load_defines();

%get Camera Description to test if camera has internal memory
cam_desc=libstruct('PCO_Description');
set(cam_desc,'wSize',cam_desc.structsize);
[errorCode,~,cam_desc] = calllib('PCO_CAM_SDK', 'PCO_GetCameraDescription', out_ptr,cam_desc);
pco_errdisp('PCO_GetCameraDescription',errorCode);

if(bitand(cam_desc.dwGeneralCapsDESC1,GENERALCAPS1_NO_RECORDER)~=0)
 errorCode=PCO_ERROR_APPLICATION_FUNCTIONNOTSUPPORTED;
 disp('function is not supported because the selected camera does not have internal memory');
 return;
end

act_recstate = uint16(10);
[errorCode,~,act_recstate] = calllib('PCO_CAM_SDK', 'PCO_GetRecordingState',out_ptr,act_recstate);
pco_errdisp('PCO_GetRecordingState',errorCode);

if(act_recstate~=0)
 errorCode=PCO_ERROR_APPLICATION_FUNCTIONNOTSUPPORTED;
 disp('function is not supported while camera is in recording state ON');
 return;
end

dwSegment=uint32(zeros(1,4));

if(exist('segment','var'))
 if((segment<1)||(segment>4))
  errorCode=PCO_ERROR_APPLICATION|PCO_ERROR_WRONGVALUE;
  disp('value of segment must be in the range from 1 to 4');
  return;
 end

 wActSeg=uint16(0);
 [errorCode,~,wActSeg]=calllib('PCO_CAM_SDK', 'PCO_GetActiveRamSegment',out_ptr,wActSeg);
 if(segment==wActSeg)
  errorCode=PCO_ERROR_APPLICATION|PCO_ERROR_WRONGVALUE;
  disp('cannot clear active segment ',int2str(segment));
  return;
 end

 disp(['clear segment ',int2str(segment)]);
 if(errorCode==PCO_NOERROR)
  [errorCode,~,dwSegment]=calllib('PCO_CAM_SDK', 'PCO_GetCameraRamSegmentSize',out_ptr,dwSegment);
  pco_errdisp('PCO_GetCameraRamSegmentSize',errorCode);
 end
 dwSegment(segment)=0;
else
 disp('reset all segments to default state');
end

if((dwSegment(1)==0)&&(dwSegment(2)==0)&&(dwSegment(3)==0)&&(dwSegment(4)==0))
 dwRamSize=uint32(0);
 wPageSize=uint16(0);
 if(errorCode==PCO_NOERROR)
  [errorCode,~,dwRamSize]=calllib('PCO_CAM_SDK', 'PCO_GetCameraRamSize',out_ptr,dwRamSize,wPageSize);
  pco_errdisp('PCO_GetCameraRamSize',errorCode);
 end
 dwSegment(1)=dwRamSize;
 if(errorCode==PCO_NOERROR)
  [errorCode,~]=calllib('PCO_CAM_SDK', 'PCO_SetActiveRamSegment',out_ptr,1);
  pco_errdisp('PCO_SetActiveRamSegment',errorCode);
 end
end

if(errorCode==PCO_NOERROR)
 [errorCode,~]=calllib('PCO_CAM_SDK', 'PCO_SetCameraRamSegmentSize',out_ptr,dwSegment);
 pco_errdisp('PCO_SetCameraRamSegmentSize',errorCode);
end

if(errorCode==PCO_NOERROR)
 [errorCode,~]=calllib('PCO_CAM_SDK', 'PCO_ArmCamera',out_ptr);
 pco_errdisp('PCO_ArmCamera',errorCode);
end

if(exist('glvar','var'))
 glvar = close_camera(out_ptr,unload,do_close,cam_open,glvar);
else
 close_camera(out_ptr,unload,do_close,cam_open);
end

end

function [glvar] = close_camera(out_ptr,unload,do_close,cam_open,glvar)
 if((do_close==1)&&(cam_open==1))
  errorCode = calllib('PCO_CAM_SDK', 'PCO_CloseCamera',out_ptr);
  if(errorCode)
   pco_errdisp('PCO_CloseCamera',errorCode);
  else
   disp('PCO_CloseCamera done');
   cam_open=0;
   if((exist('glvar','var'))&& ...
      (isfield(glvar,'camera_open'))&& ...
      (isfield(glvar,'out_ptr')))
    glvar.out_ptr=[];
    glvar.camera_open=0;
   end
  end
 end
 if((unload==1)&&(cam_open==0))
  unloadlibrary('PCO_CAM_SDK');
  disp('PCO_CAM_SDK unloadlibrary done');
  commandwindow;
 end
end


function file= fileutil_getFilelist(spec, varargin)
% FILEUTIL_GETFILELIST - Retrieves a list of header/marker/EEG files.
%
% Synopsis:
%   File= fileutil_getFilelist(SPEC, 'Property, 'Value', ...)
%
% Arguments:
%   SPEC:  CELL|CHAR   list of file names (no extension)
%
% Properties:
%   'Ext': file extension. default: 'eeg'
%   'Folder': base directory to search for files. default: BTB.RawDir
%   'RequireMatch': boolean. This function will throw an error it this
%   property is set to true and no files were found
%
% Returns:
%   FILE: filename corresponding to spec (if found). FILE may also be a cell array of file names.
%
%

%% TODO: should also handle: spec is cell array

global BTB

props = {'Ext',             'eeg',                  'CHAR';
         'Folder',           BTB.RawDir,           '!CHAR';
         'RequireMatch',     0,                     '!BOOL';
         };

if nargin==0,
  file= props; return
end

opt= opt_proplistToStruct(varargin{:});
[opt,isdefault] = opt_setDefaults(opt, props);
opt_checkProplist(opt, props);
misc_checkType(spec,'CHAR');

if isdefault.Ext,
  is= find(spec=='.', 1, 'last');
  if ~isempty(is) && is<length(spec) && is>=length(spec)-4,
    ext= spec(is+1:end);
    if ~ismember('*',ext,'legacy') && ~ismember('/',ext,'legacy'),
      opt.Ext= ext;
    end
  else
    spec= [spec '.' opt.Ext];
  end
else
  spec= [spec '.' opt.Ext];
end

if isdefault.Folder,
  switch(lower(opt.Ext)),
   case {'eeg','vhdr','vmrk'},
    opt.Folder= BTB.RawDir;
   case 'mat',
    opt.Folder= BTB.MatDir;
  end
end

[filepath, dmy]= fileparts(spec);
if ~fileutil_isAbsolutePath(spec),
  spec= [opt.Folder filesep spec];
end

dd= dir(spec);
if isempty(dd),
  if opt.RequireMatch,
    msg= sprintf('no files matching ''%s'' found', spec);
    error(msg);
  end
  file= {};
  return;
end

if length(dd)==1,
  file= strcat(filepath, filesep, dd.name);
else
  file= strcat(filepath, filesep, {dd.name});
end
if ~isdefault.Ext,
  file= strrep(file, ['.' opt.Ext], '');
end


% startup script to make Matlab aware of the GpDyn package

disp(['executing gpdyn startup script...']);

OCT = exist('OCTAVE_VERSION') ~= 0;           % check if we run Matlab or Octave

me = mfilename;                                            % what is my filename
mydir_gpdyn = which(me); mydir_gpdyn = mydir_gpdyn(1:end-2-numel(me));        % where am I located
if OCT && numel(mydir_gpdyn)==2
  if strcmp(mydir_gpdyn,'./'), mydir_gpdyn = [pwd,mydir_gpdyn(2:end)]; end
end                 % OCTAVE 3.0.x relative, MATLAB and newer have absolute path

addpath(mydir_gpdyn(1:end-1))                                  % add dirs to path
addpath([mydir_gpdyn,'gpdyn-gp-evaluation'])
addpath([mydir_gpdyn,'gpdyn-lmgp-evaluation'])
addpath([mydir_gpdyn,'gpdyn-training'])
addpath([mydir_gpdyn,'gpdyn-utilities'])
addpath([mydir_gpdyn,'gpml-matlab'])

run([mydir_gpdyn,'gpml-matlab/startup.m'])          % execute gpml startup script

clear me mydir OCT


function SM = StreamMaker()
% StreamMaker (Factory for fie/input/output Streams)
%
% A StreamMaker can make Stream PseudoObjects based on either
%  an "fid" or "filename" (and extra arguments for `fopen`).
% The StreamMaker also contains a method `isStream` to validate whether
% the value passed is a valid stream specifier.
%
% Usage
%
%  SM = StreamMaker;
%
%    Stream = SM.make(fid)
%    Stream = SM.make(filename, ...)
%
% This returns a PseudoObject Stream with the following properties:
%   - name: (file) name of the stream
%   - fid: handle (fid) of the stream
%
% and methods:
%   - print: prints to the stream, i.e. fprintf
%   - close: closes the stream, i.e. fclose
%
% It may also contain a field to automatically close the Stream when it goes
% out of scope.
%
    SM = PseudoObject('StreamMaker', ...
                      'isStream',  @isStream, ...
                      'make', @constructStream);
end

function PseudoObj = PseudoObject(T, varargin)
% construct a Pseudo-Object with type T (no other fields yet)
    PseudoObj = struct('Type', T, varargin{:});
end

function bool = isStream(value)
    bool = ischar(value) || ismember(value, [1,2,fopen('all')]);
    %TODO: allow others kinds of streams
    %     Stream -> clipboard (write on close)
    %     Stream -> string variable
    % e.g. a quick-and-dirty way would be to write the file to `tempname`
    % putting a flag to read that file back upon completion.
end

function Stream = constructStream(streamSpecifier, varargin)
    % this is the actual constructor of a stream
    if ~isStream(streamSpecifier)
        error('StreamMaker:NotAStream', 'Invalid stream specifier "%s"', ...
              streamSpecifier);
    end

    Stream = PseudoObject('Stream');
    closeAfterUse = false;
    if ischar(streamSpecifier)
        Stream.name = streamSpecifier;
        Stream.fid = fopen(Stream.name, varargin{:});
        closeAfterUse = true;
    elseif isnumeric(streamSpecifier)
        Stream.fid  = streamSpecifier;
        Stream.name = fopen(Stream.fid);
    end

    if Stream.fid == -1
        error('Stream:InvalidStream', ...
              'Unable to create stream "%s"!', streamSpecifier);
    end

    Stream.print = @(varargin) fprintf(Stream.fid, varargin{:});
    Stream.close = @() fclose(Stream.fid);
    if closeAfterUse
        Stream.closeAfterUse = onCleanup(Stream.close);
    end
end


function script = ma_updateOptimScript(x, script, variables)
    if(any(isnan(x)))
        error(sprintf('Recieved NaN from optimizer algorithm when attempting to update script with new variable values.  Generally this means the algorithm has failed in some way.\n\nPlease try a different optimizer algorithm via the menu:\n\nScript -> Execution Settings -> Optimizer Algorithm.'));
    end

    i = 1;
    for(varC = variables) %#ok<*NO4LP>
        var = varC{1};
        event = script{var.eventNum};

        xSubset = x(i:i+length(var.x0)-1);
        event = ma_updateOptimEvent(xSubset, event);

        script{var.eventNum} = event;

        i = i + length(var.x0);
    end
end


classdef PluginOptimizationVariable < AbstractOptimizationVariable
    %LvdPluginOptimizationVariable Summary of this class goes here
    %   Detailed explanation goes here

    properties
        varObj(1,1) LvdPluginOptimVarWrapper = LvdPluginOptimVarWrapper();

        lb(1,1) double = -1;
        ub(1,1) double = 1;

        useTf(1,1) = false;
    end

    methods
        function obj = PluginOptimizationVariable(varObj)
            arguments
                varObj(1,1) LvdPluginOptimVarWrapper
            end

            obj.varObj = varObj;
            obj.varObj.optVar = obj;

            obj.id = rand();
        end

        function x = getXsForVariable(obj)
            x = [];

            if(obj.useTf)
                x = obj.varObj.value;
            end
        end

        function [lb, ub] = getBndsForVariable(obj)
            lb = obj.lb(obj.useTf);
            ub = obj.ub(obj.useTf);
        end

        function [lb, ub] = getAllBndsForVariable(obj)
            lb = obj.lb;
            ub = obj.ub;
        end

        function setBndsForVariable(obj, lb, ub)
            obj.lb = lb;
            obj.ub = ub;
        end

        function useTf = getUseTfForVariable(obj)
            useTf = obj.useTf;
        end

        function setUseTfForVariable(obj, useTf)
            obj.useTf = useTf;
        end

        function updateObjWithVarValue(obj, x)
            obj.varObj.value = x;
        end

        function nameStrs = getStrNamesOfVars(obj, evtNum, varLocType)
            nameStrs = {sprintf('Plugin Variable "%s"', obj.varObj.name)};
        end
    end
end


function cost = terminalcosts(k, x, mpcModel, varargin)
    cost = 0.0;
end


function pack(descname)
%PACK Pack a descriptor to a zip file together with meta

% Copyright (C) 2016-2017 Karel Lenc
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

if nargin < 1, error('Descriptor not specified.'); end

descInfoFile = fullfile(hb_path, 'data', 'descriptors', descname, 'info.txt');
if ~exist(descInfoFile, 'file') ||...
    numel(utls.readfile(descInfoFile)) ~= 2
  fprintf('\nTo continue, we need to know few details about your submission:\n');
  submissisonName = input('Please enter submission name: ', 's');
  emailAddress = input('Please enter contact email: ', 's');
  ifd = fopen(descInfoFile, 'w');
  fprintf(ifd, '%s\n%s', submissisonName, emailAddress);
  fclose(ifd);
  fprintf('Submission info wrote to %s. Edit this file for changes.\n', ...
    descInfoFile);
end

zipFile = fullfile(hb_path(), [descname, '_descriptors.zip']);
fprintf('Packing the descriptors to %s.\n', zipFile);
zip(zipFile, fullfile(hb_path, 'data', 'descriptors', descname));

end


function combineKeypoints(expidx)

fprintf('combineKeypoints()\n');

if (ischar(expidx))
    expidx = str2double(expidx);
end

% load annolist with full size images
[~,imgidxs] = getAnnolist(expidx);

p = rcnn_exp_params(expidx);
saveTo = [fileparts(p.evalTest) '/pred_backproj'];

fname = [saveTo '/keypoints_' padZeros(num2str(imgidxs(1)),5)];
load(fname,'keypoints');
keypointsAll = keypoints;

fname = [saveTo '/bboxes_' padZeros(num2str(imgidxs(1)),5)];
load(fname,'bboxes');
bboxAll = bboxes;

for i = 1:length(imgidxs)
    fprintf('.');

    fname = [saveTo '/keypoints_' padZeros(num2str(imgidxs(i)),5)];
    load(fname,'keypoints');
    keypointsAll(i) = keypoints;

    fname = [saveTo '/bboxes_' padZeros(num2str(imgidxs(i)),5)];
    load(fname,'bboxes');
    bboxAll(i) = bboxes;

    if (~mod(i, 100))
        fprintf(' %d/%d\n',i,length(imgidxs));
    end
end
fprintf(' done\n');

fnameKeypoints = [fileparts(p.evalTest) '/keypointsAll'];
save(fnameKeypoints, 'keypointsAll');

fnameBBox = [fileparts(p.evalTest) '/bboxAll'];
save(fnameBBox, 'bboxAll');
end


function varargout = scan(varargin)
% SCAN(f, varargin) is not supported for ballfuns.

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

error('CHEBFUN:BALLFUN:SLICE:fail',...
       'Scan is not supported for ballfuns.')

end


function varargout = gzipencode(varargin)
%
% output = gzipencode(input)
%    or
% [output, info] = gzipencode(input)
%
% Compress a string or numerical array using the GZIP-compression
%
% This function depends on JVM in MATLAB or, can optionally use the ZMat
% toolbox (http://github.com/fangq/zmat)
%
% Copyright (c) 2012, Kota Yamaguchi
% URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities
%
% Modified by: Qianqian Fang (q.fang <at> neu.edu)
%
% input:
%      input: the original data, can be a string, a numerical vector or array
%
% output:
%      output: the decompressed byte stream stored in a uint8 vector; if info is
%            given, output will restore the original data's type and dimensions
%
% examples:
%      [bytes, info]=gzipencode(eye(10));
%      orig=gzipdecode(bytes,info);
%
% license:
%     BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details
%
% -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
%

if(nargin==0)
    error('you must provide at least 1 input');
end

if(exist('zmat','file')==2 || exist('zmat','file')==3)
    [varargout{1:nargout}]=zmat(varargin{1},1,'gzip');
    return;
elseif(isoctavemesh)
    error('You must install the ZMat toolbox (http://github.com/fangq/zmat) to use this function in Octave');
end

error(javachk('jvm'));

if(ischar(varargin{1}))
    varargin{1}=uint8(varargin{1});
end

input=typecast(varargin{1}(:)','uint8');

buffer = java.io.ByteArrayOutputStream();
gzip = java.util.zip.GZIPOutputStream(buffer);
gzip.write(input, 0, numel(input));
gzip.close();

varargout{1} = typecast(buffer.toByteArray(), 'uint8')';

if(nargout>1)
    varargout{2}=struct('type',class(varargin{1}),'size',size(varargin{1}),'method','gzip','status',0);
end


function [subj_descriptions, event_descriptions] = list_variables(D, varargin)
% Prints a list of variable names and descriptions for every variable, or specified variables
%
% :Usage:
% ::
%
%    print_summary(D, [optional inputs])
%
% ..
%     Author and copyright information:
%
%     Copyright (C) 2013 Tor Wager
%
%     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/>.
% ..
%
%
% :Inputs:
%
%   **D:**
%        a canlab_dataset object
%
% :Optional Inputs:
%
%   **subj:**
%        followed by a cell array of subject level var names, to only see those vars
%
%   **event:**
%        followed by a cell array of event level var names, to only see those vars
%
%   if either varargin is unspecified, all variables will be printed
%

subj_descriptions = table;
event_descriptions = table;

subj_varnames = D.Subj_Level.names;
if iscolumn(subj_varnames), subj_varnames = subj_varnames'; end % need row

svars = find(strcmp('subj', varargin));
if ~isempty(svars), subj_varnames = varargin{svars+1}; end

% Names and descriptions - Subject level
% --------------------------------------------------------------------
Var_name = subj_varnames';

clear Description

for i=1:length(subj_varnames)

    vname = subj_varnames{i};
    [var,~,~,Description{i, 1}] = get_var(D, vname);

end

if length(subj_varnames) > 0
    subj_descriptions = table(Var_name, Description);
end

fprintf('\n\n --------- SUBJECT LEVEL VARS: data_obj.Subj_Level -------- \n\n');
disp(subj_descriptions);

% Names and descriptions - Event level
% --------------------------------------------------------------------
event_varnames = D.Event_Level.names;
if iscolumn(event_varnames), event_varnames = event_varnames'; end % need row

evars = find(strcmp('event', varargin));
if ~isempty(evars), event_varnames = varargin{evars+1}; end

Var_name = event_varnames';

clear Description

for i=1:length(event_varnames)

    vname = event_varnames{i};
    [var,~,~,Description{i, 1}] = get_var(D, vname);

end

if length(event_varnames) > 0
    event_descriptions = table(Var_name, Description);
end

fprintf('\n\n --------- EVENT LEVEL VARS: data_obj.Event_Level -------- \n\n');
disp(event_descriptions);


%-----------------------------------------------------------------------
% Job configuration created by cfg_util (rev $Rev: 3355 $)
%-----------------------------------------------------------------------
matlabbatch{1}.cfg_basicio.cfg_named_input.name = 'a';
matlabbatch{1}.cfg_basicio.cfg_named_input.input = '<UNDEFINED>';
matlabbatch{2}.cfg_basicio.cfg_named_input.name = 'b';
matlabbatch{2}.cfg_basicio.cfg_named_input.input = '<UNDEFINED>';
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.a(1) = cfg_dep;
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.a(1).tname = 'Input a';
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.a(1).tgt_spec{1}.name = 'class';
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.a(1).tgt_spec{1}.value = 'cfg_entry';
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.a(1).sname = 'Named Input: a';
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.a(1).src_exbranch = substruct('.','val', '{}',{1}, '.','val', '{}',{1});
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.a(1).src_output = substruct('.','input');
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.b(1) = cfg_dep;
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.b(1).tname = 'Input b';
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.b(1).tgt_spec{1}.name = 'class';
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.b(1).tgt_spec{1}.value = 'cfg_entry';
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.b(1).sname = 'Named Input: b';
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.b(1).src_exbranch = substruct('.','val', '{}',{2}, '.','val', '{}',{1});
matlabbatch{3}.cfg_toy{1}.add2{1}.cfg_example_add1.b(1).src_output = substruct('.','input');
matlabbatch{4}.cfg_toy{1}.cfg_example_div.a(1) = cfg_dep;
matlabbatch{4}.cfg_toy{1}.cfg_example_div.a(1).tname = 'Input a';
matlabbatch{4}.cfg_toy{1}.cfg_example_div.a(1).tgt_spec = {};
matlabbatch{4}.cfg_toy{1}.cfg_example_div.a(1).sname = 'Add1: Add1: a + b';
matlabbatch{4}.cfg_toy{1}.cfg_example_div.a(1).src_exbranch = substruct('.','val', '{}',{3}, '.','val', '{}',{1}, '.','val', '{}',{1});
matlabbatch{4}.cfg_toy{1}.cfg_example_div.a(1).src_output = substruct('()',{1});
matlabbatch{4}.cfg_toy{1}.cfg_example_div.b(1) = cfg_dep;
matlabbatch{4}.cfg_toy{1}.cfg_example_div.b(1).tname = 'Input b';
matlabbatch{4}.cfg_toy{1}.cfg_example_div.b(1).tgt_spec{1}.name = 'class';
matlabbatch{4}.cfg_toy{1}.cfg_example_div.b(1).tgt_spec{1}.value = 'cfg_entry';
matlabbatch{4}.cfg_toy{1}.cfg_example_div.b(1).sname = 'Named Input: b';
matlabbatch{4}.cfg_toy{1}.cfg_example_div.b(1).src_exbranch = substruct('.','val', '{}',{2}, '.','val', '{}',{1});
matlabbatch{4}.cfg_toy{1}.cfg_example_div.b(1).src_output = substruct('.','input');
matlabbatch{5}.cfg_basicio.cfg_assignin.name = '<UNDEFINED>';
matlabbatch{5}.cfg_basicio.cfg_assignin.output(1) = cfg_dep;
matlabbatch{5}.cfg_basicio.cfg_assignin.output(1).tname = 'Output Item';
matlabbatch{5}.cfg_basicio.cfg_assignin.output(1).tgt_spec = {};
matlabbatch{5}.cfg_basicio.cfg_assignin.output(1).sname = 'div: a div b: mod';
matlabbatch{5}.cfg_basicio.cfg_assignin.output(1).src_exbranch = substruct('.','val', '{}',{4}, '.','val', '{}',{1});
matlabbatch{5}.cfg_basicio.cfg_assignin.output(1).src_output = substruct('.','mod');


function data = parse_json(string)
% DATA = PARSE_JSON(string)
% This function parses a JSON string and returns a cell array with the
% parsed data. JSON objects are converted to structures and JSON arrays are
% converted to cell arrays.

% F. Glineur, 2009
% (inspired by the JSON parser by Joel Feenstra on MATLAB File Exchange
% (http://www.mathworks.com/matlabcentral/fileexchange/20565) but with
% faster handling of strings)

% Copyright (c) 2011, François Glineur
% 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
%
% 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.

assert(ischar(string), 'Input must be a string or a filename.');
if exist(string, 'file')
  string = fileread(string);
end

pos = 1;
len = length(string);
% String delimiters and escape characters are identified beforehand to improve speed
esc = regexp(string, '["\\]'); index_esc = 1; len_esc = length(esc);

if pos <= len
  switch(next_char)
    case '{'
      data = parse_object;
    case '['
      data = parse_array;
    otherwise
      error_pos('Outer level structure must be an object or an array');
  end
end

  function object = parse_object
    parse_char('{');
    object = [];
    if next_char ~= '}'
      while 1
        str = parse_string;
        if isempty(str)
          error_pos('Name of value at position %d cannot be empty');
        end
        parse_char(':');
        val = parse_value;
        object.(valid_field(str)) = val;
        if next_char == '}'
          break;
        end
        parse_char(',');
      end
    end
    parse_char('}');
  end

  function object = parse_array
    parse_char('[');
    object = cell(0, 1);
    if next_char ~= ']'
      while 1
        val = parse_value;
        object{end+1} = val;
        if next_char == ']'
          break;
        end
        parse_char(',');
      end
    end
    parse_char(']');
  end

  function parse_char(c)
    skip_whitespace;
    if pos > len || string(pos) ~= c
      error_pos(sprintf('Expected %c at position %%d', c));
    else
      pos = pos + 1;
      skip_whitespace;
    end
  end

  function c = next_char
    skip_whitespace;
    if pos > len
      c = [];
    else
      c = string(pos);
    end
  end

  function skip_whitespace
    while pos <= len && isspace(string(pos))
      pos = pos + 1;
    end
  end

  function str = parse_string
    if string(pos) ~= '"'
      error_pos('String starting with " expected at position %d');
    else
      pos = pos + 1;
    end
    str = '';
    while pos <= len
      while index_esc <= len_esc && esc(index_esc) < pos
        index_esc = index_esc + 1;
      end
      if index_esc > len_esc
        str = [str string(pos:end)];
        pos = len + 1;
        break;
      else
        str = [str string(pos:esc(index_esc)-1)];
        pos = esc(index_esc);
      end
      switch string(pos)
        case '"'
          pos = pos + 1;
          return;
        case '\'
          if pos+1 > len
            error_pos('End of file reached right after escape character');
          end
          pos = pos + 1;
          switch string(pos)
            case {'"' '\' '/'}
              str(end+1) = string(pos);
              pos = pos + 1;
            case {'b' 'f' 'n' 'r' 't'}
              str(end+1) = sprintf(['\' string(pos)]);
              pos = pos + 1;
            case 'u'
              if pos+4 > len
                error_pos('End of file reached in escaped unicode character');
              end
              str(end+1:end+6) = string(pos-1:pos+4);
              pos = pos + 5;
          end
        otherwise % should never happen
          str(end+1) = string(pos);
          pos = pos + 1;
      end
    end
    error_pos('End of file while expecting end of string');
  end

  function num = parse_number
    [num, one, err, delta] = sscanf(string(pos:min(len,pos+20)), '%f', 1); % TODO : compare with json(pos:end)
    if ~isempty(err)
      error_pos('Error reading number at position %d');
    end
    pos = pos + delta-1;
  end

  function val = parse_value
    switch(string(pos))
      case '"'
        val = parse_string;
        return;
      case '['
        val = parse_array;
        return;
      case '{'
        val = parse_object;
        return;
      case {'-','0','1','2','3','4','5','6','7','8','9'}
        val = parse_number;
        return;
      case 't'
        if pos+3 <= len && strcmpi(string(pos:pos+3), 'true')
          val = true;
          pos = pos + 4;
          return;
        end
      case 'f'
        if pos+4 <= len && strcmpi(string(pos:pos+4), 'false')
          val = false;
          pos = pos + 5;
          return;
        end
      case 'n'
        if pos+3 <= len && strcmpi(string(pos:pos+3), 'null')
          val = [];
          pos = pos + 4;
          return;
        end
    end
    error_pos('Value expected at position %d');
  end

  function error_pos(msg)
    poss = max(min([pos-15 pos-1 pos pos+20],len),1);
    if poss(3) == poss(2)
      poss(3:4) = poss(2)+[0 -1];         % display nothing after
    end
    msg = [sprintf(msg, pos) ' : ... ' string(poss(1):poss(2)) '<error>' string(poss(3):poss(4)) ' ... '];
    ME = MException('JSONparser:invalidFormat', msg);
    throw(ME);
  end

  function str = valid_field(str)
    % From MATLAB doc: field names must begin with a letter, which may be
    % followed by any combination of letters, digits, and underscores.
    % Invalid characters will be converted to underscores, and the prefix
    % "alpha_" will be added if first character is not a letter.
    if ~isletter(str(1))
      str = ['alpha_' str];
    end
    str(~isletter(str) & ~('0' <= str & str <= '9')) = '_';
  end

end


function [mCatalog] = import_start(sFilterDir,FilePath)
    %GUI file handler (used for MapSeis)
    %13.04.14: small fix allowing to pass in the filepath directly to avoid

    if nargin<2
        FilePath=[];
    end

    % Default return value
    mCatalog = nan;

    % Check if filter directory ends with the appropriate directory separator
    sLastChar = sFilterDir(length(sFilterDir));
    if ~(sLastChar == filesep)
        sFilterDir = [sFilterDir filesep];
    end

    % Get directory in filter directory
    vrDir = dir(sFilterDir);
    if isempty(vrDir)
        errordlg('Directory does not exist');
        return;
    elseif length(vrDir) == 2
        errordlg('Directory is empty. No Filters found.');
        return;
    end

    % Initialize filter list
    cFilter = {};
    % Counter for detected filters
    nFilter = 1;

    for nCnt = 1:length(vrDir)
        % Check for directories
        if ~((strcmp(vrDir(nCnt).name, '.')) || (strcmp(vrDir(nCnt).name, '..')))
            % Get name of file
            sName = vrDir(nCnt).name;
            nPos = strfind(sName, '.m');
            % Is it a .m-file
            if ~isempty(nPos)
                sName = sName(1:(nPos - 1));
                try
                    % Is it an import filter
                    sDescription = feval(sName, 0);
                catch
                    sDescription = [];
                end
                % Is it really an import filter
                if ischar(sDescription)
                    % Insert it into filter list
                    cFilter{nFilter, 1} = sDescription;
                    cFilter{nFilter, 2} = sName;
                    nFilter = nFilter + 1;
                end
            end
        end
    end

    % Charmatrix with names of filters
    mFilterNames = char(cFilter{:,1});
    mFilterFiles = char(cFilter{:,2});

    % Invoke the user interface
    hDialog = import_dialog(mFilterNames, mFilterFiles, sFilterDir);

    % Analyze Output
    if ~ishandle(hDialog)
        answer = 0;
    else
        handles = guidata(hDialog);
        answer = handles.answer;
        % OK pressed
        if answer == 1
            % Get the values from figure
            nFilter = get(handles.lstFilter, 'Value');
            % Remove figure from memory
            delete(hDialog);
            % Get the catalog file
            if isempty(FilePath)
                [newfile, newpath] = uigetfile('*.*', 'Choose catalog datafile');
            else
                [pathstr, name, ext] = fileparts(FilePath);
                newpath =[pathstr,filesep];
                newfile = [name,ext];
            end

            % Cancel pressed?
            if ~(isequal(newfile, 0) | isequal(newpath, 0))
                newfile = [newpath newfile];
                % Everything ok?
                if length(newfile) > 1
                    mCatalog = feval(cFilter{nFilter,2}, 1, newfile);
                end
            end
        else
            % Remove figure from memory
            delete(hDialog);
        end
    end

end