%kkdbmupdate 'print, delete, or update (ascii) DBM key value'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros kdbmupdate.pane file
%
% Parameters:
% InputFile: dbm 'DBM file', required: 'DBM file'
% String: key 'Key Name', default: ' ': 'DBM key'
% Toggle: printval 'Print Value', default: 0: 'print value of key'
% Toggle: delete 'Delete Key', default: 0: 'delete key'
% String: update 'Update Value', default: ' ': 'update value'
%
% Example: kkdbmupdate(dbm, {'dbm','';'key',' ';'printval',0;'delete',0;'update',' '})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% kdbmupdate - print, delete, or update (ascii) DBM key value
%
%  DESCRIPTION
%
%
%
%  EXAMPLES
%
%  "SEE ALSO"
%
%  RESTRICTIONS
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI")  All rights reserved.
%

function varargout = kkdbmupdate(varargin)
if nargin ==0
  Inputs={};arglist={'',''};
elseif nargin ==1
  Inputs=varargin{1};arglist={'',''};
elseif nargin ==2
  Inputs=varargin{1}; arglist=varargin{2};
else error('Usage: [out1,..] = kkdbmupdate(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'dbm', '__input';'key', ' ';'printval', 0;'delete', 0;'update', ' '};
maxval={0,0,0,0,0};
minval={0,0,0,0,0};
istoggle=[0,0,1,1,1];
was_set=istoggle * 0;
paramtype={'InputFile','String','Toggle','Toggle','String'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=0; nextinput=1; nextoutput=1;
  for ii=1:size(arglist,1)
  wasmatched=0;
  for jj=1:size(narglist,1)
   if strcmp(arglist{ii,1},narglist{jj,1})  % a given argument was matched to the possible arguments
     wasmatched = 1;
     was_set(jj) = 1;
     if strcmp(narglist{jj,2}, '__input')
      if (nextinput > length(Inputs))
        error(['Input ' narglist{jj,1} ' has no corresponding input!']);
      end
      narglist{jj,2} = 'OK_in';
      nextinput = nextinput + 1;
     elseif strcmp(narglist{jj,2}, '__output')
      if (nextoutput > nargout)
        error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
      end
      if (isempty(arglist{ii,2}))
        narglist{jj,2} = 'OK_out';
      else
        narglist{jj,2} = arglist{ii,2};
      end

      nextoutput = nextoutput + 1;
      if (minval{jj} == 0)
         NumReqOutputs = NumReqOutputs - 1;
      end
     elseif isstr(arglist{ii,2})
      narglist{jj,2} = arglist{ii,2};
     else
        if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
            error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
        end
        if (minval{jj} ~= 0 | maxval{jj} ~= 0)
          if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
            error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
          elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
            error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
          elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
            error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
          elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
            error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
            error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
          elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
            error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
          end
        end
     end
     if ~strcmp(narglist{jj,2},'OK_out') &  ~strcmp(narglist{jj,2},'OK_in')
       narglist{jj,2} = arglist{ii,2};
     end
   end
   end
   if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
        error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
   end
end
% match the remaining inputs/outputs to the unused arguments and test for missing required inputs
 for jj=1:size(narglist,1)
     if  strcmp(paramtype{jj}, 'Toggle')
        if (narglist{jj,2} ==0)
          narglist{jj,1} = '';
        end;
        narglist{jj,2} = '';
     end;
     if  ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
          narglist{jj,1} = '';
          narglist{jj,2} = '';
     end;
     if strcmp(narglist{jj,2}, '__input')
      if (minval{jj} == 0)  % meaning this input is required
        if (nextinput > size(Inputs))
           error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
        else
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        end
      else  % this is an optional input
        if (nextinput <= length(Inputs))
          narglist{jj,2} = 'OK_in';
          nextinput = nextinput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end;
     else
     if strcmp(narglist{jj,2}, '__output')
      if (minval{jj} == 0) % this is a required output
        if (nextoutput > nargout & nargout > 1)
           error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
        else
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
          NumReqOutputs = NumReqOutputs-1;
        end
      else % this is an optional output
        if (nargout - nextoutput >= NumReqOutputs)
          narglist{jj,2} = 'OK_out';
          nextoutput = nextoutput + 1;
        else
          narglist{jj,1} = '';
          narglist{jj,2} = '';
        end;
      end
     end
  end
end
if nargout
   varargout = cell(1,nargout);
else
  varargout = cell(0);
end
global KhorosRoot
if exist('KhorosRoot') && ~isempty(KhorosRoot)
w=['"' KhorosRoot];
else
if ispc
  w='"C:\Program Files\dip\khorosBin\';
else
[s,w] = system('which cantata');
w=['"' w(1:end-8)];
end
end
callKhoros([w 'kdbmupdate"  '],Inputs,narglist);


%RDIVIDE Right dataset divide. Dataset overload


min_cost_0_4000 = min_cost_0;
min_cost_1_4000 = min_cost_1;
min_cost_2_4000 = min_cost_2;
min_cost_3_4000 = min_cost_3;
min_cost_4_4000 = min_cost_4;

totalNum_0_4000 = totalNum_0;
totalNum_1_4000 = totalNum_1;
totalNum_2_4000 = totalNum_2;
totalNum_3_4000 = totalNum_3;
totalNum_4_4000 = totalNum_4;


function myResize()
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR 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.
%
% CERR 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 CERR.  If not, see <http://www.gnu.org/licenses/>.

tables = findobj('tag', 'UITable');
for i=1:length(tables)
    table('redraw', tables(i));
end


function add_io(hRD,type)

% add AXI4 and AXI4-Lite slave interfaces
hRD.addAXI4SlaveInterface( ...
    'InterfaceConnection', 'axi_cpu_interconnect/M09_AXI', ...
    'BaseAddress',         '0x43C00000', ...
    'MasterAddressSpace',  'sys_ps7/Data');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Rx Reference design interfaces
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if contains(lower(type),'rx')
    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data Valid OUT', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'dut_data_valid', ...
        'PortWidth',      1, ...
        'InterfaceConnection', 'util_ad9361_adc_pack/adc_valid_0', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 0 OUT', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'dut_data_0', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_pack/adc_data_0', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 1 OUT', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'dut_data_1', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_pack/adc_data_1', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 2 OUT', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'dut_data_2', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_pack/adc_data_2', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 3 OUT', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'dut_data_3', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_pack/adc_data_3', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 4 OUT', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'dut_data_4', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_pack/adc_data_4', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 5 OUT', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'dut_data_5', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_pack/adc_data_5', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 6 OUT', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'dut_data_6', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_pack/adc_data_6', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 7 OUT', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'dut_data_7', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_pack/adc_data_7', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 ADC Data I0', ...
        'InterfaceType',  'IN', ...
        'PortName',       'sys_wfifo_0_dma_wdata', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_fifo/dout_data_0', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 ADC Data Q0', ...
        'InterfaceType',  'IN', ...
        'PortName',       'sys_wfifo_1_dma_wdata', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_fifo/dout_data_1', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 ADC Data I1', ...
        'InterfaceType',  'IN', ...
        'PortName',       'sys_wfifo_2_dma_wdata', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_fifo/dout_data_2', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 ADC Data Q1', ...
        'InterfaceType',  'IN', ...
        'PortName',       'sys_wfifo_3_dma_wdata', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_fifo/dout_data_3', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 ADC Data I2', ...
        'InterfaceType',  'IN', ...
        'PortName',       'sys_wfifo_4_dma_wdata', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_fifo/dout_data_4', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 ADC Data Q2', ...
        'InterfaceType',  'IN', ...
        'PortName',       'sys_wfifo_5_dma_wdata', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_fifo/dout_data_5', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 ADC Data I3', ...
        'InterfaceType',  'IN', ...
        'PortName',       'sys_wfifo_6_dma_wdata', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_fifo/dout_data_6', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 ADC Data Q3', ...
        'InterfaceType',  'IN', ...
        'PortName',       'sys_wfifo_7_dma_wdata', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_adc_fifo/dout_data_7', ...
        'IsRequired',     false);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Tx Reference design interfaces
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if contains(lower(type),'tx')
    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 DAC Data I0', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'axi_ad9361_0_dac_data_i0', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'axi_ad9361_dac_fifo/din_data_0', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 DAC Data Q0', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'axi_ad9361_0_dac_data_q0', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'axi_ad9361_dac_fifo/din_data_1', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 DAC Data I1', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'axi_ad9361_0_dac_data_i1', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'axi_ad9361_dac_fifo/din_data_2', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 DAC Data Q1', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'axi_ad9361_0_dac_data_q1', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'axi_ad9361_dac_fifo/din_data_3', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 DAC Data I2', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'axi_ad9361_1_dac_data_i0', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'axi_ad9361_dac_fifo/din_data_4', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 DAC Data Q2', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'axi_ad9361_1_dac_data_q0', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'axi_ad9361_dac_fifo/din_data_5', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 DAC Data I3', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'axi_ad9361_1_dac_data_i1', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'axi_ad9361_axi_ad9361_dac_fifo/din_data_6', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'AD9361 DAC Data Q3', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'axi_ad9361_1_dac_data_q1', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'axi_ad9361_axi_ad9361_dac_fifo/din_data_7', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Load Tx Data OUT', ...
        'InterfaceType',  'OUT', ...
        'PortName',       'util_ad9361_dac_upack_dac_valid_00', ...
        'PortWidth',      1, ...
        'InterfaceConnection', 'axi_ad9361_dac_fifo/din_valid_in_0', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 0 IN', ...
        'InterfaceType',  'IN', ...
        'PortName',       'util_ad9361_dac_upack_dac_data_00', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_dac_upack/dac_data_0', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 1 IN', ...
        'InterfaceType',  'IN', ...
        'PortName',       'util_ad9361_dac_upack_dac_data_01', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_dac_upack/dac_data_1', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 2 IN', ...
        'InterfaceType',  'IN', ...
        'PortName',       'util_ad9361_dac_upack_dac_data_02', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_dac_upack/dac_data_2', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 3 IN', ...
        'InterfaceType',  'IN', ...
        'PortName',       'util_ad9361_dac_upack_dac_data_03', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_dac_upack/dac_data_3', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 4 IN', ...
        'InterfaceType',  'IN', ...
        'PortName',       'util_ad9361_dac_upack_dac_data_04', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_dac_upack/dac_data_4', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 5 IN', ...
        'InterfaceType',  'IN', ...
        'PortName',       'util_ad9361_dac_upack_dac_data_05', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_dac_upack/dac_data_5', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 6 IN', ...
        'InterfaceType',  'IN', ...
        'PortName',       'util_ad9361_dac_upack_dac_data_06', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_dac_upack/dac_data_6', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Data 7 IN', ...
        'InterfaceType',  'IN', ...
        'PortName',       'util_ad9361_dac_upack_dac_data_07', ...
        'PortWidth',      16, ...
        'InterfaceConnection', 'util_ad9361_dac_upack/dac_data_7', ...
        'IsRequired',     false);

    hRD.addInternalIOInterface( ...
        'InterfaceID',    'IP Valid Tx Data IN', ...
        'InterfaceType',  'IN', ...
        'PortName',       'util_dac_unpack_upack_valid_00', ...
        'PortWidth',      1, ...
        'InterfaceConnection', 'util_ad9361_dac_upack/dac_valid_out_0', ...
        'IsRequired',     false);
end


classdef NicoletFile < handle
  % NICOLETFILE  Reading Nicolet .e files.
  %
  %   GETTING DATA
  %   You can load data from the .e file using the GETDATA method. The
  %   inputs to the method are the object, the segment of the data file
  %   that you want to load data from, the min, and max index you want to
  %   retrieve, and a vector of channels that you want to retrieve.
  %
  %   Example:
  %     OUT = GETDATA(OBJ, 1, [1 1000], 1:10) will return the first 1000
  %     values on the first 10 channels of the first segment of the file.
  %
  %   GETTING Nr OF SAMPLES
  %     Use the GETNRSAMPLES method to find the number of samples per
  %     channel in each data segment.
  %
  %   WARNING!
  %   The .e format allows for changes in the TimeSeries map during the
  %   recording. This results in multiple TSINFO structures. Depending on
  %   where these structures are located in the .e file, the appropriate
  %   TSINFO structure should be used. However, there seems to be a bug in
  %   the Nicolet .e file writer which sometimes renders the TSINFO structures
  %   unreadable on disk (verify with hex-edit).

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Copyright 2013 Trustees of the University of Pennsylvania
  %
  % Licensed under the Apache License, Version 2.0 (the "License");
  % you may not use this file except in compliance with the License.
  % You may obtain a copy of the License at
  %
  % http://www.apache.org/licenses/LICENSE-2.0
  %
  % Unless required by applicable law or agreed to in writing, software
  % distributed under the License is distributed on an "AS IS" BASIS,
  % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  % See the License for the specific language governing permissions and
  % limitations under the License.
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  % Joost Wagenaar, Jan 2015
  % Cristian Donos, Dec 2015
  % Jan Brogger, Jun 2016
  % Callum Stewart, Apr 2018

  properties
    fileName
    patientInfo
    segments
    eventMarkers
  end

  properties (Hidden)
    sections
    index
    sigInfo
    tsInfos
    chInfo
    notchFreq
    montage
    Qi
    Qii
    allIndexIDs
    useTSinfoIdx = 1
  end

  properties (Constant, Hidden)
   LABELSIZE = 32
   TSLABELSIZE = 64
   UNITSIZE = 16
   ITEMNAMESIZE  = 64
  end

  methods
    function obj = NicoletFile(filename)
      h = fopen(filename,'r','ieee-le');

      [folder, name, ext] = fileparts(filename);
      assert(strcmp(ext,'.e'), 'File extention must be .e');
      if isempty(folder)
        filename = fullfile(pwd,filename);
      end

      obj.fileName = filename;
      % Get init
      misc1 = fread(h,5, 'uint32'); %#ok<NASGU>
      unknown = fread(h,1,'uint32'); %#ok<NASGU>
      indexIdx = fread(h,1,'uint32');

      % Get TAGS structure and Channel IDS
      fseek(h, 172,'bof');
      nrTags = fread(h,1, 'uint32');
      Tags = struct();
      for i = 1:nrTags
        Tags(i).tag = deblank(cast(fread(h, 40, 'uint16'),'char')');
        Tags(i).index = fread(h,1,'uint32');
        switch Tags(i).tag
          case 'ExtraDataTags'
            Tags(i).IDStr = 'ExtraDataTags';
          case 'SegmentStream'
            Tags(i).IDStr = 'SegmentStream';
          case 'DataStream'
            Tags(i).IDStr = 'DataStream';
          case 'InfoChangeStream'
            Tags(i).IDStr = 'InfoChangeStream';
          case 'InfoGuids'
            Tags(i).IDStr = 'InfoGuids';
          case '{A271CCCB-515D-4590-B6A1-DC170C8D6EE2}'
            Tags(i).IDStr = 'TSGUID';
          case '{8A19AA48-BEA0-40D5-B89F-667FC578D635}'
            Tags(i).IDStr = 'DERIVATIONGUID';
          case '{F824D60C-995E-4D94-9578-893C755ECB99}'
            Tags(i).IDStr = 'FILTERGUID';
          case '{02950361-35BB-4A22-9F0B-C78AAA5DB094}'
            Tags(i).IDStr = 'DISPLAYGUID';
          case '{8E94EF21-70F5-11D3-8F72-00105A9AFD56}'
            Tags(i).IDStr = 'FILEINFOGUID';
          case '{E4138BC0-7733-11D3-8685-0050044DAAB1}'
            Tags(i).IDStr = 'SRINFOGUID';
          case '{C728E565-E5A0-4419-93D2-F6CFC69F3B8F}'
            Tags(i).IDStr = 'EVENTTYPEINFOGUID';
          case '{D01B34A0-9DBD-11D3-93D3-00500400C148}'
            Tags(i).IDStr = 'AUDIOINFOGUID';
          case '{BF7C95EF-6C3B-4E70-9E11-779BFFF58EA7}'
            Tags(i).IDStr = 'CHANNELGUID';
          case '{2DEB82A1-D15F-4770-A4A4-CF03815F52DE}'
            Tags(i).IDStr = 'INPUTGUID';
          case '{5B036022-2EDC-465F-86EC-C0A4AB1A7A91}'
            Tags(i).IDStr = 'INPUTSETTINGSGUID';
          case '{99A636F2-51F7-4B9D-9569-C7D45058431A}'
            Tags(i).IDStr = 'PHOTICGUID';
          case '{55C5E044-5541-4594-9E35-5B3004EF7647}'
            Tags(i).IDStr = 'ERRORGUID';
          case '{223A3CA0-B5AC-43FB-B0A8-74CF8752BDBE}'
            Tags(i).IDStr = 'VIDEOGUID';
          case '{0623B545-38BE-4939-B9D0-55F5E241278D}'
            Tags(i).IDStr = 'DETECTIONPARAMSGUID';
          case '{CE06297D-D9D6-4E4B-8EAC-305EA1243EAB}'
            Tags(i).IDStr = 'PAGEGUID';
          case '{782B34E8-8E51-4BB9-9701-3227BB882A23}'
            Tags(i).IDStr = 'ACCINFOGUID';
          case '{3A6E8546-D144-4B55-A2C7-40DF579ED11E}'
            Tags(i).IDStr = 'RECCTRLGUID';
          case '{D046F2B0-5130-41B1-ABD7-38C12B32FAC3}'
            Tags(i).IDStr = 'GUID TRENDINFOGUID';
          case '{CBEBA8E6-1CDA-4509-B6C2-6AC2EA7DB8F8}'
            Tags(i).IDStr = 'HWINFOGUID';
          case '{E11C4CBA-0753-4655-A1E9-2B2309D1545B}'
            Tags(i).IDStr = 'VIDEOSYNCGUID';
          case '{B9344241-7AC1-42B5-BE9B-B7AFA16CBFA5}'
            Tags(i).IDStr = 'SLEEPSCOREINFOGUID';
          case '{15B41C32-0294-440E-ADFF-DD8B61C8B5AE}'
            Tags(i).IDStr = 'FOURIERSETTINGSGUID';
          case '{024FA81F-6A83-43C8-8C82-241A5501F0A1}'
            Tags(i).IDStr = 'SPECTRUMGUID';
          case '{8032E68A-EA3E-42E8-893E-6E93C59ED515}'
            Tags(i).IDStr = 'SIGNALINFOGUID';
          case '{30950D98-C39C-4352-AF3E-CB17D5B93DED}'
            Tags(i).IDStr = 'SENSORINFOGUID';
          case '{F5D39CD3-A340-4172-A1A3-78B2CDBCCB9F}'
            Tags(i).IDStr = 'DERIVEDSIGNALINFOGUID';
          case '{969FBB89-EE8E-4501-AD40-FB5A448BC4F9}'
            Tags(i).IDStr = 'ARTIFACTINFOGUID';
          case '{02948284-17EC-4538-A7FA-8E18BD65E167}'
            Tags(i).IDStr = 'STUDYINFOGUID';
          case '{D0B3FD0B-49D9-4BF0-8929-296DE5A55910}'
            Tags(i).IDStr = 'PATIENTINFOGUID';
          case '{7842FEF5-A686-459D-8196-769FC0AD99B3}'
            Tags(i).IDStr = 'DOCUMENTINFOGUID';
          case '{BCDAEE87-2496-4DF4-B07C-8B4E31E3C495}'
            Tags(i).IDStr = 'USERSINFOGUID';
          case '{B799F680-72A4-11D3-93D3-00500400C148}'
            Tags(i).IDStr = 'EVENTGUID';
          case '{AF2B3281-7FCE-11D2-B2DE-00104B6FC652}'
            Tags(i).IDStr = 'SHORTSAMPLESGUID';
          case '{89A091B3-972E-4DA2-9266-261B186302A9}'
            Tags(i).IDStr = 'DELAYLINESAMPLESGUID';
          case '{291E2381-B3B4-44D1-BB77-8CF5C24420D7}'
            Tags(i).IDStr = 'GENERALSAMPLESGUID';
          case '{5F11C628-FCCC-4FDD-B429-5EC94CB3AFEB}'
            Tags(i).IDStr = 'FILTERSAMPLESGUID';
          case '{728087F8-73E1-44D1-8882-C770976478A2}'
            Tags(i).IDStr = 'DATEXDATAGUID';
          case '{35F356D9-0F1C-4DFE-8286-D3DB3346FD75}'
            Tags(i).IDStr = 'TESTINFOGUID';

          otherwise
            if isstrprop(Tags(i).tag, 'digit')
              Tags(i).IDStr = num2str(Tags(i).tag);
            else
              Tags(i).IDStr = 'UNKNOWN';
            end
        end

      end

      obj.sections = Tags;

      %% QI index
      fseek(h, 172208,'bof');
      obj.Qi=struct();
      obj.Qi.nrEntries = fread(h,1,'uint32');
      obj.Qi.misc1 = fread(h,1,'uint32');
      obj.Qi.indexIdx = fread(h,1,'uint32');
      obj.Qi.misc3 = fread(h,1,'uint32');
      obj.Qi.LQi = fread(h,1,'uint64')';
      obj.Qi.firstIdx = fread(h,nrTags,'uint64');

      % Don't know what this index is for... Not required to get data and
      % can be huge...

%       fseek(h, 188664,'bof');
%       Qindex  = struct();
%       for i = 1:obj.Qi.LQi
% %         Qindex(i).ftel = ftell(h);
%         Qindex(i).index = fread(h,2,'uint16')';  %4
%         Qindex(i).misc1 = fread(h,1,'uint32');   %8
%         Qindex(i).indexIdx = fread(h,1,'uint32'); %12
%         Qindex(i).misc2 = fread(h,3,'uint32')'; %24
%         Qindex(i).sectionIdx = fread(h,1,'uint32');%28
%         Qindex(i).misc3 = fread(h,1,'uint32'); %32
%         Qindex(i).offset = fread(h,1,'uint64'); % 40
%         Qindex(i).blockL = fread(h,1,'uint32');%44
%         Qindex(i).dataL = fread(h,1,'uint32')';%48
%       end
%       obj.Qi.index = Qindex;

      %% Get Main Index:
      % Index consists of multiple blocks, after each block is the pointer
      % to the next block. Total number of entries is in obj.Qi.nrEntries

      Index = struct();
      curIdx = 0;
      nextIndexPointer = indexIdx;
      fprintf('Parsing index ');
      curIdx2 = 1;
      while curIdx < obj.Qi.nrEntries
        if mod(curIdx2,20)
          fprintf('.');
        else
          fprintf('\n.');
        end

        fseek(h, nextIndexPointer, 'bof');
        nrIdx = fread(h,1, 'uint64');
        Index(curIdx + nrIdx).sectionIdx = 0;   % Preallocate next set of indices
        var = fread(h,3*nrIdx, 'uint64');
        for i = 1: nrIdx
%           Index(curIdx + i).sectionIdx = fread(h,1, 'uint64');
%           Index(curIdx + i).offset = fread(h,1, 'uint64');
%           Index(curIdx + i).blockL = fread(h,1, 'uint32');
%           Index(curIdx + i).sectionL = fread(h,1, 'uint32');
          Index(curIdx + i).sectionIdx = var(3*(i-1)+1);
          Index(curIdx + i).offset = var(3*(i-1)+2);
          Index(curIdx + i).blockL = mod(var(3*(i-1)+3),2^32);
          Index(curIdx + i).sectionL = round(var(3*(i-1)+3)/2^32);
        end
        nextIndexPointer = fread(h,1, 'uint64');
        curIdx = curIdx + i;
        curIdx2=curIdx2+1;

      end
      fprintf('done\n');
      obj.index = Index;
      obj.allIndexIDs = [obj.index.sectionIdx];

    %---READ DYNAMIC PACKETS---%
    dynamicPackets = struct();
    indexIdx = Tags(find(strcmp({Tags.IDStr},'InfoChangeStream'),1)).index;
    offset = Index(indexIdx).offset;
    nrDynamicPackets = Index(indexIdx).sectionL / 48;
    fseek(h, offset, 'bof');

    %Read first only the dynamic packets structure without actual data
    for i = 1: nrDynamicPackets
        dynamicPackets(i).offset = offset+i*48;
        guidmixed = fread(h,16, 'uint8')';
        guidnonmixed = [guidmixed(04), guidmixed(03), guidmixed(02), guidmixed(01), ...
                        guidmixed(06), guidmixed(05), guidmixed(08), guidmixed(07), ...
                        guidmixed(09), guidmixed(10), guidmixed(11), guidmixed(12), ...
                        guidmixed(13), guidmixed(14), guidmixed(15), guidmixed(16)];
        dynamicPackets(i).guid = num2str(guidnonmixed, '%02X');
        dynamicPackets(i).guidAsStr = sprintf('{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}', guidnonmixed);
        dynamicPackets(i).date = datenum(1899,12,31) + fread(h,1,'double');
        dynamicPackets(i).datefrac = fread(h,1,'double');
        dynamicPackets(i).internalOffsetStart = fread(h,1, 'uint64')';
        dynamicPackets(i).packetSize = fread(h,1, 'uint64')';
        dynamicPackets(i).data = zeros(0, 1,'uint8');

        switch dynamicPackets(i).guid
            case 'BF7C95EF6C3B4E709E11779BFFF58EA7'
               dynamicPackets(i).IDStr = 'CHANNELGUID';
            case '8A19AA48BEA040D5B89F667FC578D635'
                dynamicPackets(i).IDStr = 'DERIVATIONGUID';
            case 'F824D60C995E4D949578893C755ECB99'
                dynamicPackets(i).IDStr = 'FILTERGUID';
            case '0295036135BB4A229F0BC78AAA5DB094'
                dynamicPackets(i).IDStr = 'DISPLAYGUID';
            case '782B34E88E514BB997013227BB882A23'
                dynamicPackets(i).IDStr = 'ACCINFOGUID';
            case 'A271CCCB515D4590B6A1DC170C8D6EE2'
                dynamicPackets(i).IDStr = 'TSGUID';
            case 'D01B34A09DBD11D393D300500400C148'
                dynamicPackets(i).IDStr = 'AUDIOINFOGUID';
            otherwise
                dynamicPackets(i).IDStr = 'UNKNOWN';
        end
    end

    %Then read the actual data from the pointers above
    for i = 1: nrDynamicPackets
        %Look up the GUID of this dynamic packet in the Tags
        % to find the section index

        infoIdx = Tags(find(strcmp({Tags.tag},dynamicPackets(i).guidAsStr),1)).index;

        %Matching index segments
        indexInstances = Index([Index.sectionIdx] == infoIdx);

        %Then, treat all these sections as one contiguous memory block
        % and grab this packet across these instances

        internalOffset = 0;
        remainingDataToRead = dynamicPackets(i).packetSize;
        %disp(['Target packet ' dynamicPackets(i).IDStr ' : ' num2str(dynamicPackets(i).internalOffsetStart) ' to ' num2str(dynamicPackets(i).internalOffsetStart+dynamicPackets(i).packetSize) ' target read length ' num2str(remainingDataToRead)]);
        currentTargetStart = dynamicPackets(i).internalOffsetStart;
        for j = 1: size(indexInstances,2)
            currentInstance = indexInstances(j);

            %hitInThisSegment = '';
            if (internalOffset <= currentTargetStart) && (internalOffset+currentInstance.sectionL) >= currentTargetStart

                startAt = currentTargetStart;
                stopAt =  min(startAt+remainingDataToRead, internalOffset+currentInstance.sectionL);
                readLength = stopAt-startAt;

                filePosStart = currentInstance.offset+startAt-internalOffset;
                fseek(h,filePosStart, 'bof');
                dataPart = fread(h,readLength,'uint8=>uint8');
                dynamicPackets(i).data = cat(1, dynamicPackets(i).data, dataPart);

                %hitInThisSegment = ['HIT at  ' num2str(startAt) ' to ' num2str(stopAt)];
                %if (readLength < remainingDataToRead)
                %    hitInThisSegment = [hitInThisSegment ' (partial ' num2str(readLength) ' )'];
                %else
                %    hitInThisSegment = [hitInThisSegment ' (finished - this segment contributed ' num2str(readLength) ' )'];
                %end
                %hitInThisSegment = [hitInThisSegment ' abs file pos ' num2str(filePosStart) ' - ' num2str(filePosStart+readLength)];

                remainingDataToRead = remainingDataToRead-readLength;
                currentTargetStart = currentTargetStart + readLength;

            end
            %disp(['    Index ' num2str(j) ' Offset: ' num2str(internalOffset) ' to ' num2str(internalOffset+currentInstance.sectionL) ' ' num2str(hitInThisSegment)]);

            internalOffset = internalOffset + currentInstance.sectionL;
        end
    end

      %% Get PatientGUID
      info = struct();

      infoProps = { 'patientID', 'firstName','middleName','lastName',...
        'altID','mothersMaidenName','DOB','DOD','street','sexID','phone',...
        'notes','dominance','siteID','suffix','prefix','degree','apartment',...
        'city','state','country','language','height','weight','race','religion',...
        'maritalStatus'};

      infoIdxStruct = Tags(find(strcmp({Tags.IDStr},'PATIENTINFOGUID'),1));
      if ~isempty(infoIdxStruct)
        infoIdx = infoIdxStruct.index;
        indexInstance = Index(find([Index.sectionIdx]==infoIdx,1));
        fseek(h, indexInstance.offset,'bof');
        guid = fread(h, 16, 'uint8'); %#ok<NASGU>
        lSection = fread(h, 1, 'uint64'); %#ok<NASGU>
%        reserved = fread(h, 3, 'uint16'); %#ok<NASGU>
        nrValues = fread(h,1,'uint64');
        nrBstr = fread(h,1,'uint64');

        for i = 1:nrValues
          id = fread(h,1,'uint64');
          switch id
            case {7,8}
              unix_time = (fread(h,1, 'double')*(3600*24)) - 2209161600;% 2208988800; %8
              obj.segments(i).dateStr = datestr(unix_time/86400 + datenum(1970,1,1));
              value = datevec( obj.segments(i).dateStr );
              value = value([3 2 1]);
            case {23,24}
              value = fread(h,1,'double');
              otherwise
              value = 0;
          end
          info.(infoProps{id}) = value;
        end

        strSetup = fread(h,nrBstr*2,'uint64');

        for i=1:2:(nrBstr*2)
          id  = strSetup(i);
          value = deblank(cast(fread(h, strSetup(i+1) + 1, 'uint16'),'char')');
          info.(infoProps{id}) = value;
        end
      end

      obj.patientInfo = info;

      %% Get INFOGUID
      infoIdx = Tags(find(strcmp({Tags.IDStr},'InfoGuids'),1)).index;
      indexInstance = Index(find([Index.sectionIdx]==infoIdx,1));
      fseek(h, indexInstance.offset,'bof');

      % Ignoring, is list of GUIDS in file.

      %% Get SignalInfo (SIGNALINFOGUID): One per file
      SIG_struct = struct();
      sensorIdx = Tags(find(strcmp({Tags.IDStr},'SIGNALINFOGUID'),1)).index;
      indexInstance = Index(find([Index.sectionIdx]==sensorIdx,1));
      fseek(h, indexInstance.offset,'bof');
      SIG_struct.guid = fread(h, 16, 'uint8');
      SIG_struct.name = fread(h, obj.ITEMNAMESIZE, '*char');
      unkown = fread(h, 152, '*char');         %#ok<NASGU>
      fseek(h, 512, 'cof');
      nrIdx = fread(h,1, 'uint16');  %783
      misc1 = fread(h,3, 'uint16'); %#ok<NASGU>
      obj.sigInfo = struct();
      for i = 1: nrIdx
        obj.sigInfo(i).sensorName = deblank(cast(fread(h, obj.LABELSIZE, 'uint16'),'char')');
        obj.sigInfo(i).transducer = deblank(cast(fread(h, obj.UNITSIZE, 'uint16'),'char')');
        obj.sigInfo(i).guid = fread(h, 16, '*uint8');
        obj.sigInfo(i).bBiPolar = logical(fread(h, 1 ,'uint32'));
        obj.sigInfo(i).bAC = logical(fread(h, 1 ,'uint32'));
        obj.sigInfo(i).bHighFilter = logical(fread(h, 1 ,'uint32'));
        obj.sigInfo(i).color =  fread(h, 1 ,'uint32');
        reserved = fread(h, 256, '*char'); %#ok<NASGU>
      end

      %% Get CHANNELINFO (CHANNELGUID)
      CH_struct = struct();
      sensorIdx = Tags(find(strcmp({Tags.IDStr},'CHANNELGUID'),1)).index;
      indexInstance = Index(find([Index.sectionIdx]==sensorIdx,1));
      fseek(h, indexInstance.offset,'bof');
            CH_struct.guid = fread(h, 16, 'uint8');
      CH_struct.name = fread(h, obj.ITEMNAMESIZE, '*char');
      fseek(h, 152, 'cof');
      CH_struct.reserved = fread(h, 16, 'uint8');
      CH_struct.deviceID = fread(h, 16, 'uint8');
      fseek(h, 488, 'cof');

      nrIdx = fread(h,2, 'uint32');  %783
      obj.chInfo = struct();
      for i = 1: nrIdx(2)
        obj.chInfo(i).sensor = deblank(cast(fread(h, obj.LABELSIZE, 'uint16'),'char')');
        obj.chInfo(i).samplingRate = fread(h,1,'double');
        obj.chInfo(i).bOn = logical(fread(h, 1 ,'uint32'));
        obj.chInfo(i).lInputID = fread(h, 1 ,'uint32');
        obj.chInfo(i).lInputSettingID = fread(h,1,'uint32');
        obj.chInfo(i).reserved = fread(h,4,'char');
        fseek(h, 128, 'cof');
      end

      curIdx = 0;
      for i = 1: length(obj.chInfo)
        if obj.chInfo(i).bOn
         obj.chInfo(i).indexID = curIdx;
         curIdx = curIdx+1;
        else
          obj.chInfo(i).indexID = -1;
        end
      end

      %% Get TS info (TSGUID):(One per segment, last used if no new for segment)
      %% To simplify things, we only read the first TSINFO.
	  tsPackets = dynamicPackets(strcmp({dynamicPackets.IDStr},'TSGUID'));

      if isempty(tsPackets)
          warning(['No TSINFO found']);
      else
          obj.tsInfos = {};
          for j = 1:length(tsPackets)

          tsPacket = tsPackets(j);
          elems = typecast(tsPacket.data(753:756),'uint32');
          alloc = typecast(tsPacket.data(757:760),'uint32');

          offset = 761;
          tsInfo = struct();
          for i = 1:elems
              internalOffset = 0;
              tsInfo(i).label = deblank(char(typecast(tsPacket.data(offset:(offset+obj.TSLABELSIZE-1))','uint16')));
              internalOffset = internalOffset + obj.TSLABELSIZE*2;
              tsInfo(i).activeSensor = deblank(char(typecast(tsPacket.data(offset+internalOffset:(offset+internalOffset-1+obj.LABELSIZE))','uint16')));
              internalOffset = internalOffset + obj.TSLABELSIZE;
              tsInfo(i).refSensor = deblank(char(typecast(tsPacket.data(offset+internalOffset:(offset+internalOffset-1+8))','uint16')));
              internalOffset = internalOffset + 8;
              internalOffset = internalOffset + 56;
              tsInfo(i).dLowCut = typecast(tsPacket.data(offset+internalOffset:(offset+internalOffset-1+8))','double');
              internalOffset = internalOffset + 8;
              tsInfo(i).dHighCut = typecast(tsPacket.data(offset+internalOffset:(offset+internalOffset-1+8))','double');
              internalOffset = internalOffset + 8;
              tsInfo(i).dSamplingRate = typecast(tsPacket.data(offset+internalOffset:(offset+internalOffset-1+8))','double');
              internalOffset = internalOffset + 8;
              tsInfo(i).dResolution = typecast(tsPacket.data(offset+internalOffset:(offset+internalOffset-1+8))','double');
              internalOffset = internalOffset + 8;
              tsInfo(i).bMark = typecast(tsPacket.data(offset+internalOffset:(offset+internalOffset-1+2))','uint16');
              internalOffset = internalOffset + 2;
              tsInfo(i).bNotch = typecast(tsPacket.data(offset+internalOffset:(offset+internalOffset-1+2))','uint16');
              internalOffset = internalOffset + 2;
              tsInfo(i).dEegOffset = typecast(tsPacket.data(offset+internalOffset:(offset+internalOffset-1+8))','double');
              offset = offset + 552;
              %disp([num2str(i) ' : ' TSInfo(i).label ' : ' TSInfo(i).activeSensor ' : ' TSInfo(i).refSensor ' : ' num2str(TSInfo(i).samplingRate)]);

          end
          obj.tsInfos{j} = tsInfo;
          end
      end

      % -- -- --

      %% Get Segment Start Times
      segmentIdx = Tags(find(strcmp({Tags.IDStr}, 'SegmentStream'),1)).index;
      indexIdx = find([Index.sectionIdx] == segmentIdx, 1);
      segmentInstance = Index(indexIdx);

      nrSegments = segmentInstance.sectionL/152;
      fseek(h, segmentInstance.offset,'bof');
      obj.segments = struct();
      for i = 1: nrSegments
        dateOLE = fread(h,1, 'double');
        obj.segments(i).dateOLE = dateOLE;
        unix_time = (dateOLE*(3600*24)) - 2209161600;% 2208988800; %8
        obj.segments(i).dateStr = datestr(unix_time/86400 + datenum(1970,1,1));
        datev = datevec( obj.segments(i).dateStr );
        obj.segments(i).startDate = datev(1:3);
        obj.segments(i).startTime = datev(4:6);
        fseek(h, 8 , 'cof'); %16
        obj.segments(i).duration = fread(h,1, 'double');%24
        fseek(h, 128 , 'cof'); %152
      end

      % Get nrValues per segment and channel
      for iSeg = 1:length(obj.segments)
        if iSeg > length(obj.tsInfos)
            obj.tsInfos{iSeg} = obj.tsInfos{iSeg-1}
        end

        % Add Channel Names to segments
        obj.segments(iSeg).chName = {obj.tsInfos{iSeg}.label};
        obj.segments(iSeg).refName = {obj.tsInfos{iSeg}.refSensor};
        obj.segments(iSeg).samplingRate = [obj.tsInfos{iSeg}.dSamplingRate];
        obj.segments(iSeg).scale = [obj.tsInfos{iSeg}.dResolution];

      end

      %% Get events  - Andrei Barborica, Dec 2015
      % Find sequence of events, that are stored in the section tagged 'Events'
      idxSection = find(strcmp('Events',{Tags.tag}));
      indexIdx = find([obj.index.sectionIdx] == obj.sections(idxSection).index);
      offset = obj.index(indexIdx).offset;

      ePktLen = 272;    % Event packet length, see EVENTPACKET definition
      eMrkLen = 240;    % Event marker length, see EVENTMARKER definition
      evtPktGUID = hex2dec({'80', 'F6', '99', 'B7', 'A4', '72', 'D3', '11', '93', 'D3', '00', '50', '04', '00', 'C1', '48'}); % GUID for event packet header
      HCEVENT_ANNOTATION = '{A5A95612-A7F8-11CF-831A-0800091B5BDA}';
      HCEVENT_SEIZURE    =  '{A5A95646-A7F8-11CF-831A-0800091B5BDA}';
      HCEVENT_FORMATCHANGE      =  '{08784382-C765-11D3-90CE-00104B6F4F70}';
      HCEVENT_PHOTIC            =  '{6FF394DA-D1B8-46DA-B78F-866C67CF02AF}';
      HCEVENT_POSTHYPERVENT     =  '{481DFC97-013C-4BC5-A203-871B0375A519}';
      HCEVENT_REVIEWPROGRESS    =  '{725798BF-CD1C-4909-B793-6C7864C27AB7}';
      HCEVENT_EXAMSTART         =  '{96315D79-5C24-4A65-B334-E31A95088D55}';
      HCEVENT_HYPERVENTILATION  =  '{A5A95608-A7F8-11CF-831A-0800091B5BDA}';
      HCEVENT_IMPEDANCE         =  '{A5A95617-A7F8-11CF-831A-0800091B5BDA}';
      HCEVENT_AMPLIFIERDISCONNECT = '{A71A6DB5-4150-48BF-B462-1C40521EBD6F}';
      HCEVENT_AMPLIFIERRECONNECT = '{6387C7C8-6F98-4886-9AF4-FA750ED300DE}';
      HCEVENT_PAUSED = '{71EECE80-EBC4-41C7-BF26-E56911426FB4}';

      DAYSECS = 86400.0;  % From nrvdate.h

      fseek(h,offset,'bof');
      pktGUID = fread(h,16,'uint8');
      pktLen  = fread(h,1,'uint64');
      obj.eventMarkers = struct();
      i = 0;    % Event counter
      while (pktGUID == evtPktGUID)
          i = i + 1;
          % Please refer to EVENTMARKER structure in the Nervus file documentation
          fseek(h,8,'cof'); % Skip eventID, not used
          evtDate           = fread(h,1,'double');
          evtDateFraction   = fread(h,1,'double');
          obj.eventMarkers(i).dateOLE = evtDate;
          obj.eventMarkers(i).dateFraction = evtDateFraction;
          evtPOSIXTime = evtDate*DAYSECS + evtDateFraction - 2209161600;% 2208988800; %8
          obj.eventMarkers(i).dateStr = datestr(evtPOSIXTime/DAYSECS + datenum(1970,1,1),'dd-mmmm-yyyy HH:MM:SS.FFF'); % Save fractions of seconds, as well
          obj.eventMarkers(i).duration  = fread(h,1,'double');
          fseek(h,48,'cof');
          evtUser                       = fread(h,12,'uint16');
          obj.eventMarkers(i).user      = deblank(char(evtUser).');
          evtTextLen                    = fread(h,1,'uint64');
          evtGUID                       = fread(h,16,'uint8');
          obj.eventMarkers(i).GUID      = sprintf('{%.2X%.2X%.2X%.2X-%.2X%.2X-%.2X%.2X-%.2X%.2X-%.2X%.2X%.2X%.2X%.2X%.2X}',evtGUID([4 3 2 1 6 5 8 7 9:16]));
          fseek(h,16,'cof');    % Skip Reserved4 array
          evtLabel                      = fread(h,32,'uint16'); % LABELSIZE = 32;
          evtLabel                      = deblank(char(evtLabel).');    % Not used
          eventMarkers(i).label         = evtLabel;

          %disp(sprintf('Offset: %s, TypeGUID:%s, User:%s, Label:%s',dec2hex(offset),evtGUID,evtUser,evtLabel));

          % Only a subset of all event types are dealt with
          switch obj.eventMarkers(i).GUID
              case HCEVENT_SEIZURE
                  obj.eventMarkers(i).IDStr = 'Seizure';
                  %disp(' Seizure event');
              case HCEVENT_ANNOTATION
                  obj.eventMarkers(i).IDStr = 'Annotation';
                  fseek(h,32,'cof');    % Skip Reserved5 array
                  evtAnnotation = fread(h,evtTextLen,'uint16');
                  obj.eventMarkers(i).annotation = deblank(char(evtAnnotation).');
                  %disp(sprintf(' Annotation:%s',evtAnnotation));
              case HCEVENT_FORMATCHANGE
                  obj.eventMarkers(i).IDStr = 'Format change';
              case HCEVENT_PHOTIC
                  obj.eventMarkers(i).IDStr = 'Photic';
              case HCEVENT_POSTHYPERVENT
                  obj.eventMarkers(i).IDStr = 'Posthyperventilation';
              case HCEVENT_REVIEWPROGRESS
                  obj.eventMarkers(i).IDStr = 'Review progress';
              case HCEVENT_EXAMSTART
                  obj.eventMarkers(i).IDStr = 'Exam start';
              case HCEVENT_HYPERVENTILATION
                  obj.eventMarkers(i).IDStr = 'Hyperventilation';
              case HCEVENT_IMPEDANCE
                  obj.eventMarkers(i).IDStr = 'Impedance';
              case HCEVENT_AMPLIFIERDISCONNECT
                  obj.eventMarkers(i).IDStr = 'Amplifier Disconnect';
              case HCEVENT_AMPLIFIERRECONNECT
                  obj.eventMarkers(i).IDStr = 'Amplifier Reconnect';
              case HCEVENT_PAUSED
                  obj.eventMarkers(i).IDStr = 'Recording Paused';
              otherwise
                  obj.eventMarkers(i).IDStr = 'UNKNOWN';
          end

          % Next packet
          offset = offset + pktLen;
          fseek(h,offset,'bof');
          pktGUID = fread(h,16,'uint8');
          pktLen  = fread(h,1,'uint64');
      end

      %% Get montage  - Andrei Barborica, Dec 2015
      % Derivation (montage)
      mtgIdx  = Tags(find(strcmp({Tags.IDStr},'DERIVATIONGUID'),1)).index;
      indexIdx      = find([obj.index.sectionIdx]==mtgIdx,1);
      fseek(h,obj.index(indexIdx(1)).offset + 40,'bof');    % Beginning of current montage name
      mtgName       = deblank(char(fread(h,32,'uint16')).');
      fseek(h,640,'cof');                             % Number of traces in the montage
      numDerivations = fread(h,1,'uint32');
      numDerivations2 = fread(h,1,'uint32');

      obj.montage = struct();
      for i = 1:numDerivations
          obj.montage(i).derivationName = deblank(char(fread(h,64,'uint16')).');
          obj.montage(i).signalName1    = deblank(char(fread(h,32,'uint16')).');
          obj.montage(i).signalName2    = deblank(char(fread(h,32,'uint16')).');
          fseek(h,264,'cof');         % Skip additional info
      end

      % Display properties
      dispIdx = Tags(find(strcmp({Tags.IDStr},'DISPLAYGUID'),1)).index;
      indexIdx  = find([obj.index.sectionIdx]==dispIdx,1);
      fseek(h,obj.index(indexIdx(1)).offset + 40,'bof');    % Beginning of current montage name
      displayName          = deblank(char(fread(h,32,'uint16')).');
      fseek(h,640,'cof');                             % Number of traces in the montage
      numTraces = fread(h,1,'uint32');
      numTraces2 = fread(h,1,'uint32');

      if (numTraces == numDerivations)
          for i = 1:numTraces
              fseek(h,32,'cof');
              obj.montage(i).color = fread(h,1,'uint32'); % Use typecast(uint32(montage(i).color),'uint8') to convert to RGB array
              fseek(h,136-4,'cof');
          end
      else
          disp('Could not match montage derivations with display color table');
      end

      % Close File
      fclose(h);

    end

    function out = getNrSamples(obj, segment)
      % GETNRSAMPLES  Returns the number of samples per channel in segment.
      %
      %   OUT = GETNRSAMPLES(OBJ, SEGMENT) returns a 1xn array of values
      %   indicating the number of samples for each of the channels in the
      %   associated SEGMENT, where SEGMENT is the index of the
      %   OBJ.segments array.

      assert(length(obj.segments)>= segment, ...
        'Incorrect SEGMENT argument; must be integer representing segment index.');

      out = obj.segments(segment).samplingRate .* obj.segments(segment).duration;

    end

    function cSumSegs = getCSumSegs(obj, chI)
      % GETCSUMSEGS  Returns the cumulative sum of a channels segments
      %
      %   CSUMSEGS = GETCSUMSEGS(OBJ, CHI) returns a 1xn array of the
      %   cumulative sum of the given channel, where chI is the channel
      %   index. Different TsInfos can have different numbers of channels
      %   and different sampling rates.
      samplingRates = zeros(1, length(obj.tsInfos));
      for ts_i = 1:length(obj.tsInfos)
          if length(obj.tsInfos{ts_i}) < chI
              continue
          else
              samplingRates(ts_i) = obj.tsInfos{ts_i}(chI).dSamplingRate;
          end
      end
      cSumSegs = [0 cumsum(samplingRates.*[obj.segments.duration])];
  end

    function out = getdata(obj, segment, range, chIdx)
      % GETDATA  Returns data from Nicolet file.
      %
      %   OUT = GETDATA(OBJ, SEGMENT, RANGE, CHIDX) returns data in an nxm array of
      %   doubles where n is the number of datapoints and m is the number
      %   of channels. RANGE is a 1x2 array with the [StartIndex EndIndex]
      %   and CHIDX is a vector of channel indeces.

      % Assert range is 1x2 vector
      if isempty([obj.tsInfos{segment}.label])
          warning('Segment %d has an empty tsInfo. Skipping', segment)
          out = 0;
          return
      end

      assert(length(range) == 2, 'Range is [firstIndex lastIndex]');
      assert(length(segment) == 1, 'Segment must be single value.');

      % Reopen .e file.
      h = fopen(obj.fileName,'r','ieee-le');

      % Find sectionID for channels
      lChIdx = length(chIdx);
      sectionIdx = zeros(lChIdx,1);
      for i = 1:lChIdx
        tmp = find(strcmp(num2str(chIdx(i)-1),{obj.sections.tag}),1);
        sectionIdx(i) = obj.sections(tmp).index;
      end

      % Iterate over all requested channels and populate array.
      out = zeros(range(2) - range(1) + 1, lChIdx);
      for i = 1 : lChIdx
        % Get cumulative sum segments.
        cSumSegments = obj.getCSumSegs(chIdx(i));

        % Get sampling rate for current channel
        curSF = obj.segments(segment).samplingRate(chIdx(i));
        mult = obj.segments(segment).scale(chIdx(i));

        % Find all sections
        allSectionIdx = obj.allIndexIDs == sectionIdx(i);
        allSections = find(allSectionIdx);

        % Find relevant sections
        sectionLengths = [obj.index(allSections).sectionL]./2;
        cSectionLengths = [0 cumsum(sectionLengths)];

        skipValues = cSumSegments(segment);
        firstSectionForSegment = find(cSectionLengths > skipValues, 1) - 1 ;
        lastSectionForSegment = firstSectionForSegment + ...
          find(cSectionLengths > curSF*obj.segments(segment).duration,1) - 2 ;

        if isempty(lastSectionForSegment)
          lastSectionForSegment = length(cSectionLengths);
        end

        offsetSectionLengths = cSectionLengths - cSectionLengths(firstSectionForSegment);

        firstSection = find(offsetSectionLengths < range(1) ,1,'last');
        lastSection = find(offsetSectionLengths >= range(2),1)-1;

        if isempty(lastSection)
          lastSection = length(offsetSectionLengths);
        end

        if lastSection > lastSectionForSegment
          error('Index out of range for current section: %i > %i, on channel: %i', ...
            range(2), cSectionLengths(lastSectionForSegment+1), chIdx(i));
        end

        useSections = allSections(firstSection: lastSection) ;
        useSectionL = sectionLengths(firstSection: lastSection) ;

        % First Partial Segment
        curIdx = 1;
        curSec = obj.index(useSections(1));
        fseek(h, curSec.offset,'bof');

        firstOffset = range(1) - offsetSectionLengths(firstSection);
        lastOffset = min([range(2) useSectionL(1)]);
        lsec = lastOffset-firstOffset + 1;

        fseek(h, (firstOffset-1) * 2,'cof');
        out(1 : lsec,i) = fread(h, lsec, 'int16') * mult;
        curIdx = curIdx +  lsec;

        if length(useSections) > 1
          % Full Segments
          for j = 2: (length(useSections)-1)
            curSec = obj.index(useSections(j));
            fseek(h, curSec.offset,'bof');

            out(curIdx : (curIdx + useSectionL(j) - 1),i) = ...
              fread(h, useSectionL(j), 'int16') * mult;
            curIdx = curIdx +  useSectionL(j);
          end

          % Final Partial Segment
          curSec = obj.index(useSections(end));
          fseek(h, curSec.offset,'bof');
          out(curIdx : end,i) = fread(h, length(out)-curIdx + 1, 'int16') * mult;
        end

      end

      % Close the .e file.
      fclose(h);

    end

     function out = getdataQ(obj, segment, range, chIdx)
      % GETDATAQ  Returns data from Nicolet file. This is a "QUICK" version of getdata,
      % that uses more memory but operates faster on large datasets by reading
      % a single block of data from disk that contains all data of interest.
      %
      %   OUT = GETDATAQ(OBJ, SEGMENT, RANGE, CHIDX) returns data in an nxm array of
      %   doubles where n is the number of datapoints and m is the number
      %   of channels. RANGE is a 1x2 array with the [StartIndex EndIndex]
      %   and CHIDX is a vector of channel indeces.
      %
      % Andrei Barborica, Dec 2015
      %
      if isempty([obj.tsInfos{segment}.label])
          warning('Segment %d has an empty tsInfo. Skipping', segment)
          out = 0;
          return
      end

      % Assert range is 1x2 vector
      assert(length(range) == 2, 'Range is [firstIndex lastIndex]');
      assert(length(segment) == 1, 'Segment must be single value.');

      % Reopen .e file.
      h = fopen(obj.fileName,'r','ieee-le');

      % Find sectionID for channels
      lChIdx = length(chIdx);
      sectionIdx = zeros(lChIdx,1);
      for i = 1:lChIdx
        tmp = find(strcmp(num2str(chIdx(i)-1),{obj.sections.tag}),1);
        sectionIdx(i) = obj.sections(tmp).index;
      end

      usedIndexEntries = zeros(size([obj.index.offset]));

      % Iterate over all requested channels and populate array.
      out = zeros(range(2) - range(1) + 1, lChIdx);
      for i = 1 : lChIdx
        % Get cumulative sum segments.
        cSumSegments = obj.getCSumSegs(chIdx(i));

        % Get sampling rate for current channel
        curSF = obj.segments(segment).samplingRate(chIdx(i));
        mult = obj.segments(segment).scale(chIdx(i));

        % Find all sections
        allSectionIdx = obj.allIndexIDs == sectionIdx(i);
        allSections = find(allSectionIdx);

        % Find relevant sections
        sectionLengths = [obj.index(allSections).sectionL]./2;
        cSectionLengths = [0 cumsum(sectionLengths)];

        skipValues = cSumSegments(segment);
        firstSectionForSegment = find(cSectionLengths > skipValues, 1) - 1 ;
        lastSectionForSegment = firstSectionForSegment + ...
          find(cSectionLengths > curSF*obj.segments(segment).duration,1) - 2 ;

        if isempty(lastSectionForSegment)
          lastSectionForSegment = length(cSectionLengths);
        end

        offsetSectionLengths = cSectionLengths - cSectionLengths(firstSectionForSegment);

        firstSection = find(offsetSectionLengths < range(1) ,1,'last');
        lastSection = find(offsetSectionLengths >= range(2),1)-1;

        if isempty(lastSection)
          lastSection = length(offsetSectionLengths);
        end

        if lastSection > lastSectionForSegment
          error('Index out of range for current section: %i > %i, on channel: %i', ...
            range(2), cSectionLengths(lastSectionForSegment+1), chIdx(i));
        end

        useSections = allSections(firstSection: lastSection) ;
        useSectionL = sectionLengths(firstSection: lastSection) ;

        % First Partial Segment
        usedIndexEntries(useSections(1)) = 1;

        if length(useSections) > 1
          % Full Segments
          for j = 2: (length(useSections)-1)
            usedIndexEntries(useSections(j)) = 1;
          end

          % Final Partial Segment
          usedIndexEntries(useSections(end)) = 1;
        end

      end

      % Read a big chunk of the file, containing data of interest.
      ix = find(usedIndexEntries);
      fseek(h, obj.index(ix(1)).offset,'bof');
      dsize =  obj.index(ix(end)).offset - obj.index(ix(1)).offset + obj.index(ix(end)).sectionL;
      tmp = fread(h,dsize/2,'int16').';

      % Close the .e file.
      fclose(h);

      baseOffset = obj.index(ix(1)).offset;

      % Extract specified channels
      for i = 1 : lChIdx
        % Get cumulative sum segments.
        cSumSegments = obj.getCSumSegs(chIdx(i));

        % Get sampling rate for current channel
        curSF = obj.segments(segment).samplingRate(chIdx(i));
        mult = obj.segments(segment).scale(chIdx(i));

        % Find all sections
        allSectionIdx = obj.allIndexIDs == sectionIdx(i);
        allSections = find(allSectionIdx);

        % Find relevant sections
        sectionLengths = [obj.index(allSections).sectionL]./2;
        cSectionLengths = [0 cumsum(sectionLengths)];

        skipValues = cSumSegments(segment);
        firstSectionForSegment = find(cSectionLengths > skipValues, 1) - 1 ;
        lastSectionForSegment = firstSectionForSegment + ...
          find(cSectionLengths > curSF*obj.segments(segment).duration,1) - 2 ;

        if isempty(lastSectionForSegment)
          lastSectionForSegment = length(cSectionLengths);
        end

        offsetSectionLengths = cSectionLengths - cSectionLengths(firstSectionForSegment);

        firstSection = find(offsetSectionLengths < range(1) ,1,'last');
        lastSection = find(offsetSectionLengths >= range(2),1)-1;

        if isempty(lastSection)
          lastSection = length(offsetSectionLengths);
        end

        if lastSection > lastSectionForSegment
          error('Index out of range for current section: %i > %i, on channel: %i', ...
            range(2), cSectionLengths(lastSectionForSegment+1), chIdx(i));
        end

        useSections = allSections(firstSection: lastSection) ;
        useSectionL = sectionLengths(firstSection: lastSection) ;

        % First Partial Segment
        curIdx = 1;
        curSec = obj.index(useSections(1));
        %fseek(h, curSec.offset,'bof');

        firstOffset = range(1) - offsetSectionLengths(firstSection);
        lastOffset = min([range(2) useSectionL(1)]);
        lsec = lastOffset-firstOffset + 1;

        out(1 : lsec,i) = tmp( (curSec.offset - baseOffset)/2 + (firstOffset-1) + (1:lsec) ) * mult;
        curIdx = curIdx +  lsec;

        if length(useSections) > 1
          % Full Segments
          for j = 2: (length(useSections)-1)
            curSec = obj.index(useSections(j));
            out(curIdx : (curIdx + useSectionL(j) - 1),i) = ...
                tmp( (curSec.offset - baseOffset)/2 + (1:useSectionL(j)) ) * mult;
            curIdx = curIdx +  useSectionL(j);
          end

          % Final Partial Segment
          curSec = obj.index(useSections(end));
          out(curIdx : end,i) = tmp( (curSec.offset - baseOffset)/2 + (1:(length(out)-curIdx + 1)) ) * mult; % length(out) ??????
        end

      end
    end

    function labels = getlabels(obj,str)
        % Returns annotations containing specified string
        %
        % Cristian Donos, Dec 2015
        %
        labels=[]; counter = 1;
        for i = 1:length(obj.eventMarkers)
            if strfind(lower(obj.eventMarkers(i).annotation),lower(str))
            labels{counter,1} = obj.eventMarkers(i).annotation;  % annotation string
            labels{counter,2} = i;  % annotation index in obj.eventMarkers
            % identify segment
            time_vector = [];
            for j = 1:length(obj.segments)
                time_vector = [time_vector etime(datevec(obj.eventMarkers(i).dateStr),datevec(obj.segments(j).dateStr))];
            end
            labels{counter,3}= find(time_vector==min(time_vector(time_vector>0)));  % annotation part of this segment
            labels{counter,4}= min(time_vector(time_vector>0));  % annotation offset in seconds, relative to its segment start
            counter = counter+1;
            end
        end
    end
  end

end


function asb_vrmfunc(hBlk)
%ASB_VRMFUNC  Helper function for On-Board Camera model

% Copyright 2018 The MathWorks, Inc.

vrmfunc('FnInit', hBlk);
vrmfunc('FnSetupVideo', hBlk);
ud = get_param(hBlk, 'UserData');
if ~strcmp(get(ud.VideoFigure, 'Viewpoint'),'Quadcopter Camera')
    set(ud.VideoFigure, 'Viewpoint', 'Quadcopter Camera');
end
end


% Root class for composite user controls. More form than function, it seems...

% Copyright 2008-2009 Levente Hunyadi
classdef UIControl < hgsetget
    properties (Abstract, Dependent)
        % The graphics handle that represents the entire user control.
        % This handle is used in setting the parent, position, measurement
        % unit, etc. properties of the control. In order to use MatLab's Handle
        % Graphics semantics in a derived user interface control, you should
        % query the Control property.
        Control;
    end
    properties (Dependent)
        NormalizedPosition;
        % The parent control of this UI control.
        Parent;
        % Units in which the Position property is expressed.
        % Note: this property is deliberately put before the Position property
        % to ensure proper initialization when both Units and Position are set
        % in a constructor argument list. For the constructor processes
        % arguments in the order in which they occur within the class
        % definition rather than the order in which they are specified, we
        % always get the desired behavior that Position is interpreted in terms
        % of the specified Units.
        Units = 'normalized';
        Position;
    end
    methods (Abstract)
        % Forces instantiation of underlying MatLab Handle Graphics objects.
        % Some dependent properties refer to MatLab Handle Graphics object
        % properties in an early phase of object construction. These properties
        % might fail if existence of objects they depend on cannot be
        % guaranteed.
        obj = Instantiate(obj, parent);
    end
    methods
        function obj = UIControl(arg, varargin)
            if nargin > 0 && isscalar(arg) && ishandle(arg)
                obj = obj.Instantiate(arg);
            else
                obj = obj.Instantiate();
            end
            if nargin > 0
                if isscalar(arg) && ishandle(arg)
                    obj.Parent = arg;
                    obj = constructor(obj, varargin{:});
                else
                    if ~strcmp('figure', get(obj.Control, 'Type'))
                        obj.Parent = gcf;
                    end
                    obj = constructor(obj, arg, varargin{:});
                end
            end
        end

        function parent = get.Parent(obj)
            parent = get(obj.Control, 'Parent');
        end

        function obj = set.Parent(obj, parent)
            if ~strcmp(get(obj.Control, 'Type'), 'figure')  % figures do not require a parent
                set(obj.Control, 'Parent', parent);
            end
        end

        function units = get.Units(obj)
            units = get(obj.Control, 'Units');
        end

        function obj = set.Units(obj, units)
            set(obj.Control, 'Units', units);
        end

        function position = get.Position(obj)
            position = get(obj.Control, 'Position');
        end

        function obj = set.Position(obj, position)
            set(obj.Control, 'Position', position);
        end

        function obj = set.NormalizedPosition(obj, position)
            units = get(obj.Control, 'Units');
            if isempty(units)
                units = 'normalized';
            end
            switch units
                case 'normalized'
                    set(obj.Control, 'Position', position);
                otherwise
                    set(obj.Control, 'Units', 'normalized');
                    set(obj.Control, 'Position', position);
                    set(obj.Control, 'Units', units);
            end
        end

        function position = get.NormalizedPosition(obj)
            units = get(obj.Control, 'Units');
            if isempty(units)
                units = 'normalized';
            end
            switch units
                case 'normalized'
                    position = get(obj.Control, 'Position');
                otherwise
                    set(obj.Control, 'Units', 'normalized');
                    position = get(obj.Control, 'Position');
                    set(obj.Control, 'Units', units);
            end
        end

        function position = getpixelposition(obj)
            position = getpixelposition(obj.Control);
        end

        function obj = setpixelposition(obj, position)
            setpixelposition(obj.Control, position);
        end
    end
end


% ReadSegyTraceHeaderValue : Read a spedicifc trace header value
%
% Call:
%    % By Name
%    cdp=ReadSegyTraceHeaderValue(filename,'key','cdp');
%    SourceX=ReadSegyTraceHeaderValue(filename,'key','SourceX');
%    SourceY=ReadSegyTraceHeaderValue(filename,'key','SourceY');
%
%    % By location in Trace Header
%    SourceX=ReadSegyTraceHeaderValue(filename,'pos',72,'precision','int32');
%
%    % Call 'TraceHeaderDef(1)' to see a list of TraceHeader 'key' names
%
% See also WriteSegyTraceHeaderValue, TraceHeaderDef
%

%

function hval=ReadSegyTraceHeaderValue(filename,varargin);%pos,type)

pos=0;
precision='int32';

ninput=nargin;
% TRANSFORM VARARGING INTO PARAMETERS
cargin=1;
while (cargin<ninput)

    % ENDIAN FORMAT
    endian='ieee-be'; % Big Endian is default
    if strcmp(varargin{cargin},'endian')
       cargin=cargin+1;
       eval(['endian_tight=varargin{cargin};'])
       if endian_tight=='l',
         disp(['USING LITTLE ENDIAN TYPE'])
         endian='ieee-le';
       else
         disp(['USING BIG ENDIAN TYPE'])
       end
    end

    if strcmp(varargin{cargin},'pos')
       cargin=cargin+1;
       eval(['pos=',num2str(varargin{cargin}),';']);
       disp(['Reading at header postision : pos=',num2str(pos+1)])
    end

    if strcmp(varargin{cargin},'precision')
       cargin=cargin+1;
       eval(['precision=''',varargin{cargin},''';']);
       disp(['precision : ',precision])
    end

    if strcmp(varargin{cargin},'key')
       cargin=cargin+1;
       eval(['key=''',varargin{cargin},''';']);

       STH=TraceHeaderDef;
       try
            pos=STH.(key).pos;
            precision=STH.(key).precision;
       catch
           disp(sprintf('Trace Header Value %s not defined',key))
           pos=0; precision='int32';
           hval=[];
           return
       end
       SegymatVerbose(sprintf('key=%s, startpos=%d, precision=%s ',key,pos+1,precision))
    end

    cargin=cargin+1;
end

if nargin<2
  pos=0;
end

if nargin<3
  type='int32';
end

if exist('endian')==1,
  segyid = fopen(filename,'r',endian);
else
  segyid = fopen(filename,'r','ieee-be');  % ALL DISK FILES ARE IN BIG
end                                        % ENDIAN FORMAT, ACCORDING TO

[SegyHeader]=ReadSegyHeader(filename);

Revision=SegyHeader.SegyFormatRevisionNumber;
if Revision>0, Revision=1; end
if (SegyHeader.DataSampleFormat>length(SegyHeader.Rev(Revision+1).DataSampleFormat));
    SegymatVerbose([mfilename,' : WARNING : YOU HAVE SELECTED (OR THE FILE IS FORMATTED SUCH THAT) A DATASAMPLE FORMAT THAT IS NOT DEFINED. \nREMEBER IEEE IS NOT SPECIFIED IN THE SEGY REV0 STANDARD !'])
    if (Revision==0)
        SegymatVerbose([mfilename,' : TRYING TO USE REVISION 1 AS OPPOSED TO REVISION 0'])
        Revision=1;
        if (SegyHeader.DataSampleFormat>length(SegyHeader.Rev(Revision+1).DataSampleFormat));
            SegymatVerbose([mfilename,' : FATAL ERROR : STILL THE DATASAMPLE FORMAT IS NOT SUPPRTED - EXITING (Report error to tmh@gfy.ku.dk)'])
        else
            SegymatVerbose([mfilename,' : APPARENT SUCCES CHANING FROM Revision 0 to 1 - Continuing'])
            SegyHeader.SegyFormatRevisionNumber=1; % FORCING REVISION TO BE 1 !!!
        end
    end
end

FormatName=SegyHeader.Rev(Revision+1).DataSampleFormat(SegyHeader.DataSampleFormat).name;
Format=SegyHeader.Rev(Revision+1).DataSampleFormat(SegyHeader.DataSampleFormat).format;
BPS=SegyHeader.Rev(Revision+1).DataSampleFormat(SegyHeader.DataSampleFormat).bps;
txt=['SegyRevision ',sprintf('%0.4g',Revision),', ',FormatName,'(',num2str(SegyHeader.DataSampleFormat),')'];

%Revision=SegyHeader.SegyFormatRevisionNumber;
%if Revision>0, Revision=1; end
%FormatName=SegyHeader.Rev(Revision+1).DataSampleFormat(SegyHeader.DataSampleFormat).name;
%Format=SegyHeader.Rev(Revision+1).DataSampleFormat(SegyHeader.DataSampleFormat).format;
%BPS=SegyHeader.Rev(Revision+1).DataSampleFormat(SegyHeader.DataSampleFormat).bps;
%txt=['SegyRevision ',sprintf('%0.4g',Revision),',
%',FormatName,'(',num2str(SegyHeader.DataSampleFormat),')'];%

fseek(segyid,0,'eof'); DataEnd=ftell(segyid);

DataStart=3600+3200*SegyHeader.NumberOfExtTextualHeaders;
fseek(segyid,DataStart,'bof');       % Go to the beginning of the file

ntraces=(DataEnd-DataStart)./(240+(SegyHeader.ns)*(BPS/8));

hval=zeros(1,ntraces);
for itrace=1:ntraces
        if ((itrace/10000)==round(itrace/10000))
	  progress_txt(itrace,ntraces,'Trace #')
 	end

	%GOTO START OF TRACE HEADER
 	skip=DataStart+(itrace-1)*(240+(BPS/8)*SegyHeader.ns);
	fseek(segyid,skip,'bof');
	fseek(segyid,pos,'cof');
	hval(itrace)=fread(segyid,1,precision);

end
fclose(segyid);


function [rd, boardName] = hdlcoder_ref_design_customization
% Reference design plugin registration file
% 1. The registration file with this name inside of a board plugin folder
%    will be picked up
% 2. Any registration file with this name on MATLAB path will also be picked up
% 3. The registration file returns a cell array pointing to the location of
%    the reference design plugins
% 4. The registration file also returns its associated board name
% 5. Reference design plugin must be a package folder accessible from
%    MATLAB path, and contains a reference design definition file

%   Copyright 2013-2014 The MathWorks, Inc.

rd = {...
    'AnalogDevices.pluto.plugin_rd_rx', ...
    'AnalogDevices.pluto.plugin_rd_tx', ...
    'AnalogDevices.pluto.plugin_rd_rxtx', ...
    };

boardName = 'AnalogDevices ADALM-PLUTO';

end


function res=mocov_find_files(root_dir, file_pat, monitor, exclude_pat)
% Finds files recursively in a directory
%
% res=mocov_find_files([root_dir[, file_pat]])
%
% Inputs:
%   root_dir            Optional directory in which files are sought.
%                       If not provided or empty, the current working
%                       directory is used.
%   file_pat            Optional wildcard pattern, e.g. '*.m' for all
%                       files ending with '.m'. If omitted, the pattern '*'
%                       is used, corresponding to all files.
%   monitor             Optional progress monitory that supports a
%                       'notify' method.
%   exclude_pat         Optional cell array of patterns to exclude. Both
%                       files and directories which match one of these
%                       patterns will be omitted from the output.
%
% Output:
%   res                 Kx1 cell with names of files in root_dir matching
%                       the pattern.
%
% NNO May 2015

    if nargin<1
        root_dir='';
    end

    if ~(isempty(root_dir) || mocov_util_isfolder(root_dir))
        error('first argument must be directory');
    end

    if nargin<2
        file_pat='*';
    end

    if nargin<3
        monitor=[];
    end

    if nargin<4
        exclude_pat={};
    end

    if ischar(exclude_pat)
        exclude_pat={exclude_pat};
    end

    file_re=pattern2re(file_pat);
    exclude_re=get_exclude_re(exclude_pat);

    if ~isempty(monitor)
        msg=sprintf('Finding files matching %s from %s',file_pat,root_dir);
        notify(monitor, msg);
    end

    res=find_files_recursively(root_dir,file_re,monitor,exclude_re);

function re=pattern2re(pat)
    re=['^' ... % start of the string
        regexptranslate('wildcard',pat) ...
        '$'];   % end of the string

function re=get_exclude_re(exclude_pat)
    n=numel(exclude_pat);
    if n==0
        re='';
        return;
    end

    excl_re_cell=cellfun(@pattern2re,exclude_pat,...
                        'UniformOutput',false);

    joined=sprintf('|%s',excl_re_cell{:});
    re=joined(2:end);

function res=find_files_recursively(root_dir,file_re,monitor,exclude_re)
    if isempty(root_dir)
        dir_arg={};
    else
        dir_arg={root_dir};
    end

    d=dir(dir_arg{:});
    n=numel(d);

    res_cell=cell(n,1);
    for k=1:n
        fn=d(k).name;

        ignore_fn=strcmp(fn,'.') || strcmp(fn,'..');

        res=cell(0,1);
        if ~ignore_fn
            path_fn=fullfile(root_dir, fn);

            if ~isempty(regexp(fn,exclude_re,'once'));
                continue;
            elseif mocov_util_isfolder(path_fn)
                res=find_files_recursively(path_fn,file_re,...
                                                monitor,exclude_re);
            elseif ~isempty(regexp(fn,file_re,'once'));
                res={path_fn};
                if ~isempty(monitor)
                    notify(monitor,'.',path_fn);
                end
            end
        end
        res_cell{k}=res;
    end

    res_cell=res_cell(~cellfun(@isempty,res_cell));
    res=cat(1,res_cell{:});


function job = mergeInclusions(job, varargin)
% merge inclusions into grains
%
% Syntax
%   job.mergeInclusions
%
% Input
%  job - @parentGrainReconstructor
%
% Output
%  job.grains - reconstructed parent grains
%  job.mergeId -
%
% Options
%  maxSize - maximum pixel size of an inclusion to be merged
%

[job.grains, mergeId] = merge(job.grains, 'inclusions', job.isChild | job.isParent, ...
  'host', job.isParent, varargin{:});
job.mergeId = mergeId(job.mergeId); %#ok<*PROPLC>

end


%% (Internal) Display as formated strings an XML node array
%
%
% See also read_hl7a_format
%
% Author: Mariano Llamedo Soria llamedom@electron.frba.utn.edu.ar
% Version: 0.1 beta
% Last update: 10/05/2016
% Birthdate  : 10/05/2016
% Copyright 2008-2016
%
function strAux = disp_xml_nodes(thisNode)

    strAux = [];

    for jj = 0:(thisNode.getLength-1)

        element = thisNode.item(jj);

        strAux = sprintf( '%s <%s' , strAux, char(element.getTagName) );

        thisCode_att = element.getAttributes;

        for ii = 0:(thisCode_att.getLength-1)

            this_att = thisCode_att.item(ii);

            strAux = sprintf( '%s %s ' , strAux, char(this_att.toString) );

        end

        strAux = sprintf( '%s>\n' , strAux );

    end


%  converts a basic IRIS file into a RISE one
%
%  iris2rise(irisFileName)
%  iris2rise(irisFileName,riseFileName)
%  iris2rise(irisFileName,riseFileName,stderr_name)
%


function snf=snirfcreate(varargin)
%
%    snf=snirfcreate
%       or
%    snf=snirfcreate(option)
%    snf=snirfcreate('Format',format,'Param1',value1, 'Param2',value2,...)
%
%    Create a empty SNIRF data structure defined in the SNIRF
%    specification: https://github.com/fNIRS/snirf
%
%    author: Qianqian Fang (q.fang <at> neu.edu)
%
%    input:
%        option (optional): option can be ignored. If it is a string with a
%             value 'snirf', this creates a default SNIRF data structure;
%             otherwise, a JSNIRF data structure is created.
%        format: save as option.
%        param/value:   a list of name/value pairs specify
%             additional subfields to be stored under the /nirs object.
%
%    output:
%        snf: a default SNIRF or JSNIRF data structure.
%
%    example:
%        snf=snirfcreate('data',mydata,'aux',myauxdata,'comment','test');
%
%    this file is part of JSNIRF specification: https://github.com/fangq/snirf
%
%    License: GPLv3 or Apache 2.0, see https://github.com/NeuroJSON/jsnirf for details
%

if(nargin==1)
    snf=jsnirfcreate(varargin{:});
else
    snf=jsnirfcreate('Format','snirf',varargin{:});
end


function y = testall( func, x )
y = do_test( func, x.value_ );

function y = do_test( func, x )
switch class( x ),
    case 'struct',
        y = do_test( func, struct2cell( x ) );
    case 'cell',
        y = all( cellfun( func, x ) );
    otherwise,
        y = feval( func, x );
end

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


function varargout = kj_grid(varargin)
% KJ_GRID Application M-file for kj_grid.fig
%    FIG = KJ_GRID launch kj_grid GUI.
%    KJ_GRID('callback_name', ...) invoke the named callback.

% Last Modified by GUIDE v2.0 12-Jun-2002 11:51:21

if nargin == 1  % LAUNCH GUI

  fig = openfig(mfilename,'reuse');

  % Use system color scheme for figure:
  set(fig,'Color',get(groot,'defaultUicontrolBackgroundColor'));

  % Generate a structure of handles to pass to callbacks, and store it.
  handles = guihandles(fig);
  guidata(fig, handles);

  if varargin{1} == 1
    set(handles.lblSpacingDepth, 'String', 'Latitude spacing [deg]:');
    set(handles.txtSpacingDepth, 'String', '0.1');
    set(handles.lblSpacingHorizontal, 'String', 'Longitude spacing [deg]:');
    set(handles.txtSpacingHorizontal, 'String', '0.1');
  else
    set(handles.lblSpacingDepth, 'String', 'Depth spacing [km]:');
    set(handles.txtSpacingDepth, 'String', '1');
    set(handles.lblSpacingHorizontal, 'String', 'Horizontal spacing [km]:');
    set(handles.txtSpacingHorizontal, 'String', '1');
  end

  if get(handles.chkRandomNode, 'Value') == 1
    set(handles.txtNumberCalculationNode, 'Enable', 'on');
    set(handles.chkRandomArea, 'Enable', 'on');
    if get(handles.chkRandomArea, 'Value') == 1
      set(handles.txtNumberCalculationArea, 'Enable', 'on');
    else
      set(handles.txtNumberCalculationArea, 'Enable', 'off');
    end
  else
    set(handles.txtNumberCalculationNode, 'Enable', 'off');
    set(handles.chkRandomArea, 'Enable', 'off');
    set(handles.txtNumberCalculationArea, 'Enable', 'off');
  end

  if get(handles.chkLearningPeriod, 'Value') == 1
    set(handles.txtLearningPeriod, 'Enable', 'on');
  else
    set(handles.txtLearningPeriod, 'Enable', 'off');
  end

  if get(handles.chkForecastPeriod, 'Value') == 1
    set(handles.txtForecastPeriod, 'Enable', 'on');
  else
    set(handles.txtForecastPeriod, 'Enable', 'off');
  end

  if get(handles.radNumber, 'Value') == 1
    set(handles.txtNumber, 'Enable', 'on');
    set(handles.radRadius, 'Value', [0]);
    set(handles.txtRadius, 'Enable', 'off');
  else
    set(handles.txtNumber, 'Enable', 'off');
    set(handles.radRadius, 'Value', [1]);
    set(handles.txtRadius, 'Enable', 'on');
  end

  if get(handles.chkSaveParameter, 'Value') == 1
    set(handles.btnSaveParameter, 'Enable', 'on');
  else
    set(handles.btnSaveParameter, 'Enable', 'off');
  end

  if get(handles.chkMinMag, 'Value') == 1
    set(handles.txtMinMag, 'Enable', 'off');
  else
    set(handles.txtMinMag, 'Enable', 'on');
  end

  % Wait for callbacks to run and window to be dismissed:
  uiwait(fig);

  if nargout > 0
    varargout{1} = fig;
  end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

  try
    [varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
  catch
    disp(lasterr);
  end

end

% --------------------------------------------------------------------
function varargout = radNumber_Callback(h, eventdata, handles, varargin)

if get(handles.radNumber, 'Value') == 1
  set(handles.txtNumber, 'Enable', 'on');
  set(handles.radRadius, 'Value', [0]);
  set(handles.txtRadius, 'Enable', 'off');
  set(handles.radRectangle, 'Value', [0]);
  set(handles.txtSizeRectHorizontal, 'Enable', 'off');
  set(handles.txtSizeRectDepth, 'Enable', 'off');
else
  set(handles.txtNumber, 'Enable', 'off');
  set(handles.radRadius, 'Value', [1]);
  set(handles.txtRadius, 'Enable', 'on');
end

% --------------------------------------------------------------------
function varargout = radRadius_Callback(h, eventdata, handles, varargin)

if get(handles.radRadius, 'Value') == 1
  set(handles.txtRadius, 'Enable', 'on');
  set(handles.radNumber, 'Value', [0]);
  set(handles.txtNumber, 'Enable', 'off');
  set(handles.radRectangle, 'Value', [0]);
  set(handles.txtSizeRectHorizontal, 'Enable', 'off');
  set(handles.txtSizeRectDepth, 'Enable', 'off');
else
  set(handles.txtRadius, 'Enable', 'off');
  set(handles.radNumber, 'Value', [1]);
  set(handles.txtNumber, 'Enable', 'on');
end

% --------------------------------------------------------------------
function varargout = radRectangle_Callback(h, eventdata, handles, varargin)

if get(handles.radRectangle, 'Value') == 1
  set(handles.txtSizeRectHorizontal, 'Enable', 'on');
  set(handles.txtSizeRectDepth, 'Enable', 'on');
  set(handles.radRadius, 'Value', [0]);
  set(handles.txtRadius, 'Enable', 'off');
  set(handles.radNumber, 'Value', [0]);
  set(handles.txtNumber, 'Enable', 'off');
else
  set(handles.txtRadius, 'Enable', 'off');
  set(handles.radNumber, 'Value', [1]);
  set(handles.txtNumber, 'Enable', 'on');
end

% --------------------------------------------------------------------
function varargout = chkRandomNode_Callback(h, eventdata, handles, varargin)

if get(handles.chkRandomNode, 'Value') == 1
  set(handles.txtNumberCalculationNode, 'Enable', 'on');
  set(handles.chkRandomArea, 'Enable', 'on');
  if get(handles.chkRandomArea, 'Value') == 1
    set(handles.txtNumberCalculationArea, 'Enable', 'on');
  else
    set(handles.txtNumberCalculationArea, 'Enable', 'off');
  end
else
  set(handles.txtNumberCalculationNode, 'Enable', 'off');
  set(handles.chkRandomArea, 'Enable', 'off');
  set(handles.txtNumberCalculationArea, 'Enable', 'off');
end

% --------------------------------------------------------------------
function varargout = chkRandomArea_Callback(h, eventdata, handles, varargin)

if get(handles.chkRandomArea, 'Value') == 1
  set(handles.txtNumberCalculationArea, 'Enable', 'on');
else
  set(handles.txtNumberCalculationArea, 'Enable', 'off');
end

% --------------------------------------------------------------------
function varargout = chkLearningPeriod_Callback(h, eventdata, handles, varargin)

if get(handles.chkLearningPeriod, 'Value') == 1
  set(handles.txtLearningPeriod, 'Enable', 'on');
else
  set(handles.txtLearningPeriod, 'Enable', 'off');
end

% --------------------------------------------------------------------
function varargout = chkForecastPeriod_Callback(h, eventdata, handles, varargin)

if get(handles.chkForecastPeriod, 'Value') == 1
  set(handles.txtForecastPeriod, 'Enable', 'on');
else
  set(handles.txtForecastPeriod, 'Enable', 'off');
end

% --------------------------------------------------------------------
function varargout = chkSaveParameter_Callback(h, eventdata, handles, varargin)

if get(handles.chkSaveParameter, 'Value') == 1
  set(handles.btnSaveParameter, 'Enable', 'on');
else
  set(handles.btnSaveParameter, 'Enable', 'off');
end

% --------------------------------------------------------------------
function varargout = chkMinMag_Callback(h, eventdata, handles, varargin)

if get(handles.chkMinMag, 'Value') == 1
  set(handles.txtMinMag, 'Enable', 'off');
else
  set(handles.txtMinMag, 'Enable', 'on');
end

% --------------------------------------------------------------------
function varargout = btnSaveParameter_Callback(h, eventdata, handles, varargin)

[newfile, newpath] = uiputfile('*.mat','Choose parameter file');
% Cancel pressed?
if isequal(newfile, 0)  ||  isequal(newpath, 0)
  return;
end
% Everything ok?
newfile = [newpath newfile];
if length(newfile) > 1
  set(handles.lblSaveParameter, 'String', newfile);
end

% --------------------------------------------------------------------
function varargout = btnCancel_Callback(h, eventdata, handles, varargin)

handles.answer = 0;
guidata(h, handles);
uiresume(handles.figGrid);

% --------------------------------------------------------------------
function varargout = btnOk_Callback(h, eventdata, handles, varargin)

% Validation of inputs
if get(handles.radNumber, 'Value') == 1
  Tmp = str2double(get(handles.txtNumber, 'String'));
  if (isnan(Tmp) | (Tmp ~= round(Tmp)) | (Tmp <= 0))
    errordlg('Number of events must be a positive integer value');
    return;
  end
end

if get(handles.radRadius, 'Value') == 1
  Tmp = str2double(get(handles.txtRadius, 'String'));
  if (isnan(Tmp) | (Tmp <= 0))
    errordlg('Constant radius must be a positive float value');
    return;
  end
end

Tmp = str2double(get(handles.txtMinimumNumber, 'String'));
if (isnan(Tmp) | (Tmp ~= round(Tmp)) | (Tmp <= 0))
  errordlg('Minimum number of events must be a positive integer value');
  return;
end

Tmp = str2double(get(handles.txtSpacingHorizontal, 'String'));
if (isnan(Tmp) | (Tmp <= 0))
  errordlg('Horizontal spacing must be a positive float value');
  return;
end

Tmp = str2double(get(handles.txtSpacingDepth, 'String'));
if (isnan(Tmp) | (Tmp <= 0))
  errordlg('Depth spacing must be a positive float value');
  return;
end

if get(handles.chkLearningPeriod, 'Value') == 1
  Tmp = str2double(get(handles.txtLearningPeriod, 'String'));
  if (isnan(Tmp) | (Tmp <= 0))
    errordlg('Learning period must be a positive float value');
    return;
  end
end

if get(handles.chkForecastPeriod, 'Value') == 1
  Tmp = str2double(get(handles.txtForecastPeriod, 'String'));
  if (isnan(Tmp) | (Tmp <= 0))
    errordlg('Forecasting period must be a positive float value');
    return;
  end
end

Tmp = str2double(get(handles.txtSplitTime, 'String'));
if (isnan(Tmp) | (Tmp <= 0))
  errordlg('Splitting time must be a positive float value');
  return;
end

if get(handles.chkRandomNode, 'Value') == 1
  Tmp = str2double(get(handles.txtNumberCalculationNode, 'String'));
  if (isnan(Tmp) | (Tmp ~= round(Tmp)) | (Tmp <= 0))
    errordlg('Number of calculations per node must be a positive integer value');
    return;
  end
  if get(handles.chkRandomArea, 'Value') == 1
    Tmp = str2double(get(handles.txtNumberCalculationArea, 'String'));
    if (isnan(Tmp) | (Tmp ~= round(Tmp)) | (Tmp <= 0))
      errordlg('Number of calculations over area must be a positive integer value');
      return;
    end
  end
end

if get(handles.chkSaveParameter, 'Value') == 1
  Tmp = get(handles.lblSaveParameter, 'String');
  if isempty(Tmp)
    errordlg('Please select a filename for storing the parameters.');
    return;
  end
end

if get(handles.chkMinMag, 'Value') == 0
  Tmp = str2double(get(handles.txtMinMag, 'String'));
  if (isnan(Tmp) | ((Tmp * 10) ~= round(Tmp * 10)) |(Tmp <= 0))
    errordlg('Minimum magnitude must be a positive float value (precision 0.1)');
    return;
  end
end

Tmp = str2double(get(handles.txtMaxMag, 'String'));
if (isnan(Tmp) | ((Tmp * 10) ~= round(Tmp * 10)) |(Tmp <= 0))
  errordlg('Maximum magnitude must be a positive float value (precision 0.1)');
  return;
end

% OK, proceed
handles.answer = 1;
guidata(h, handles);
uiresume(handles.figGrid);


function S=nowStr(f)

switch nargin
    case 0
        S = datestr(now,'yyyy_mm_dd');
    case 1
        S = datestr(now,f);
end

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


%  Mex code here based on GrabBitmaps.cpp in DirectShow samples
%

MS_platform_sdk = 'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\';

include_dirs = [' -DMSWIN -I''', MS_platform_sdk, '\Samples\Multimedia\DirectShow\BaseClasses'' '];
include_dirs = [include_dirs, ' -I''', MS_platform_sdk, '\Include'''];
include_dirs = [include_dirs, ' -I''C:\Program Files (x86)\Microsoft DirectX SDK (November 2007)\Include'''];

libraries = [' ''', MS_platform_sdk, '\Samples\Multimedia\DirectShow\BaseClasses\Release\strmbase.lib'''];
libraries = [libraries, ' zlib.lib winmm.lib'];
libraries = [libraries, ' Filters.cpp VidHeader.cpp showErrMsgBox.cpp read-frame.cpp'];

mex_cpps = {'dxAviOpenMex.cpp', 'dxConvertToAviMex.cpp', 'dxAviReadMex.cpp', 'dxAviCloseMex.cpp'};
for mexi = 1:length(mex_cpps);
    eval(['mex -O ', mex_cpps{mexi}, ' ', include_dirs, libraries]);
end


if (~isdeployed)
    addpath('lib/pose');
    addpath('lib/pose/multicut');
    addpath('lib/utils');
    addpath('lib/vis');
    addpath('lib/eval');
    addpath('lib/multicut');
    addpath('lib/multicut/hdf5');
    caffe_dir = 'external/caffe/matlab/';
    if exist(caffe_dir)
        addpath(caffe_dir);
    else
        warning('Please install Caffe in ./external/caffe');
    end
    addpath('external/liblinear-1.94/matlab/')
    fprintf('Pose startup done\n');
end


%% patch2EdgeIm
% Below is a demonstration of the features of the |patch2EdgeIm| function

%%
clear; close all; clc;

%% Syntax
% |[varargout]=patch2EdgeIm(varargin);|

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


function res = read(varargin)
opts.scoresroot = fullfile(hb_path, 'scores_new');
opts = vl_argparse(opts, varargin);
scoresroot = opts.scoresroot;
dirs = utls.listdirs(scoresroot);

res.verification = cell(1, numel(dirs));
res.matching = cell(1, numel(dirs));
res.retrieval = cell(1, numel(dirs));

for resi = 1:numel(dirs)
  res.verification{resi} = readtable(fullfile(scoresroot, dirs{resi}, 'verification.csv'));
  res.matching{resi} = readtable(fullfile(scoresroot, dirs{resi}, 'matching.csv'));
  res.retrieval{resi} = readtable(fullfile(scoresroot, dirs{resi}, 'retrieval.csv'));
end
res.verification = vertcat(res.verification{:});
res.matching = vertcat(res.matching{:});
res.retrieval = vertcat(res.retrieval{:});
end


classdef FMS_Cmd < Simulink.IntEnumType
    enumeration
        None(0)
        PreArm(1000)
        Arm(1001)
        Disarm(1002)
        Takeoff(1003)
        Land(1004)
        Return(1005)
        Pause(1006)
        Continue(1007)
    end

    methods (Static)

        function defaultValue = getDefaultValue()
            % GETDEFAULTVALUE  Returns the default enumerated value.
            %   If this method is not defined, the first enumeration is used.
            defaultValue = FMS_Cmd.None;
        end

        function dScope = getDataScope()
            % GETDATASCOPE  Specifies whether the data type definition should be imported from,
            %               or exported to, a header file during code generation.
            dScope = 'Auto';
        end

        function desc = getDescription()
            % GETDESCRIPTION  Returns a description of the enumeration.
            desc = 'enumeration of FMS command';
        end

        function fileName = getHeaderFile()
            % GETHEADERFILE  Returns path to header file if non-empty.
            fileName = '';
        end

        function flag = addClassNameToEnumNames()
            % ADDCLASSNAMETOENUMNAMES  Indicate whether code generator applies the class name as a prefix
            %                          to the enumeration.
            flag = true;
        end

    end
end


function err = fitFunction(var,funName,params,freeList,origVarargin)
%err = fitFunction(var,funName,params,freeList,origVarargin)
%
%Support function for 'fit.m'
%Written by G.M Boynton

%stick values of var into params

params = var2params(var,params,freeList);

%evaluate the function

evalStr = sprintf('err = %s(params',funName);
for i=1:length(origVarargin)
  evalStr= [evalStr,',origVarargin{',num2str(i),'}'];
end
evalStr = [evalStr,');'];
eval(evalStr);


function namesPhysContrasts = tapas_physio_get_contrast_names_default()
% Returns cell of defaults names for phys contrasts used e.g. in reporting
%
%   namesPhysContrasts = tapas_physio_get_contrast_names_default()
%
% IN
%
% OUT
%
% EXAMPLE
%   tapas_physio_get_contrast_names_default
%
%   See also tapas_physio_report_contrasts tapas_physio_compute_tsnr_gains

% Author: Lars Kasper
% Created: 2016-10-03
% Copyright (C) 2016 TNU, Institute for Biomedical Engineering,
%                    University of Zurich and ETH Zurich.
%
% This file is part of the TAPAS PhysIO Toolbox, which is released under the terms of the GNU General Public
% License (GPL), version 3. You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version). For further details, see the file
% COPYING or <http://www.gnu.org/licenses/>.

namesPhysContrasts = {
    'All Phys'
    'Cardiac'
    'Respiratory'
    'Card X Resp Interation'
    'HeartRateVariability'
    'RespiratoryVolumePerTime'
    'Noise Rois'
    'Movement'
    'All Phys + Move'
    };


%SUM Dataset overload


function ufmf2avi(infile,outfile,frms)

[readframe,nframes,movie_fid,headerinfo]= ...
  get_readframe_fcn(infile);

if nargin>2
  nframes = frms;
end

writerObj = VideoWriter(outfile);

writerObj.FrameRate = 30;
writerObj.Quality = 60;

open(writerObj);

for ndx = 1:nframes
  ii = readframe(ndx);
  if mod(ndx,1000) == 0,
      fprintf('Frame %d / %d, video %s\n',ndx,nframes,infile);
  end
   writeVideo(writerObj,ii);
end

close(writerObj);

if movie_fid>0
  fclose(movie_fid);

end


classdef FminconUseParallelEnum < matlab.mixin.SetGet
    %FminconUseParallelEnum Summary of this class goes here
    %   Detailed explanation goes here

    enumeration
        UseParallel('Compute Gradients in Parallel',true)
        DoNotUseParallel('Compute Gradients in Serial',false);
    end

    properties
        name char = '';
        optionVal(1,1) logical = true
    end

    methods
        function obj = FminconUseParallelEnum(name, optionVal)
            obj.name = name;
            obj.optionVal = optionVal;
        end
    end

    methods(Static)
        function listBoxStr = getListBoxStr()
            m = enumeration('FminconUseParallelEnum');
            [~,I] = sort({m.name});
            listBoxStr = {m(I).name};
        end

        function [ind, enum] = getIndForName(name)
            m = enumeration('FminconUseParallelEnum');
            [~,I] = sort({m.name});
            m = m(I);
            ind = find(ismember({m.name},name),1,'first');
            enum = m(ind);
        end

        function [enum, ind] = getEnumForListboxStr(nameStr)
            m = enumeration('FminconUseParallelEnum');
            ind = find(ismember({m.name},nameStr),1,'first');
            enum = m(ind);
        end
    end
end