function cellcell = BF_cell2cellcell(cellin,delimiter)
% BF_cell2cellcell  Turn a cell of strings into a cell of cells, splitting on a delimiter.
%
% Inputs a cell with some delimiter, and outputs a cell of cells using this
% delimiter.
%
%---INPUTS:
% cellin, the cell
% delimiter, the delimiter
%
%---OUTPUT:
% cellcell, the cell of cells, using this delimiter

% (Used for some tasks involving mySQL)

% ------------------------------------------------------------------------------
% Copyright (C) 2020, Ben D. Fulcher <ben.d.fulcher@gmail.com>,
% <http://www.benfulcher.com>
%
% If you use this code for your research, please cite the following two papers:
%
% (1) B.D. Fulcher and N.S. Jones, "hctsa: A Computational Framework for Automated
% Time-Series Phenotyping Using Massive Feature Extraction, Cell Systems 5: 527 (2017).
% DOI: 10.1016/j.cels.2017.10.001
%
% (2) B.D. Fulcher, M.A. Little, N.S. Jones, "Highly comparative time-series
% analysis: the empirical structure of time series and their methods",
% J. Roy. Soc. Interface 10(83) 20130048 (2013).
% DOI: 10.1098/rsif.2013.0048
%
% This work is licensed under the Creative Commons
% Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of
% this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ or send
% a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View,
% California, 94041, USA.
% ------------------------------------------------------------------------------

if nargin < 2 || isempty(delimiter)
    delimiter = ','; % comma as the default delimiter
end

numElements = length(cellin); % number of elements in the input cell
cellcell = cell(numElements,1);

for i = 1:numElements
    cellcell{i} = regexp(cellin{i}, delimiter, 'split');
end

end


function t = fieldnames(obj)
% Fieldnames of a file-array object
%__________________________________________________________________________
% Copyright (C) 2005-2017 Wellcome Trust Centre for Neuroimaging

%
% $Id: fieldnames.m 7147 2017-08-03 14:07:01Z spm $

t = {...
    'fname'
    'dim'
    'dtype'
    'offset'
    'scl_slope'
    'scl_inter'
};


% GetSegyTraceHeaderInfo : Returns a array of a SEGY Y TraceHeader value
%
% Call :
% [value]=GetSegyHeaderInfo(SegyTraceHeaders,header)
%
% header is a header value like 'cdp','dt','TraceNumber'
%

%
% (C) 2001-2004, Thomas Mejer Hansen, tmh@gfy.ku.dk/thomas@cultpenguin.com
%
%
%
%    This program is free software; you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation; either version 2 of the License, or
%    (at your option) any later version.
%
%    This program is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this program; if not, write to the Free Software
%    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
%
function [value]=GetSegyTraceHeaderInfo(SegyTraceHeaders,header)

  try
    value=[SegyTraceHeaders.(header)];
  catch
    SegymatVerbose(['Could not get  ',header,' header information from supplied SegyTraceHeaders']);
  end


function popmail_demo(site,user,pass)
% popmail_demo - Demo that read mail from pop mail server (not delete).
%                The first lines of each mail will be printed out.
%
% Syntax:
%    popmail_demo(site,user,password)
%  or
%    popmail_demo site user password
%  or
%    popmail_demo
%
%  In the last case you will be asked for intput parameters.
%
%  Version: 2002-02-01 Uppgraded to use the API in tcpiptoolbox 2.x, from tcpiptoolbox 1.x API
%

  if nargin<3,
    site=input('Input adress to pop server:','s');
    user=input('user:','s');
    pass=input('password: (sorry, will be displayed on the screen)','s');
  end
  % CONNECT
  fid=pnet('tcpconnect',site,110);
  if fid==-1,
    disp 'Cant connect to server!';
    return;
  end
  %LOGIN
  read_mresp(fid);
  pnet(fid,'printf','USER %s\n',user);
  read_mresp(fid);
  pnet(fid,'printf','PASS %s\n',pass);
  read_mresp(fid);
  pnet(fid,'printf','STAT\n');
  pnet(fid,'readline');
  all=0;
  % READ HEADERS OF FIRST 50 mail.
  for a=1:50 ,
    if all, break; end
    pnet(fid,'printf','TOP %d 0\n',a);
    s='';
    b=0;
    while strncmp(s,'.',1)==0,
      s=pnet(fid,'readline');
      b=b+1;
      if strncmp(s,'-ERR',4),
        all=1;
        nummes=a-1;
        break;
      elseif strncmp('Subject:',s,8);
        subject{a}=s(9:end);
      elseif strncmp('From:',s,5);
        from{a}=s(6:end);
      end
    end
    mlines(a)=b-1;
  end
  disp(sprintf('Number of mails in mailbox on server: %d\n',nummes));
  % DISPLAY HEADER AND READ MESSAGE LINES
  for a=1:nummes,
    disp '###############################################################'
    disp(sprintf('Subject: %s\n   From: %s',subject{a},from{a}));
    disp '---------------------------------------------------------------'
    %Request next line in current mail message.
    pnet(fid,'printf','RETR %d\n',a);
    for b=1:mlines(a),
      s=pnet(fid,'readline');
    end
    b=0;
    atflag=0;   % Set "not displaying" flag to false.
    while strcmp(s,'.')==0,
      b=b+1;
      s=pnet(fid,'readline');

      % Don't display attachment lines and similar stuff.
      if atflag==0 & b<100,
        disp(s);
      end
      if strncmp(s,'Content-',8),
        atflag=1;  % If start of attachment set "not displaying" flag.
      end
    end
  end
  pnet(fid,'close');
  return;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Read and check that response is OK
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function ok=read_mresp(fid)
  s=pnet(fid,'readline');
  if strncmp(s,'+OK',3)==0,
    pnet(fid,'close');
    error('Response error!');
  end
  return;


function [dat] = set_x(dat,inp,ind,fInd)

%   data=set_x(data,x) sets the X matrix
%   data=set_x(data,x,ind) sets the X matrix for specific indexes

if nargin==2 | (isempty(ind)&isempty(fInd)),
  dat.myX=inp;
  if ~(size(inp,1)==length(dat.index))
    dat.index  = [1:size(inp,1)];
  end
  if ~(size(inp,2)==length(dat.findex) )
    dat.findex = [1:size(inp,2)];
  end
  return;
end

if nargin<3 | isempty(ind),
    ind=[1:size(inp,1)];
end
if nargin<4|isempty(fInd),
    fInd=[1:size(inp,2)];
end

if isempty(dat.myX)&nargin>2
    global X;
    dat.myX=X;
    disp('warning -- instantiated some values of x when using globals');
end

dat.myX(ind,fInd)=inp;


function [grRules_new,genes,rxnGeneMat] = replaceGrRules(grRules,idMapping)
%replaceGrRules  Replace grRules with another set of gene IDs.
%
% NOTE: This function is adapted from "translateGrRules" and specifically
%       designed for converting grRules from current gene ID to another
%       gene ID type
%
% NOTE: The function also "cleans" the grRules, meaning duplicate genes,
%       extra parentheses, etc. will be removed from each grRule.
%
% Usage:
%
%   [grRules_new,genes,rxnGeneMat] = replaceGrRules(grRules,idMapping)
%
%
% Inputs:
%
%   grRules      A cell array of gene-reaction rules (e.g., model.grRules).
%
%
%   idMapping    must be an Nx2 cell array, where the first column contains
%                gene IDs corresponding to the current grRules, and the
%                second column contains new gene IDs to which the rules
%                will be translated.
%
% Outputs:
%
%   grRules_new  grRules with the gene IDs converted to the new IDs.
%
%   genes        A list of all genes found in the converted grRules.
%
%   rxnGeneMat   A matrix associating reactions to genes, built from the
%                converted grRules and genes list.
%

% handle input arguments
if nargin < 2
    error('Missing input.');
end

% check input data

% get original list of genes from the grRules
genes_orig = getGenesFromGrRules(grRules);
if ismember('and',genes_orig) || ismember('or',genes_orig)
    error('Problem reading grRules. Verify that all "and" and "or" elements are lowercase and surrounded by spaces.');
end

% remove duplicate genes
genes_orig  = unique(genes_orig,'stable');

% idMapping should be a NX2 cell array
if ~(size(idMapping,2) == 2)
    error('The idMapping data structure must be a NX2 cell array.');
% input genes should be consistent with those retrieved from grRules
elseif all(~ismember(idMapping(:,1), genes_orig))
    error('The input genes are Not consistent with those retrieved from grRules.');
end

% conduct replacement

% begin by "cleaning" the original grRules
% this is not necessary but can speed up the translation if the original
% grRules are not in a simplified format.
rules_orig = cleanGrRules(grRules);

% determine logical operator type and change to "&/|" for easy manipulation
textBooleanType = false;
if any(contains(grRules,{' and ',' or '}))
    textBooleanType = true;
    grRules_new = rules_orig;
    grRules_new = regexprep(grRules_new, ' or ', ' | ');
    grRules_new = regexprep(grRules_new, ' and ', ' & ');
end

% define function convertGeneId to convert gene IDs
% use strjoin to combine ids with 'or' operator if multiple hits are found
convertGeneId = @(g) strjoin(idMapping(ismember(idMapping(:,1),g),2), ' | ');

% replace grRules with another ID type
% The next line identifies gene IDs as collections of characters that
% are not spaces, parentheses, or the symbols '&' or '|'. It then replaces
% those gene IDs with the new gene ID type, which calls the convertGeneId
% inline function to retrieve.
grRules_new = regexprep(grRules_new, '[^&|\(\) ]+', '(${convertGeneId($0)})');

% prepare output

% clean up rules (removes extra parentheses, repeated genes, etc.)
grRules_new = cleanGrRules(grRules_new);

% restore "&" as "and" and "|" as "or"
if textBooleanType
    grRules_new = regexprep(grRules_new, ' \| ', ' or ');
    grRules_new = regexprep(grRules_new, ' & ', ' and ');
end

% generate new rxnGeneMat and gene list based on converted grRules
[genes,rxnGeneMat] = getGenesFromGrRules(grRules_new);


classdef testNumericalHomogenizerPrinter < testNotShowingError...
                                          & testPrintingComparator

    properties (Access = protected)
        fileOutputName = 'testNumericalHomogenizerPrinter';
        iter = 0;
    end

    properties (Access = private)
        dataBase
    end

    methods (Access = public)

        function obj = testNumericalHomogenizerPrinter()
            d.iter     = 0;
            d.file     = obj.fileOutputName;
            d.postCase = 'NumericalHomogenizer';
            tp = testPrintingPostProcessComputer(d);
            tp.print();
        end

    end

end


function model = updateFieldOrderForType(model,type,newOrder)
% Reorder the fields associated with the provided type to the new order.
% USAGE:
%     matchingFields = updateFieldOrderForType(model, type, newOrder)
%
% INPUTS:
%
%    model:              the model to update
%    type:               the Type of field to update one of
%                        ('rxns','mets','comps','genes')
%    newOrder:           The new Order. must be of the same size as the
%                        requested model.(type) field.
%
% OUTPUT:
%
%    model:              The model with all field associated with type
%                        reordered
%
% .. Authors:
%                   - Thomas Pfau June 2017

parser = inputParser();
parser.addRequired('model',@isstruct);
parser.addRequired('type',@(x) any(ismember(x,{'rxns','mets','comps','genes','proteins'})));
parser.addRequired('newOrder',@(x) isnumeric(x) && all(ismember(newOrder,1:numel(model.(type)))));

parser.parse(model,type,newOrder);

[fields,dimensions] = getModelFieldsForType(model,type);

for i = 1:numel(fields)
    %For now, we will only handle 2 dimensional arrays
    if dimensions(i) == 1
        model.(fields{i})(:,:) = model.(fields{i})(newOrder,:);
    elseif dimensions(i) == 2
        model.(fields{i})(:,:) = model.(fields{i})(:,newOrder);
    end
end

if strcmp(type,'genes')
    %the gene positions changed, so we have to rebuild the rules field.

    if isfield(model,'rules')
        for i = 1:numel(model.genes)
            if i ~= newOrder(i)
                %replace by new with an indicator that this is new.
                model.rules = strrep(model.rules,['x(' num2str(newOrder(i)) ')'],['x(' num2str(i) '$)']);
            end
        end
        %remove the indicator.
        model.rules = strrep(model.rules,'$','');
    end
end


function LU = getbounds(F,avoidequalitybounds)

if nargin == 1
    LU = getbounds(lmi(F));
else
    LU = getbounds(lmi(F),avoidequalitybounds);
end


function [fnOut, args] = tapas_uniqc_save_fig(varargin)
%save figure with current name as filename (with some removal of bad
%characters for saving
%
%  fnOut = tapas_uniqc_save_fig(fh, type, pathSave, fn, res)
%
% IN
%   varargin:   property name / value pairs for extra options
%
%   fh          figure handle (default gcf) OR vector of figure handles
%   imageType   fig save file type (default 'png');
%   pathSave    path to save to (default pwd)
%
%   fn          file name (default: nice name created from figure name/title)
%   res         resolution
%   doPrefixFigNumber
%               prefixes figure number to file name of figure
%               true if no file name was given
% OUT
%   fnOut       full name (incl path) of output file)
%   args        possible tapas_uniqc_save_fig arguments returned as a structure
%
% EXAMPLE
%   tapas_uniqc_save_fig
%
%   See also tapas_uniqc_get_fig_name str2fn

% Author: Lars Kasper
% Created: 2013-11-07
% Copyright (C) 2013 Institute for Biomedical Engineering, ETH/Uni Zurich.

defaults.fh = gcf;
defaults.imageType = 'png';
defaults.res = 150;
defaults.doCreateName = true;
defaults.pathSave = pwd;
defaults.doPrefixFigNumber = true;
defaults.fn = [];

args = tapas_uniqc_propval(varargin,defaults);
tapas_uniqc_strip_fields(args);

if ~(isempty(fn)) && (numel(fh) == 1)
    doCreateName = false;
    doPrefixFigNumber = false;
end

% Get handles of all figures

if isequal(fh, 'all')
        fhArray = get(0, 'Children');
else
    fhArray = fh;
end

for iFh = 1:numel(fhArray)
    fh = fhArray(iFh);
    if doCreateName
        fn = tapas_uniqc_get_fig_name(fh,1);
    end

      % compatibility with Matlab 2014b
    if tapas_uniqc_isNewGraphics() && ishandle(fh)
        figure(fh);
        fh = gcf;
        fhNumber = fh.Number;
    else
        fhNumber = fh;
    end

    if doPrefixFigNumber
        fn = sprintf('Fig_%03d_%s', fhNumber, fn);
    end

    if iscell(fn), fn = fn{1}; end; % for multiline strings in title, take 1st line only
    fnOut = fullfile(pathSave, [fn, '.', imageType]);
    if ~exist(pathSave, 'dir'), mkdir(pathSave); end;
    set(fh, 'PaperPositionMode', 'auto');
    disp(sprintf('saving figure %d to %s\n', fhNumber, fnOut));
    switch imageType
        case 'fig'
            saveas(fh, fnOut);
        otherwise
            switch imageType
                case 'eps'
                    dFormat = '-depsc2'; renderer = '-painter';
                case 'tif'
                    dFormat = '-dtiff'; renderer = '-OpenGL';
                case 'jpg'
                    dFormat = '-djpeg'; renderer = '-OpenGL';
                otherwise
                    dFormat = sprintf('-d%s',imageType);
            end
            print(fh, sprintf('-r%d',res), dFormat, fnOut);
    end
end


function fb = h_goNogo(yt,t,in)
% generates the feedback (go/nogo task) given the agent's last choice
if yt==1 % 'go'
    fb = in.u(t);
else % 'nogo'
    fb = 0;
end


function st = addfix( st, x, fx )
% x2 = addfix( st, x, fx )
    st(~fx) = x;
end


%     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/>.

% % SynPerData
% hdcTrajFile = 'C:\NeuroSLAM_Datasets\03_NeuroSLAM_Experiments_Results\SynPerData\06_hdc_trajectory.txt';
%
%
% % SynPanData
% hdcTrajFile = 'C:\NeuroSLAM_Datasets\03_NeuroSLAM_Experiments_Results\SynPanData\06_hdc_trajectory.txt';

% QUTCarparkData
hdcTrajFile = 'C:\NeuroSLAM_Datasets\03_NeuroSLAM_Experiments_Results\QUTCarparData\06_hdc_trajectory.txt';

plot_hdc_traj_main(hdcTrajFile);


%% t_mrdFibersLoad
%
% OLD - probably should be deleted.
%
% Initialize a fiber group, potentially cull them using old ER code, and
% save them (culled).
%
% See: t_mrdArcuatePredictions
%
% (c) Stanford VISTA Team

doculling = 0;

%% Read the dt6 file.

% We load up the dt6 and open the mrDiffusion window so that we can easily
% transform between spaces.
dt6Name = fullfile(dataDir,'dti40','dt6.mat');
[dtiF, dtiH] = mrDiffusion('off',dt6Name);

% get the xForm from image space 3 acpc space
xForm.img2acpc = dtiGet(dtiH,'img 2 acpc xform');

% get the xForm from acpc space to image space
xForm.acpc2img = dtiGet(dtiH,'acpc2img xform');

% Set the colors of the three fiber groups.
cList = {[200,50 ,50],[50,200,50],[50,50,200]};

%% Load the first STT group

fgName{1} = fullfile(mrvDataRootPath,'diffusion','fiberPrediction','fibers','R_Arcuate_Box_STT.mat');
temp = dtiReadFibers(fgName{1}); % Fiber coordinates in acpc space

if doculling
 % Remove redundant fibers from the group:
 fgAcpc(1) = dtiCullFibers(temp, dt6Name);
else
 fgAcpc(1) = temp;
end

%% read ConTrac fiber group
fgName{2} = fullfile(mrvDataRootPath,'diffusion','fiberPrediction','fibers','R_Arcuate_ctr_clean.mat');
temp = dtiReadFibers(fgName{2}); % Fiber coordinates in acpc space

if doculling
 % Remove redundant fibers from the group:
 fgAcpc(2) = dtiCullFibers(temp, dt6Name);
else
  fgAcpc(2) = temp;
end

%% Merge them first fiber group
fgName{3} = 'R_Arcuate_Box_merged_stt_ctr-culled.mat';
fgAcpc(3) = dtiMergeFiberGroups(fgAcpc(1),fgAcpc(2),fgName{3}); % Fiber coordinates in acpc space

%% Spatial transforms into image space

% Fibers are stored in ACPC space.
% In this space, they are in mm
%    fLengths = fgGet(fg,'fiber lengths');
%     \mrvNewGraphWin; hist(fLengths,100)
fgImg = struct(fgAcpc);
for ii = 1:length(fgAcpc)
 dtiH = dtiSet(dtiH,'add fiber group',fgAcpc(ii));

 % Have a look at the fibers.  Visualizations are in ACPC space.
 % fgMesh(fgAcpc{i},dtiH);

 % Create a version of the fiber group in image space for computations
 % There is a problem:  See dtiXformFiberCoords.  But since this script
 % should probably go away, I am not fixing it now.
 fgImg(ii) = dtiXformFiberCoords(fgAcpc(ii),xForm.acpc2img);

 fgImg(ii).colorRgb = cList{ii};

end

%% Save

% Becasuse dtiCullFibers takes a while for the large group, we save these
% out.
culledFiberGroups = ...
    fullfile(mrvDataRootPath,'diffusion','fiberPrediction','fibers','culledFiberGroups.mat');
save(culledFiberGroups,'fgImg');

%% To view the saved fibers ...

% guidata(dtiF,dtiH);
% figure(dtiF)

% To load the fiber groups:
%   load(culledFiberGroups,'fgImg')

%% End


function varargout = surf(m,cdata,varargin)
%
% Syntax
%   surf(m,cdata)
%
% Input
%
% Output
%
% Options
%
% See also
%

varargin = [m.CS.plotOptions,varargin];
[varargout{1:nargout}] = surf@vector3d(m,cdata,varargin{:},m.CS);


function definput = arg_wfbtcommon(definput)

% definput.keyvals.J = 1;
% definput.flags.treetype = {'full','dwt'};
% Frequency vs. natral ordering of the output subbands
definput.flags.forder = {'freq','nat'};


function [] = extract_ros_data(file_name, load_folder, save_folder, cam_name)
%EXTRACT_ROS_DATA reads a ROS bag, and saves the events, IMU messages and
%camera info in a mat file.
%
% Syntax: extract_ros_data(file_name, load_folder, save_folder)
%
% You will need the matlab_rosbag package:
% https://github.com/bcharrow/matlab_rosbag
%
% Inputs:
%    file_name   - name of the bag file (no extension).
%    load_folder - folder of the bag. No trailing slash. Set to . by
%                  default.
%    save_folder - folder the mat is saved in. Set to load_folder by
%                  default.
%    cam_name    - OPTIONAL name of the event camera topic if not davis or
%                  dvs.
%
% See also GENERATE_UNDISTORT_MAP
%
% Author: Alex Zihao Zhu, University of Pennsylvania
% Email: alexzhu(at)seas.upenn.edu
% Copyright 2018 University of Pennsylvania
% Alex Zihao Zhu, Nikolay Atanasov, Kostas Daniilidis
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, CONTRIBUTORS, AND THE
% TRUSTEES OF THE UNIVERSITY OF PENNSYLVANIA "AS IS" AND ANY EXPRESS OR
% IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
% OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
% IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE TRUSTEES OF
% THE UNIVERSITY OF PENNSYLVANIA BE LIABLE FOR ANY DIRECT, INDIRECT,
% INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
% NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
% DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
% THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
% (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
% THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

if nargin==1
    load_folder = '.';
end

if nargin < 3
    save_folder = load_folder;
end

if nargin == 4
    fprintf(['Warning: You have set the cam_name argument to ''%s''. ', ...
        'If this is intentional, please ignore this message.\n'], cam_name)
end

bag_name = strcat(load_folder,'/', file_name, '.bag');

fprintf('Reading ROS bag %s. This may take some time.\n', bag_name)

bag = ros.Bag.load(bag_name);

event_topics = bag.topics('.*events');

if isempty(event_topics)
    fprintf('Error, no topic with events found in bag %s\n', bag_name);
    return
end

if contains(event_topics{1}, 'davis')
    cam_name = 'davis';
elseif contains(event_topics{1}, 'dvs')
    cam_name = 'dvs';
elseif nargin < 4
    fprintf(['Could not find the default camera names ''davis'' or ''dvs'' in the bag.', ...
        'Please enter the camera name as a fourth argument to this function.\n']);
    return
end

if length(event_topics) == 1
    event_topic = ['/' cam_name '/events'];
    cinfo_topic = ['/' cam_name '/camera_info'];
    imu_topic = ['/' cam_name '/imu'];
elseif length(event_topics) == 2
    if contains(event_topics{1}, 'left') || contains(event_topics{2}, 'left')
        event_topic = ['/' cam_name '/left/events'];
        cinfo_topic = ['/' cam_name '/left/camera_info'];
        imu_topic = ['/' cam_name '/left/imu'];
    else
        fprintf('No left event topic found despite two event topics found.\n')
    end
else
    fprintf('Can''t find monocular or stereo events.\n')
end

[event_msgs, ~] = bag.readAll(event_topic);
[imu_msgs, ~] = bag.readAll(imu_topic);
[cinfo_msgs, ~] = bag.readAll(cinfo_topic);

num_event = 0;

for i=1:length(event_msgs)
    num_event = num_event + size(event_msgs{i}.events, 2);
end

cinfo = cinfo_msgs{1};

events = zeros(4, num_event);

iter = 1;

for i=1:length(event_msgs)
    events(:, iter:iter+size(event_msgs{i}.events,2)-1) = event_msgs{i}.events;
    iter = iter+size(event_msgs{i}.events,2);
end

num_imu = length(imu_msgs);

lin_acc = zeros(3, num_imu);
ang_vel = zeros(3, num_imu);
imu_time = zeros(num_imu, 1);

for i=1:num_imu
    lin_acc(:,i) = imu_msgs{i}.linear_acceleration;
    ang_vel(:,i) = imu_msgs{i}.angular_velocity;
    imu_time(i) = imu_msgs{i}.header.stamp.time;
end

output_name = strcat(save_folder,'/',file_name);

fprintf('Saving data to %s. This may take some time.\n', output_name)

save(output_name,'file_name','events',...
    'lin_acc','ang_vel','imu_time', 'cinfo', '-v7.3');
end


function model=addRxnsGenesMets(model,sourceModel,rxns,addGene,rxnNote,confidence)
% addRxnsGenesMets
%   Copies reactions from a source model to a new model, including
%   (new) metabolites and genes
%
%   model           draft model where reactions should be copied to
%   sourceModel     model where reactions and metabolites are sourced from
%   rxns            cell array with reaction IDs (from source model). Can also
%                   be string if only one reaction is added
%   addGene         three options:
%                   false   no genes are annotated to the new reactions
%                   true    grRules ared copied from the sourceModel and
%                           new genes are added when required
%                   string or cell array
%                           new grRules are specified as string or cell
%                           array, and any new genes are added when
%                           required
%                   (opt, default false)
%   rxnNote         cell array with strings explaining why reactions were copied
%                   to the model, to be included as newModel.rxnNotes. Can also
%                   be string if same rxnNotes should be added for each new
%                   reaction, or only one reaction is to be added (opt, default
%                   'Added via addRxnsAndMets()')
%   confidence      integer specifying confidence score for all reactions.
%                   4:  biochemical data: direct evidence from enzymes
%                       assays
%                   3:  genetic data: knockout/-in or overexpression
%                       analysis
%                   2:  physiological data: indirect evidence, e.g.
%                       secretion products or defined medium requirement
%                       sequence data: genome annotation
%                   1:  modeling data: required for functional model,
%                       hypothetical reaction
%                   0:  no evidence
%                   following doi:10.1038/nprot.2009.203 (opt, default 0)
%
%   newModel        an updated model structure
%
% 	This function only works if the draft model and source model follow
%	the same metabolite and compartment naming convention. Metabolites are
%	only matched by metaboliteName[compartment]. Useful if one wants to copy
%	additional reactions from source to draft after getModelFromHomology was
%	used involving the same models.
%
%   Usage: newModel=addRxnsGenesMets(model,sourceModel,rxns,addGene,rxnNote,confidence)

if nargin<6
    confidence=0;
end
rxns=convertCharArray(rxns);
if nargin<5
    rxnNote={'Added via addRxnsGenesMets()'};
else
    rxnNote=convertCharArray(rxnNote);
end
if numel(rxnNote)==1 && numel(rxns)>1
    rxnNoteArray=cell(1,numel(rxns));
    rxnNoteArray(:)=rxnNote;
    rxnNote=rxnNoteArray;
end
if nargin<4
    addGene=false;
end

% Obtain indexes of reactions in source model
[notNewRxn,oldRxn]=ismember(rxns,model.rxns);
rxns=rxns(~notNewRxn);
if isempty(rxns)
    error('All reactions are already in the model.');
elseif ~isempty(notNewRxn)
    fprintf('The following reactions were already present in the model and will not be added:\n')
    fprintf([strjoin(model.rxns(oldRxn(find(oldRxn))),'\n') '\n'])
end

[~, rxnIdx]=ismember(rxns,sourceModel.rxns); % Get rxnIDs
if any(rxnIdx==0)
    error('Not all reaction IDs could be found in the source model')
end

% Add new metabolites
metIdx=find(any(sourceModel.S(:,rxnIdx),2)); % Get metabolite IDs
% Many of the metabolites in are already in the draft model, so only add
% the new metabolites

% Match by metNames[metComps]. First make these structures for each model.
metCompsN =cellstr(num2str(model.metComps));
map=containers.Map(cellstr(num2str(transpose([1:length(model.comps)]))),model.comps);
metCompsN = map.values(metCompsN);
metCompsN = strcat(model.metNames,'[',metCompsN,']');

sourcemetCompsN=cellstr(num2str(sourceModel.metComps));
map=containers.Map(cellstr(num2str(transpose([1:length(sourceModel.comps)]))),sourceModel.comps);
sourcemetCompsN = map.values(sourcemetCompsN);
sourcemetCompsN=strcat(sourceModel.metNames,'[',sourcemetCompsN,']');

newMetCompsN=sourcemetCompsN(metIdx);
notNewMet=newMetCompsN(ismember(newMetCompsN,metCompsN));

if ~isempty(notNewMet)
    fprintf('\nThe following metabolites were already present in the model and will not be added:\n')
    fprintf([strjoin(transpose(notNewMet),'\n') '\n'])
end

metIdx=metIdx(~ismember(sourcemetCompsN(metIdx),metCompsN));

if ~isempty(metIdx)
    fprintf('\nThe following metabolites will be added to the model:\n')
    fprintf([strjoin(transpose(sourcemetCompsN(metIdx)),'\n') '\n'])

    if isfield(sourceModel,'mets')
        metsToAdd.mets=sourceModel.mets(metIdx);
    end
    if isfield(sourceModel,'metNames')
        metsToAdd.metNames=sourceModel.metNames(metIdx);
    end
    if isfield(sourceModel,'metFormulas')
        metsToAdd.metFormulas=sourceModel.metFormulas(metIdx);
    end
    if isfield(sourceModel,'metCharge')
        metsToAdd.metCharge=sourceModel.metCharge(metIdx);
    end
    if isfield(sourceModel,'metMiriams')
        metsToAdd.metMiriams=sourceModel.metMiriams(metIdx);
    end
    if isfield(sourceModel,'metFormulas')
        metsToAdd.metFormulas=sourceModel.metFormulas(metIdx);
    end
    if isfield(sourceModel,'inchis')
        metsToAdd.inchis=sourceModel.inchis(metIdx);
    end
    if isfield(sourceModel,'metSmiles')
        metsToAdd.metSmiles=sourceModel.metSmiles(metIdx);
    end

    metsToAdd.compartments=strtrim(cellstr(num2str(sourceModel.metComps(metIdx)))); % Convert from compartment string to compartment number
    [~,idx]=ismember(metsToAdd.compartments,strsplit(num2str(1:length(sourceModel.comps)))); % Match compartment number to compartment abbreviation
    metsToAdd.compartments=sourceModel.comps(idx); % Fill in compartment abbreviations

    model=addMets(model,metsToAdd);
end
fprintf('\nNumber of metabolites added to the model:\n')
fprintf([num2str(numel(metIdx)),'\n'])

% Add new genes
if ~islogical(addGene) | addGene ~= false
    if ischar(addGene)
        rxnToAdd.grRules={addGene};
    elseif iscell(addGene)
        rxnToAdd.grRules=addGene(~notNewRxn);
    else
        rxnToAdd.grRules=sourceModel.grRules(rxnIdx); % Get the relevant grRules
    end
end
% Add new reactions
rxnToAdd.equations=constructEquations(sourceModel,rxnIdx);
rxnToAdd.rxnNames=sourceModel.rxnNames(rxnIdx);
rxnToAdd.rxns=sourceModel.rxns(rxnIdx);
rxnToAdd.lb=sourceModel.lb(rxnIdx);
rxnToAdd.ub=sourceModel.ub(rxnIdx);
rxnToAdd.rxnNotes(:)=rxnNote(~notNewRxn);
rxnToAdd.rxnConfidenceScores=NaN(1,numel(rxnToAdd.rxns));
if ~isnumeric(confidence)
    EM='confidence score must be numeric';
    dispEM(EM, true);
end
rxnToAdd.rxnConfidenceScores(:)=confidence;
if isfield(sourceModel,'subSystems')
    rxnToAdd.subSystems=sourceModel.subSystems(rxnIdx);
end
if isfield(sourceModel,'eccodes')
    rxnToAdd.eccodes=sourceModel.eccodes(rxnIdx);
end
model=addRxns(model,rxnToAdd,3,'',false,true);

fprintf('\nNumber of reactions added to the model:\n')
fprintf([num2str(numel(rxnIdx)),'\n'])
end


close all;
%findBestAndWorstMCMCRunByLogPr( 1515157:1515161, 10 );

% plotLogPrVsTime( [1515157 1515159 1515160], 1:10, {'SM+DD one', 'Prior u5', 'SM+DD u5'} )
% ylim( [-5.8 -5.33]*1e4 );
% set( gcf, 'Name', 'LogPrCompare_ValidSamplers' );
% set(gca,'FontSize', 20);
%
% plotLogPrVsTime( [1515157 1515158], 1:10, {'SM+DD one', 'SMnoq+DD one'} )
% ylim( [-5.8 -5.33]*1e4 );
% set( gcf, 'Name', 'LogPrCompare_HastingsFactor_ONE' );
% set(gca,'FontSize', 20);
%
% plotLogPrVsTime( [1515160 1515161], 1:10, {'SM+DD unique5', 'SMnoq+DD unique5'} )
% ylim( [-5.8 -5.33]*1e4 );
% set( gcf, 'Name', 'LogPrCompare_HastingsFactor_Unique5' );
% set(gca,'FontSize', 20);

plotStateSeq( 1515157, 'best' );
set(gcf,'Name', 'StateSeq_SMvalid_ONE_Best' );

plotStateSeq( 1515158, 'best' );
set(gcf,'Name', 'StateSeq_SMnoq_ONE_Best' );

plotStateSeq( 1515160, 'best' );
set(gcf,'Name', 'StateSeq_SMvalid_UNIQUE5_Best' );

plotStateSeq( 1515161, 'best' );
set(gcf,'Name', 'StateSeq_SMnoq_UNIQUE5_Best' );


function x = cvx_reshape( x, s, rmap, cperm, cperm2 )
sx = size( x );
if nargin < 5,
    cperm2 = [];
    if nargin < 4,
        cperm = [];
        if nargin < 3,
            rmap = [];
            if nargin < 2,
                s = sx;
            end
        end
    end
end
usp = cvx_use_sparse( s, nnz( x ), isreal( x ) );
isp = issparse( x );
if ~usp && isp,
    x = full( x );
end
if ~isequal( s, sx ) || ~isempty( rmap ) || ~isempty( cperm ) || ~isempty( cperm2 ),
    if usp && ( numel( x ) > 2147483647 || ~isempty( rmap ) || ~isempty( cperm ) ),
        [ ii, jj, x ] = find( x );
        if ~isempty( rmap ),
            sx( 1 ) = length( rmap );
            rmap = find( rmap );
            ii = rmap( ii );
        end
        if ~isempty( cperm ),
            temp = 1 : sx( 2 );
            temp( cperm ) = temp;
            jj = temp( :, jj )';
        end
        ij = ii + ( jj - 1 ) * sx( 1 ) - 1;
        ii = rem( ij, s( 1 ) ) + 1;
        jj = floor( ij / s( 1 ) ) + 1;
        if ~isempty( cperm2 ),
            temp = 1 : s( 2 );
            temp( cperm2 ) = temp;
            jj = temp( :, jj )';
        end
        x = sparse( ii, jj, x, s( 1 ), s( 2 ) );
        clear ii jj ij
        isp = true;
    else
        if ~isempty( cperm ),
            x = x( :, cperm );
        end
        if ~isempty( rmap ),
            x = x( max( 1, cumsum( rmap ) ), : );
            x( ~rmap, : ) = 0;
        end
        x = reshape( x, s );
        if ~isempty( cperm2 ),
            x = x( :, cperm2 );
        end
    end
end
if usp && ~isp,
    x = sparse( x );
end

% Copyright 2010 Michael C. Grant and Stephen P. Boyd.
% See the file COPYING.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


% This function will find all subfolders of a directory
function subfolders = findSubfolders(rootdir)

[list ISDIR]= my_dir(rootdir);
subfolders = {};

for i=1:length(list)
    tmp = [rootdir '/' list{i}];
    if ISDIR(i)==1
        subfolders{end+1} = tmp;
        subsubfolders = findSubfolders(subfolders{end});
        subfolders = [subfolders subsubfolders];
    end
end


%msre_newton_solver is a function.
%    [T, retcode, c, Q] = msre_newton_solver(obj, inner_probs, T0, x0, control_shocks, options, kron_method)
%


function tutorial_visual_group(ProtocolName, reports_dir)
% TUTORIAL_VISUAL_GROUP: Runs the Brainstorm/SPM group analysis pipeline (group analysis, BIDS VERSION)
%
% ONLINE TUTORIALS:
%    - https://neuroimage.usc.edu/brainstorm/Tutorials/VisualSingle
%    - https://neuroimage.usc.edu/brainstorm/Tutorials/VisualGroup
%
% INPUTS:
%    - ProtocolName : Name of the protocol in which the recordings for the 19 subjects have been imported (TutorialVisual or TutorialGroup)
%                     This folder must include: the run-level averages (recordings and time-frequency) and the source kernels for each run
%    - reports_dir  : If defined, exports all the reports as HTML to this folder

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

% ===== CHECK PROTOCOL =====
% Start Brainstorm without the GUI
if ~brainstorm('status')
    brainstorm nogui
end
% Output folder for reports
if (nargin < 2) || isempty(reports_dir) || ~isdir(reports_dir)
    reports_dir = [];
end
% You have to specify the folder in which the tutorial dataset is unzipped
if (nargin < 1) || isempty(ProtocolName)
    ProtocolName = 'TutorialGroup';
end
% Select current protocol
iProtocol = bst_get('Protocol', ProtocolName);
if isempty(iProtocol)
    error(['Unknown protocol: ' ProtocolName]);
end
if (iProtocol ~= bst_get('iProtocol'))
    gui_brainstorm('SetCurrentProtocol', iProtocol);
end
% Process: Select results files in: sub-01/sub-01_ses-meg_task-facerecognition_run-01_proc-sss_meg_notch
sFiles = bst_process('CallProcess', 'process_select_files_results', [], [], ...
    'subjectname', 'sub-01', ...
    'condition',   'sub-01_ses-meg_task-facerecognition_run-01_proc-sss_meg_notch');
if isempty(sFiles)
    error(['No source files available in folder: sub-01/sub-01_ses-meg_task-facerecognition_run-01_proc-sss_meg_notch.' 10 ...
           'You should run tutorial_visual_single first, or download the ' 10 ...
           'protocol TutorialGroup.zip from the Brainstorm website.']);
end
% Process: Select file comments with tag: Unconstr
sFiles = bst_process('CallProcess', 'process_select_tag', sFiles, [], 'tag', 'Unconstr');
if ~isempty(sFiles)
    isUnconstrained = 1;
else
    isUnconstrained = 0;
end
% Start a new report
bst_report('Start');

% ===== DELETE ALL THE EXISTING FILES =====
GroupSubjectName = bst_get('NormalizedSubjectName');
DirIntra = bst_get('DirAnalysisIntra');
% Delete group analysis
[sSubject, iSubject] = bst_get('Subject', GroupSubjectName);
if ~isempty(sSubject)
    db_delete_subjects(iSubject);
end
% Get all the files in the intra subjects
sAvgSrc = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'includeintra',  1);
% If there are existing files: delete the contents of the folders
if ~isempty(sAvgSrc)
    % Get the base folder of the protocol
    ProtocolInfo = bst_get('ProtocolInfo', iProtocol);
    % Get all the folders
    AllIntraDir = unique(cellfun(@bst_fileparts, {sAvgSrc.FileName}, 'UniformOutput', 0));
    % Loop over the intra folders
    for iSubj = 1:length(AllIntraDir)
        % Get all the files
        subjIntraDir = dir(fullfile(ProtocolInfo.STUDIES, AllIntraDir{iSubj}, '*.mat'));
        subjIntraFiles = setdiff({subjIntraDir.name}, 'brainstormstudy.mat');
        % Delete all the files
        for iFile = 1:length(subjIntraFiles)
            delete(fullfile(ProtocolInfo.STUDIES, AllIntraDir{iSubj}, subjIntraFiles{iFile}));
        end
    end
    % Reload protocol
    db_reload_database(iProtocol);
end

%% ===== SUBJECT AVERAGES: FAMOUS, UNFAMILIAR, SCRAMBLED ==============================
%  ====================================================================================

% ===== SUBJECT AVERAGE: MEG+EEG =====
% Process: Select data files in: */*/Avg
sAvgRun = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname', 'All', ...
    'tag',         'Avg');
% Process: Weighted Average: By trial group (subject average)
sAvgSubj = bst_process('CallProcess', 'process_average', sAvgRun, [], ...
    'avgtype',    6, ...  % By trial group (subject average)
    'avg_func',   1, ...  % Arithmetic average:  mean(x)
    'weighted',   1, ...
    'keepevents', 1);
% Process: Average: By trial group (grand average)
sAvgGroup = bst_process('CallProcess', 'process_average', sAvgSubj, [], ...
    'avgtype',    7, ...  % By trial group (grand average)
    'avg_func',   1, ...  % Arithmetic average:  mean(x)
    'weighted',   0, ...
    'keepevents', 0);

% ===== SUBJECT AVERAGES: SOURCES (EEG) =====
% Process: Select source files in: */*/EEG
sAvgRunSrcEeg = bst_process('CallProcess', 'process_select_files_results', [], [], 'tag', 'EEG');
% Process: Weighted Average: By trial group (subject average) - EEG
sAvgSubjSrcEeg = bst_process('CallProcess', 'process_average', sAvgRunSrcEeg, [], ...
    'avgtype',         6, ...  % By trial group (subject average)
    'avg_func',        1, ...  % Arithmetic average:  mean(x)
    'weighted',        1, ...
    'scalenormalized', 0);
% Process: Add tag: EEG
sAvgSubjSrcEeg = bst_process('CallProcess', 'process_add_tag', sAvgSubjSrcEeg, [], ...
    'tag',    'EEG', ...
    'output', 1);  % Add to comment

% ===== SUBJECT AVERAGES: SOURCES (MEG) =====
% Process: Select source files in: */*/MEG
sAvgRunSrcMeg = bst_process('CallProcess', 'process_select_files_results', [], [], 'tag', 'MEG');
% Process: Weighted Average: By trial group (subject average) - MEG
sAvgSubjSrcMeg = bst_process('CallProcess', 'process_average', sAvgRunSrcMeg, [], ...
    'avgtype',         6, ...  % By trial group (subject average)
    'avg_func',        1, ...  % Arithmetic average:  mean(x)
    'weighted',        1, ...
    'scalenormalized', 1);
% Process: Add tag: MEG
sAvgSubjSrcMeg = bst_process('CallProcess', 'process_add_tag', sAvgSubjSrcMeg, [], ...
    'tag',    'MEG', ...
    'output', 1);  % Add to comment

% ===== SUBJECT AVERAGES: TIMEFREQ =====
% Process: Select time-frequency files in: */*
sAvgRunTf = bst_process('CallProcess', 'process_select_files_timefreq', [], []);
% Process: Weighted Average: By trial group (subject average)
sAvgSubjTf = bst_process('CallProcess', 'process_average', sAvgRunTf, [], ...
    'avgtype',         6, ...  % By trial group (subject average)
    'avg_func',        1, ...  % Arithmetic average:  mean(x)
    'weighted',        1, ...
    'scalenormalized', 1);

%% ===== SUBJECT AVERAGES: FACES ======================================================
%  ====================================================================================

% ===== FACES AVERAGE: MEG+EEG ======
% Process: Select data files in: */*
sAllData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   'All', ...
    'includeintra',  1);
% Process: Select file comments with tag: "WAvg: Avg: Famous (6 files)"
sAvgSubjFamous = bst_process('CallProcess', 'process_select_tag', sAllData, [], 'tag', 'WAvg: Avg: Famous (6 files)');
% Process: Select file comments with tag: "WAvg: Avg: Unfamiliar (6 files)"
sAvgSubjUnfamiliar = bst_process('CallProcess', 'process_select_tag', sAllData, [],  'tag', 'WAvg: Avg: Unfamiliar (6 files)');
% Process: Weighted Average A&B
sAvgSubjFaces = bst_process('CallProcess', 'process_average_ab', sAvgSubjFamous, sAvgSubjUnfamiliar, ...
    'weighted', 1);
% Process: Add tag: Faces
sAvgSubjFaces = bst_process('CallProcess', 'process_add_tag', sAvgSubjFaces, [], ...
    'tag',    'Faces', ...
    'output', 2);  % Add to file name
% Process: Set comment
sAvgSubjFaces = bst_process('CallProcess', 'process_set_comment', sAvgSubjFaces, [], ...
    'tag',     'WAvg: Avg: Faces', ...
    'isindex', 0);
% Process: Average: By trial group (grand average)
sAvgGroupFaces = bst_process('CallProcess', 'process_average', sAvgSubjFaces, [], ...
    'avgtype',    7, ...  % By trial group (grand average)
    'avg_func',   1, ...  % Arithmetic average:  mean(x)
    'weighted',   0, ...
    'keepevents', 0);

% ===== FACES AVERAGE: SOURCES (EEG) ======
% Process: Select source files in: */*/EEG
sSrcEeg = bst_process('CallProcess', 'process_select_files_results', [], [], ...
    'subjectname',   'All', ...
    'tag',           'EEG', ...
    'includeintra',  1);
% Process: Select file comments with tag: "WAvg: Avg: Famous"
sAvgSubjFamousSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Famous');
% Process: Select file comments with tag: "WAvg: Avg: Unfamiliar"
sAvgSubjUnfamiliarSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Unfamiliar');
% Process: Weighted Average A&B
sAvgSubjFacesSrcEeg = bst_process('CallProcess', 'process_average_ab', sAvgSubjFamousSrcEeg, sAvgSubjUnfamiliarSrcEeg, ...
    'weighted',        1, ...
    'scalenormalized', 1);
% Process: Add tag: Faces
sAvgSubjFacesSrcEeg = bst_process('CallProcess', 'process_add_tag', sAvgSubjFacesSrcEeg, [], ...
    'tag',    'Faces', ...
    'output', 2);  % Add to file name
% Process: Set comment
sAvgSubjFacesSrcEeg = bst_process('CallProcess', 'process_set_comment', sAvgSubjFacesSrcEeg, [], ...
    'tag',     'WAvg: Avg: Faces | EEG', ...
    'isindex', 0);

% ===== FACES AVERAGE: SOURCES (MEG) ======
% Process: Select source files in: */*
sSrcMeg = bst_process('CallProcess', 'process_select_files_results', [], [], ...
    'subjectname',   'All', ...
    'tag',           'MEG', ...
    'includeintra',  1);
% Process: Select file comments with tag: Famous
sAvgSubjFamousSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'Famous');
% Process: Select file comments with tag: Unfamiliar
sAvgSubjUnfamiliarSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'Unfamiliar');
% Process: Weighted Average A&B
sAvgSubjFacesSrcMeg = bst_process('CallProcess', 'process_average_ab', sAvgSubjFamousSrcMeg, sAvgSubjUnfamiliarSrcMeg, ...
    'weighted',        1, ...
    'scalenormalized', 1);
% Process: Add tag: Faces
sAvgSubjFacesSrcMeg = bst_process('CallProcess', 'process_add_tag', sAvgSubjFacesSrcMeg, [], ...
    'tag',    'Faces', ...
    'output', 2);  % Add to file name
% Process: Set comment
sAvgSubjFacesSrcMeg = bst_process('CallProcess', 'process_set_comment', sAvgSubjFacesSrcMeg, [], ...
    'tag',     'WAvg: Avg: Faces | MEG', ...
    'isindex', 0);

% ===== FACES AVERAGE: TIMEFREQ ======
% Process: Select time-frequency files in: */*
sAllTf = bst_process('CallProcess', 'process_select_files_timefreq', [], [], ...
    'subjectname',   'All', ...
    'includeintra',  1);
% Process: Select file comments with tag: "WAvg: Avg: Famous"
sAvgSubjFamousTf = bst_process('CallProcess', 'process_select_tag', sAllTf, [], 'tag', 'WAvg: Avg: Famous');
% Process: Select file comments with tag: "WAvg: Avg: Unfamiliar"
sAvgSubjUnfamiliarTf = bst_process('CallProcess', 'process_select_tag', sAllTf, [], 'tag', 'WAvg: Avg: Unfamiliar');
% Process: Weighted Average A&B
sAvgSubjFacesTf = bst_process('CallProcess', 'process_average_ab', sAvgSubjFamousTf, sAvgSubjUnfamiliarTf, ...
    'weighted', 1);
% Process: Add tag: Faces
sAvgSubjFacesTf = bst_process('CallProcess', 'process_add_tag', sAvgSubjFacesTf, [], ...
    'tag',    'Faces', ...
    'output', 2);  % Add to file name
% Process: Set comment
sAvgSubjFacesTf = bst_process('CallProcess', 'process_set_comment', sAvgSubjFacesTf, [], ...
    'tag',     'WAvg: Avg: Faces', ...
    'isindex', 0);

%% ===== SUBJECT AVERAGES: WITHIN-SUBJECT DIFFERENCES =================================
%  ====================================================================================

% ===== FACES - SCRAMBLED: SOURCES EEG =====
% Process: Select source files in: */*/EEG
sSrcEeg = bst_process('CallProcess', 'process_select_files_results', [], [], ...
    'subjectname',   'All', ...
    'tag',           'EEG', ...
    'includeintra',  1);
% Process: Select file comments with tag: "WAvg: Avg: Faces"
sAvgSubjFacesSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Faces');
% Process: Select file comments with tag: "WAvg: Avg: Scrambled"
sAvgSubjScrambledSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Scrambled');
% Process: Difference: A-B
sDiffFacesSubjSrcEeg = bst_process('CallProcess', 'process_diff_ab', sAvgSubjFacesSrcEeg, sAvgSubjScrambledSrcEeg, ...
    'source_abs', 0);
% Process: Set comment
sDiffFacesSubjSrcEeg = bst_process('CallProcess', 'process_set_comment', sDiffFacesSubjSrcEeg, [], ...
    'tag',     'Faces - Scrambled | EEG', ...
    'isindex', 0);

% ===== FACES - SCRAMBLED: SOURCES MEG =====
% Process: Select source files in: */*/MEG
sSrcMeg = bst_process('CallProcess', 'process_select_files_results', [], [], ...
    'subjectname',   'All', ...
    'tag',           'MEG', ...
    'includeintra',  1);
% Process: Select file comments with tag: "WAvg: Avg: Faces"
sAvgSubjFacesSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'WAvg: Avg: Faces');
% Process: Select file comments with tag: "WAvg: Avg: Scrambled"
sAvgSubjScrambledSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'WAvg: Avg: Scrambled');
% Process: Difference: A-B
sDiffFacesSubjSrcMeg = bst_process('CallProcess', 'process_diff_ab', sAvgSubjFacesSrcMeg, sAvgSubjScrambledSrcMeg, ...
    'source_abs', 0);
% Process: Set comment
sDiffFacesSubjSrcMeg = bst_process('CallProcess', 'process_set_comment', sDiffFacesSubjSrcMeg, [], ...
    'tag',     'Faces - Scrambled | MEG', ...
    'isindex', 0);

% ===== FAMOUS - UNFAMILIAR: SOURCE EEG =====
% Process: Select file comments with tag: "WAvg: Avg: Famous"
sAvgSubjFamousSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Famous');
% Process: Select file comments with tag: "WAvg: Avg: Unfamiliar"
sAvgSubjUnfamiliarSrcEeg = bst_process('CallProcess', 'process_select_tag', sSrcEeg, [], 'tag', 'WAvg: Avg: Unfamiliar');
% Process: Difference: A-B
sDiffFamousSubjSrcEeg = bst_process('CallProcess', 'process_diff_ab', sAvgSubjFamousSrcEeg, sAvgSubjUnfamiliarSrcEeg, ...
    'source_abs', 0);
% Process: Set comment
sDiffFamousSubjSrcEeg = bst_process('CallProcess', 'process_set_comment', sDiffFamousSubjSrcEeg, [], ...
    'tag',     'Famous - Unfamiliar | EEG', ...
    'isindex', 0);

% ===== FAMOUS - UNFAMILIAR: SOURCE MEG =====
% Process: Select file comments with tag: "WAvg: Avg: Famous"
sAvgSubjFamousSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'WAvg: Avg: Famous');
% Process: Select file comments with tag: "WAvg: Avg: Unfamiliar"
sAvgSubjUnfamiliarSrcMeg = bst_process('CallProcess', 'process_select_tag', sSrcMeg, [], 'tag', 'WAvg: Avg: Unfamiliar');
% Process: Difference: A-B
sDiffFamousSubjSrcMeg = bst_process('CallProcess', 'process_diff_ab', sAvgSubjFamousSrcMeg, sAvgSubjUnfamiliarSrcMeg, ...
    'source_abs', 0);
% Process: Set comment
sDiffFamousSubjSrcMeg = bst_process('CallProcess', 'process_set_comment', sDiffFamousSubjSrcMeg, [], ...
    'tag',     'Famous - Unfamiliar | MEG', ...
    'isindex', 0);

%% ===== SUBJECT AVERAGES: FILTER AND NORMALIZE =======================================
%  ====================================================================================

% ===== FILTER: MEG+EEG =====
% Process: Select data files in: */Intra
sAvgData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'includeintra',  1);
% Process: Low-pass:32Hz
sAvgData = bst_process('CallProcess', 'process_bandpass', sAvgData, [], ...
    'sensortypes', 'MEG, EEG', ...
    'highpass',    0, ...
    'lowpass',     32, ...
    'attenuation', 'strict', ...  % 60dB
    'mirror',      0, ...
    'overwrite',   1);
% Process: Extract time: [-202ms,900ms]
sAvgData = bst_process('CallProcess', 'process_extract_time', sAvgData, [], ...
    'timewindow', [-0.2018, 0.9], ...
    'overwrite',  1);

% ===== FILTER AND NORMALIZE: SOURCES =====
% Process: Select source files in: */Intra
sAvgSrc = bst_process('CallProcess', 'process_select_files_results', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'includeintra',  1);
% Process: Low-pass:32Hz
sAvgSrc = bst_process('CallProcess', 'process_bandpass', sAvgSrc, [], ...
    'highpass',    0, ...
    'lowpass',     32, ...
    'attenuation', 'strict', ...  % 60dB
    'mirror',      0, ...
    'overwrite',   1);
% Process: Extract time: [-202ms,900ms]
sAvgSrc = bst_process('CallProcess', 'process_extract_time', sAvgSrc, [], ...
    'timewindow', [-0.2018, 0.9], ...
    'overwrite',  1);
% Process: Z-score transformation: [-202ms,-5ms]
sAvgSrc = bst_process('CallProcess', 'process_baseline_norm', sAvgSrc, [], ...
    'baseline',   [-0.2018, -0.005], ...
    'source_abs', 0, ...
    'method',     'zscore', ...  % Z-score transformation:    x_std = (x - μ) / σ
    'overwrite',  1);

% ===== NORMALIZE: TIMEFREQ =====
% Process: Select time-frequency files in: */Intra
sAvgTf = bst_process('CallProcess', 'process_select_files_timefreq', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'includeintra',  1);
% Process: Event-related perturbation (ERS/ERD): [-200ms,-4ms]
sAvgTf = bst_process('CallProcess', 'process_baseline_norm', sAvgTf, [], ...
    'baseline',  [-0.2, -0.004], ...
    'method',    'ersd', ...  % Event-related perturbation (ERS/ERD):    x_std = (x - μ) / μ * 100
    'overwrite', 1);

% Save report
ReportFile = bst_report('Save', []);
if ~isempty(reports_dir) && ~isempty(ReportFile)
    bst_report('Export', ReportFile, bst_fullfile(reports_dir, ['report_' ProtocolName '_1prepare.html']));
end

%% ===== SUBJECT AVERAGES: SCREEN CAPTURES ============================================
%  ====================================================================================
% Start a new report
bst_report('Start');
% Set colormap: local color scale
bst_colormaps('SetMaxMode', 'stat2', 'local');

% ===== FACES: RECORDINGS ======
% Process: Select data files in: */*/WAvg: Avg: Faces |
sAvgFaces = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   'All', ...
    'tag',           'WAvg: Avg: Faces |', ...
    'includeintra',  1);
% Process: Snapshot: Recordings time series
bst_process('CallProcess', 'process_snapshot', sAvgFaces, [], ...
    'target',         1, ...  % Sensor/MRI registration
    'modality',       1);     % MEG
% Process: Snapshot: Recordings time series
bst_process('CallProcess', 'process_snapshot', sAvgFaces, [], ...
    'target',         5, ...  % Recordings time series
    'modality',       4, ...  % EEG
    'time',           0.1055);

% ===== FACES: SOURCES MEG ======
% Process: Select source files in: */*/WAvg: Avg: Faces | MEG
sAvgFacesSrcMeg = bst_process('CallProcess', 'process_select_files_results', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'tag',           'WAvg: Avg: Faces | MEG', ...
    'includeintra',  1);
% Process: Snapshot: Sources (one time)
bst_process('CallProcess', 'process_snapshot', sAvgFacesSrcMeg, [], ...
    'target',         8, ...  % Sources (one time)
    'orient',         6, ...  % back
    'time',           0.1055, ...
    'threshold',      10);

% ===== FACES: TIME-FREQ EEG ======
% Process: Select time-frequency files in: */*/WAvg: Avg: Faces
sAvgFacesTf = bst_process('CallProcess', 'process_select_files_timefreq', [], [], ...
    'subjectname',   'All', ...
    'tag',           'WAvg: Avg: Faces', ...
    'includeintra',  1);
% Process: Snapshot: Time-frequency maps
bst_process('CallProcess', 'process_snapshot', sAvgFacesTf, [], ...
    'target',         14, ...  % Time-frequency maps
    'time',           0.1055, ...
    'rowname',        'EEG070');

% Save report
ReportFile = bst_report('Save', []);
if ~isempty(reports_dir) && ~isempty(ReportFile)
    bst_report('Export', ReportFile, bst_fullfile(reports_dir, ['report_' ProtocolName '_2snapshots.html']));
end

%% ===== GROUP ANALYSIS: FACES-SCRAMBLED: MEG/EEG =====================================
%  ====================================================================================
% Start a new report
bst_report('Start');
% Set colormap: global color scale
bst_colormaps('SetMaxMode', 'meg', 'global');
bst_colormaps('SetMaxMode', 'eeg', 'global');
% Set display properties for statistics: p<0.05, FDR-corrected
StatThreshOptions = bst_get('StatThreshOptions');
StatThreshOptions.pThreshold = 0.05;
StatThreshOptions.Correction = 'fdr';
StatThreshOptions.Control    = [1 2 3];
bst_set('StatThreshOptions', StatThreshOptions);

% ===== GRAND AVERAGES =====
% Process: Select data files in: Group_analysis/Intra
sAvgData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   GroupSubjectName, ...
    'condition',     DirIntra, ...
    'includeintra',  1);
% Take screen captures
DataScreenCapture(sAvgData(1), 1, 1, '');
DataScreenCapture(sAvgData(2), 1, 1, '');
DataScreenCapture(sAvgData(3), 1, 1, '');
DataScreenCapture(sAvgData(4), 1, 1, '');
% Define function for screen captures
function DataScreenCapture(sFiles, isMEG, isEEG, Comment)
    if isMEG
        % Process: Snapshot: Recordings time series
        bst_process('CallProcess', 'process_snapshot', sFiles, [], ...
            'target',         5, ...  % Recordings time series
            'modality',       3, ...  % MEG (Magnetometers)
            'time',           0.1055, ...
            'Comment',        ['MEG MAG: ' Comment]);
        % Process: Snapshot: Recordings topography (contact sheet)
        bst_process('CallProcess', 'process_snapshot', sFiles, [], ...
            'target',         7, ...  % Recordings topography (contact sheet)
            'modality',       3, ...  % MEG (Magnetometers)
            'contact_time',   [0.050, 0.300], ...
            'contact_nimage', 6, ...
            'Comment',        ['MEG MAG: ' Comment]);
    end
    if isEEG
        % Process: Snapshot: Recordings time series
        bst_process('CallProcess', 'process_snapshot', sFiles, [], ...
            'target',         5, ...  % Recordings time series
            'modality',       4, ...  % EEG
            'time',           0.1055, ...
            'Comment',        ['EEG: ' Comment]);
        % Process: Snapshot: Recordings topography (contact sheet)
        bst_process('CallProcess', 'process_snapshot', sFiles, [], ...
            'target',         7, ...  % Recordings topography (contact sheet)
            'modality',       4, ...  % EEG
            'contact_time',   [0.050, 0.300], ...
            'contact_nimage', 6, ...
            'Comment',        ['EEG: ' Comment]);
    end
end

% ===== FACES-SCRAMBLED: MEAN DIFF =====
% Process: Select data files in: */DirIntra/"Avg: Faces | "
sSubjAvgFacesData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'tag',           'Avg: Faces | ', ...
    'includeintra',  1);
% Process: Select data files in: */DirIntra/"WAvg: Avg: Scrambled (6 files)"
sSubjAvgScrambledData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'tag',           'WAvg: Avg: Scrambled (6 files)', ...
    'includeintra',  1);
% Process: Difference of means [mean]
sDiffFacesData = bst_process('CallProcess', 'process_diff_mean', sSubjAvgFacesData, sSubjAvgScrambledData, ...
    'avg_func', 1, ...  % Arithmetic average mean(A) - mean(B)
    'weighted', 0);
% Process: Set comment
sDiffFacesData = bst_process('CallProcess', 'process_set_comment', sDiffFacesData, [], ...
    'tag',     'Faces - Scrambled', ...
    'isindex', 0);
% Take screen captures
DataScreenCapture(sDiffFacesData, 1, 1, sDiffFacesData.Comment);

% ===== FACES-SCRAMBLED: PARAMETRIC T-TEST =====
% Process: Select data files in: */DirIntra/"Avg: Faces | "
sSubjAvgFacesData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'tag',           'Avg: Faces | ', ...
    'includeintra',  1);
% Process: Select data files in: */DirIntra/"WAvg: Avg: Scrambled (6 files)"
sSubjAvgScrambledData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'tag',           'WAvg: Avg: Scrambled (6 files)', ...
    'includeintra',  1);
% Process: t-test paired [ALL]          H0:(A=B), H1:(A<>B)
sStatParamFacesData = bst_process('CallProcess', 'process_test_parametric2p', sSubjAvgFacesData, sSubjAvgScrambledData, ...
    'timewindow',    [], ...
    'sensortypes',   '', ...
    'isabs',         0, ...
    'avgtime',       0, ...
    'avgrow',        0, ...
    'Comment',       '', ...
    'test_type',     'ttest_paired', ...  % Paired Student's t-test        (A-B)~N(m,v)t = mean(A-B) / std(A-B) * sqrt(n)      df=n-1
    'tail',          'two');  % Two-tailed
% Process: Set comment
sStatParamFacesData = bst_process('CallProcess', 'process_set_comment', sStatParamFacesData, [], ...
    'tag',     'Faces - Scrambled: Parametric t-test', ...
    'isindex', 0);
% Take screen captures
DataScreenCapture(sStatParamFacesData, 1, 1, sStatParamFacesData.Comment);

% ===== FACES-SCRAMBLED: NON-PARAMETRIC T-TEST =====
% Process: Perm t-test paired [All]          H0:(A=B), H1:(A<>B)
sStatPermFacesData = bst_process('CallProcess', 'process_test_permutation2p', sSubjAvgFacesData, sSubjAvgScrambledData, ...
    'timewindow',     [], ...
    'sensortypes',    '', ...
    'isabs',          0, ...
    'avgtime',        0, ...
    'avgrow',         0, ...
    'iszerobad',      0, ...
    'Comment',        '', ...
    'test_type',      'ttest_paired', ...  % Paired Student's t-test T = mean(A-B) / std(A-B) * sqrt(n)
    'randomizations', 1000, ...
    'tail',           'two');  % Two-tailed
% Process: Set comment
sStatPermFacesData = bst_process('CallProcess', 'process_set_comment', sStatPermFacesData, [], ...
    'tag',     'Faces - Scrambled: Permutation t-test', ...
    'isindex', 0);
% Take screen captures
DataScreenCapture(sStatPermFacesData, 1, 1, sStatPermFacesData.Comment);

% ===== FACES-SCRAMBLED: CLUSTER T-TEST =====
% Process: FT t-test paired cluster [all EEG]          H0:(A=B), H1:(A<>B)
sStatClustFacesData = bst_process('CallProcess', 'process_ft_timelockstatistics', sSubjAvgFacesData, sSubjAvgScrambledData, ...
    'sensortypes',    'EEG', ...
    'timewindow',     [], ...
    'isabs',          0, ...
    'avgtime',        0, ...
    'avgchan',        0, ...
    'randomizations', 1000, ...
    'statistictype',  2, ...  % Paired t-test
    'tail',           'two', ...  % Two-tailed
    'correctiontype', 2, ...  % cluster
    'minnbchan',      0, ...
    'clusteralpha',   0.05);
% If FieldTrip is available and results were returned
if ~isempty(sStatClustFacesData)
    % Process: Set comment
    sStatClustFacesData = bst_process('CallProcess', 'process_set_comment', sStatClustFacesData, [], ...
        'tag',     'Faces - Scrambled: Cluster t-test EEG', ...
        'isindex', 0);
    % Take screen captures
    DataScreenCapture(sStatClustFacesData, 0, 1, sStatClustFacesData.Comment);
end

%% ===== GROUP ANALYSIS: FACES-SCRAMBLED: MEG/EEG =====================================
%  ====================================================================================
% ===== FAMOUS-UNFAMILIAR: MEAN DIFF =====
% Process: Select data files in: */DirIntra/"Avg: Famous | "
sSubjAvgFamousData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'tag',           'Avg: Famous (6 files)', ...
    'includeintra',  1);
% Process: Select data files in: */DirIntra/"WAvg: Avg: Unfamiliar (6 files)"
sSubjAvgUnfamiliarData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'tag',           'WAvg: Avg: Unfamiliar (6 files)', ...
    'includeintra',  1);
% Process: Difference of means [mean]
sDiffFamousData = bst_process('CallProcess', 'process_diff_mean', sSubjAvgFamousData, sSubjAvgUnfamiliarData, ...
    'avg_func', 1, ...  % Arithmetic average mean(A) - mean(B)
    'weighted', 0);
% Process: Set comment
sDiffFamousData = bst_process('CallProcess', 'process_set_comment', sDiffFamousData, [], ...
    'tag',     'Famous - Unfamiliar', ...
    'isindex', 0);
% Take screen captures
DataScreenCapture(sDiffFamousData, 1, 1, sDiffFamousData.Comment);

% ===== FAMOUS-UNFAMILIAR: PARAMETRIC T-TEST =====
% Process: t-test paired [All]          H0:(A=B), H1:(A<>B)
sStatParamFamousData = bst_process('CallProcess', 'process_test_parametric2p', sSubjAvgFamousData, sSubjAvgUnfamiliarData, ...
    'timewindow',    [], ...
    'sensortypes',   '', ...
    'isabs',         0, ...
    'avgtime',       0, ...
    'avgrow',        0, ...
    'Comment',       '', ...
    'test_type',     'ttest_paired', ...  % Paired Student's t-test        (A-B)~N(m,v)t = mean(A-B) / std(A-B) * sqrt(n)      df=n-1
    'tail',          'two');  % Two-tailed
% Process: Set comment
sStatParamFamousData = bst_process('CallProcess', 'process_set_comment', sStatParamFamousData, [], ...
    'tag',     'Famous - Unfamiliar: Parametric t-test', ...
    'isindex', 0);
% Take screen captures
DataScreenCapture(sStatParamFamousData, 1, 1, sStatParamFamousData.Comment);

% ===== FAMOUS-UNFAMILIAR: CLUSTER T-TEST =====
% Process: FT t-test paired cluster [all EEG]          H0:(A=B), H1:(A<>B)
sStatClustFamousData = bst_process('CallProcess', 'process_ft_timelockstatistics', sSubjAvgFamousData, sSubjAvgUnfamiliarData, ...
    'sensortypes',    'EEG', ...
    'timewindow',     [], ...
    'isabs',          0, ...
    'avgtime',        0, ...
    'avgchan',        0, ...
    'randomizations', 1000, ...
    'statistictype',  2, ...  % Paired t-test
    'tail',           'two', ...  % Two-tailed
    'correctiontype', 2, ...  % cluster
    'minnbchan',      0, ...
    'clusteralpha',   0.05);
% If FieldTrip is available and results were returned
if ~isempty(sStatClustFacesData)
    % Process: Set comment
    sStatClustFamousData = bst_process('CallProcess', 'process_set_comment', sStatClustFamousData, [], ...
        'tag',     'Famous - Unfamiliar: Cluster t-test EEG', ...
        'isindex', 0);
    % Take screen captures
    DataScreenCapture(sStatClustFamousData, 0, 1, sStatClustFamousData.Comment);
end

% Save report
ReportFile = bst_report('Save', []);
if ~isempty(reports_dir) && ~isempty(ReportFile)
    bst_report('Export', ReportFile, bst_fullfile(reports_dir, ['report_' ProtocolName '_3meeg.html']));
end

%% ===== FACES-SCRAMBLED: SOURCES (MEG) ===============================================
%  ====================================================================================
% Start a new report
bst_report('Start');

% ===== PROJECT SOURCES =====
% Process: Select source files in: */Intra
sAvgSrc = bst_process('CallProcess', 'process_select_files_results', [], [], ...
    'subjectname',   'All', ...
    'condition',     DirIntra, ...
    'includeintra',  1);
% Process: Absolute values / Norm for unconstrained
if isUnconstrained
    % Process: Unconstrained to flat map
    sAvgSrc = bst_process('CallProcess', 'process_source_flat', sAvgSrc, [], ...
        'method', 1);  % Norm: sqrt(x^2+y^2+z^2)
else
    sAvgSrc = bst_process('CallProcess', 'process_absolute', sAvgSrc, [], ...
        'overwrite', 1);
end
% Process: Project on default anatomy
sProjSrc = bst_process('CallProcess', 'process_project_sources', sAvgSrc, [], ...
    'headmodeltype', 'surface');  % Cortex surface
% Process: Spatial smoothing (3.00,abs)
sProjSrc = bst_process('CallProcess', 'process_ssmooth_surfstat', sProjSrc, [], ...
    'fwhm',       3, ...
    'overwrite',  1, ...
    'source_abs', 1);

% ===== MOVE FILES =====
% File tags / destination folder
ListTags = {'Avg: Faces | EEG',                 'Faces_EEG'; ...
            'Avg: Faces | MEG',                 'Faces_MEG'; ...
            'Avg: Famous (6 files) | EEG',      'Famous_EEG'; ...
            'Avg: Famous (6 files) | MEG',      'Famous_MEG'; ...
            'Avg: Unfamiliar (6 files) | EEG',  'Unfamiliar_EEG'; ...
            'Avg: Unfamiliar (6 files) | MEG',  'Unfamiliar_MEG'; ...
            'Avg: Scrambled (6 files) | EEG',   'Scrambled_EEG'; ...
            'Avg: Scrambled (6 files) | MEG',   'Scrambled_MEG'; ...
            'Faces - Scrambled | EEG',          'Faces-Scrambled_EEG'; ...
            'Faces - Scrambled | MEG',          'Faces-Scrambled_MEG'; ...
            'Famous - Unfamiliar | EEG',        'Famous-Unfamiliar_EEG'; ...
            'Famous - Unfamiliar | MEG',        'Famous-Unfamiliar_MEG'};
% Move group by group
for i = 1:size(ListTags,1)
    % Find names of files to move
    iTag = find(~cellfun(@(c)isempty(strfind(c, ListTags{i,1})), {sProjSrc.Comment}));
    if isempty(iTag)
        continue;
    end
    % Process: Move files
    bst_process('CallProcess', 'process_movefile', {sProjSrc(iTag).FileName}, [], ...
        'subjectname', GroupSubjectName, ...
        'folder',      ListTags{i,2});
end

% ===== LOOP ON MODALITY =====
AllModalities = {'MEG','EEG'};
for iMod = 1:length(AllModalities)
    % Selected modality for this loop
    Mod = AllModalities{iMod};

    % ===== |FACES-SCRAMBLED|: MEAN DIFF ======
    % Process: Select source files in: Group_analysis/Faces-Scrambled_MOD
    sDiffFaces = bst_process('CallProcess', 'process_select_files_results', [], [], ...
        'subjectname',   GroupSubjectName, ...
        'condition',     ['Faces-Scrambled_', Mod]);
    % Process: Weighted Average: By folder (grand average)
    sAbsDiffFaces = bst_process('CallProcess', 'process_average', sDiffFaces, [], ...
        'avgtype',         4, ...  % By folder (grand average)
        'avg_func',        1, ...  % Arithmetic average:  mean(x)
        'weighted',        0, ...
        'scalenormalized', 0);
    % Process: Set comment
    sAbsDiffFaces = bst_process('CallProcess', 'process_set_comment', sAbsDiffFaces, [], ...
        'tag',     ['mean(|Faces-Scrambled|) | ' Mod], ...
        'isindex', 0);
    % Process: Move files
    sAbsDiffFaces = bst_process('CallProcess', 'process_movefile', sAbsDiffFaces, [], ...
        'subjectname', GroupSubjectName, ...
        'folder',      DirIntra);
    % Colormap: Custom max: [-10,+10] Z
    bst_colormaps('SetMaxCustom', 'stat2', [], -10, 10);
    % Process: Snapshot: Sources (contact sheet)
    bst_process('CallProcess', 'process_snapshot', sAbsDiffFaces, [], ...
        'target',         9, ...  % Sources (contact sheet)
        'orient',         4, ...  % bottom
        'contact_time',   [0.05, 0.4], ...
        'contact_nimage', 16, ...
        'threshold',      30, ...
        'Comment',        [Mod ': mean(|Faces-Scrambled|)']);
    % Process: Snapshot: Sources (contact sheet)
    bst_process('CallProcess', 'process_snapshot', sAbsDiffFaces, [], ...
        'target',         9, ...  % Sources (contact sheet)
        'orient',         2, ...  % right
        'contact_time',   [0.05, 0.4], ...
        'contact_nimage', 16, ...
        'threshold',      30, ...
        'Comment',        [Mod ': mean(|Faces-Scrambled|)']);

    % ===== |FACES-SCRAMBLED|: PARAMETRIC CHI2-TEST ======
    % Process: Select source files in: Group_analysis/Faces-Scrambled_MOD
    sDiffFaces = bst_process('CallProcess', 'process_select_files_results', [], [], ...
        'subjectname',   GroupSubjectName, ...
        'condition',     ['Faces-Scrambled_' Mod]);
    % Process: Chi2-test [all]          H0:(|Zi| = 0)
    sChiParamFaces = bst_process('CallProcess', 'process_test_parametric1', sDiffFaces, [], ...
        'timewindow',    [], ...
        'scoutsel',      {}, ...
        'scoutfunc',     1, ...  % Mean
        'isnorm',        0, ...
        'avgtime',       0, ...
        'Comment',       '', ...
        'test_type',     'chi2_onesample', ...  % One-sample Chi2 test     Zi~N(0,1), i=1..nQ = sum(|Zi|^2)     Q~Chi2(n)
        'tail',          'two');  % Two-tailed
    % Process: Set comment
    sChiParamFaces = bst_process('CallProcess', 'process_set_comment', sChiParamFaces, [], ...
        'tag',     ['|Faces-Scrambled|=0: Parametric Chi2 test | ' Mod], ...
        'isindex', 0);
    % Process: Move files
    sChiParamFaces = bst_process('CallProcess', 'process_movefile', sChiParamFaces, [], ...
        'subjectname', GroupSubjectName, ...
        'folder',      DirIntra);
    % Set colormap: global color scale
    bst_colormaps('SetMaxMode', 'stat2', 'global');
    % Process: Snapshot: Sources (contact sheet)
    bst_process('CallProcess', 'process_snapshot', sChiParamFaces, [], ...
        'target',         9, ...  % Sources (contact sheet)
        'orient',         4, ...  % bottom
        'contact_time',   [0.05, 0.4], ...
        'contact_nimage', 16, ...
        'Comment',        [Mod ': |Faces-Scrambled|=0: Parametric Chi2-test']);
    % Process: Snapshot: Sources (contact sheet)
    bst_process('CallProcess', 'process_snapshot', sChiParamFaces, [], ...
        'target',         9, ...  % Sources (contact sheet)
        'orient',         2, ...  % right
        'contact_time',   [0.05, 0.4], ...
        'contact_nimage', 16, ...
        'Comment',        [Mod ': |Faces-Scrambled|=0: Parametric Chi2-test']);

    % ===== LOG(|FACES-SCRAMBLED|): PARAMETRIC CHI2-TEST ======
    % Process: Select source files in: Group_analysis/Faces-Scrambled_MOD
    sDiffFaces = bst_process('CallProcess', 'process_select_files_results', [], [], ...
        'subjectname',   GroupSubjectName, ...
        'condition',     ['Faces-Scrambled_' Mod]);
    % Process: Duplicate folders: Add tag "_log"
    sDiffFacesLog = bst_process('CallProcess', 'process_duplicate', sDiffFaces, [], ...
        'target', 2, ...  % Duplicate folders
        'tag',    '_log');
    % Process: Run Matlab command
    sDiffFacesLog = bst_process('CallProcess', 'process_matlab_eval', sDiffFacesLog, [], ...
        'matlab',    'Data = log(Data);', ...
        'overwrite', 1);
    % Process: Chi2-test [all]          H0:(|Zi| = 0)
    sChiParamFacesLog = bst_process('CallProcess', 'process_test_parametric1', sDiffFacesLog, [], ...
        'timewindow',    [], ...
        'scoutsel',      {}, ...
        'scoutfunc',     1, ...  % Mean
        'isnorm',        0, ...
        'avgtime',       0, ...
        'Comment',       '', ...
        'test_type',     'chi2_onesample', ...  % One-sample Chi2 test     Zi~N(0,1), i=1..nQ = sum(|Zi|^2)     Q~Chi2(n)
        'tail',          'two');  % Two-tailed
    % Process: Set comment
    sChiParamFacesLog = bst_process('CallProcess', 'process_set_comment', sChiParamFacesLog, [], ...
        'tag',     ['log(|Faces-Scrambled|)=0: Parametric Chi2 test | ' Mod], ...
        'isindex', 0);
    % Process: Move files
    sChiParamFacesLog = bst_process('CallProcess', 'process_movefile', sChiParamFacesLog, [], ...
        'subjectname', GroupSubjectName, ...
        'folder',      DirIntra);
    % Set colormap: global color scale
    bst_colormaps('SetMaxMode', 'stat2', 'global');
    % Process: Snapshot: Sources (contact sheet)
    bst_process('CallProcess', 'process_snapshot', sChiParamFacesLog, [], ...
        'target',         9, ...  % Sources (contact sheet)
        'orient',         4, ...  % bottom
        'contact_time',   [0.05, 0.4], ...
        'contact_nimage', 16, ...
        'Comment',        [Mod ': log(|Faces-Scrambled|)=0: Parametric Chi2-test']);
    % Process: Snapshot: Sources (contact sheet)
    bst_process('CallProcess', 'process_snapshot', sChiParamFacesLog, [], ...
        'target',         9, ...  % Sources (contact sheet)
        'orient',         2, ...  % right
        'contact_time',   [0.05, 0.4], ...
        'contact_nimage', 16, ...
        'Comment',        [Mod ': log(|Faces-Scrambled|)=0: Parametric Chi2-test']);

    % ===== |FACES|-|SCRAMBLED|: MEAN DIFF ======
    % Process: Select source files in: Group_analysis/Faces_MOD
    sAvgFaces = bst_process('CallProcess', 'process_select_files_results', [], [], ...
        'subjectname',   GroupSubjectName, ...
        'condition',     ['Faces_' Mod]);
    % Process: Select source files in: Group_analysis/Scrambled_MOD
    sAvgScrambled = bst_process('CallProcess', 'process_select_files_results', [], [], ...
        'subjectname',   GroupSubjectName, ...
        'condition',     ['Scrambled_' Mod]);
    % Process: Difference of means [abs(mean)]
    sDiffAbsFaces = bst_process('CallProcess', 'process_diff_mean', sAvgFaces, sAvgScrambled, ...
        'avg_func',   2, ...  % Absolute value of average abs(mean(A)) - abs(mean(B))
        'weighted',   0);
    % Process: Set comment
    sDiffAbsFaces = bst_process('CallProcess', 'process_set_comment', sDiffAbsFaces, [], ...
        'tag',     ['mean(|Faces|)-mean(|Scrambled|) | ' Mod], ...
        'isindex', 0);
    % Colormap: Custom max: [-10,+10] Z
    bst_colormaps('SetMaxCustom', 'stat2', [], -10, 10);
    % Process: Snapshot: Sources (contact sheet)
    bst_process('CallProcess', 'process_snapshot', sDiffAbsFaces, [], ...
        'target',         9, ...  % Sources (contact sheet)
        'orient',         4, ...  % bottom
        'contact_time',   [0.05, 0.4], ...
        'contact_nimage', 16, ...
        'threshold',      30, ...
        'Comment',        [Mod ': mean(|Faces|)-mean(|Scrambled|)']);
    % Process: Snapshot: Sources (contact sheet)
    bst_process('CallProcess', 'process_snapshot', sDiffAbsFaces, [], ...
        'target',         9, ...  % Sources (contact sheet)
        'orient',         2, ...  % right
        'contact_time',   [0.05, 0.4], ...
        'contact_nimage', 16, ...
        'threshold',      30, ...
        'Comment',        [Mod ': mean(|Faces|)-mean(|Scrambled|)']);

    % ===== |FACES|-|SCRAMBLED|: PARAMETRIC T-TEST ======
    % Process: Select source files in: Group_analysis/Faces_MOD
    sAvgFaces = bst_process('CallProcess', 'process_select_files_results', [], [], ...
        'subjectname',   GroupSubjectName, ...
        'condition',     ['Faces_' Mod]);
    % Process: Select source files in: Group_analysis/Scrambled_MOD
    sAvgScrambled = bst_process('CallProcess', 'process_select_files_results', [], [], ...
        'subjectname',   GroupSubjectName, ...
        'condition',     ['Scrambled_' Mod]);
    % Process: t-test paired [-202ms,900ms]          H0:(A=B), H1:(A<>B)
    sTtestParamFaces = bst_process('CallProcess', 'process_test_parametric2p', sAvgFaces, sAvgScrambled, ...
        'timewindow',    [], ...
        'scoutsel',      {}, ...
        'scoutfunc',     1, ...  % Mean
        'isnorm',        0, ...
        'avgtime',       0, ...
        'Comment',       '', ...
        'test_type',     'ttest_paired', ...  % Paired Student's t-test        (A-B)~N(m,v)t = mean(A-B) / std(A-B) * sqrt(n)      df=n-1
        'tail',          'two');  % Two-tailed
    % Process: Set comment
    sTtestParamFaces = bst_process('CallProcess', 'process_set_comment', sTtestParamFaces, [], ...
        'tag',     ['|Faces|=|Scrambled|: Parametric t-test | ' Mod], ...
        'isindex', 0);
    % Set colormap: global color scale
    bst_colormaps('SetMaxMode', 'stat2', 'global');
    % Process: Snapshot: Sources (contact sheet)
    bst_process('CallProcess', 'process_snapshot', sTtestParamFaces, [], ...
        'target',         9, ...  % Sources (contact sheet)
        'orient',         4, ...  % bottom
        'contact_time',   [0.05, 0.4], ...
        'contact_nimage', 16, ...
        'Comment',        [Mod ': |Faces|-|Scrambled|: Parametric t-test']);
    % Process: Snapshot: Sources (contact sheet)
    bst_process('CallProcess', 'process_snapshot', sTtestParamFaces, [], ...
        'target',         9, ...  % Sources (contact sheet)
        'orient',         2, ...  % right
        'contact_time',   [0.05, 0.4], ...
        'contact_nimage', 16, ...
        'Comment',        [Mod ': |Faces|-|Scrambled|: Parametric t-test']);
end

% Save report
ReportFile = bst_report('Save', []);
if ~isempty(reports_dir) && ~isempty(ReportFile)
    bst_report('Export', ReportFile, bst_fullfile(reports_dir, ['report_' ProtocolName '_4sources.html']));
end

end


function [f,file] = stripfile(x,flag,sep)

% function [f,file] = stripfile(x,flag,sep)
%
% <x> is a string referring to a file (it is okay if the file
%   does not actually exist).  if <x> ends in /, we automatically
%   act as if that / does not exist.
% <flag> (optional) is whether to swap the output arguments.  default: 0.
% <sep> (optional) is the actual "/" character to use.  default is
%   the output of filesep.m.
%
% if <flag> is 0,
%   return <f> as the string but with the file name removed.
%   return <file> with the file name.
% if <flag> is 1, these arguments are swapped.
%
% history:
% 2014/07/14 - make more general by defaulting <sep> to filesep.m.
%
% example:
% isequal(stripfile('blah/temp.png',[],'/'),'blah/')
% isequal(stripfile('temp.png',[],'/'),'')
% isequal(stripfile('ok/blah/',1,'/'),'blah')

% input
if ~exist('flag','var') || isempty(flag)
  flag = 0;
end
if ~exist('sep','var') || isempty(sep)
  sep = filesep;
end

% find any /
locs = strfind(x,sep);

% if none, return ''
if isempty(locs)
  f = '';
  file = x;
% otherwise, return entire string up to the last /
else
  if locs(end)==length(x)  % ignore trailing /
    x = x(1:end-1);
    locs = locs(1:end-1);
  end
  if isempty(locs)
    f = '';
    file = x;
  else
    f = x(1:locs(end));
    file = x(locs(end)+1:end);
  end
end

% swap the output?
if flag
  [f,file] = swap(f,file);
end


function ezlabels(command)
    %
    %   GUI input for labels and titles
    %
    %   typing 'ezlabels' from the command line opens an
    %   interactive dialogue box, allowing the user to specify
    %   axes labels and the figure title as well as the Font, Size, Weight
    %   and Angle using pulldown menus.
    %
    %   Note: This function uses the ten standard postscript fonts
    %         available on most platforms.  Not all font
    %         combinations are available on all platforms and/or
    %         hardcopy devices.
    %
    %   Richard G. Cobb    3/96
    %   rcobb@afit.af.mil
    %
    if nargin < 1
        siblines(4)=get(gca,'Title');
        siblines(3)=get(gca,'Xlabel');
        siblines(2)=get(gca,'Ylabel');
        siblines(1)=get(gca,'Zlabel');
        %
        haold=gcf;
        T1=['Avant Garde           ';...
            'Bookman               ';...
            'Courier               ';...
            'Helvetica             ';...
            'Helvetica Narrow      ';...
            'New Century Schoolbook';...
            'Palatino              ';...
            'Symbol                ';...
            'Times                 ';...
            'Zapf Chancery         ';...
            'Zapf Dingbats         '];
        T2=['cyan   ';'magenta';'green  ';'red    ';'yellow ';...
            'blue   ';'black  ';'white  '];
        T5=['Normal ';...
            'Light  ';...
            'Demi   ';...
            'Bold   '];
        T4=['Normal ';'Italic ';'Oblique'];
        T3=['10';'12';'16';'20';'24';'30'];

        si=[0 0 0 0 0 0]';si2=si;
        si(1:length(siblines))=siblines;
        leginp=figure_w_normalized_uicontrolunits('Color',[0.9 0.9 0.9],'NumberTitle','off','Name',...
            'EZ LABELS',...
            'NextPlot','new',...
            'Units','Normalized',...
            'Position',[.1 .1  .4 .1+.05*length(siblines)]);
        sfactor=.25/(.1+.05*length(siblines));
        axis off
        axis([0,1,0,1])
        Y = linspace(0,.75,length(siblines))';
        ui=[0 0 0 0 0 0]'; bi=[0 0 0 0 0 0]';
        for i=1:length(siblines)
            examps(i)=text(0,[Y(i)],get(siblines(i),'string'),...
                'FontName',get(siblines(i),'FontName'),...
                'Color',get(siblines(i),'Color') ,...
                'FontSize',get(siblines(i),'FontSize'),...
                'FontAngle',get(siblines(i),'FontAngle'),...
                'FontWeight',get(siblines(i),'FontWeight'));
            ui(i) = uicontrol('Parent',leginp,...
                'style','edit',...
                'string',get(siblines(i),'string'),...
                'units','normalized',...
                'position',[.35 (Y(i)+.1)/1.2 .3 .1*sfactor]);
            bi(i) = uicontrol('Style','checkbox','Units','Normalized',...
                'Position',[.28 (Y(i)+.1)/1.2 .05 .1*sfactor],...
                'Visible','on');
        end

        si2(1:length(examps))=examps;
        mi(1) = uicontrol('Style','Popup','Units','Normalized',...
            'Position',[.7 .8 .25 .1*sfactor],...
            'String',T1,...
            'Visible','on',...
            'HorizontalAlignment', 'left',...
            'Callback','ezlabels(1)');
        li(1) = uicontrol('Style','pushbutton','Units','Normalized',...
            'Position',[.7 .8 .25 .1*sfactor],...
            'String','Fontname',...
            'Visible','on',...
            'Callback','ezlabels(8)');
        mi(2) = uicontrol('Style','Popup','Units','Normalized',...
            'Position',[.7 .6 .25 .1*sfactor],...
            'String',T2,...
            'Visible','on',...
            'HorizontalAlignment', 'left',...
            'Callback','ezlabels(2)');
        li(2) = uicontrol('Style','pushbutton','Units','Normalized',...
            'Position',[.7 .6 .25 .1*sfactor],...
            'String','Color',...
            'Visible','on',...
            'Callback','ezlabels(9)');

        mi(3) = uicontrol('Style','Popup','Units','Normalized',...
            'Position',[.7 .4 .25 .1*sfactor],...
            'String',T3,...
            'Visible','on',...
            'HorizontalAlignment', 'left',...
            'Callback','ezlabels(3)');
        li(3) = uicontrol('Style','pushbutton','Units','Normalized',...
            'Position',[.7 .4 .25 .1*sfactor],...
            'String','FontSize',...
            'Visible','on',...
            'Callback','ezlabels(10)');

        mi(4) = uicontrol('Style','Popup','Units','Normalized',...
            'Position',[.7 .2 .25 .1*sfactor],...
            'String',T4,...
            'Visible','off',...
            'HorizontalAlignment', 'left',...
            'Callback','ezlabels(4)');
        li(4) = uicontrol('Style','pushbutton','Units','Normalized',...
            'Position',[.7 .2 .25 .1*sfactor],...
            'String','Fontangle',...
            'Visible','on',...
            'Callback','ezlabels(7)');
        mi(5) = uicontrol('Style','Popup','Units','Normalized',...
            'Position',[.7 0 .25 .1*sfactor],...
            'String',T5,...
            'Visible','off',...
            'HorizontalAlignment', 'left',...
            'Callback','ezlabels(12)');
        li(5) = uicontrol('Style','pushbutton','Units','Normalized',...
            'Position',[.7 0 .25 .1*sfactor],...
            'String','Fontweight',...
            'Visible','on',...
            'Callback','ezlabels(11)');

        uicontrol('Parent',leginp,...
            'style','text',...
            'string','Title',...
            'units','normalized',...
            'position',[.4 ((max(Y)+.1)/1.2)+.1*sfactor .2 .07*sfactor],...
            'BackgroundColor',[ 0 0 0 ],...
            'ForegroundColor',[ 0 1 0 ]);
        uicontrol('Parent',leginp,...
            'style','text',...
            'string','Xlabel',...
            'units','normalized',...
            'position',[.4 ((Y(3)+.1)/1.2)+.1*sfactor .2 .07*sfactor],...
            'BackgroundColor',[ 0 0 0 ],...
            'ForegroundColor',[ 0 1 0 ]);

        uicontrol('Parent',leginp,...
            'style','text',...
            'string','Ylabel',...
            'units','normalized',...
            'position',[.4 ((Y(2)+.1)/1.2)+.1*sfactor .2 .07*sfactor],...
            'BackgroundColor',[ 0 0 0 ],...
            'ForegroundColor',[ 0 1 0 ]);
        uicontrol('Parent',leginp,...
            'style','text',...
            'string','Zlabel',...
            'units','normalized',...
            'position',[.4 ((Y(1)+.1)/1.2)+.1*sfactor .2 .07*sfactor],...
            'BackgroundColor',[ 0 0 0 ],...
            'ForegroundColor',[ 0 1 0 ]);

        uicontrol('Parent',leginp,...
            'style','pushbutton',...
            'string','Close',...
            'units','normalized',...
            'position',[.3 .92 .15 .07*sfactor],...
             'Callback','delete(gcf)');

        uicontrol('Parent',leginp,...
            'style','pushbutton',...
            'string','Add Labels',...
            'units','normalized',...
            'position',[.5 .92 .2 .07*sfactor],...
             'Callback','ezlabels(6)');

        mh=zeros(size(ui));mh(1:5)=mi;mh(6)=haold;
        lh=zeros(size(ui));lh(1:5)=li;
        set(leginp,'UserData',[si ui bi mh si2 lh]);

    elseif command==1
        T1=['Avant Garde           ';...
            'Bookman               ';...
            'Courier               ';...
            'Helvetica             ';...
            'Helvetica Narrow      ';...
            'New Century Schoolbook';...
            'Palatino              ';...
            'Symbol                ';...
            'Times                 ';...
            'Zapf Chancery         ';...
            'Zapf Dingbats         '];

        handles = get(gcf,'UserData');
        checked=zeros(4,1);
        for i=1:4
            checked(i)=get(handles(i,3),'Value');
        end
        for i=find(checked)
            set(handles(i,1),'Fontname',deblank(T1(get(handles(1,4),'Value'),:)))
            set(handles(i,5),'Fontname',deblank(T1(get(handles(1,4),'Value'),:)))
        end
        refresh
        refresh(handles(6,4))
        set(handles(1,4),'Visible', 'off')
        set(handles(1,6),'Visible', 'on')

    elseif command==2
        T2=['cyan   ';'magenta';'green  ';'red    ';'yellow ';...
            'blue   ';'black  ';'white  '];
        handles = get(gcf,'UserData');
        checked=zeros(4,1);
        for i=1:4
            checked(i)=get(handles(i,3),'Value');
        end
        for i=find(checked)
            set(handles(i,1),'Color',T2(get(handles(2,4),'Value'),:))
            set(handles(i,5),'Color',T2(get(handles(2,4),'Value'),:))
        end
        set(handles(2,4),'Visible', 'off')
        set(handles(2,6),'Visible', 'on')

    elseif command==3
        T3=['10';'12';'16';'20';'24';'30'];
        handles = get(gcf,'UserData');
        checked=zeros(4,1);
        for i=1:4
            checked(i)=get(handles(i,3),'Value');
        end
        for i=find(checked)
            set(handles(i,1),'FontSize',eval(T3(get(handles(3,4),'Value'),:)))
            set(handles(i,5),'FontSize',eval(T3(get(handles(3,4),'Value'),:)))
        end
        refresh
        refresh(handles(6,4))
        set(handles(3,4),'Visible', 'off')
        set(handles(3,6),'Visible', 'on')

    elseif command==4
        T4=['normal ';'italic ';'oblique'];
        handles = get(gcf,'UserData');
        checked=zeros(4,1);
        for i=1:4
            checked(i)=get(handles(i,3),'Value');
        end
        for i=find(checked)
            set(handles(i,1),'FontAngle',T4(get(handles(4,4),'Value'),:))
            set(handles(i,5),'FontAngle',T4(get(handles(4,4),'Value'),:))
        end
        refresh
        refresh(handles(6,4))
        set(handles(4,4),'Visible', 'off')
        set(handles(4,6),'Visible', 'on')
    elseif command==12
        T5=['Normal ';...
            'Light  ';...
            'Demi   ';...
            'Bold   '];
        handles = get(gcf,'UserData');
        checked=zeros(4,1);
        for i=1:4
            checked(i)=get(handles(i,3),'Value');
        end
        for i=find(checked)
            set(handles(i,1),'FontWeight',T5(get(handles(5,4),'Value'),:))
            set(handles(i,5),'FontWeight',T5(get(handles(5,4),'Value'),:))
        end
        refresh
        refresh(handles(6,4))
        set(handles(5,4),'Visible', 'off')
        set(handles(5,6),'Visible', 'on')

    elseif command == 5

    elseif command == 6
        handles = get(gcf,'UserData');
        for i=1:4
            set(handles(i,1),'string', get(handles(i,2),'string'))
            set(handles(i,5),'string', get(handles(i,2),'string'))
        end
    elseif command == 7
        handles = get(gcf,'UserData');
        set(handles(4,6),'Visible', 'off')
        set(handles(4,4),'Visible', 'on')
    elseif command == 8
        handles = get(gcf,'UserData');
        set(handles(1,6),'Visible', 'off')
        set(handles(1,4),'Visible', 'on')
    elseif command == 9
        handles = get(gcf,'UserData');
        set(handles(2,6),'Visible', 'off')
        set(handles(2,4),'Visible', 'on')
    elseif command == 10
        handles = get(gcf,'UserData');
        set(handles(3,6),'Visible', 'off')
        set(handles(3,4),'Visible', 'on')
    elseif command == 11
        handles = get(gcf,'UserData');
        set(handles(5,6),'Visible', 'off')
        set(handles(5,4),'Visible', 'on')

    end


function srImage = callSRMethod(slidingWindow, magFactor, srMethod)

    % Assemble name of the SR wrapper function.
    funName = sprintf('superresolve_%s', srMethod.name);

    % Call the desired SR method.
    srImage = feval(funName, slidingWindow, magFactor);


function CreateMovie(T, fileName)
[height, width, layer] = size(T{1});
aviobj = avifile(fileName, 'fps', 30, 'compression', 'None');
for i = 1:layer
    img(:,:,1) = T{1}(:,:,i);
    img(:,:,2) = T{2}(:,:,i);
    img(:,:,3) = T{3}(:,:,i);
    aviobj = addframe(aviobj, img);
end
aviobj = close(aviobj);


%% CELL_JOB_ITHACA sets up a job of tasks making animation frames.
%
%  Discussion:
%
%    There are 10 TIF files, constituting a time sequence of images
%    of cells under a microscope.
%
%    Each file is to be processed in such a way that the cells are
%    detected and indicated by a white boundary.
%
%    The processed data is then to be saved in a new TIF file.
%
%    The processing of each file is independent of the others.
%    This means that MATLAB's batch processing facility can be used,
%    involving one job of 10 tasks.
%
%    We assume that this script will be submitted from a desktop machine,
%    for execution on a remote machine.  This raises the question of
%    where the input files are at the beginning, where the output files
%    are at the end, and how the particular task is able to find the
%    input and create the output!
%
%    Unlike the BATCH command, the CREATE_JOB and CREATE_TASK commands
%    do not seem to allow for any way to choose the directory where
%    execution begins.
%
%    One awkward way to try to deal with these problems is as follows:
%    a) "by hand", create a directory on the remote machine, and move the input
%       files there before submitting the job.
%    b) inserting a CD command in the task code that moves to the directory.
%    c) "by hand", collect the processed files from the directory
%       once the tasks are completed.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    30 March 2010
%
%  Author:
%
%    John Burkardt
%
  clear

  fprintf ( 1, '\n' );
  fprintf ( 1, 'CELL_JOB_ITHACA\n' );
  fprintf ( 1, '  Set up and execute a job of independent tasks.\n' );
  fprintf ( 1, '  Each task opens a TIF file that is an image of cells,\n' );
  fprintf ( 1, '  marks the border of each cell in white,\n' );
  fprintf ( 1, '  and writes the modified image to a new TIF file.\n' );
%
%  There are exactly 10 frames.
%
%  We could set this value explicitly:
%
  if ( 0 )

    frame_total = 10;
%
%  but here is a way to count the files automatically.
%
  else
    p = which ( 'AT3_1m4_01.tif' );
    filelist = dir ( [ fileparts(p) filesep 'AT3_1m4_*.tif' ] );
    frame_total = length ( { filelist.name } );
  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  There are %d files to process.\n', frame_total );
  fprintf ( 1, '  The first file is called          "AT3_1m4_01.tif",\n' );
  fprintf ( 1, '  and its processed version will be "BT3_1m4_01.tif".\n' );
%
%  Define the job.
%  Our image files are on the local machine, so our processing must also
%  be here.
%
  work_directory = '/home/burkardt/public_html/m_src/cell_detection_tasks';

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Define the job:\n' );

  job = createJob ( ...
    'configuration', 'ithaca_2009b', ...
    'FileDependencies', { 'cell_task.m' } );
%
%  Define the tasks that constitute the job.
%  The value of TASK is enough to identify the file to be processed.
%
  task_num = frame_total;

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Define %d tasks:\n', task_num );
  fprintf ( 1, '  Working directory is "%s".\n', work_directory );

  for task = 1 : task_num
    task_id = createTask ( job, @cell_task, 0, { work_directory, task } );
  end
%
%  Submit the job.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Submit the job:\n' );

  submit ( job );
%
%  Wait for results.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Wait for job to finish:\n' );

  timestamp ( );
  wait ( job );
  timestamp ( );
%
%  The following commands will capture and print error messages
%  from the tasks, if something bad occurs.
%
  errmsgs = get ( job.Tasks, {'ErrorMessage'} );
  nonempty = ~cellfun ( @isempty, errmsgs );
  celldisp ( errmsgs(nonempty) );
%
%  There are no output arguments from the tasks.  Otherwise, we
%  would gather and inspect them here.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  The individual frame files have been created.\n' );
%
%  Clean up by freeing memory associated with the job.
%
  destroy ( job );
%
%  Terminate;
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'CELL_JOB_ITHACA:\n' );
  fprintf ( 1, '  Normal end of execution.\n' );


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

%%
clear; close all; clc;

%% Syntax
% |Mn=dataNorm(M,normOpt);|

%% 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/>.