function roi = roiCreate(reference,coords,varargin)
% Create an ROI for an MR object. [May want to add distinct
% function for creating mesh ROIs, though it seems they may
% rather be Xformed from mrMesh...?]
%
%  roi = roiCreate(reference,coords,'Property',[value],...)
%
% Inputs:
% reference: can be either a string specifying a space type
%   (see mrFormatDescription for some possible spaces) or an
%   mr object.
%
%   If it is a string, the ROI can only be processed
%   by mr objects which have that space defined in their spaces
%   fields, and the coordinates will be transformed into the
%   data space of each MR object as needed.
%
%   If it is an mr object,
%   the coords will be considered to refer to rows, columns, and
%   slices in the mr.data field, and can be xformed to other mr objects
%   which share a common space definition with the reference MR object.
%
% coords: 3xN array (integer or double) in which different columns
%   represent different coordinates/voxels in the reference space.
%   The rows describe [Y X Z] in that space: that is the first row of
%   coords describes the rows in each space, the second row describes
%   columns, and the third describes slices. If omitted, coords are
%   left empty.
%
% Properties are:
%   'name',[string]: specify a name for the ROI.
%   'color',[char or [R G B]]: specify a color [default 'b', blue]
%   'referenceMR',[mr]:  mr object on which the ROI has been defined (for when
%       defining with reference to an xformed space -- e.g, if defined
%       on a talairached volume anatomy)
%    'type':  ROI types include:
%               'volume': volume of interest, usually defined on an MR object
%               'patch': 2D patch, usually defined on a surface mesh
%               'line': 1D line, e.g. AC/PC line, or isoeccentricity line
%               'point': single 0D point, e.g. AC or PC, center of a volume ROI
% Wandell and ras, 2005
% ras, 2006: removed requirement for a reference space. Can just return an
% empty ROI.

if notDefined('reference'), reference = 'Raw Data in Pixels'; end
if notDefined('coords'), coords = []; end

%%%%%create a blank ROI
roi.name = 'New ROI';
roi.type = 'volume';
roi.reference = ''; % coordinate space on which ROI is defined
roi.coords = coords;
roi.space = '';
roi.referenceMR =[]; % MR object on which ROI is defined
roi.definedCoords = coords; % coords on which ROI was initially defined
roi.voxelSize = [];  % size of voxels for coords
roi.dimUnits = {'mm' 'mm' 'mm'};
roi.color = 'b';     % can be [R G B] or 'c' -- here 'b'=blue
roi.fillMode = 'perimeter'; % 'perimeter', 'filled', 'patches'
roi.viewType = 'Inplane'; % default: should be over-ridden later
roi.created = datestr(clock);  % permanent stamp on when ROI is created
roi.modified = datestr(clock); % stamp on date of last ROI modification
roi.comments = '';
roi.local = 'local'; % save in local or shared directory

%%%%%parse reference space
if ischar(reference)
    roi.reference = reference;

elseif isstruct(reference)
    roi.reference = 'Pixel Space';
    roi.referenceMR.name = reference.name;
    roi.referenceMR.path = reference.path;
    roi.referenceMR.voxelSize = reference.voxelSize;
    roi.referenceMR.dims = reference.dims;
    roi.referenceMR.extent = reference.extent;
    roi.referenceMR.spaces = reference.spaces;

end

%%%%%parse properties
for i = 1:2:length(varargin)
    switch lower(varargin{i})
        case 'name', roi.name = varargin{i+1};
        case 'color', roi.color = varargin{i+1};
        case 'referencemr', roi.referenceMR = varargin{i+1};
        case 'type', roi.type = varargin{i+1};
		case 'voxelsize', roi.voxelSize = varargin{i+1};
        otherwise, % quietly ignore
    end
end

%%%%%if an mr struct is provided, get the voxel size from it
if ~isempty(roi.referenceMR)
	if ischar(roi.referenceMR), hdr = mrLoadHeader(roi.referenceMR);
	else,						hdr = roi.referenceMR;
	end
	roi.voxelSize = hdr.voxelSize;
end

return;


function [f] = ma_maxTotalPropMassObjFunc(stateLog, eventID, celBodyData, maData)
%ma_maxTotalPropMass Summary of this function goes here
%   Detailed explanation goes here

    if(ischar(eventID) && strcmpi(eventID,'final'))
        eventNum = max(stateLog(:,13));
    else
        [~, eventNum] = getEventByID(eventID, maData.script);
    end

    eventLog = stateLog(stateLog(:,13)==eventNum,:);
    finalEntry = eventLog(end,:);
    f = -sum(finalEntry(10:12));
end


%% Extentions
% This script shows some of the extensions I have created for accessing
% (and writing) midi files.

%% Tracks
% The standard note matrix from the
% <https://www.jyu.fi/hum/laitokset/musiikki/en/research/coe/materials/miditoolbox/ Midi Toolbox>.
% does not have track information.  My extensions add an eighth column to
% the note matrix with track information.

% Read in a midi file an get the track information
nm = readmidi_java('202.kar',true);
fprintf('There are %d tracks with notes in this midi file.\n', ...
    length(unique(nm(:,8))));
% And write out tracks ...
writemidi_java(nm,'track_demo.mid');
% If we read this newly created midi file back in again, we should get the
% tracks...
nm_new = readmidi_java('track_demo.mid',true);
figure(1);
clf;
plot(nm(:,8) == nm_new(:,8),'b*');
title('Note track numbers check');
xlabel('note number');
ylim([-0.2 1.2]);
set(gca,'YTick',[0,1])
set(gca,'YTickLabel',{'different','same'})

%% Lyrics
% Some midi files have lyrics embedded in them.  If the file extension is
% .kar rather than .mid or .midi, it will almost certainly have lyrics.

% Get the lyrics in text form.  get_lyrics_as_bytes() will give you the raw
% bytes, which may be easier to use for more complex processing.  Some of
% the original lyric commands in the midi file may have unprintable
% characters.  These unprintable characters are converted into hex strings
% by get_lyrics_as_text().
[lyrics info] = get_lyrics_as_text('202.kar');

% Now go ahead and print out the first 20 lyric commands and their times in
% seconds
fprintf('********* FIRST 20 RAW LYRICS ********* \n\n');
for i=1:20
   fprintf('%g: |%s|\n',info(i,2),lyrics{i});
end
fprintf('\n\n');

% Now try to do something a little smarter so that we can see the lyrics
% as lines.  In this particular midi file, 0xd indicates and end of line
% and 0xa indicates a new stanza.
fprintf('********* LYRICS IN STANZAS ********* \n\n');
for i=1:length(lyrics)
    if strcmp(lyrics{i},'[0xd]')
        fprintf('\n');
    elseif strcmp(lyrics{i},'[0xa]')
        fprintf('\n');
    else
        fprintf('%s',lyrics{i});
    end
end

%% Instrumentation
% Program commands change the instrumentation for individual channels in
% tracks.  Each <http://www.midi.org/techspecs/gm1sound.php patch number>
% corresponds to a particular instrument.  My extensions allow you to read
% the patch commands out of an existing midi file and they allow you to
% specify a single patch per channel per track when writing midi files.
% You can listen to the original midi file - with the extension changed to
% .mid - <202.mid here> and the midi file with trumpet vocals
% <vocals_with_trumpet.mid here>.  The vocals start about 6 seconds in.

% first get the note matrix with track information
nm = readmidi_java('202.kar',true);

% now get the program changes
changes = get_program_changes('202.kar');

% let's find out what the patch was for the vocal channel
vocal_patch = changes(changes(:,5) == 3,:);

% it's a piccolo, number 73
fprintf('Vocal patch #: %d\n', vocal_patch(1));

% now let's create a new .mid file where the vocals are on a trumpet (57)
writemidi_seconds(nm,'vocals_with_trumpet.mid',[3 vocal_patch(4) 57]);

%% Tempos
% Tempo commands change the lengths of beats.  The note matrix returned by
% readmidi_java takes these tempo changes into account.

tempos = get_tempos('202.kar');
% There are quite a lot of these changes
figure(1);
clf;
plot(tempos(:,3), tempos(:,1),'*-');
title('Tempo changes in 202.kar');
xlabel('Time (s)');
ylabel('Beats per minute');
ylim([0 max(ylim)]);

% 2010-05-03 Christine Smit csmit@ee.columbia.edu


function [dat] = read_brainvision_eeg(filename, hdr, begsample, endsample, chanindx)

% READ_BRAINVISION_EEG reads raw data from an EEG file and returns it as a Nchans x
% Nsamples matrix.
%
% Use as
%   dat = read_brainvision_eeg(filename, hdr, begsample, endsample)
% where the header should be first read using READ_BRAINVISION_VHDR
%
% See https://www.brainproducts.com/productdetails.php?id=21&tab=5 for the formal
% specification.
%
% See also READ_BRAINVISION_VHDR, READ_BRAINVISION_VMRK

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

if nargin<5
  % read all channels
  chanindx = [];
end

if isequal(chanindx(:)', 1:hdr.NumberOfChannels)
  % read all channels
  chanindx = [];
end

% FIXME it would be nice to also implement the efficient reading of the
% selected channels for the other file formats but at the moment only the
% implementation of the binary multiplexed formats is smart enough.

if strcmpi(hdr.DataFormat, 'binary')
  % this applies both to multiplexed and vectorized
  switch lower(hdr.BinaryFormat)
    case 'int_16'
      sampletype = 'int16';
      samplesize = 2;
    case 'int_32'
      sampletype = 'int32';
      samplesize = 4;
    case 'ieee_float_32'
      sampletype = 'float32';
      samplesize = 4;
  end % case
end % if

if strcmpi(hdr.DataFormat, 'binary') && strcmpi(hdr.DataOrientation, 'multiplexed') && any(strcmpi(hdr.BinaryFormat, {'int_16', 'int_32', 'ieee_float_32'}))
  fid = fopen_or_error(filename, 'rb', 'ieee-le');

  if isempty(chanindx)
    % read all the channels
    fseek(fid, hdr.NumberOfChannels*samplesize*(begsample-1), 'cof');
    dat = fread(fid, [hdr.NumberOfChannels, (endsample-begsample+1)], sampletype);
    % compute real microvolts using the calibration factor (resolution)
    calib = reshape(hdr.resolution,[],1);
    for k = 1:size(dat,2)
      dat(:,k) = calib.*dat(:,k);
    end

  else
    % read only the selected channels
    dat = zeros(length(chanindx), endsample-begsample+1);
    for chan = length(chanindx):-1:1
      fseek(fid, hdr.NumberOfChannels*samplesize*(begsample-1) + (chanindx(chan)-1)*samplesize, 'bof');
      dat(chan,:) = fread(fid, [1, (endsample-begsample+1)], sampletype, (hdr.NumberOfChannels-1)*samplesize);
    end
    % compute real microvolts using the calibration factor (resolution)
    calib = reshape(hdr.resolution(chanindx),[],1);
    for k = 1:size(dat,2)
      dat(:,k) = calib.*dat(:,k);
    end

    % don't do the channel selection again at the end of the function
    chanindx = [];
  end

  fclose(fid);

elseif strcmpi(hdr.DataFormat, 'binary') && strcmpi(hdr.DataOrientation, 'vectorized') && any(strcmpi(hdr.BinaryFormat, {'int_16', 'int_32', 'ieee_float_32'}))
  fid = fopen_or_error(filename, 'rb', 'ieee-le');

  fseek(fid, 0, 'eof');
  hdr.nSamples = ftell(fid)/(4*hdr.NumberOfChannels);
  fseek(fid, 0, 'bof');

  numsamples = (endsample-begsample+1);
  for chan=1:hdr.NumberOfChannels
    fseek(fid, (begsample-1)*4, 'cof');                 % skip the first N samples
    [tmp, siz] = fread(fid, numsamples, sampletype);    % read these samples
    fseek(fid, (hdr.nSamples-endsample)*4, 'cof');      % skip the last M samples
    dat(chan,:) = tmp(:)';
  end

  % compute real microvolts using the calibration factor (resolution)
  calib = reshape(hdr.resolution,[],1);
  for k = 1:size(dat,2)
    dat(:,k) = calib.*dat(:,k);
  end

  fclose(fid);

elseif strcmpi(hdr.DataFormat, 'ascii') && strcmpi(hdr.DataOrientation, 'multiplexed')
  fid = fopen_or_error(filename, 'rt');

  % skip lines if hdr.skipLines is set and not zero
  if isfield(hdr,'skipLines') && hdr.skipLines > 0
    for line=1:hdr.skipLines
      str = fgets(fid);
    end
  end

  for line=1:(begsample-1)
    % read first lines and discard the data in them
    str = fgets(fid);
  end
  dat = zeros(endsample-begsample+1, hdr.NumberOfChannels);
  for line=1:(endsample-begsample+1)
    str = fgets(fid);         % read a single line with Nchan samples
    str(str==',') = '.';      % replace comma with point
    dat(line,:) = str2num(str);
  end

  % transpose the data
  dat = dat';

  fclose(fid);

elseif strcmpi(hdr.DataFormat, 'ascii') && strcmpi(hdr.DataOrientation, 'vectorized')
  fid = fopen_or_error(filename, 'rt');

  % this is a very inefficient fileformat to read data from, since it requires to
  % read in all the samples of each channel and then select only the samples of interest

  dat = zeros(hdr.NumberOfChannels, endsample-begsample+1);
  skipColumns = 0;
  for chan=1:hdr.NumberOfChannels
    % this is very slow, so better give some feedback to indicate that something is happening
    fprintf('reading channel %d from ascii file to get data from sample %d to %d\n', chan, begsample, endsample);

    % check whether columns have to be skipped
    if isfield(hdr,'skipColumns'); skipColumns = hdr.skipColumns; end

    str = fgets(fid);             % read all samples of a single channel
    str(str==',') = '.';          % replace comma with point

    if ~isempty(regexp(str(1:10), '[a-zA-Z]', 'once'))
      % the line starts with letters, not numbers: probably it is a channel label
      % find the first number and remove the preceding part
      sel   = regexp(str(1:10), ' [-0-9]');   % find the first number, or actually the last space before the first number
      label = str(1:(sel));                   % this includes the space
      str   = str((sel+1):end);               % keep only the numbers

      % as heading columns are already removed, set skipColumns to zero
      skipColumns = 0;
    end

    % convert the string into numbers and copy the desired samples over into the data matrix
    tmp = str2num(str);
    dat(chan,:) = tmp(skipColumns+begsample:skipColumns+endsample);
  end

  fclose(fid);

else
  ft_error('unsupported sub-fileformat');
end

if ~isempty(chanindx)
  % for the the multiplexed binary formats the channel selection was
  % already done in the code above, for the other formats the selection
  % still has to be done here
  dat = dat(chanindx,:);
end


function plotx2east
% set the default plot direction of the x-axis

setMTEXpref('xAxisDirection','east');


function [M,behavior,stim] = GetTimeIndexedData(hfig,isAllCells) %#ok<INUSD>
%{
% naming convention used:
M = GetTimeIndexedData(hfig);
M_0 = GetTimeIndexedData(hfig,'isAllCells');
%}

isZscore = getappdata(hfig,'isZscore');
isTrialRes = getappdata(hfig,'isTrialRes');
isClusRes = getappdata(hfig,'isClusRes');

% main data input
if ~isZscore,
    cellResp = getappdata(hfig,'CellResp');
    cellRespAvr = getappdata(hfig,'CellRespAvr');
else
    cellResp = getappdata(hfig,'CellRespZ');
    cellRespAvr = getappdata(hfig,'CellRespAvrZ');
end

isMotorseed = getappdata(hfig,'isMotorseed');
if ~isMotorseed,
    Behavior_full = getappdata(hfig,'Behavior_full');
    BehaviorAvr = getappdata(hfig,'BehaviorAvr');
else
    Behavior_full = getappdata(hfig,'Behavior_full_motorseed');
    BehaviorAvr = getappdata(hfig,'BehaviorAvr_motorseed');
end
stim_full = getappdata(hfig,'stim_full');
stimAvr = getappdata(hfig,'stimAvr');
% other params
isStimAvr = getappdata(hfig,'isStimAvr');
cIX = getappdata(hfig,'cIX');
tIX = getappdata(hfig,'tIX');
% absIX = getappdata(hfig,'absIX');

%% set data
isFullData = getappdata(hfig,'isFullData');
if isFullData

    if isStimAvr,
        if exist('isAllCells','var'),
            M = cellRespAvr(:,tIX);
        else
            M = cellRespAvr(cIX,tIX);
        end
        behavior = BehaviorAvr(:,tIX);
        stim = stimAvr(:,tIX);
    else
        if exist('isAllCells','var'),
            M = cellResp(:,tIX);
        else
            M = cellResp(cIX,tIX);
        end
        behavior = Behavior_full(:,tIX);
        stim = stim_full(:,tIX);
    end

    if isTrialRes
        [~,M] = GetTrialAvrLongTrace(hfig,M);
        [~,behavior] = GetTrialAvrLongTrace(hfig,behavior);
        %     cellRespAvr = getappdata(hfig,'CellRespAvrZ');
    end

    if isClusRes
        gIX = getappdata(hfig,'gIX');
        [~,M] = FindClustermeans(gIX,M);
    end
else
    M = [];
    if isStimAvr,
        behavior = BehaviorAvr(:,tIX);
        stim = stimAvr(:,tIX);
    else
        behavior = Behavior_full(:,tIX);
        stim = stim_full(:,tIX);
    end
end

setappdata(hfig,'behavior',behavior);
setappdata(hfig,'stim',stim);
end


classdef SegmentationLossSemiSupervised < dagnn.Loss
    % SegmentationLossSemiSupervised
    %
    % Similar to dagnn.SegmentationLoss, but also sets pixel weights.
    %
    % Inputs: prediction, labels, labelsImage, [classWeights],
    % isWeaklySupervised, [masksThingsCell]
    % Outputs: loss
    %
    % Note:
    %    - classWeights can be empty, which means they are ignored.
    %    - labels or labelsImage can be empty.
    %
    % Copyright by Holger Caesar, 2016

    properties
        layerFS
        layerWS
    end

    methods
        function outputs = forward(obj, inputs, params) %#ok<INUSD>
            assert(numel(inputs) == 6);
            scoresMap = inputs{1};
            labels = inputs{2};
            labelsImage = inputs{3};
            classWeights = inputs{4};
            isWeaklySupervised = inputs{5};
            masksThingsCell = inputs{6};
            assert(~isempty(isWeaklySupervised));

            if isWeaklySupervised
                outputs = obj.layerWS.forward({scoresMap, labelsImage, classWeights, masksThingsCell}, {});
            else
                outputs = obj.layerFS.forward({scoresMap, labels, classWeights}, {});
            end

            % Combine loss statistics
            imageCount = size(scoresMap, 4);
            n = obj.numAveraged;
            m = n + imageCount;
            obj.average = (n * obj.average + double(gather(outputs{1}))) / m;
            obj.numAveraged = m;
        end

        function [derInputs, derParams] = backward(obj, inputs, ~, derOutputs)
            scoresMap = inputs{1};
            labels = inputs{2};
            labelsImage = inputs{3};
            classWeights = inputs{4};
            isWeaklySupervised = inputs{5};

            if isWeaklySupervised
                derInputs = obj.layerWS.backward({scoresMap, labelsImage, classWeights}, {}, derOutputs);
            else
                derInputs = obj.layerFS.backward({scoresMap, labels, classWeights}, {}, derOutputs);
            end
            derInputs{5} = [];
            derInputs{6} = [];
            derParams = {};
        end

        function obj = SegmentationLossSemiSupervised(varargin)
            obj.load(varargin);
        end

        function forwardAdvanced(obj, layer)
            % Modification: Overrides standard forward pass to avoid giving up when any of
            % the inputs is empty.

            in = layer.inputIndexes;
            out = layer.outputIndexes;
            par = layer.paramIndexes;
            net = obj.net;
            inputs = {net.vars(in).value};

            % clear inputs if not needed anymore
            for v = in
                net.numPendingVarRefs(v) = net.numPendingVarRefs(v) - 1;
                if net.numPendingVarRefs(v) == 0
                    if ~net.vars(v).precious && ~net.computingDerivative && net.conserveMemory
                        net.vars(v).value = [];
                    end
                end
            end

            % call the simplified interface
            outputs = obj.forward(inputs, {net.params(par).value});
            for oi = 1:numel(out)
                net.vars(out(oi)).value = outputs{oi};
            end
        end
    end
end


function printPostSolver(fid, expInfo)
%PRINTPOSTSOLVER   Print commands after solution has been found
%
% Calling sequence:
%   PRINTPOSTSOLVER(FID, EXPINFO)
% where
%   FID:        ID of a file-writing stream.
%   EXPINFO:    Struct containing information for printing the problem.

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

% Extract info from the EXPINFO struct:
allVarNames = expInfo.allVarNames;
allVarString = expInfo.allVarString;
numVars = expInfo.numVars;
indVarNameSpace = expInfo.indVarNameSpace;

% Print commands that will create a plot of the solution obtained:
fprintf(fid, '\n%%%% Plot the solution.\n');
fprintf(fid, 'figure\n');
if ( numVars == 1 ) % Scalar case
    fprintf(fid, 'plot(%s, ''LineWidth'', 2)\n', allVarString);
else
    fprintf(fid, 'plot([%s], ''LineWidth'', 2)\n', allVarString);
end

% Title and xlabel
fprintf(fid, 'title(''Final solution''), xlabel(''%s'')', indVarNameSpace);

% Deal with ylabel (scalar problem) or legend (systems):
if ( numVars == 1 )
    % Scalar problem:
    fprintf(fid, ', ylabel(''%s'')', allVarNames{:});
else
    % Coupled system. Create a legend.
    leg = '';
    for k = 1:numel(allVarNames)-1
        leg = [leg '''' allVarNames{k} '''' ','];
    end
    leg = [leg '''' allVarNames{k+1} ''''];
    fprintf(fid, ', legend(%s)\n', leg);
end

end


function fp = hlp_fingerprint(data,hashed)
% Make a fingerprint (hash) of the given data structure.
% Fingerprint = hlp_fingerprint(Data)
%
% This includes all contents; however, large arrays (such as EEG.data) are only spot-checked. For
% thorough checking, use hlp_cryptohash.
%
% In:
%   Data   : some data structure
%
%   Hashed : whether to return a hash of the fingerprint instead of the full fingerprint string
%            (default: true)
%
% Out:
%   Fingerprint : an integer that identifies the data (or string if Hashed=false)
%
% Notes:
%   The fingerprint is not unique and identifies the data set only with a certain (albeit high)
%   probability.
%
%   On MATLAB versions prior to 2008b, hlp_fingerprint cannot be used concurrently from timers,
%   and also may alter the random generator's state if cancelled via Ctrl+C.
%
% Examples:
%   % calculate the hash of a large data structure
%   hash = hlp_fingerprint(data);
%
% See also:
%   hlp_cryptohash
%
%                                   Christian Kothe, Swartz Center for Computational Neuroscience, UCSD
%                                   2010-04-02

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

if nargin < 2
    hashed = true; end

warning off MATLAB:structOnObject

if hlp_matlab_version >= 707
    fp = fingerprint(data,RandStream('swb2712','Seed',5183),hashed);
else
    try
        % save & override random state
        randstate = rand('state'); %#ok<*RAND>
        rand('state',5183);
        % make the fingerprint
        fp = fingerprint(data,0,hashed);
        % restore random state
        rand('state',randstate);
    catch e
        % restore random state in case of an error...
        rand('state',randstate);
        rethrow(e);
    end
end

% make a fingerprint of the given data structure
function fp = fingerprint(data,rs,hashed)
% convert data into a string representation
data = summarize(data,rs);
% make sure that it does not contain 0's
data(data==0) = 'x';
if hashed
    % obtain a hash code via Java (MATLAB does not support proper integer arithmetic...)
    str = java.lang.String(data);
    fp = str.hashCode()+2^31;
else
    fp = data;
end

% get a recursive string summary of arbitrary data
function x = summarize(x,rs)
if isnumeric(x)
    % numeric array
    if ~isreal(x)
        x = [real(x) imag(x)]; end
    if issparse(x)
        try
            x = [find(x) nonzeros(x)];
        catch
            x = [find(x)' nonzeros(x)];
        end
    end
    if numel(x) <= 4096
        % small matrices are hashed completely
        try
            x = ['n' typecast([size(x) x(:)'],'uint8')];
        catch
            if hlp_matlab_version <= 702
                x = ['n' typecast([size(x) double(x(:))'],'uint8')]; end
        end
    else
        % large matrices are spot-checked
        ne = numel(x);
        count = floor(256 + (ne-256)/1000);
        if hlp_matlab_version < 707
            indices = 1+floor((ne-1)*rand(1,count));
        else
            indices = 1+floor((ne-1)*rand(rs,1,count));
        end
        if size(x,2) == 1
            % x is a column vector: reindexed expression needs to be transposed
            x = ['n' typecast([size(x) x(indices)'],'uint8')];
        else
            % x is a matrix or row vector: shape follows that of indices
            x = ['n' typecast([size(x) x(indices)],'uint8')];
        end
    end
elseif iscell(x)
    % cell array
    sizeprod = cellfun('prodofsize',x(:));
    if all(sizeprod <= 1) && any(sizeprod)
        % all scalar elements (some empty, but not all)
        if all(cellfun('isclass',x(:),'double')) || all(cellfun('isclass',x(:),'single'))
            % standard floating-point scalars
            if cellfun('isreal',x)
                % all real
                x = ['cdr' typecast([size(x) x{:}],'uint8')];
            else
                % some complex
                x = ['cdc' typecast([size(x) real([x{:}]) imag([x{:}])],'uint8')];
            end
        elseif cellfun('isclass',x(:),'logical')
            % all logical
            x = ['cl' typecast(uint32(size(x)),'uint8') uint8([x{:}])];
        elseif cellfun('isclass',x(:),'char')
            % all single chars
            x = ['ccs' typecast(uint32(size(x)),'uint8') x{:}];
        else
            % generic types (structs, cells, integers, handles, ...)
            tmp = cellfun(@summarize,x,repmat({rs},size(x)),'UniformOutput',false);
            x = ['cg' typecast(uint32(size(x)),'uint8') tmp{:}];
        end
    elseif isempty(x)
        % empty cell array
        x = ['ce' typecast(uint32(size(x)),'uint8')];
    else
        % some non-scalar elements
        dims = cellfun('ndims',x(:));
        size1 = cellfun('size',x(:),1);
        size2 = cellfun('size',x(:),2);
        if all((size1+size2 == 0) & (dims == 2))
            % all empty and nondegenerate elements
            if all(cellfun('isclass',x(:),'double'))
                % []'s
                x = ['ced' typecast(uint32(size(x)),'uint8')];
            elseif all(cellfun('isclass',x(:),'cell'))
                % {}'s
                x = ['cec' typecast(uint32(size(x)),'uint8')];
            elseif all(cellfun('isclass',x(:),'struct'))
                % struct()'s
                x = ['ces' typecast(uint32(size(x)),'uint8')];
            elseif length(unique(cellfun(@class,x(:),'UniformOutput',false))) == 1
                % same class
                x = ['cex' class(x{1}) typecast(uint32(size(x)),'uint8')];
            else
                % arbitrary class...
                tmp = cellfun(@summarize,x,repmat({rs},size(x)),'UniformOutput',false);
                x = ['cg' typecast(uint32(size(x)),'uint8') tmp{:}];
            end
        elseif all((cellfun('isclass',x(:),'char') & size1 <= 1) | (sizeprod==0 & cellfun('isclass',x(:),'double')))
            % all horizontal strings or proper empty strings, possibly some []'s
            x = ['cch' [x{:}] typecast(uint32(size2'),'uint8')];
        else
            % arbitrary sizes...
            if all(cellfun('isclass',x(:),'double')) || all(cellfun('isclass',x(:),'single'))
                % all standard floating-point types...
                tmp = cellfun(@vectorize,x,'UniformOutput',false);
                % treat as a big vector...
                x = ['cn' typecast(uint32(size(x)),'uint8')  summarize([tmp{:}],rs)];
            else
                tmp = cellfun(@summarize,x,repmat({rs},size(x)),'UniformOutput',false);
                x = ['cg' typecast(uint32(size(x)),'uint8') tmp{:}];
            end
        end
    end
elseif ischar(x)
    % char array
    x = ['c' x(:)'];
elseif isstruct(x)
    % struct
    fn = fieldnames(x)';
    if numel(x) > length(fn)
        % summarize over struct fields to expose homogeneity
        x = cellfun(@(f)summarize({x.(f)},rs),fn,'UniformOutput',false);
        x = ['s' [fn{:}] ':' [x{:}]];
    else
        % summarize over struct elements
        x = ['s' [fn{:}] ':' summarize(struct2cell(x),rs)];
    end
elseif islogical(x)
    % logical array
    x = ['l' typecast(uint32(size(x)),'uint8') uint8(x(:)')];
elseif isa(x,'function_handle')
    if strncmp(char(x),'@(',2)
        f = functions(x);
        x = ['f' f.function summarize(f.workspace{1},rs)];
    else
        x = ['f ' char(x)];
    end
elseif isobject(x)
    x = ['o' class(x) ':' summarize(struct(x),rs)];
else
    try
        x = ['u' class(x) ':' summarize(struct(x),rs)];
    catch
        warning('BCILAB:hlp_fingerprint:unsupported_type','Unsupported type: %s',class(x));
        error; %#ok<LTARG>
    end
end

function x = vectorize(x)
x = x(:)';


function nSlices = numSlices(vw)
%
% nSlices = numSlices(view)
%
% Number of anatomy slices. Use slices(view,scan) to get
% the slices for a functional scan.
% For volumes/grays, this is a hack that simply returns 1 because
% the data are stored in a vector.
% For flats, there are 2 slices, one for each hemisphere.
% (except across-level flat views, this number is different
% in that case).
%
% djh, 2/21/2001
% ras, 10/04, support for flat level view
%
% jw, 6/2010: Obsolete. Use nSlices = viewGet(vw, 'numSlices') instead

warning('vistasoft:obsoleteFunction', 'numSlices.m is obsolete.\nUsing\n\tnSlices = viewGet(vw, ''numSlices'')\ninstead.');

nSlices = viewGet(vw, 'numSlices');

return

%
% global mrSESSION
%
% switch view.viewType
%     case 'Inplane'
%         nSlices = mrSESSION.inplanes.nSlices;
%     case {'Volume' 'Gray'}
%         nSlices = 1;
%     case 'Flat'
%         if isfield(view,'numLevels') % acr levels view
%             nSlices = 2 + sum(view.numLevels);
%         else
%             nSlices = 2;
%         end
% end
%
% return


function dwped = dtiInitPhaseDim(dwRawPed)
%
%  dwped = dtiInitPhaseDim(dwParams,dwRaw)
%
% Make sure there is a valid phase-encode dir, as this is crucial for
% eddy-current correction. If the phase_dim is not valid in the dwRaw or
% not set in dwParams.phaseEncode prompt the user for it.
%
% If the phase encode direction is not correct in dwRaw.phase_encode. Here
% we ask the user to tell us what it is. We could read this from the dicom
% if we were smart about it. It would be in the dicom header - we would
% have to know where the raw dicoms are and get them out if they're zipped.
% (dicominfo will read the dicom header).
%
%
% INPUTS
%       (dwRawPed) - passed in from dtiInit
% RETURNS
%       dwped - with a valid phase_dim
%
% Web Resources
%       mrvBrowseSVN('dtiInitPhaseDim');
%
% (C) Stanford VISTA, 8/2011 [lmp]
%

%%
%
% Set it to output what was passed in and check it
dwped = dwRawPed;

% Handle the case where the value is passed in as a string
if ischar(dwped)
    dwped = str2double(dwped);
end

% Check the value passed in: If the phase encode direction is not a valid
% value prompt the user until they give a valid value (default is 2 = 'col'
% =  'A/P').
while (dwped < 1 || dwped > 3)
    prompt = sprintf('Phase-encode dir is currently [ %d ], but must be 1 2 or 3. \n (1 = L/R "row", 2 = A/P "col"). \n Enter new value:\n', dwRawPed);
    resp = inputdlg(prompt, 'Set phase encode direction', 1, {'2'});
    if ~isempty(resp)
        dwped = round(str2double(resp{1}));
    elseif isempty(resp)
        error('User aborted! [dtiInitPhaseDim]');
    end
end

return


function add_ndt_paths_and_init_rand_generator

% This function adds all the appropriate directories for the NDT toolbox to work
%   and initializes the random number generator based on the clock (by default
%   Matlab uses the same seed everything it is started which can lead to unwanted behavior).

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

%     This code is part of the Neural Decoding Toolbox.
%     Copyright (C) 2011 by Ethan Meyers (emeyers@mit.edu)
%
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 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/>.

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

% file the path where the toolbox is
toolbox_basedir_name = [fileparts(which('add_ndt_paths_and_init_rand_generator')) '/']

% add all the appropriate sub-directories
addpath([toolbox_basedir_name 'datasources/']);
addpath([toolbox_basedir_name 'feature_preprocessors/']);
addpath([toolbox_basedir_name 'classifiers/']);
addpath([toolbox_basedir_name 'cross_validators/']);
addpath([toolbox_basedir_name 'tools/']);
addpath([toolbox_basedir_name 'helper_functions/']);
addpath(genpath([toolbox_basedir_name 'external_libraries/']));  % include subdirectories of any external libraries

if isOctave
    addpath([toolbox_basedir_name 'octave_code/']);
    'Running Octave - adding Octave specific code to the search path'
end

% initialize the random number generator
rand('state',sum(100*clock));
disp('initializing the matlab random number generator to an aribrary clock value, i.e., the ''rand'' function should now work properly');


classdef EdgeCutInElemComputer < handle

    properties (Access = private)
       nElem
       nEdgeByElem
    end

    properties (Access = private)
      edgesInElem
      isEdgeCut
    end

    methods (Access = public)

        function obj = EdgeCutInElemComputer(cParams)
            obj.init(cParams)
        end

        function isEdgeCut = compute(obj)
            isEdgeCut = false(obj.nEdgeByElem,obj.nElem);
            for iedge = 1:obj.nEdgeByElem
                edge = obj.edgesInElem(:,iedge);
                isEdgeCut(iedge,:) = obj.isEdgeCut(edge);
            end
        end

    end

    methods (Access = private)

        function init(obj,cParams)
            obj.edgesInElem = cParams.edgesInElem;
            obj.isEdgeCut   = cParams.isEdgeCut;
            obj.nElem       = size(obj.edgesInElem,1);
            obj.nEdgeByElem = size(obj.edgesInElem,2);
        end

    end

end


function [classes,uStrings] = prtUtilStringsToClassNumbers(stringCell,uStrings)
%[classes,uniqueStrings] = prtUtilStringsToClassNumbers(stringCell)
%[classes,uniqueStrings] = prtUtilStringsToClassNumbers(stringCell,uStrings)
% xxx Need Help xxx

if nargin < 2
    [uStrings,~,classes] = unique(stringCell);
    return;
end
classes = nan(length(stringCell),1);
for i = 1:length(uStrings);
    classes(strcmpi(uStrings{i},stringCell)) = i;
end


function out = load_volcanoes(~, filename, vname)
    % loads volcano information from a file
    % by default, this loads volcao.mat, which contains
    % a Table called GVPHoloceneVolcanoes
    % This table has several fields that describe the volcano.
    % Most importantly:
    %  VolcanoName - name of volcano
    %  LastKnownEruption - year in which eruption occurred (numeric, not a datetime)
    %  Latitude, Longitude - lat & lon in degrees
    %  Elevationm - elevation in meters
    %  Depth - negative elevation in km

    if ~exist('filename','var')
        filename = 'features/volcano.mat';
    end

    if ~exist('vname','var')
        vname = 'data';
    end

    out = [];

    try
        XX = load(filename, vname);
    catch ME
        error('unable to load volcanoes. Expected variable "%s" in file "%s"',...
        vname, filename)
    end

    if isfield(XX,vname)
        out = XX.(vname);
    end

    if ~isfield(out,'Depth')
        out.Depth= -(out.Elevationm ./ 1000);
    end

    fn = fieldnames(out);
    if ~all(ismember({'VolcanoName','Latitude','Longitude','Elevationm','LastKnownEruption'}, fn))
        warning('loaded volcano file, but it doesn''t appear to have all the required fields');
    end
    out.Name=out.VolcanoName;

end


%kvcocASF 'Alternating Sequential Filter of type Closing(Opening(Closing()))'
% This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros vcocASF.pane file
%
% Parameters:
% InputFile: i 'Input Image ', required: 'input image'
% InputFile: str 'Struct Element', required: 'Structuring Element'
% Integer: n 'Size Struct Elem. ', default: 5: 'size of structure element'
% OutputFile: o 'Output Image ', required: 'resulting output image'
%
% Example: o = kvcocASF({i, str}, {'i','';'str','';'n',5;'o',''})
%
% Khoros helpfile follows below:
%
%  PROGRAM
% vcocASF - Alternating Sequential Filter of type Closing(Opening(Closing()))
%
%  DESCRIPTION
% .I vcocASF
% will do N successive close/open/closes by the same structuring element.
%
% Non-sequential filtering can be selected, so that no iteration is done. Otherwise, there will be iteration from 1 to n.
%
% The output image data type will be the same as that of the highest data type
% of the input image.
%
%
%
%  EXAMPLES
% vcocASF -i feath.xv -str b.str -n 5 -o outimage.xv
%
% Will do 5 successive close/open/closes (vcocASF) of the input image "feath.xv" by the structuring element "b.str" and the resulting image will be written to  "outimage.xv".
%
%  "SEE ALSO"
% vcast1(1)
%
%  RESTRICTIONS
% .I vcocASF
% can be defined for all data types supported by Khoros, but at the moment it has been implemented just for the bit and unsigned char types.
%
%  REFERENCES
%
%  COPYRIGHT
% Copyright (C) 1993-1997 Junior Barrera, Roberto Lotufo.  All rights reserved.
%

function varargout = kvcocASF(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,..] = kvcocASF(Inputs,arglist).');
end
if size(arglist,2)~=2
  error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
 end
narglist={'i', '__input';'str', '__input';'n', 5;'o', '__output'};
maxval={0,0,2,0};
minval={0,0,2,0};
istoggle=[0,0,0,0];
was_set=istoggle * 0;
paramtype={'InputFile','InputFile','Integer','OutputFile'};
% identify the input arrays and assign them to the arguments as stated by the user
if ~iscell(Inputs)
Inputs = {Inputs};
end
NumReqOutputs=1; 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(1,1);
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
[varargout{:}]=callKhoros([w 'vcocASF"  '],Inputs,narglist);


function Z = uplus(Y)
%UPLUS (overloaded)

disp('Most likely you meant to write a + b, but you wrote a +b')
disp('This can easily lead to bugs, as [a +b] is a vector with two elements')
disp('If you really want to use unitary plus, you will have to edit sdpvar/uplus')
disp('and delete this message')
if isa(Y,'blkvar')
    Y = sdpvar(Y);
end

switch Y.typeflag
case {0,5}
	Z = Y;
case {1,3,4}
	error('Relational objects canot be manipulated')
otherwise
	error('Please report internal bug in sdpvar/uplus')
end


classdef pivprogress < handle

	%   Inspired by the parfor_progress script made by Daniel Terry:
	%   https://www.mathworks.com/matlabcentral/fileexchange/53773-parfor-progressbar

	% Public properties
	properties (SetAccess=protected, GetAccess=public)
		hdl;      % Waitbar figure object handle
		N;        % Total number of iterations expected before completion
	end

	properties (Dependent, GetAccess=public)
		percent;  % Percentage of completed iterations
	end

	% Internal properties
	properties (SetAccess=protected, GetAccess=protected, Hidden)
		ipcfile;  % Path to temporary file for inter-process communication
		htimer;   % Timer object that checks ipcfile for completed iterations
	end

	methods
		% Create a new progress bar with N_init iterations before completion.
		function this = pivprogress(N_init, handle)
			% Create a unique inter-process communication file.
			for i=1:10
				f = sprintf('%s%d.txt', mfilename, round(rand*1000));
				this.ipcfile = fullfile(tempdir, f);
				if ~exist(this.ipcfile,'file'), break; end
			end
			if exist(this.ipcfile,'file')
				error('Too many temporary files. Clear out tempdir.');
			end
			try
				setappdata(0,'par_start_time',tic)
				setappdata(0,'par_percent',0)
			catch
			end

			% Create a new waitbar
			this.N = N_init;
			if nargin == 2
				this.hdl = handle;% waitbar(0, varargin{:});
			else
				this.hdl = [];
			end
			% Create timer to periodically update the waitbar in the GUI thread.
			this.htimer = timer( 'ExecutionMode','fixedSpacing', 'Period',2, ...
				'BusyMode','drop', 'Name',mfilename, ...
				'TimerFcn',@(x,y)this.tupdate);
			start(this.htimer);
		end

		function delete(this)
			this.close();
		end

		function close(this)
			% Closer the progress bar and clean up internal state.
			% Stop the timer
			if isa(this.htimer,'timer') && isvalid(this.htimer)
				stop(this.htimer);
				pause(0.01);
				delete(this.htimer);
			end
			this.htimer = [];
			% Delete the IPC file.
			if exist(this.ipcfile,'file')
				delete(this.ipcfile);
			end
			this.hdl = [];
		end

		function percent = get.percent(this)
			% Calculate the fraction of completed iterations from IPC file.
			if ~exist(this.ipcfile, 'file')
				percent = 0;  % File may not exist before the first iteration
			else
				fid = fopen( this.ipcfile, 'r' );
				percent = sum(fscanf(fid, '%d')) / this.N;
				percent = max(0, min(1,percent) );
				fclose(fid);
			end
		end

		function iterate(this, Nitr)
			% Update the progress bar by Nitr iterations (or 1 if not specified).
			if nargin<2,  Nitr = 1;  end
			fid = fopen(this.ipcfile, 'a');
			fprintf(fid, '%d\n', Nitr);
			fclose(fid);
		end
	end %public methods

	methods (Access=protected, Hidden)
		function tupdate(this)
			% Check the IPC file and update the waitbar with progress.
			if ishandle(this.hdl)
				try
					par_start_time=getappdata(0,'par_start_time');
					last_par_percent=getappdata(0,'par_percent');
					elapsd = toc(par_start_time);
					if this.percent > 0.01
						remain_t = elapsd / this.percent *(1-this.percent);
					else
						remain_t=inf;
					end
					hrs=remain_t/60^2;
					mins=(hrs-floor(hrs))*60;
					secs=(mins-floor(mins))*60;
					hrs=floor(hrs);
					mins=floor(mins);
					secs=floor(secs);

					if elapsd < 5
						remain_string='Remaining time: calculating...';
					else
						remain_string=['Remaining time: ' sprintf('%2.2d', hrs) 'h ' sprintf('%2.2d', mins) 'm ' sprintf('%2.2d', secs) 's'];
					end
					if this.percent ~= last_par_percent
						if ~isinf(remain_t)
							set(this.hdl, 'string' , ['Total progress: ' num2str(floor(100*this.percent)) '%' sprintf('\n') remain_string ]); %#ok<SPRINTFN>
						end
						setappdata(0,'par_percent',this.percent)
					end
				catch
				end
				drawnow;
			elseif isempty(this.hdl)
				clc
				disp([num2str(floor(100*this.percent)) ' %']);
			else
				% Kill the timer if the waitbar is closed.
				close(this);
			end
			if exist('cancel_piv','file')
				close(this)
			end
		end
	end %private methods

end %classdef


% The COBRAToolbox: testSurfNet.m
%
% Purpose:
%     - testSurfNet tests the functionality of surfNet
%       and compares it to expected data.
%
% Authors:
%     - Lemmer El Assal March 2017
%     - Siu Hung Joshua Chan July 2017
%

global CBTDIR

% save the current path
currentDir = pwd;

% initialize the test
fileDir = fileparts(which('testSurfNet'));
cd(fileDir);

model = getDistributedModel('ecoli_core_model.mat');

% generate flux data for testing
s = optimizeCbModel(model, 'max', 'one');
model2 = changeRxnBounds(model, {'EX_glc(e)'; 'EX_fru(e)'}, [0; -10], {'L'; 'L'});
s2 = optimizeCbModel(model2, 'max', 'one');
fluxMatrix = [s.x, s2.x];
rxnsDiff = model.rxns(abs(fluxMatrix(:, 1) - fluxMatrix(:, 2)) > 1e-6);
[m, n] = size(model2.S);

% remove old generated file
if exist('surfNet.txt', 'file')
    delete('surfNet.txt');
end

% check normal functionalities
diary('surfNet.txt');

% start with a metabolite
metrxn = '13dpg[c]';
surfNet(model, metrxn);
% continue with a reaction (through clicking only)
surfNet([], 'GAPD', 0, NaN, 0, 1, [], 0);
% continue with a metabolite (through clicking only)
surfNet([], 'g3p[c]', 0, NaN, 0, 1, [], 0);
% print objective reactions given no second input
surfNet(model);
% print a list of reactions without showing details of metabolites
surfNet(model, {'GAPD'; 'FBA'}, [], [], [], 0);
% print *.metNames in reaction formulae
surfNet(model, {'13dpg[c]'; 'GAPD'}, 1);
% show previous steps (through clicking only)
surfNet([], [], 1, NaN, 0, 1, [], 0, [], struct('showPrev', true));

% print with a fixed number of characters per line
surfNet(model, [model.mets(1:10)'; model.rxns(1:10)'], [], [], [], 0, [], 60);
% show previous steps (through clicking only)
surfNet([], [], 0, NaN, 0, 0, [], 60, [], struct('showPrev', true));

% print connected reactions and the corresponding fluxes in a flux vector
surfNet(model, 'pyr[c]', [], s.x, 0);
% print connected reactions with nonzero fluxes only in a flux vector
surfNet(model, 'pyr[c]', [], s.x);
% compare multiple flux vectors
surfNet(model, rxnsDiff, [], fluxMatrix, [], 0);
surfNet(model, rxnsDiff, [], fluxMatrix', [], 0);

% print customized fields
[model2.newRxnProp, model2.newMetProp] = deal(cell(1, n), cell(1, m));
model2.newRxnProp{findRxnIDs(model2, 'GAPD')} = {'a', 'b'};  % cellstr with cells
model2.newMetProp{findMetIDs(model2, '13dpg[c]')} = {'c', 'd'};
[model2.newRxnProp2, model2.newMetProp2] = deal(char('C' * ones(n, 1)), char('E' * ones(m, 1)));  % character arrays
surfNet(model2, {'13dpg[c]'; 'GAPD'}, [], [], [], [], {'metFormulas', 'subSystems', ...
    'grRules', 'b', 'c', 'ub', 'newRxnProp', 'newMetProp', 'newRxnProp2', 'newMetProp2'});
surfNet(model2, {'13dpg[c]'; 'GAPD'}, [], [], [], [], 'lb');

% starting with a gene
surfNet(model, 'b1241')
% continue with another gene shown in the reactions
surfNet([], 'b1478', 0, NaN, 0, 1, [], 0);

% test the search function
surfNet(model, 'glucose')
surfNet(model, 'glucose', 't', 0.6)  % with a more relaxed threshold
surfNet(model, 'ATP')  % a query term with multiple matches in the same object
diary off;

% load the text files
[text1, text2] = deal('');
f = fopen('refData_surfNet.txt', 'r');
l = fgets(f);
while ~isequal(l, -1)
    text1 = [text1, l];
    l = fgets(f);
end
fclose(f);

f = fopen('surfNet.txt', 'r');
l = fgets(f);
while ~isequal(l, -1)
    text2 = [text2, l];
    l = fgets(f);
end
fclose(f);
% locations of linebreaks not constant. Replace linebreaks and consecutive spaces with single space
text1 = regexprep(text1, '\s*', ' ');
text2 = regexprep(text2, '\s*', ' ');

% remove the generated file
delete('surfNet.txt');

% compare the similarity of text using a simple scheme
% (no need to solve a DP here, the two strings are supposed to be highly similar)
[j1, j2, match] = deal(1, 1, 0);
while j1 <= numel(text1) && j2 <= numel(text2)
    if ~strcmp(text1(j1), text2(j2))
        % find the next closest identical character
        [j1skip, j2skip] = deal(1);
        while j2 + j2skip <= numel(text2) && ~strcmp(text1(j1), text2(j2 + j2skip))
            j2skip = j2skip + 1;
        end
        while j1 + j1skip <= numel(text1) && ~strcmp(text1(j1 + j1skip), text2(j2))
           j1skip = j1skip + 1;
        end
        % take the closer identical character from the two strings
        [j1, j2] = deal(j1 + (j1skip <= j2skip) * j1skip, j2 + (j1skip > j2skip) * j2skip);
    end
    match = match + 1;
    [j1, j2] = deal(j1 + 1, j2 + 1);
end
% subtract the last false match if the comparison is terminated due to the
% end of the strings rather than match found
match = match - (j1 == numel(text1) + 2 | j2 == numel(text2) + 2);
score = ((match / numel(text1)) * (match / numel(text2))) ^ 0.5;

fprintf('Compare the printed with the expected results ...\n')
assert(score > 1 - 1e-3);  % some mismatches due to linebreaks and space
fprintf('\nSuccess. Finish testing normal functionalities of surfNet.\n')

% check warnings
diary('surfNet.txt');

% fields not printable
%surfNet(model, object, metNameFlag, flux, nonzeroFluxFlag, showMets, printFields, charPerLine, similarity)
surfNet(model2, '13dpg[c]', [], [], [], [], {'S'});
surfNet(model2, '13dpg[c]', [], [], [], [], {{}, {'rxnGeneMat'}});
% non-existing met/rxn or incorrect input type
surfNet(model2, 'NOTEXIST');
surfNet({{}});

diary off;

% load the text file
textSurfNet = '';
f = fopen('surfNet.txt', 'r');
l = fgets(f);
while ~isequal(l, -1)
    textSurfNet = [textSurfNet, l];
    l = fgets(f);
end
textSurfNet = regexprep(textSurfNet, '\s*', ' ');
fclose(f);

fprintf('Compare the printed warnings with the expected results ...\n')
assert(contains(textSurfNet, 'Warning: surfNet does not support showing S. Ignore.'))
assert(contains(textSurfNet, 'Warning: surfNet does not support showing rxnGeneMat. Ignore.'))
assert(contains(textSurfNet, 'Warning: No related mets, rxns or genes are found from the search. Please try other query terms.'))
assert(contains(textSurfNet, 'Warning: The query term must be either a string or an array of string.'))
assert(contains(textSurfNet, '''NOTEXIST'' is not a metabolite, reaction or gene of the model. Searching for related objects:'))

fprintf('\nSuccess. Finish testing warning output of surfNet.\n')

% remove the generated file
delete('surfNet.txt');

% print a random reaction when the 2nd input 'metrxn' is not given and
% no objective reactions exist.
fprintf('Test printing random reactions ...\n')
model2.c(:) = 0;
surfNet(model2)
surfNet(model2, [], [], fluxMatrix);

fprintf('Test error messages ...\n')
% error messages
% no initialized model exists
clear surfNet
try
    surfNet;
    assert(false)
catch ME
    assert(strcmp(ME.message, 'The persistent variable modelLocal in surfNet is empty. Please supply a COBRA model.'))
end

% incorrect flux matrix input
try
    surfNet(model2, 'fdp[c]', [], fluxMatrix(1:(end - 1), :));
    assert(false)
catch ME
    assert(strcmp(ME.message, 'Input flux vector has incorrect dimension.'))
end

% add two fields with incorrect size and unsupported datatype
[model2.rxnABC, model2.metABC] = deal(repmat(struct(), n - 1, 2), repmat(struct(), m - 1, 2));
incorrectFieldInput = {{'NOTEXIST'}; 'description'; {'rxnABC', 'metABC'}; 0};
% nonexistent fields
errMsg = {'The following field(s) is(are) not in the model: NOTEXIST'; ...
    ... % unrecognizable fields
    'The following field(s) cannot be recognized as met or rxn field(s): description'; ...
    ... % incorrect size and data type
    sprintf(['Incorrect size of the following met field(s): metABC\n', ...
    'The following met field(s) is(are) neither numeric nor cell array of characters: metABC\n', ...
    'Incorrect size of the following rxn field(s): rxnABC\n', ...
    'The following rxn field(s) is(are) neither numeric nor cell array of characters: rxnABC']); ...
    ... % incorrect input format
    ['The value of ''printFields'' is invalid. Must be (1) a cell array of two cells, ', ...
    '1st cell being a character array for met fields and 2nd for rxn fields, ', ...
    'or (2) a character array of field names recognizable from the field names or the sizes.']};
for j = 1:numel(incorrectFieldInput)
    try
        surfNet(model2, 'fdp[c]', [], [], [], [], incorrectFieldInput{j});
        assert(false)
    catch ME
        assert(strcmp(ME.message, errMsg{j}))
    end
end

fprintf('\nSuccess. Finish testing error messages of surfNet.\n')

% test name-value pair input
for j = 1:3
    if exist(['surfNet' num2str(j) '.txt'], 'file')
        delete(['surfNet' num2str(j) '.txt']);
    end
end
surfNet(model, metrxn);

for j = 1:3
    if exist(['surfNet' num2str(j) '.txt'], 'file')
        delete(['surfNet' num2str(j) '.txt'])
    end
end

% reference data
diary('surfNet1.txt')
surfNet(model, 'GAPD');
surfNet([], [], [], [], [], 0);
% print a list of reactions without showing details of metabolites
surfNet(model, {'GAPD'; 'FBA'}, [], [], [], 0);
% print *.metNames in reaction formulae
surfNet(model, {'13dpg[c]'; 'GAPD'}, 1);
% print with a fixed number of characters per line
surfNet(model, [model.mets(1:10)'; model.rxns(1:10)'], [], [], [], 0, [], 60);
surfNet(model, 'pyr[c]', [], s.x, 0);
surfNet(model, 'pyr[c]', [], s.x);
surfNet(model, rxnsDiff, [], fluxMatrix, [], 0);
surfNet(model2, '13dpg[c]', [], [], [], [], {'default', 'lb', 'subSystems'});
diary off

% name-value pair input
diary('surfNet2.txt')
surfNet(model, 'GAPD');
surfNet('showMets', 0);
surfNet(model, {'GAPD'; 'FBA'}, 'showMets', 0)
surfNet(model, {'13dpg[c]'; 'GAPD'}, 'metNameFlag', 1);
surfNet(model, [model.mets(1:10)'; model.rxns(1:10)'], 'showMets', 0, 'charPerLine', 60);
surfNet(model, 'pyr[c]', 'flux', s.x, 'nonzeroFluxFlag', 0);
surfNet(model, 'pyr[c]', 'flux', s.x);
surfNet(model, rxnsDiff, 'flux', fluxMatrix, 'showMets', 0);
surfNet(model2, '13dpg[c]', 'printFields', {'default', 'lb', 'subSystems'});
diary off

% name-value pair input with partial matching
diary('surfNet3.txt')
surfNet(model, 'GAPD');
surfNet('s', 0);
surfNet(model, {'GAPD'; 'FBA'}, 's', 0)
surfNet(model, {'13dpg[c]'; 'GAPD'}, 'm', 1);
surfNet(model, [model.mets(1:10)'; model.rxns(1:10)'], 's', 0, 'c', 60);
surfNet(model, 'pyr[c]', 'f', s.x, 'n', 0);
surfNet(model, 'pyr[c]', 'f', s.x);
surfNet(model, rxnsDiff, 'f', fluxMatrix, 's', 0);
surfNet(model2, '13dpg[c]', 'p', {'d', 'lb', 'sub'});
diary off

textSurfNet = repmat({''}, 3, 1);
for j = 1:3
    f = fopen(['surfNet' num2str(j) '.txt'], 'r');
    l = fgets(f);
    while ~isequal(l, -1)
        textSurfNet{j} = [textSurfNet{j}, l];
        l = fgets(f);
    end
    fclose(f);
    delete(['surfNet' num2str(j) '.txt']);
end
assert(isequal(textSurfNet{1}, textSurfNet{2}))
assert(isequal(textSurfNet{1}, textSurfNet{3}))

% change the directory
cd(currentDir)


function [exp_index, exp_id] = load_em_history_data(emHistoryFile)
%     NeuroSLAM System Copyright (C) 2018-2019
%     NeuroSLAM: A Brain inspired SLAM System for 3D Environments
%
%     Fangwen Yu (www.yufangwen.com), Jianga Shang, Youjian Hu, Michael Milford(www.michaelmilford.com)
%
%     The NeuroSLAM V1.0 (MATLAB) was developed based on the OpenRatSLAM (David et al. 2013).
%     The RatSLAM V0.3 (MATLAB) developed by David Ball, Michael Milford and Gordon Wyeth in 2008.
%
%     Reference:
%     Ball, David, Scott Heath, Janet Wiles, Gordon Wyeth, Peter Corke, and Michael Milford.
%     "OpenRatSLAM: an open source brain-based SLAM system." Autonomous Robots 34, no. 3 (2013): 149-176.
%
%     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/>.

    %% Import data from text file.
    % Script for importing data from the following text file:

    %% Initialize variables.
    delimiter = ',';
    startRow = 1;

    %% Format string for each line of text:
    %   column1: double (%d)
    %	column2: double (%f)
    %   column3: double (%f)
    %	column4: double (%f)
    %   column5: double (%f)
    %	column6: double (%f)
    %   column7: double (%f)
    % For more information, see the TEXTSCAN documentation.
    formatSpec = '%d%d%[^\n\r]';

    %% Open the text file.
    fileID = fopen(emHistoryFile,'r');

    %% Read columns of data according to format string.
    % This call is based on the structure of the file used to generate this
    % code. If an error occurs for a different file, try regenerating the code
    % from the Import Tool.
    dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'EmptyValue' ,NaN,'HeaderLines' ,startRow-1, 'ReturnOnError', false);

    %% Close the text file.
    fclose(fileID);

    %% Allocate imported array to column variable names
    exp_index = dataArray{:, 1};
    exp_id = dataArray{:, 2};

    %% Clear temporary variables
    clearvars emHistoryFile delimiter startRow formatSpec fileID dataArray ans;
end


function t = uplus(t)
%UPLUS Unary plus for a ktensor.
%
%   See also KTENSOR.
%
%MATLAB Tensor Toolbox.
%Copyright 2012, Sandia Corporation.

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

% This function does nothing!


function [y,fs,wrd,phn,ffx]=v_readsph(filename,mode,nmax,nskip)
%V_READSPH  Read a SPHERE/TIMIT format sound file [Y,FS,WRD,PHN,FFX]=(FILENAME,MODE,NMAX,NSKIP)
%
% Input Parameters:
%
%	FILENAME gives the name of the file (with optional .SPH extension) or alternatively
%                 can be the FFX output from a previous call to READSPH having the 'f' mode option
%	MODE		specifies the following (*=default):
%
%    Scaling: 's'    Auto scale to make data peak = +-1 (use with caution if reading in chunks)
%             'r'    Raw unscaled data (integer values)
%             'p' *	Scaled to make +-1 equal full scale
%             'o'    Scale to bin centre rather than bin edge (e.g. 127 rather than 127.5 for 8 bit values)
%                     (can be combined with n+p,r,s modes)
%             'n'    Scale to negative peak rather than positive peak (e.g. 128.5 rather than 127.5 for 8 bit values)
%                     (can be combined with o+p,r,s modes)
%   Format    'l'    Little endian data (Intel,DEC) (overrides indication in file)
%             'b'    Big endian data (non Intel/DEC) (overrides indication in file)
%
%   File I/O: 'f'    Do not close file on exit
%             'd'    Look in data directory: v_voicebox('dir_data')
%             'w'    Also read the annotation file *.wrd if present (as in TIMIT)
%             't'    Also read the phonetic transcription file *.phn if present (as in TIMIT)
%                    Eac line of the annotation and transcription files is of the form: m n token
%                    where m and n are start end end times in samples and token is a word or phoneme test descriptor
%                    The corresponding cell arrays WRD and PHN contain two elements per row: {[m n]/fs 'token'}
%                    These outputs are only present if the corresponding 'w' and 't' options are selected
%
%	NMAX     maximum number of samples to read (or -1 for unlimited [default])
%	NSKIP    number of samples to skip from start of file
%               (or -1 to continue from previous read when FFX is given instead of FILENAME [default])
%ff
% Output Parameters:
%
%	Y          data matrix of dimension (samples,channels)
%	FS         sample frequency in Hz
%	WRD{*,2}   cell array with word annotations: WRD{*,:)={[t_start t_end],'text'} where times are in seconds
%              with the first sample at t=0 [only present if 'w' option is selected]
%	PHN{*,2}   cell array with phoneme annotations: PHN{*,:)={[t_start	t_end],'phoneme'} where times are in seconds
%              with the first sample at t=0 [only present if 't' option is selected]
%	FFX        Cell array containing
%
%     {1}     filename
%     {2}     header information
%        {1}  first header field name
%        {2}  first header field value
%     {3}     format string (e.g. NIST_1A)
%     {4}(1)  file id
%        (2)  current position in file
%        (3)  dataoff	byte offset in file to start of data
%        (4)  order  byte order (l or b)
%        (5)  nsamp	number of samples
%        (6)  number of channels
%        (7)  nbytes	bytes per data value
%        (8)  bits	number of bits of precision
%        (9)  fs	sample frequency
%		 (10) min value
%        (11) max value
%        (12) coding: 0=PCM,1=uLAW + 0=no compression,10=shorten,20=wavpack,30=shortpack
%        (13) file not yet decompressed
%     {5}     temporary filename
%
%   If no output parameters are specified, header information will be printed.
%   To decode shorten-encoded files, the program shorten.exe must be in the same directory as this m-file
%
%  Usage Examples:
%
% (a) Draw an annotated spectrogram of a TIMIT file
%           filename='....TIMIT/TEST/DR1/FAKS0/SA1.WAV';
%           [s,fs,wrd,phn]=v_readsph(filename,'wt');
%           v_spgrambw(s,fs,'Jwcpta',[],[],[],[],wrd);

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

persistent BYTEORDER
codes={'sample_count'; 'channel_count';  'sample_n_bytes';'sample_sig_bits'; 'sample_rate'; 'sample_min'; 'sample_max'};
codings={'pcm'; 'ulaw'};
compressions={',embedded-shorten-';',embedded-wavpack-'; ',embedded-shortpack-'};
if isempty(BYTEORDER), BYTEORDER='l'; end
if nargin<1, error('Usage: [y,fs,hdr,fidx]=READSPH(filename,mode,nmax,nskip)'); end
if nargin<2, mode='p';
else mode = [mode(:).' 'p'];
end
k=find((mode>='p') & (mode<='s'));
mno=all(mode~='o');                      % scale to input limits not output limits
sc=mode(k(1));
if any(mode=='l'), BYTEORDER='l';
elseif any(mode=='b'), BYTEORDER='b';
end
if nargout
    ffx=cell(5,1);
    if ischar(filename)
        if any(mode=='d')
            filename=fullfile(v_voicebox('dir_data'),filename);
        end
        fid=fopen(filename,'rb',BYTEORDER);
        if fid == -1
            fn=[filename,'.sph'];
            fid=fopen(fn,'rb',BYTEORDER);
            if fid ~= -1, filename=fn; end
        end
        if fid == -1
            error('Can''t open %s for input',filename);
        end
        ffx{1}=filename;
    else
        if iscell(filename)
            ffx=filename;
        else
            fid=filename;
        end
    end

    if isempty(ffx{4})
        fseek(fid,0,-1);
        str=char(fread(fid,16)');
        if str(8) ~= 10 || str(16) ~= 10, fclose(fid); error('File does not begin with a SPHERE header'); end
        ffx{3}=str(1:7);
        hlen=str2double(str(9:15));
        hdr={};
        while 1
            str=fgetl(fid);
            if str(1) ~= ';'
                [tok,str]=strtok(str);
                if strcmp(tok,'end_head'), break; end
                hdr(end+1,1)={tok};
                [tok,str]=strtok(str);
                if tok(1) ~= '-', error('Missing ''-'' in SPHERE header'); end
                if tok(2)=='s'
                    hdr(end,2)={str(2:str2num(tok(3:end))+1)};
                elseif tok(2)=='i'
                    hdr(end,2)={sscanf(str,'%d',1)};
                else
                    hdr(end,2)={sscanf(str,'%f',1)};
                end
            end
        end
        i=find(strcmp(hdr(:,1),'sample_byte_format'));
        if ~isempty(i)
            bord=char('b'+('l'-'b')*(hdr{i,2}(1)=='0'));
            if bord ~= BYTEORDER && all(mode~='b') && all(mode ~='l')
                BYTEORDER=bord;
                fclose(fid);
                fid=fopen(filename,'rb',BYTEORDER);
            end
        end
        i=find(strcmp(hdr(:,1),'sample_coding'));
        icode=0;                % initialize to PCM coding
        if ~isempty(i)
            icode=-1;                   % unknown code
            scode=hdr{i,2};
            nscode=length(scode);
            for j=1:length(codings)
                lenj=length(codings{j});
                if strcmp(scode(1:min(nscode,lenj)),codings{j})
                    if nscode>lenj
                        for k=1:length(compressions)
                            lenk=length(compressions{k});
                            if strcmp(scode(lenj+1:min(lenj+lenk,nscode)),compressions{k})
                                icode=10*k+j-1;
                                break;
                            end
                        end
                    else
                        icode=j-1;
                    end
                    break;
                end
            end
        end

        info=[fid; 0; hlen; double(BYTEORDER); 0; 1; 2; 16; 1 ; 1; -1; icode];
        for j=1:7
            i=find(strcmp(hdr(:,1),codes{j}));
            if ~isempty(i)
                info(j+4)=hdr{i,2};
            end
        end
        if ~info(5)
            fseek(fid,0,1);
            info(5)=floor((ftell(fid)-info(3))/(info(6)*info(7)));
        end
        ffx{2}=hdr;
        ffx{4}=info;
    end
    info=ffx{4};
    if nargin<4, nskip=info(2);
    elseif nskip<0, nskip=info(2);
    end

    ksamples=info(5)-nskip;
    if nargin>2
        if nmax>=0
            ksamples=min(nmax,ksamples);
        end
    end

    if ksamples>0
        fid=info(1);
        if icode>=10 && isempty(ffx{5})
            fclose(fid);
            dirt=v_voicebox('dir_temp');
            filetemp=fullfile(dirt,'shorten.wav');
            cmdtemp=fullfile(dirt,'shorten.bat');               % batch file needed to convert to short filenames
            % if ~exist(cmdtemp,'file')                   % write out the batch file if it doesn't exist
                cmdfid=fopen(cmdtemp,'wt');
                fprintf(cmdfid,'@"%s" -x -a %%1 "%%~s2" "%%~s3"\n',v_voicebox('shorten'));
                fclose(cmdfid);
            % end
            if exist(filetemp,'file')                          % need to explicitly delete old file since shorten makes read-only
                doscom=['del /f "' filetemp '"'];
                if dos(doscom) % run the program
                    error('Error running DOS command: %s',doscom);
                end
            end
            if floor(icode/10)==1               % shorten
                doscom=['"' cmdtemp '" ' num2str(info(3)) ' "' filename '" "' filetemp '"'];
                %                     fprintf(1,'Executing: %s\n',doscom);
                if dos(doscom) % run the program
                    error('Error running DOS command: %s',doscom);
                end
            else
                error('unknown compression format');
            end
            ffx{5}=filetemp;
            fid=fopen(filetemp,'r',BYTEORDER);
            if fid<0, error('Cannot open decompressed file %s',filetemp); end
            info(1)=fid;                            % update fid
        end
        info(2)=nskip+ksamples;
        pk=pow2(0.5,8*info(7))*(1+(mno/2-all(mode~='n'))/pow2(0.5,info(8)));  % use modes o and n to determine effective peak
        fseek(fid,info(3)+info(6)*info(7)*nskip,-1);
        nsamples=info(6)*ksamples;
        if info(7)<3
            if info(7)<2
                y=fread(fid,nsamples,'uchar');
                if mod(info(12),10)==1
                    y=v_pcmu2lin(y);
                    pk=2.005649;
                elseif mod(info(12),10)==2,
                    y=v_pcma2lin(y);
                    pk=2.005649;
                else
                    y=y-128;
                end
            else
                y=fread(fid,nsamples,'short');
            end
        else
            if info(7)<4
                y=fread(fid,3*nsamples,'uchar');
                y=reshape(y,3,nsamples);
                y=[1 256 65536]*y-pow2(fix(pow2(y(3,:),-7)),24);
            else
                y=fread(fid,nsamples,'long');
            end
        end
        if sc ~= 'r'
            if sc=='s'
                if info(10)>info(11)
                    info(10)=min(y);
                    info(11)=max(y);
                end
                sf=1/max(max(abs(info(10:11))),1);
            else sf=1/pk;
            end
            y=sf*y;
        end
        if info(6)>1, y = reshape(y,info(6),ksamples).'; end
    else
        y=[];
    end

    if mode~='f'
        fclose(fid);
        info(1)=-1;
        if ~isempty(ffx{5})
            doscom=['del /f ' ffx{5}];
            if dos(doscom) % run the program
                error('Error running DOS command: %s',doscom);
            end
            ffx{5}=[];
        end
    end
    ffx{4}=info;
    fs=info(9);
    wrd=ffx;        % copy ffx into the other arguments in case 'w' and/or 't' are not specified
    phn=ffx;
    if any(mode=='w')
        wrd=cell(0,0);
        fidw=fopen([filename(1:end-3) 'wrd'],'r');
        if fidw>0
            while 1
                tline = fgetl(fidw); % read an input line
                if ~ischar(tline)
                    break
                end
                [wtim, ntim, ee, nix] = sscanf(tline,'%d%d',2);
                if ntim==2
                    wrd{end+1,1}=wtim(:)'/fs;
                    wrd{end,2}=strtrim(tline(nix:end));
                end
            end
            fclose(fidw);
        end
    end
    if any(mode=='t')
        ph=cell(0,0);
        fidw=fopen([filename(1:end-3) 'phn'],'r');
        if fidw>0
            while 1
                tline = fgetl(fidw); % read an input line
                if ~ischar(tline)
                    break
                end
                [wtim, ntim, ee, nix] = sscanf(tline,'%d%d',2);
                if ntim==2
                    ph{end+1,1}=wtim(:)'/fs;
                    ph{end,2}=strtrim(tline(nix:end));
                end
            end
            fclose(fidw);
        end
        if any(mode=='w')
            phn=ph;             % copy into 4th argument
        else
            wrd=ph;             % copy into 3rd argument
        end
    end
else
    [y1,fs,ffx]=v_readsph(filename,mode,0);
    info=ffx{4};
    icode=info(12); % could convert this into text
    if ~isempty(ffx{1}), fprintf(1,'Filename: %s\n',ffx{1}); end
    fprintf(1,'Sphere file type: %s, coding %d\n',ffx{3}, icode);
    fprintf(1,'Duration = %ss: %d channel * %d samples @ %sHz\n',v_sprintsi(info(5)/info(9)),info(6),info(5),v_sprintsi(info(9)));
end


function [seedRow, seedCol] = FindSeedFromUnlabeled( regionMatrix )
%FINDSEEDFROMUNLABELED Summary of this function goes here
%   Detailed explanation goes here

[seedRow, seedCol] = find(regionMatrix == 0, 1);

end


function varargout = dual( varargin )

%DUAL Declares one or more dual variables.
%
%   DUAL VARIABLE x
%   where x is a valid MATLAB variable name, declares a dual variable
%   for the current cvx problem. A dual variable with that name is added
%   to the problem and a cvxdual object with that name is created in
%   the current worksapce. An error is generated if a cvx problem is not
%   in the current workspace.
%
%   Note that a dual variable initially has no size; i.e., SIZE(x) returns
%   [0,0]. This is because the size of a dual variable is determined by the
%   constraint to which it is attached. To attach a dual variable to a
%   constraint, use the colon notation as follows:
%
%      variable x(n)
%      dual variable z
%      A * x == b : z
%
%   In this example, the dual variable z is attached to the equality
%   constraint A * x == b. Assuming SIZE(A) = [m,n] and SIZE(B) = [m,1],
%   the size of z will be set at [m,1] by this operation.
%
%   DUAL VARIABLES x1 x2 ... xk
%   where x1, x2, ..., xk are valid MATLAB variable names, declares
%   multiple dual variables.
%
%   DUAL VARIABLE x{s1,s2,...,sk}
%   DUAL VARIABLES x1{s1,s2,...,sk} x2{...
%   creates a cell array of dual variables, of dimension [s1,s2,..,sk].
%   This is useful if you want to create a sequence of related constraints,
%   using a FOR loop for example, and assign a separate dual variable to
%   each one; for example:
%
%       variable x(n)
%       dual variables z{10}
%       for k = 1 : 10,
%           A(:,:,k) * x <= b(:,k) : z{k}
%       end
%
%   Assuming SIZE(A) = [m,n,10] and SIZE(B) = [m,10], this loop assigns
%   each of the dual variables z{k} to a constraint and sets their sizes
%   to [m,1]. Note that the elements of the dual variable cell array need
%   not end up the same size.
%
%   See also VARIABLE, VARIABLES.

if nargin < 2,
    error( 'Incorrect syntax for DUAL VARIABLE(S). Type HELP DUAL for details.' );
elseif nargout && nargout ~= length( varargin ) - 1,
    error( 'Incorrect number of output arguments.' );
elseif ~iscellstr( varargin ),
    error( 'All arguments must be strings.' );
end

global cvx___
prob = evalin( 'caller', 'cvx_problem', '[]' );
if ~isa( prob, 'cvxprob' ),
    error( 'No CVX model exists in this scope.' );
elseif isempty( cvx___.problems ) || cvx___.problems( end ).self ~= prob,
    error( 'Internal CVX data corruption. Please CLEAR ALL and rebuild your model.' );
end

if strcmp( varargin{1}, 'variable' ),
    if nargin > 2,
        error( 'Too many input arguments.\nTrying to declare multiple dual variables? Use the DUAL VARIABLES command instead.', 1 ); %#ok
    end
elseif ~strcmp( varargin{1}, 'variables' ),
    error( 'Incorrect syntax for DUAL VARIABLE(S). Type HELP DUAL for details.' );
end

for k = 2 : nargin,
    arg = varargin{k};
    toks = regexp( arg, '^\s*([a-zA-Z]\w*)\s*({.*})?\s*$', 'tokens' );
    if isempty( toks ),
        error( 'Invalid dual variable specification: %s', arg );
    end
    tok = toks{1};
    nam = tok{1};
    if length(tok) < 2,
        siz = {};
    else
        siz = tok{2};
    end
    if nam(end) == '_',
        error( 'Invalid dual variable specification: %s\n   Variables ending in underscores are reserved for internal use.', arg );
    end
    if ~isempty( siz ),
        try
            siz = evalin( 'caller', [ '[', siz(2:end-1), ']' ] );
        catch exc
            error( exc.identifier, 'Error attempting to determine size of: %s\n   %s', arg, exc.message );
        end
        [ temp, siz ] = cvx_check_dimlist( siz, true );
        if ~temp,
            error( 'Invalid dual variable specification: %s\n   Dimension list must be a vector of finite nonnegative integers.', arg );
        end
    end
    temp = newdual( prob, nam, siz );
    if nargout,
        varargout{k-1} = temp; %#ok
    end
    assignin( 'caller', nam, temp );
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 f = real(f)
%REAL   Real part of a SINGFUN.
%   REAL(F) is the real part of F.
%
% See also IMAG, ISREAL, CONJ.

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

% Check for empty arguments:
if ( isempty(f) )
    return;
end

% Compute the real part of the smooth part of F.
f.smoothPart = real(f.smoothPart);

% Return a SMOOTHFUN object if F is smooth:
if ( issmooth(f) )
    f = f.smoothPart;
end

end


function time=str2time(str)

global gls
time=gls.gtime;

ep(1:6)=0;
for i=1:6
    [tmp,str]=strtok(str); %#ok
    if isempty(tmp)
        break;
    end
    ep(i)=str2double(tmp);
end

idx=(ep==NaN); %#ok
if any(idx),return;end

if ep(1)<100
    if ep(1)<80
        ep(1)=ep(1)+2000;
    else
        ep(1)=ep(1)+1900;
    end
end

time=epoch2time(ep);

return


function excelrecord4favarfcn(favar, IRFperiods, endo, IRFt, strctident, pref)
% script excelrecord4
% records the information contained in the worksheet 'IRF' of the excel spreadsheet 'results.xls'

% create the cell that will be saved on excel
irfcell={};

% build preliminary elements: space between the tables
horzspace=repmat({''},2,5*favar.IRF.npltXshck);
vertspace=repmat({''},IRFperiods+3,1);

%subsample
endo2={endo{favar.IRF.plotXshock_index,1}};
informationvariablestrings=favar.informationvariablestrings(1,favar.plotX_index);

% loop over variables (vertical dimension)
for ii=1:favar.npltX
tempcell={};
   % loop over shocks (horizontal dimension)
   for jj=1:favar.IRF.npltXshck %:nfactorshocks, insert again when all dimensions are considered in the irf favar estimation
   % create cell of IRF record for variable ii in response to shock jj
      % if a sign restriction identification scheme has been used, use the structural shock labels
      if IRFt==4
      temp=['response of ' informationvariablestrings{1,ii} ' to ' strctident.signreslabels{jj,1} ' shocks'];
      else
      temp=['response of ' informationvariablestrings{1,ii} ' to ' endo2{1,jj} ' shocks'];
      end
   irf_ij=[temp {''} {''} {''};{''} {''} {''} {''};{''} {'lw. bound'} {'median'} {'up. bound'};num2cell((1:IRFperiods)') num2cell((favar.IRF.favar_irf_estimates{ii,jj})')];
   tempcell=[tempcell irf_ij vertspace];
   end
irfcell=[irfcell;horzspace;tempcell];
end

% trim
irfcell=irfcell(3:end,1:end-1);

% write in excel
if pref.results==1
    bear.xlswritegeneral(fullfile(pref.results_path, [pref.results_sub '.xlsx']),irfcell,'IRF FAVAR','B2');
end


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

%%
clear; close all; clc;

%% Syntax
% |y=nonlinspace(range_in,range_out,fform,n);|

%% 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 c = mtimes(a,b)
	checkinputs(a,b);
	if numel(a)>1 && numel(b)>1
		error('Only elementwise multiplication supported.');
	end
	c = uint64times(uint64(a),uint64(b));
end


%Primitives Primitives enumeration for the brick
%
% Notes::
% - Primitives can be found in the EV3 documentation and source code
% (bytecodes.h 1584-1606)

classdef Primitives < uint8
    enumeration
        pshort (0) % PRIMPAR_SHORT = 0x00
        plong (128) % PRIMPAR_LONG = 0x80

        pconst(0) % PRIMPAR_CONST = 0x00
        pvariabel(64) % PRIMPAR_VARIABEL = 0x40
        plocal(0) % PRIMPAR_LOCAL = 0x00
        pglobal(32) % PRIMPAR_GLOBAL = 0x20
        phandle(16) % PRIMPAR_HANDLE = 0x10
        paddr(8) % PRIMPAR_ADDR = 0x08

        pindex(31) % PRIMPAR_INDEX = 0x1F
        pconst_sign(32) % PRIMPAR_CONST_SIGN = 0x20
        pvalue (63) % PRIMPAR_VALUE = 0x3F

        pbytes(7) % PRIMPAR_BYTES = 0x07

        pstring_old (0) % PRIMPAR_STIRNG_OLD = 0
        p1_byte (1) % PRIMPAR_1_BYTE = 1
        p2_byte (2) % PRIMPAR_2_BYTE = 2
        p4_byte (3) % PRIMPAR_4_BYTE = 3
        pstring (4) % PRIMPAR_STRING = 4

        plabel (32) % PRIMPAR_LABEL = 0x20
    end
end


function [adfreq, n, ts, fn, ad] = plx_ad_v(filename, channel)
% plx_ad_v(filename, channel): read all a/d data for the specified channel from a .plx or .pl2 file
%              returns a/d values in millivolts
%
% [adfreq, n, ts, fn, ad] = plx_ad_v(filename, channel)
% [adfreq, n, ts, fn, ad] = plx_ad_v(filename, 0)
% [adfreq, n, ts, fn, ad] = plx_ad_v(filename, 'FP01')
%
% INPUT:
%   filename - if empty string, will use File Open dialog
%   channel - 0-based channel number or channel name
%
%           a/d data come in fragments. Each fragment has a timestamp
%           and a number of a/d data points. The timestamp corresponds to
%           the time of recording of the first a/d value in this fragment.
%           All the data values stored in the vector ad.
%
% OUTPUT:
%   adfreq - digitization frequency for this channel
%   n - total number of data points
%   ts - array of fragment timestamps (one timestamp per fragment, in seconds)
%   fn - number of data points in each fragment
%   ad - array of a/d values converted to millivolts

adfreq = 0;
n = 0;
ts = -1;
fn = -1;
ad = -1;

if nargin ~= 2
    error 'Expected 2 input arguments';
end

[ filename, isPl2 ] = internalPL2ResolveFilenamePlx( filename );
if isPl2 == 1
    % return data from .pl2 file
    pl2Channel = channel;
    % PL2 uses 1-based channel numbers
    if ischar(channel) == 0
        pl2Channel = channel+1;
    end
    pl2ad = PL2Ad(filename, pl2Channel);
    if numel(pl2ad.Values) > 0
        adfreq = pl2ad.ADFreq;
        n = numel(pl2ad.Values);
        ts = pl2ad.FragTs;
        fn = pl2ad.FragCounts;
        ad = pl2ad.Values;
    end
    return;
end

channelNumber = plx_ad_resolve_channel(filename, channel);
if channelNumber == -1
    fprintf('\n plx_ad_v: no header for the specified A/D channel.');
    fprintf('\n    use plx_ad_info(filename) to print the list of a/d channels\n');
    return
end

[adfreq, n, ts, fn, ad] = mexPlex(17, filename, channelNumber);

end


classdef io
  % a class for input and output functions

  methods (Static)
    function im_data = load_image(im_file)
      % im_data = load_image(im_file)
      %   load an image from disk into Caffe-supported data format
      %   switch channels from RGB to BGR, make width the fastest dimension
      %   and convert to single
      %   returns im_data in W x H x C. For colored images, C = 3 in BGR
      %   channels, and for grayscale images, C = 1
      CHECK(ischar(im_file), 'im_file must be a string');
      CHECK_FILE_EXIST(im_file);
      im_data = imread(im_file);
      % permute channels from RGB to BGR for colored images
      if size(im_data, 3) == 3
        im_data = im_data(:, :, [3, 2, 1]);
      end
      % flip width and height to make width the fastest dimension
      im_data = permute(im_data, [2, 1, 3]);
      % convert from uint8 to single
      im_data = single(im_data);
    end
    function mean_data = read_mean(mean_proto_file)
      % mean_data = read_mean(mean_proto_file)
      %   read image mean data from binaryproto file
      %   returns mean_data in W x H x C with BGR channels
      CHECK(ischar(mean_proto_file), 'mean_proto_file must be a string');
      CHECK_FILE_EXIST(mean_proto_file);
      mean_data = caffe_('read_mean', mean_proto_file);
    end
    function write_mean(mean_data, mean_proto_file)
      % write_mean(mean_data, mean_proto_file)
      %   write image mean data to binaryproto file
      %   mean_data should be W x H x C with BGR channels
      CHECK(ischar(mean_proto_file), 'mean_proto_file must be a string');
      CHECK(isa(mean_data, 'single'), 'mean_data must be a SINGLE matrix');
      caffe_('write_mean', mean_data, mean_proto_file);
    end
  end
end


function x = solve_triu(T,b)
% SOLVE_TRIU      Left division by upper triangular matrix.
% SOLVE_TRIU(T,b) is the same as T\b but requires T to be upper triangular
% and runs faster.

error('You must run install_lightspeed in order to use this function.')


function index=set_index(ver,sys,opt,tobs) %#ok

global glc
obscodes='CLDS';
index.n=0;
index.frq(1:glc.MAXOBSTYPE)=0;
index.pos(1:glc.MAXOBSTYPE)=0;
index.pri(1:glc.MAXOBSTYPE)=0;
index.type(1:glc.MAXOBSTYPE)=0;
index.code(1:glc.MAXOBSTYPE)=0;
index.shift(1:glc.MAXOBSTYPE)=0;

nn=size(tobs,1); n=0;
for i=1:nn
    if isempty(strfind(obscodes,tobs(i,1))),break;end

    [index.code(i),index.frq(i)]=obs2code(tobs(i,2:3),sys);

    type=strfind(obscodes,tobs(i,1));
    if ~isempty(type)
        index.type(i)=type;
    else
        index.type(i)=0;
    end

    index.pri(i)=getcodepri(sys,index.code(i),opt);
    index.pos(i)=-1;
    index.code(i)=index.code(i)-1;
    n=n+1;
end

for i=1:glc.MAXFREQ

    % search for the highest level code
    k=-1;
    for j=1:n
        if index.frq(j)==i&&index.pri(j)~=0&&(k<0||index.pri(j)>index.pri(k))
            k=j;
        end
    end

    if k<0,continue;end

    for j=1:n
        if index.code(j)==index.code(k),index.pos(j)=i;end
    end
end

index.n=n;

return


function test_old_trialdef

% MEM 2gb
% WALLTIME 00:10:00
% DEPENDENCY

% This script tests the implementation of the new representation of trial
% specific information in the data structure.
% The idea is as follows:
% -instead of relying on data.cfg.previous....trl, the trial information
% (when consistent with data representation, so only on the level of raw
% data, and in original sampling rate) should be directly on the main level
% of the structure.
% -this means that raw data should get a field sampleinfo containing the
% first 2 columns of the original trl-matrix.
% -the 3rd column of the trl matrix is the offset column and is represented
% in each trial's individual time axis.
% -user-defined columns > 3 should go to the field trialinfo. this field
% can percolate deeper into the pipeline. yet, once data is not raw
% datatype anymore (or resampled) the sampleinfo field should be removed,
% because consistency with the data is lost.
% -the sampleinfo and trialinfo fields will be updated by subselecting rows
% -sampleinfo should be changed by ft_redefinetrial
% -sampleinfo should be removed by ft_resampledata and any other function
% working on the raw datatype and outputting any other datatype
% -sampleinfo and trialinfo should be concatenated in ft_appenddata
% -sampleinfo and trialinfo should be adjusted by ft_rejectartifact

% needed for the dccnpath function, since we will change directory later on
addpath(fileparts(mfilename('fullpath')));

cd(dccnpath('/home/common/matlab/fieldtrip/data/test/original/meg/ctf275/A0132_Aud-Obj-Recognition_20051115_02.ds'));
headerfile = 'A0132_Aud-Obj-Recognition_20051115_02.res4';
datafile   = 'A0132_Aud-Obj-Recognition_20051115_02.meg4';
%hdr        = ft_read_header(headerfile);

cfg          = [];
cfg.datafile = datafile;
cfg.trl      = [[1001:1000:10001]' [2000:1000:11000]' round(randn(10,1)*100)];
cfg.trl(:,4) = [ones(5,1); ones(5,1)*2];
cfg.continuous = 'yes';
data1          = ft_preprocessing(cfg);
cfg.trl(:,1:2) = cfg.trl(:,1:2) + 11000;
cfg.trl(:,3)   = round(randn(10,1)*100);
data2          = ft_preprocessing(cfg);

% test subselection of trialsclear
cfg        = [];
cfg.trials = (1:5);
datax      = ft_preprocessing(cfg, data1);

% test some other preprocessing (so nargin==2 for ft_preprocessing)
cfg        = [];
cfg.demean = 'yes';
datax2     = ft_preprocessing(cfg, data1);

% test ft_checkdata
datay = data1;
datay = rmfield(datay,   'sampleinfo');
datay = rmfield(datay,   'trialinfo');
datay = ft_checkdata(datay, 'hastrialdef', 'yes');

datay.trialinfo(:) = 3;
datay = ft_checkdata(datay, 'hastrialdef', 'yes'); % should give all(datay.trialinfo==3)

datay.trialinfo = [];
datay = ft_checkdata(datay, 'hastrialdef', 'yes'); % should give all(datay.trialinfo==trl(:,4))

datay = data1;
datay = rmfield(datay,   'sampleinfo');
datay = rmfield(datay,   'trialinfo');
datay.cfg = rmfield(datay.cfg, 'trl');
datay = ft_checkdata(datay, 'hastrialdef', 'yes');

% test appenddata
data1b = rmfield(data1, 'sampleinfo');
data1b = rmfield(data1b, 'trialinfo');
%data1b.cfg = rmfield(data1b.cfg, 'trl');
data2b = rmfield(data2, 'sampleinfo');
data2b = rmfield(data2b, 'trialinfo');
%data2b.cfg = rmfield(data2b.cfg, 'trl');
data3 = ft_appenddata([], data1b, data2b);

% test ft_redefinetrial with and without sampleinfo and trialinfo present in data
cfg = [];
cfg.toilim = [-0.5 0.5];
data1bx    = ft_redefinetrial(cfg, data1b);
data1x     = ft_redefinetrial(cfg, data1 );

cfg = [];
cfg.begsample =    1 + round(rand(10,1)*200);
cfg.endsample = 1000 - round(rand(10,1)*200);
data1by    = ft_redefinetrial(cfg, data1b);
data1y     = ft_redefinetrial(cfg, data1 );

cfg = [];
cfg.trl      = data1.cfg.trl;
cfg.trl(:,1) = cfg.trl(:,1)+round(rand(10,1)*20);
cfg.trl(:,2) = cfg.trl(:,2)-round(rand(10,1)*20);
data1bz      = ft_redefinetrial(cfg, data1b);
data1z       = ft_redefinetrial(cfg, data1 );

% test ft_resampledata
cfg = [];
cfg.resamplefs = 300;
cfg.detrend    = 'no';
cfg.demean     = 'yes';
data1rs        = ft_resampledata(cfg, data1);
data1brs       = ft_resampledata(cfg, data1b);
cfg.trials     = [1:5];
data1rs2       = ft_resampledata(cfg, data1b);

% test ft_databrowser
cfg = [];
cfg.viewmethod      = 'butterfly';
cfg.preproc.demean  = 'yes';
cfg.channel         = 'MEG';
cfg.continuous      = 'yes';
ft_databrowser(cfg, data1b);

% test ft_rejectartifact
cd(dccnpath('/home/common/matlab/fieldtrip/data/test/original/meg/ctf275/A0132_Aud-Obj-Recognition_20051115_02.ds'));
headerfile = 'A0132_Aud-Obj-Recognition_20051115_02.res4';
datafile   = 'A0132_Aud-Obj-Recognition_20051115_02.meg4';
hdr        = ft_read_header(headerfile);

cfg          = [];
cfg.datafile = datafile;
cfg.trl      = [[1001:1000:10001]' [2000:1000:11000]' round(randn(10,1)*100)];
cfg.trl(:,4) = [ones(5,1); ones(5,1)*2];
cfg.continuous = 'yes';
cfg.artfctdef.type  = 'eog';
cfg.artfctdef.eog.channel = 'MLO11';
cfg.artfctdef.eog.feedback = 'no'; % yes does not work in the test script, see http://bugzilla.fieldtriptoolbox.org/show_bug.cgi?id=2840
cfg          = ft_rejectartifact(cfg);

datay = data1;
datay = rmfield(datay,   'sampleinfo');
datay = rmfield(datay,   'trialinfo');
datay2       = ft_rejectartifact(cfg, datay);

% test all other functions using raw data as input (to remove sampleinfo)

% test all high level functions to correctly pass on the trialinfo field
% ft_timelockanalysis
cfg              = [];
cfg.vartrllength = 2;
timelock         = ft_timelockanalysis(cfg, data1);

%ft_denoise_synthetic
cfg          = [];
cfg.gradient = 'G1BR';
dataG1BR     = ft_denoise_synthetic(cfg, data1);


function [data,compress,gridlocs,node_sizes,voxel_sizes] = fns_read_recipdata(infile)
%
% This function reads the reciprocity data and the related
% information into the MATLAB workspace.

% $Copyright (C) 2010 by Hung Dang$

% Read in the reciprocity data
data = hdf5read(infile,'/recipdata/data');

% Read in other parameters
compress    = hdf5read(infile,'/recipdata/roicompress') + 1;
gridlocs    = hdf5read(infile,'/recipdata/gridlocs');
node_sizes  = hdf5read(infile,'/model/node_sizes');
voxel_sizes = hdf5read(infile,'/model/voxel_sizes');