function nonlin_param_mod_brain(ons, modulator, image_names, SETUP, varargin)
% Nonlinear fits with a parametric modulator on a set of brain images
%
% :Usage:
% ::
%
%     nonlin_param_mod_brain(X, image_names, SETUP, [SETUPional inputs])
%
% :Inputs:
%
%   **ons:**
%        onsets for each condition; one cell per
%        condition, one col. vector per series of onsets
%
%   **modulator:**
%        modulator values for each condition; same
%        format as above
%
%   **image_names:**
%        outcome variable; Images (volume names) for each subject, in
%        string matrix (list of image names); 3-D for now!
%
% :SETUP.(fields):
%
%   **.mask:**
%        name of mask image
%
%   **.preprocX:**
%        flag for whether to HP filter X data
%
%   **.preprocY:**
%        flag for whether to HP filter Y data
%
%   **'nopreproc':**
%        Turn off preproc
%
%   **.TR:**
%        repetition time of volume (image) acquisition
%
%   **.HPlength:**
%        high-pass filter length, in s
%
%   **.scans_per_session:**
%        vector of # volumes in each run, e.g., [128 128 128 128 128]
%
%   **.dummyscans:**
%        indices of images in each run that will be modeled
%        with separate dummy variables
%
%   **.startslice:**
%        starting slice number (to resume analysis)
%
% SETUPional inputs:
% Any of the SETUPions in mediation.m
%
% Also: 'nopreproc' to skip preprocessing (i.e., for trial-level inputs)
%
% ..
%    Tor Wager, May 2008
% ..

    % ..
    %    Set up preprocessing
    %    To skip, enter 'nopreproc' as var. arg.
    % ..

    [preprochandle, SETUP] = filter_setup(SETUP, varargin{:});

    % SETUPional: preproc Y?  Should do mostly only if not brain
    % Should not do if using trial-level estimates

    N = size(image_names, 1);  % number of subjects; one cell per subject

    % do high-pass filter preprocessing on X, if specified
    if SETUP.preprocX, for i = 1:N, X{i} = preprochandle(X{i}); end, end

    if ~SETUP.preprocY
        preprochandle = [];

    else
        tmp = cell(1, N);
        for i = 1:N, tmp{i} = preprochandle; end
        preprochandle = tmp;
    end

    tr = SETUP.TR;

    % ---------------------------------------------------------------------
    % Set up mask
    % ---------------------------------------------------------------------
    SETUP.mask_unresampled = SETUP.mask;
    disp('Writing resampled mask.img in current directory.');

    scn_map_image(SETUP.mask, image_names(1, :), 'write', 'mask.img');
    SETUP.mask = fullfile(pwd, 'mask.img');

    % ---------------------------------------------------------------------
    % Set up analysis
    % ---------------------------------------------------------------------

    % THIS stuff is the same for each voxel
    % --------------------------------------
    modulator_centered = modulator - nanmean(modulator);
    xvals = (1:N)';

    % This runs the whole thing given a data vector (y)
    fhandle = @(y) nonlin_param_modulator(y, ons, modulator_centered, tr, xvals);

    SETUP.names = {'amplitude_mean.img' 'amplitude_by_modulator.img' 'duration_mean.img' 'duration_by_modulator.img' ...
    'intercept.img' 'auc_mean_trial.img' ...
    'auc_by_modulator.img' 'variance.img' };

    SETUP.preprochandle = preprochandle;
    SETUP.fhandle = fhandle;

    SETUP.data.descrip = 'Data after any preprocessing specified (for X and Y)';
    SETUP.data.ons = ons;
    SETUP.data.modulator = modulator;
    SETUP.data.modulator_centered = modulator_centered;
    SETUP.data.image_names = image_names;
    save nonlin_param_mod_SETUP SETUP

    % ---------------------------------------------------------------------
    % Run preprocessing and analysis
    % ---------------------------------------------------------------------
    if ~isfield(SETUP, 'startslice') || isempty(SETUP.startslice), SETUP.startslice = 1; end

    [a, b, c, d, e, f, g, h] = image_eval_function(image_names, fhandle, 'mask', SETUP.mask, 'preprochandle', preprochandle, 'outnames', SETUP.names, 'start', SETUP.startslice);

end    % End Main Function

% Set up preprocessing
function [preprochandle, SETUP] = filter_setup(SETUP, varargin)

    preprochandle = [];
    wh_elim = [];
    hpflag = 1;  % only does it if requested, though

    for i = 1:length(varargin)
        if ischar(varargin{i})
            switch varargin{i}
                % reserved keywords
                case 'custompreproc'
                    preprochandle = varargin{i + 1};  % e.g., 'custompreproc', @(data) scale(data) for z=scores;

                    hpflag = 0;
                    SETUP.TR = NaN;
                    SETUP.HPlength = [];
                    SETUP.dummyscans = [];
                    wh_elim = i;

                case {'nopreproc'}
                    hpflag = 0;
                    SETUP.preprocY = 0; SETUP.preprocX = 0;
                    if ~isfield(SETUP, 'TR') || isempty(SETUP.TR), SETUP.TR = NaN; end
                    SETUP.HPlength = [];
                    SETUP.dummyscans = [];
                    wh_elim = i;

                    % We need to allow mediation SETUPions here, so eliminate this from list and do not error check here.
                    %otherwise, warning(['Unknown input string SETUPion:' varargin{i}]);
            end
        end
    end

    varargin(wh_elim) = [];

    N = fieldnames(SETUP);
    for i = 1:length(N)
        if ~isfield(SETUP, N{i}) || isempty(SETUP.(N{i}))
            switch N{i}
                case {'TR', 'mask', 'scans_per_session', 'preprocY'}
                    error(['Enter SETUP.' N{i}]);

                case 'HPlength'
                    SETUP.(N{i}) = [];

                case 'dummyscans'
                    SETUP.(N{i}) = 1:2;

                otherwise
                    disp('Warning! Unrecognized field in SETUPions structure SETUP.');
            end
        end
    end

    SETUP.preproc_any = SETUP.preprocX || SETUP.preprocY

    if ~isfield(SETUP, 'TR') || isempty(SETUP.TR) || isnan(SETUP.TR)
        error('SETUP.TR must be entered.');
    end

    if SETUP.preproc_any && hpflag

        error('THIS CODE IS NOT SET UP TO PREPROCESS YET.');

        [tmp, I, S] = hpfilter(X(:,1), SETUP.TR, SETUP.HPlength, SETUP.scans_per_session, SETUP.dummyscans); % creates intercept and smoothing matrices

        preprochandle = @(Y) hpfilter(Y,  [], S, SETUP.scans_per_session, I);  % function handle with embedded fixed inputs

    end

end


function s = getStatisticsHeaderSizeWordAligned(this)

% Assume a word is 4 bytes

s = getStatisticsHeaderSize(this);
s = ceil(s/4)*4;


function drosPlot(model, totgenes, thisgene)

% DROSPLOT Plot a GPDISIM model/models
% FORMAT
% DESC Plot a GPDISIM model/models
% ARG model : The model to plot
% ARG totgenes : Total number of genes if plotting several single
% target models in a single figure (optional)
% ARG thisgene : Index of this gene in the above case (optional)
%
% COPYRIGHT : Antti Honkela, 2009

% SHEFFIELDML

FONTSIZE = 8;
LINEWIDTH = 1;
MARKERSIZE = 6;

if strcmp(model.type, 'cgpdisim'),
  numGenes = model.comp{1}.numGenes + 1;
else
  numGenes = model.comp{1}.numGenes;
end

selectgenes = 1:numGenes;

numPlots = length(selectgenes);

tf = model.comp{1}.annotation.tf;
genes = model.comp{1}.annotation.genes;
targets = genes(2:end);

genenames = genes;
times = model.comp{1}.t;

y = {};
yvar = {};
for k=1:length(model.comp),
  y{k} = reshape(model.comp{k}.y, [length(times), length(genes)]);
  yvar{k} = reshape(model.comp{k}.yvar, [length(times), length(genes)]);
end

for j = 1:length(model.comp)

  % Generate predictions of the functions.
  % to do this we need to compute the K_xf portions of the kernel
  % (simXrbfKernCompute does this for us).
  predt = [1:0.1:12 model.comp{j}.t']';

  if model.comp{j}.includeNoise,
    simMultiKern = model.comp{j}.kern.comp{1};
  else
    simMultiKern = model.comp{j}.kern;
  end
  if strcmp(model.type, 'cgpdisim'),
    proteinKern = kernCreate(model.comp{j}.t, 'sim');
    proteinKern.inverseWidth = simMultiKern.comp{1}.inverseWidth;
    proteinKern.decay = model.comp{j}.delta;
    proteinKern.variance = simMultiKern.comp{2}.di_variance;
    % simXrbf requires an RBF with unit variance
    inputKern = kernCreate(model.comp{j}.t, 'rbf');
    inputKern.inverseWidth = simMultiKern.comp{1}.inverseWidth;
    inputKern.variance = 1;
    K = simXrbfKernCompute(proteinKern, inputKern, ...
			   predt, model.comp{j}.t);
    K = K * simMultiKern.comp{1}.variance;
    warning('off', 'KERN:simRBFVariance');
    for i=2:simMultiKern.numBlocks
      blockK =  disimXsimKernCompute(simMultiKern.comp{i}, proteinKern, ...
				     model.comp{j}.t, predt);
      K = [K blockK'];
    end
    warning('on', 'KERN:simRBFVariance');

    ymean = reshape(ones(length(times),1)*[0, model.comp{j}.mu], ...
		    size(model.comp{j}.y));
  else
    proteinKern = kernCreate(model.comp{1}.t, 'rbf');
    proteinKern.inverseWidth = ...
	simMultiKern.comp{1}.inverseWidth;
    K = [];

    for i=1:simMultiKern.numBlocks
      K = [K; simXrbfKernCompute(simMultiKern.comp{i}, proteinKern, ...
				 model.comp{j}.t, predt)];
    end

    K = K';
    ymean = reshape(ones(length(times),1)*model.comp{j}.mu, ...
		    size(model.comp{j}.y));
  end

  predF = K*model.comp{j}.invK*(model.comp{j}.y-ymean);
  if strcmp(model.type, 'cgpdisim'),
    varF = simMultiKern.comp{1}.variance * ...
	   kernDiagCompute(proteinKern, predt) - sum(K'.* ...
						     (model.comp{j}.invK* ...
						      K'), 1)';
  else
    varF = kernDiagCompute(proteinKern, predt) - sum(K'.* ...
						     (model.comp{j}.invK* ...
						      K'), 1)';
  end

  % Predicted Gene Expressions
  if strcmp(model.type, 'cgpdisim'),
    Kxx = multiKernCompute(simMultiKern, predt, model.comp{j}.t);
    varX = real(kernDiagCompute(simMultiKern, predt) - ...
		sum(Kxx'.* (model.comp{j}.invK*Kxx'), 1)');
    meanPredX = reshape(ones(length(predt),1)*([0 model.comp{j}.B./ ...
		    model.comp{j}.D]), length(predt)*(numGenes), 1);
  else
    Kxx = multiKernCompute(simMultiKern, predt, model.comp{j}.t);
    varX = real(kernDiagCompute(simMultiKern, predt) - ...
		sum(Kxx'.* (model.comp{j}.invK*Kxx'), 1)');
    meanPredX = reshape(ones(length(predt),1)*(model.comp{j}.B./ ...
		    model.comp{j}.D), length(predt)*(numGenes), 1);
  end

  predX = meanPredX + real(Kxx*model.comp{j}.invK*(model.comp{j}.y-ymean));

  % Take out predictions at data points.
  % Use them to get the scale for the other data.
  numData = length(predX)/(numGenes);
  predExprs = reshape(predX, numData, numGenes);
  meanExprs = ones(numData, 1)*mean(predExprs);
  scaleExprs = ones(numData, 1)*(sqrt(var(predExprs))./sqrt(var(y{j})));

  predExprs(end-length(model.comp{j}.t)+1:end,:) = [];
  varExprs = reshape(varX, numData, numGenes);
  varExprs = varExprs./scaleExprs./scaleExprs;
  varExprs(end-length(model.comp{j}.t)+1:end,:) = [];
  predF(end-length(model.comp{j}.t)+1:end) = [];
  varF(end-length(model.comp{j}.t)+1:end) = [];
  predt(end-length(model.comp{j}.t)+1:end) = [];

  yscale = ones(length(times), 1)*sqrt(var(y{j}));
  ymean = ones(length(times),1)*mean(y{j});
  ynormal = ymean + (y{j}-ymean)./yscale;
  yvarNormal = yvar{j}./yscale./yscale;

  scalePred = sqrt(var(predExprs));

  if nargin < 2,
    figure;
    if strcmp(model.type, 'cgpdisim'),
      numRows = 3;
      numCols = numGenes - 1;
      inputCol = floor((numCols+1)/2);

      subplot(numRows, numCols, inputCol + numCols);
    else
      numRows = 2;
      numCols = numGenes;
      inputCol = floor((numCols+1)/2);

      subplot(numRows, numCols, inputCol);
    end
  else
    figure(j);
    subplot(numPlots+1, totgenes, totgenes + thisgene);
  end
  bh = fill([predt', fliplr(predt')], [predF' + 2*sqrt(varF'), fliplr(predF' - 2*sqrt(varF'))], [.8 .8 .8], 'EdgeColor', [.8, .8, .8]);
  hold on,
  lin = plot(predt, predF, '-');
  hold off
  title(sprintf('Inferred %s protein', tf), 'fontsize', FONTSIZE);
  set(bh, 'lineWidth', LINEWIDTH);
  set(lin, 'lineWidth', 1.5*LINEWIDTH);
  %set(lin, 'markersize', 20);
  set(gca, 'fontname', 'arial', 'fontsize', FONTSIZE, 'xlim', [min(model.comp{j}.t) ...
                                                    max(model.comp{j} ...
                                                    .t)]);
    set(gca, 'YTick', []);
    set(gca, 'XTickLabel', []);
    axis tight
    v = axis;
    axis([v(1)-.05*(v(2)-v(1)), v(2)+.05*(v(2)-v(1)), ...
	  v(3)-.05*(v(4)-v(3)), v(4)+.05*(v(4)-v(3))])
%  set(gca, 'ylim', [-0.1 0.4]);

  for index = 1:numPlots
    if nargin >= 2,
      if index==1,
	subplot(numPlots+1, totgenes, thisgene);
      else
	subplot(numPlots+1, totgenes, index*totgenes+thisgene);
      end
    else
      if strcmp(model.type, 'cgpdisim'),
	if index == 1,
	  subplot(numRows, numCols, inputCol);
	else
	  subplot(numRows, numCols, (numRows-1)*numCols + index - 1);
	end
      else
	subplot(numRows, numCols, (numRows-1)*numCols + index);
      end
    end
    bh = fill([predt', fliplr(predt')], [predExprs(:,selectgenes(index))' + 2*sqrt(varExprs(:,selectgenes(index))'), fliplr(predExprs(:,selectgenes(index))' - 2*sqrt(varExprs(:,selectgenes(index))'))], [.8, .8, .8], 'EdgeColor', [.8, .8, .8]);
    hold on,
    lin = plot(predt, predExprs(:,selectgenes(index)), '-');
    lin = [lin plot(times, y{j}(:,selectgenes(index)), 'rx')];
    lin1 = errorbar(times, y{j}(:,selectgenes(index)), 2*sqrt(yvar{j}(:,selectgenes(index))), ...
                    'rx');
    hold off
    if strcmp(model.type, 'cgpdisim') && selectgenes(index) == 1,
      titleText = sprintf('%s mRNA (input)', tf);
%      lin = [lin plot(predt, predDi, 'm-')];
    else
      titleText = sprintf('%s mRNA', genenames{selectgenes(index)});
    end
    title(titleText, 'fontsize', FONTSIZE);
    set(bh, 'lineWidth', LINEWIDTH);
    set(lin, 'lineWidth', 1.5*LINEWIDTH);
    set(lin, 'markersize', MARKERSIZE);
    set(lin1, 'lineWidth', LINEWIDTH);
    set(gca, 'fontname', 'arial', 'fontsize', FONTSIZE, 'xlim', [min(predt) ...
                        max(predt)]);
    set(gca, 'YTick', []);
    if nargin < 2,
      if strcmp(model.type, 'cgpdisim') && index == 1,
	set(gca, 'XTickLabel', []);
      else
	xlabel('Time (h)')
      end
    else
      if index ~= numPlots,
	set(gca, 'XTickLabel', []);
      else
	xlabel('Time (h)')
      end
    end
    axis tight
    v = axis;
    axis([v(1)-.05*(v(2)-v(1)), v(2)+.05*(v(2)-v(1)), ...
	  v(3)-.05*(v(4)-v(3)), v(4)+.05*(v(4)-v(3))])
  end
end


function [IterationMap,Metrics,err] = bst_connectivity_mra(F, Surface, Options)
% BST_CONNECTIVITY_MRA: Multiresolution analysis of connectivity
%
% USAGE:  [ItMap,Metrics] = bst_connectivity_mra(F, Surface, HeadModel.Gain(Results.GoodChannel,:))
%
% INPUTS:
%    - F           : N-source x N-sample time-series for analysis
%    - Surface     : tesselation structure (Faces,Vertices,VertConn)
%    - Options     : N-source gain matrix from the head model
%
% OUTPUTS:
%    - IterationMap  : N-source vector with each number corresponding to
%                      the iteration at which they left the process (indicative
%                      of their probability of high connectivity)
%    - Metrics       : N-iteration cells containing connectivity metric for
%                      each iteration
%    - err           : Error message, if any
%
% NOTE:
%    - Selection model that doesn't work:
%       Using the upper half of subdivision - Weird results
%       Using a high prctile value - Too discriminatory
%
%    - Selection model that work:
%       Hard threshold works well, but arbitrary threshold
%
% @=============================================================================
% This function is part of the Brainstorm software:
% https://neuroimage.usc.edu/brainstorm
%
% Copyright (c) University of Southern California & McGill University
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPLv3
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Sebastien Dery, 2013

    Verbose = 0;
    ShuffleVertices = 1;

    nSample = size(F,2);
    nVertices = length(Surface.Vertices);
    % Init varout
    IterationMap = zeros(nVertices,1);
    Metrics = [];
    err = [];

    %S1 = extend(3664, sSurf.VertConn, 4);
    %S2 = extend(10588, sSurf.VertConn, 4);
    %Source = [find(S1(3664,:)) find(S2(10588,:))];

    isAbsolute = 1;
    nChannel = 272;
    SplitFactor = 2;

    % Unconstrained function
    isNorm = 1;
    if isNorm
        XyzFunction = 'norm';
    else
        XyzFunction = 'none';
    end
    ScoutFunction = 'mean';
    nComponents = 1;

    % Equal to the number of recorded channel
    nTessScouts = nChannel / SplitFactor;

    % Remaining vertices
    RemVert = 1:nVertices;
    % Initial tesselation
    Vert = 1:length(RemVert);
    VertConn = Surface.VertConn(RemVert,RemVert);
    Scouts = tess_cluster_seed(Vert(randperm(length(Vert))), VertConn, nTessScouts);

    iter = 1;
    nDipole = round(length(RemVert) / nTessScouts);
    while (nDipole > 2)
        % Switch variable to prevent mixing
        OldScouts = Scouts;
        % Tesselate the scout vertices
        uScouts = unique(OldScouts(OldScouts ~= 0));
        Label = 0;
        for i=1:length(uScouts)
            iRows = find(OldScouts == uScouts(i));
            Scouts(iRows) = tess_cluster(Surface.VertConn(iRows,iRows), SplitFactor, ShuffleVertices, Verbose) + Label;
            Label = Label + 2;
        end

        %
        uScouts = unique(Scouts(Scouts ~= 0));
        nScouts = length(uScouts);
        %
        Fs = zeros(nScouts, nSample);
        %
        for i=1:nScouts
            % Get the scout vertices
            iRows = find(Scouts == uScouts(i));
            % Get the scout orientation
            ScoutOrient = Surface.VertNormals(iRows,:);
            % Get scout value
            Fs(i,:) = bst_scout_value(F(iRows,:), ScoutFunction, ScoutOrient, nComponents, XyzFunction);
        end

        % Compute normalised distance
        % D = dist(Center');
        % D = (D - min(D(:))) ./ (max(D(:)) - min(D(:)));
        % D = 1 ./ D;
        % Compute metric
        switch (Options.method)
            case 'corr'
                % R = real(bst_corrn(Fs, Fs, inputs.removemean));
                R = corrcoef([Fs Fs]');
            case 'cohere'
                % R = bst_coherence(Fs, Fs, Options);
                error('Not supported yet.');
            case 'granger'
                R = bst_granger(Fs, Fs, Options.GrangerOrder, Options);
            case 'spgranger'
                error('Not supported yet.');
            case 'plv'

            otherwise
        end
        % Remove diagonal
        R(eye(length(R)) == 1) = 0;
        %
        if isAbsolute
            R = abs(R);
        end

        % Higher than mean - Rows
        tLowCorr = max(R,[],2);
        minCorr = mean(tLowCorr);
        Keep = tLowCorr > minCorr;
        % If directional data, check the other way around
        if (strcmpi(Options.method,'granger') || strcmpi(Options.method,'spgranger'))
            % Higher than mean - Columns
            tLowCorr = max(R);
            minCorr = mean(tLowCorr);
            Keep = Keep | (tLowCorr > minCorr)';
        end
        % Remove everything else
        lRow = find(~Keep);
        if isempty(lRow)
            break;
        end
        %
        RowId = ismember(Scouts,lRow);
        % Keep track of when these dipoles left the iteration process
        IterationMap(RemVert(RowId == 1)) = iter;
        % Leave these vertices out
        Scouts(RowId == 1) = 0;
        % Keep metric matrix
        Metrics{iter} = R;
        % Update iterative variables
        nDipole = floor(sum(Scouts ~= 0) / (nScouts - length(lRow)));
        iter = iter + 1;
    end
    % Assign victorious last
    IterationMap(IterationMap == 0) = iter;
end


function [xDeformV,yDeformV,zDeformV] = getDeformationAt(deformS,toPlanC,toScanNum,fromPlanC,fromScanNum,fromXYZv)
% function [xDeformV,yDeformV,zDeformV] = getDeformationAt(deformS,toPlanC,toScanNum,fromPlanC,fromScanNum,fromXYZv)
%
% APA, 08/20/2012

% % Obtain base and moving scan UIDs
% baseScanUID = deformS.baseScanUID;
% movScanUID  = deformS.movScanUID;
%
% Figure out whether an inverse Vector field is required
indexToS = toPlanC{end};
indexFromS = fromPlanC{end};
%
% toScanUID = toPlanC{indexToS.scan}(toScanNum).scanUID;
% fromScanUID = fromPlanC{indexFromS.scan}(fromScanNum).scanUID;
% if baseScanUID == fromScanUID
%     calc_inv_vf_flag = 1;
% else
%     calc_inv_vf_flag = 0;
% end
%
% % Create b-spline coefficients file
% bspFileName = fullfile(getCERRPath,'ImageRegistration','tmpFiles',['bsp_coeffs_',baseScanUID,'_',toScanUID,'.txt']);
% success     = write_bspline_coeff_file(bspFileName,deformS.algorithmParamsS);
%
% % Obtain Vf from b-splice coefficients
% vfFileName = fullfile(getCERRPath,'ImageRegistration','tmpFiles',['vf_',baseScanUID,'_',toScanUID,'.mha']);
% system(['plastimatch xf-convert --input ',escapeSlashes(bspFileName), ' --output ', escapeSlashes(vfFileName), ' --output-type vf'])
%
% % Obtain Inverse Vf if required
% if calc_inv_vf_flag
%     system(['plastimatch vf_invert --input ', escapeSlashes(vfFileName), ' --output ', escapeSlashes(vfFileName), ' --dims="x y z" --origin="x y z" --spacing="x y z"'])
% end
%
% % Read .mha file for Vf
% infoS  = mha_read_header(vfFileName);
% data3M = mha_read_volume(infoS);
% xDeform3M = flipdim(permute(data3M(:,:,:,1),[2,1,3]),3);
% yDeform3M = flipdim(permute(data3M(:,:,:,2),[2,1,3]),3);
% zDeform3M = flipdim(permute(data3M(:,:,:,3),[2,1,3]),3);

vf = get_vector_field(deformS,toPlanC,toScanNum,fromPlanC,fromScanNum);

% Get grid coordinates for "fromScan"
[xV, yV, zV] = getScanXYZVals(fromPlanC{indexFromS.scan}(fromScanNum));

% Interolate fromXYZv points to get Vf based on the "fromScan" grid
xDeformV = finterp3(fromXYZv(:,1), fromXYZv(:,2), fromXYZv(:,3), vf(:,:,:,1), [xV(1)-eps*10^10 xV(2)-xV(1) xV(end)+eps*10^10], [yV(end)-eps*10^10 yV(1)-yV(2) yV(1)+eps*10^10], zV, 0);
yDeformV = finterp3(fromXYZv(:,1), fromXYZv(:,2), fromXYZv(:,3), vf(:,:,:,2), [xV(1)-eps*10^10 xV(2)-xV(1) xV(end)+eps*10^10], [yV(end)-eps*10^10 yV(1)-yV(2) yV(1)+eps*10^10], zV, 0);
zDeformV = finterp3(fromXYZv(:,1), fromXYZv(:,2), fromXYZv(:,3), vf(:,:,:,3), [xV(1)-eps*10^10 xV(2)-xV(1) xV(end)+eps*10^10], [yV(end)-eps*10^10 yV(1)-yV(2) yV(1)+eps*10^10], zV, 0);


% new procedure: generate motor seed/map in trialRes space
% find top 100 cells correlating to motor, screen with Rh4+Rh5(+Rh6??) masks

% corr sweep (0.5-0.7) to get top %2 cells, then kmeans, save; rank by stim-lock, save
clear all; close all; clc

%% folder setup
isSaveFig = 1;
isPlotFig = 1;

outputDir = GetOutputDataDir;
saveDir1 = fullfile(outputDir,'motor_map_030317');
saveDir2 = fullfile(outputDir,'motor_map_seed_030317');
if ~exist(saveDir1, 'dir'), mkdir(saveDir1), end;
if ~exist(saveDir2, 'dir'), mkdir(saveDir2), end;

%% init

hfig = figure;
InitializeAppData(hfig);
ResetDisplayParams(hfig);

setappdata(hfig,'isMotorseed',0);

%% run fish
range_fish = GetFishRange;%[1:3,5:18];
M_thres_reg = zeros(3,18);
M_numTopCorr = zeros(1,18);
M_motorseedRegs = cell(1,18);
M_compareMotorCellNumber = zeros(2,18);

for i_fish = 14 %range_fish
    ClusterIDs = [1,1];
    [~,~,~,stim,behavior,M_0] = LoadSingleFishDefault(i_fish,hfig,ClusterIDs);

    numTopCorr = 100;
    [~,~,regressor_m_raw] = GetMotorRegressor(behavior,i_fish);

    %% convert to trialRes (converting locally, not updating hfig to isTrialRes)
    [~,regressor_m_raw_tRes] = GetTrialAvrLongTrace(hfig,regressor_m_raw);
    [~,M_0_tRes] = GetTrialAvrLongTrace(hfig,M_0);

    %%
    M_lr = [1,3];
%     M_name = {'Left','Right'};
    cIX_seed = [];
    gIX_seed = [];
    for i_lr = 1:2,
        % left:
        reg_tRes = regressor_m_raw_tRes(M_lr(i_lr),:);

        %% for each cell, find correlation coeff
        M_corr = corr(reg_tRes',M_0_tRes');%cell_resp_ave');

        [~,I] = sort(M_corr,'descend');
        cIX = I(1:numTopCorr)';
        gIX = i_lr*ones(size(cIX));

        %% screen with anat masks #222 and #233 (Rhombomore 4 and 5)
        MASKs = getappdata(hfig,'MASKs');
        CellXYZ_norm = getappdata(hfig,'CellXYZ_norm');
        absIX = getappdata(hfig,'absIX');

        Msk_IDs = [222,223,224]; % manual input
        [cIX,gIX] = ScreenCellsWithMasks(Msk_IDs,cIX,gIX,MASKs,CellXYZ_norm,absIX);

        % enforce that seed cells for the left are in the left hemisphere,
        % and vice versa for the right
        if i_lr ==1,
            [cIX,gIX]  = DivideCellsbyHemisphere(CellXYZ_norm,absIX,cIX,gIX);
        else
            [~,~,cIX,gIX] = DivideCellsbyHemisphere(CellXYZ_norm,absIX,cIX,gIX);
        end

        num = numTopCorr;
        % need at least 10 cells to qualify as a seed
        while length(cIX)<10, % repeat with larger numTopCorr
            num = num+100;
            cIX = I(1:num)';
            gIX = i_lr*ones(size(cIX));
            [cIX,gIX] = ScreenCellsWithMasks(Msk_IDs,cIX,gIX,MASKs,CellXYZ_norm,absIX);
            M_numTopCorr(i_fish) = num;

            % screen by left/right again
            if i_lr ==1,
                [cIX,gIX]  = DivideCellsbyHemisphere(CellXYZ_norm,absIX,cIX,gIX);
            else
                [~,~,cIX,gIX] = DivideCellsbyHemisphere(CellXYZ_norm,absIX,cIX,gIX);
            end
        end

        cIX_seed = [cIX_seed;cIX];
        gIX_seed = [gIX_seed;gIX];

    end
    % this is not tRes, just loading default:
    M = UpdateIndices_Manual(hfig,cIX_seed,gIX_seed);
    Reg = FindClustermeans(gIX_seed,M);
    % save motor seed functional trace, e.g. new motor regressors
    M_motorseedRegs{i_fish} = Reg;

    %% save motor seeds in VAR, and visualize (not in tRes)
    clusgroupID = 11;
    clusIDoverride = 2;
    name = 'Motor_seed_030317';
    SaveCluster_Direct(cIX_seed,gIX_seed,absIX,i_fish,name,clusgroupID,clusIDoverride);

    %% left-right combined plot
    figure('Position',[50,100,1400,800]);
    % isCentroid,isPlotLines,isPlotBehavior,isPlotRegWithTS
    subplot(121)
    setappdata(hfig,'isPlotBehavior',1);
    setappdata(hfig,'isStimAvr',0);
    setappdata(hfig,'isPlotLines',0);
    UpdateTimeIndex(hfig);
    DrawTimeSeries(hfig,cIX_seed,gIX_seed);

    % right plot
    ax = subplot(122)
    I = LoadCurrentFishForAnatPlot(hfig,cIX_seed,gIX_seed);
    DrawCellsOnAnat(I,ax);

    if isSaveFig,
        filename = fullfile(saveDir2, ['Fish',num2str(i_fish),'_motormap_seed']);
        saveas(gcf, filename, 'png');
        close(gcf)
    end

    %% regression (in tRes), thresholding by % of cells (instead of corr thres)

    [~,Reg_tRes] = GetTrialAvrLongTrace(hfig,Reg);

    Corr = corr(Reg_tRes',M_0_tRes');
    [corr_max,IX] = max(Corr,[],1);
    [~,I] = sort(corr_max,'descend');

    M_target_prctcell= [1,2,3];
    for i_numcell = 2,
        nCells_total = size(M_0,1);
        prctcell = M_target_prctcell(i_numcell);
        nCells_target = round(prctcell/100 * nCells_total);

        %% target cell number: counting cells in hindbrain only

        Msk_IDs = 114; % mask for full hindbrain

        % isScreenMskFromAllCells
        cIX = (1:length(absIX))';
        gIX = ones(size(cIX));
        [cIX_hb,gIX_hb] = ScreenCellsWithMasks(Msk_IDs,cIX,gIX,MASKs,CellXYZ_norm,absIX);

        I_hb = ismember(I,cIX_hb);
        cum_I_hb = cumsum(I_hb);
        lastIX = find(cum_I_hb==nCells_target);

        % cut off the desired number of cells to display
        cIX = I(1:lastIX)';
        gIX = IX(cIX)';
        M = UpdateIndices_Manual(hfig,cIX,gIX);

        M_thres_reg(i_numcell,i_fish) = corr_max(I(nCells_target));
        M_compareMotorCellNumber(1,i_fish) = length(cIX);

        %% k-means (not in tRes)
        numK = 16; % manual
        gIX = Kmeans_Direct(M,numK);

        %% Plot anat
        if isPlotFig,
            %             figure('Position',[50,100,800,1000]);
            %             I = LoadCurrentFishForAnatPlot(hfig,cIX,gIX);
            %             DrawCellsOnAnat(I);
            figure('Position',[50,100,1400,800]);
            % isCentroid,isPlotLines,isPlotBehavior,isPlotRegWithTS
            subplot(121)
            setappdata(hfig,'isPlotBehavior',1);
            setappdata(hfig,'isStimAvr',0);
            setappdata(hfig,'isPlotLines',0);
            UpdateTimeIndex(hfig);
            DrawTimeSeries(hfig,cIX,gIX);

            % right plot
            ax = subplot(122)
            I = LoadCurrentFishForAnatPlot(hfig,cIX,gIX);
            DrawCellsOnAnat(I,ax);

            %% Save plot
            if isSaveFig,
                filename = fullfile(saveDir1, ['Fish',num2str(i_fish),'_motormap_',num2str(prctcell),'%']);
                saveas(gcf, filename, 'png');
                close(gcf)
            end
        end
        %%
%         %% Rank by stim-lock
%         [gIX,rankscore] = RankByStimLock_Direct(hfig,gIX);
%
%         setappdata(hfig,'rankscore',round(rankscore*100)/100);
%         setappdata(hfig,'clrmap_name','jet');
%
%         % Plot anat
%         if isPlotFig,
%             figure('Position',[50,100,800,1000]);
%             I = LoadCurrentFishForAnatPlot(hfig,cIX,gIX);
%             DrawCellsOnAnat(I);
%
%
%             % Save plot
%             if isSaveFig,
%                 filename = fullfile(saveDir2, ['Fish',num2str(i_fish),'_motormap_',num2str(target_numcell),'_stimlock_anat']);
%                 saveas(gcf, filename, 'png');
%                 close(gcf)
%             end
%
%             % Plot functional traces
%             figure('Position',[50,100,800,1000]);
%             % isCentroid,isPlotLines,isPlotBehavior,isPlotRegWithTS
%             setappdata(hfig,'isPlotBehavior',1);
%             setappdata(hfig,'isStimAvr',0);
%             UpdateTimeIndex(hfig);
%             DrawTimeSeries(hfig,cIX,gIX);
%
%             % Save plot
%             isSaveFig
%             filename = fullfile(saveDir2, ['Fish',num2str(i_fish),'_motormap_',num2str(target_numcell),'_stimlock_func']);
%             saveas(gcf, filename, 'png');
%             close(gcf)
%         end
%     end
%     % reset colormap
%     setappdata(hfig,'clrmap_name','hsv_new');

    end

    %% count cell numbers regressed (in tRes) with fictive trace
    thres_reg = M_thres_reg(2,i_fish);
%     [~,~,regressor_m_raw] = GetMotorRegressor(behavior,i_fish);

    [rawmotorcorr,IX] = max(corr(regressor_m_raw_tRes',M_0_tRes'),[],1);
    ix = find(rawmotorcorr>thres_reg);
    M_compareMotorCellNumber(2,i_fish) = length(ix);
end
SaveVARwithBackup();

%%
% range_fish excludes Fish 4
M_compareMotorCellNumber(:,4) = NaN;
figure;bar(M_compareMotorCellNumber')

github-repos/MATLAB/xiuyechen-FishExplorer/FishExplorer-c61392cf0835480d64fc03c15f1992935fdc7106/figure scripts/SensoryMotor/arc code/motormap, tRes versions, comparisons, w Clusters or Autoclus to follow/fig3_motormap_trialRes_030317.m


function net = load_cnn(fparams, im_size)

	net = load(['networks/' fparams.nn_name]);
	net = vl_simplenn_tidy(net);
	net.layers = net.layers(1:max(fparams.output_layer));

	if strcmpi(fparams.input_size_mode, 'cnn_default')
	    base_input_sz = net.meta.normalization.imageSize(1:2);
	elseif strcmpi(fparams.input_size_mode, 'adaptive')
	    base_input_sz = im_size(1:2);
	else
	    error('Unknown input_size_mode');
	end

	net.meta.normalization.imageSize(1:2) = round(base_input_sz .* fparams.input_size_scale);
	net.meta.normalization.averageImageOrig = net.meta.normalization.averageImage;

	if isfield(net.meta,'inputSize')
	    net.meta.inputSize = base_input_sz;
	end

	if size(net.meta.normalization.averageImage,1) > 1 || size(net.meta.normalization.averageImage,2) > 1
	    net.meta.normalization.averageImage = imresize(single(net.meta.normalization.averageImage), net.meta.normalization.imageSize(1:2));
	end

	net.info = vl_simplenn_display(net);
end


% Copyright (C) 1993-2014, by Peter I. Corke
%
% This file is part of The Robotics Toolbox for Matlab (RTB).
%
% RTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% RTB is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with RTB.  If not, see <http://www.gnu.org/licenses/>.
function [sys,x0,str,ts] = quadrotor_plot(t,x,u,flag,s,plot,enable,vehicle)
    % Flyer plot, lovingly coded by Paul Pounds, first coded 17/4/02
    % version 2 2004 added scaling and ground display
    % version 3 2010 improved rotor rendering and fixed mirroring bug
    %
    % Displays X-4 flyer position and attitude in a 3D plot.
    % GREEN ROTOR POINTS NORTH
    % BLUE ROTOR POINTS EAST

    % PARAMETERS
    % s defines the plot size in meters
    % swi controls flyer attitude plot; 1 = on, otherwise off.

    % INPUTS
    % 1 Center X position
    % 2 Center Y position
    % 3 Center Z position
    % 4 Yaw angle in rad
    % 5 Pitch angle in rad
    % 6 Roll angle in rad

    % OUTPUTS
    %   None
    ts = [-1 0];

    if ~isfield(vehicle, 'nrotors')
        vehicle.nrotors = 4;    % sensible default for quadrotor function
    end

    switch flag
        case 0
            [sys,x0,str,ts] = mdlInitializeSizes(ts,plot,enable); % Initialization
        case 3
            sys = mdlOutputs(t,u,s,plot,enable, vehicle); % Calculate outputs
        case {1,2, 4, 9} % Unused flags
            sys = [];
        otherwise
            error(['unhandled flag = ',num2str(flag)]); % Error handling
    end

    % Initialize
function [sys,x0,str,ts] = mdlInitializeSizes(ts,plot,enable)
    % Call simsizes for a sizes structure, fill it in, and convert it
    % to a sizes array.
    sizes = simsizes;
    sizes.NumContStates  = 0;
    sizes.NumDiscStates  = 0;
    sizes.NumOutputs     = 0;
    sizes.NumInputs      = 6;
    sizes.DirFeedthrough = 1;
    sizes.NumSampleTimes = 1;
    sys = simsizes(sizes);
    x0  = [];
    str = [];          % Set str to an empty matrix.
    ts = [0.05 0];

    if enable == 1
        figure(plot);
        clf;
        %colordef(1,'none');
        %global anim
        %anim = Animate('quad-movie');

        %TODO enable animation saving from the block
    end
    % End of mdlInitializeSizes.

function sys = mdlOutputs(t,u,s, plot, enable, quad)
    global a1s b1s

    % not quite sure what this is about -- PIC
    if numel(a1s) == [0];
        a1s = zeros(1, quad.nrotors);
        b1s = zeros(1, quad.nrotors);
    end

    % vehicle dimensons
    d = quad.d; %Hub displacement from COG
    r = quad.r; %Rotor radius

    for i = 1:quad.nrotors
        theta = (i-1)/quad.nrotors*2*pi;
        %   Di      Rotor hub displacements (1x3)
        % first rotor is on the x-axis, clockwise order looking down from above
        D(:,i) = [ d*cos(theta); d*sin(theta); 0];
        scal = s(1)/4;
        %Attitude center displacements
        C(:,i) = [ scal*cos(theta); scal*sin(theta); 0];
    end

    if enable == 1
        %draw ground
        figure(plot);
        clf;
        if length(s) == 1
            axis([-s s -s s 0 s]);
        else
            axis([-s(1) s(1) -s(1) s(1) 0 s(2)])
            s = s(1);
        end
        hold on;

        % plot the ground boundaries and the big cross
        plot3([-s -s],[s -s],[0 0],'-b')
        plot3([-s s],[s s],[0 0],'-b')
        plot3([s -s],[-s -s],[0 0],'-b')
        plot3([s s],[s -s],[0 0],'-b')
        plot3([s -s],[-s s],[0 0],'-b')
        plot3([-s s],[-s s],[0 0],'-b')
        grid on

        %READ STATE
        z = [u(1);u(2);u(3)];
        n = [u(4);u(5);u(6)];

        %PREPROCESS ROTATION MATRIX
        phi = n(1);    %Euler angles
        the = n(2);
        psi = n(3);

        R = [cos(the)*cos(phi) sin(psi)*sin(the)*cos(phi)-cos(psi)*sin(phi) cos(psi)*sin(the)*cos(phi)+sin(psi)*sin(phi);   %BBF > Inertial rotation matrix
            cos(the)*sin(phi) sin(psi)*sin(the)*sin(phi)+cos(psi)*cos(phi) cos(psi)*sin(the)*sin(phi)-sin(psi)*cos(phi);
            -sin(the)         sin(psi)*cos(the)                            cos(psi)*cos(the)];

        %Manual Construction
        %Q3 = [cos(psi) -sin(psi) 0;sin(psi) cos(psi) 0;0 0 1];   %Rotation mappings
        %Q2 = [cos(the) 0 sin(the);0 1 0;-sin(the) 0 cos(the)];
        %Q1 = [1 0 0;0 cos(phi) -sin(phi);0 sin(phi) cos(phi)];
        %R = Q3*Q2*Q1;    %Rotation matrix

        %CALCULATE FLYER TIP POSITONS USING COORDINATE FRAME ROTATION
        F = [1 0 0;0 -1 0;0 0 -1];

        %Draw flyer rotors
        t = [0:pi/8:2*pi];
        for j = 1:length(t)
            circle(:,j) = [r*sin(t(j));r*cos(t(j));0];
        end

        for i = 1:quad.nrotors
            hub(:,i) = F*(z + R*D(:,i)); %points in the inertial frame

            q = 1; %Flapping angle scaling for output display - makes it easier to see what flapping is occurring
            Rr = [cos(q*a1s(i))  sin(q*b1s(i))*sin(q*a1s(i)) cos(q*b1s(i))*sin(q*a1s(i));   %Rotor > Plot frame
                0              cos(q*b1s(i))               -sin(q*b1s(i));
                -sin(q*a1s(i)) sin(q*b1s(i))*cos(q*a1s(i)) cos(q*b1s(i))*cos(q*a1s(i))];

            tippath(:,:,i) = F*R*Rr*circle;
            plot3([hub(1,i)+tippath(1,:,i)],[hub(2,i)+tippath(2,:,i)],[hub(3,i)+tippath(3,:,i)],'b-')
        end

        %Draw flyer
        hub0 = F*z;  % centre of vehicle
        for i = 1:quad.nrotors
            % line from hub to centre plot3([hub(1,N) hub(1,S)],[hub(2,N) hub(2,S)],[hub(3,N) hub(3,S)],'-b')
            plot3([hub(1,i) hub0(1)],[hub(2,i) hub0(2)],[hub(3,i) hub0(3)],'-b')

            % plot a circle at the hub itself
            plot3([hub(1,i)],[hub(2,i)],[hub(3,i)],'o')
        end

        % plot the vehicle's centroid on the ground plane
        plot3([z(1) 0],[-z(2) 0],[0 0],'--k')
        plot3([z(1)],[-z(2)],[0],'xk')

        % label the axes
        xlabel('x');
        ylabel('y');
        zlabel('z (height above ground)');
        view(3)
    end

    sys = [];
    % End of mdlOutputs.


pose = icp0301(7300:end,:);
plot(pose(:,4), pose(:,8), 'k.')


%% EXAMPLE MONTE-CARLO SETUP CONFIGURATION FILE (monteCarlo_example.m) %%%%
% This function is intended to demonstrate how the monte-carlo aspect of
% OMAS may be used to run numerous cycles of a series of different
% algorithms, agents and scenarios.

% Author: James A. Douthwaite 30/04/18

% Notes*
% - The monte-carlo object accepts a cell array of objects [studies,objects]
%   (where 'studies' are seen as independant sets of cycles/analytics).
% - It is currently more efficient to hand smaller sets of object arrays
%   per Monte-Carlo instance rather than run many studies using one.
% - The object array can be defined in same manner as OMAS, using any
%   scenario or object set, the Monte-Carlo instance will then perturb the
%   global positions of all objects before the cycle begins.

% ADD THE PROGRAM PATHS
clear all; close all;
addpath('environment');
addpath('objects');
addpath('scenarios');                                                      % Required system/toolbox paths

fprintf('[SETUP]\tInitialising Monte-Carlo example.\n');
% /////////////////// AGENT & SCENARIO PARAMETERS /////////////////////////
sim_agentOrbit  = 30;
sim_agentVelocity = 0;
sim_waypointOrbit = 35;

% //////////////////////// OMAS CONFIGURATION /////////////////////////////
sim_warningDistance = 10;
sim_maxDuration = 120;
sim_timeStep = 0.25;
sim_verbosity = 0;

% ///////////////////// MONTE-CARLO CONFIGURATION /////////////////////////
monteCarlo_algorithms = {'agent_2D_VO',...
                         'agent_2D_RVO',...
                         'agent_2D_HRVO'};
                         %'agent_2D_RVO2'};                                % The types of agents simulated
monteCarlo_agentPopulations = [2,4];

% ///////////////////// MONTE-CARLO CONFIGURATION /////////////////////////
[~, userdir] = system('echo %USERPROFILE%');    % Get desktop path
monteCarlo_outputPath = strcat(userdir,'\desktop\US18_data');
monteCarlo_positionSigma = 0.2;
monteCarlo_velocitySigma = 0;
monteCarlo_cycles = 5;                        % [FIXED]
monteCarlo_parallel = 0;
monteCarlo_offOnComplete = 0;

% ///////////////////// DEFINE THE MC OBJECT MATRIX ///////////////////////
studyVector = cell(1,2*max(monteCarlo_agentPopulations));
studyObjects = [];
for n = 1:numel(monteCarlo_agentPopulations)                               % Differing agent numbers
    % FOR EACH ALGORITHM TO BE EVALUATED
    for index = 1:numel(monteCarlo_algorithms)                             % Differing agent algorithms
        % CREATE THE AGENT SET
        agentVector = cell(1,monteCarlo_agentPopulations(n));              % Agent container
        for i = 1:monteCarlo_agentPopulations(n)
            agentVector{1,i} = eval(monteCarlo_algorithms{index});         % Assign agents
        end
        % ///////////////////// SCENARIO CONFIGURATION ////////////////////
        % Concentric scenario
%         initialisedObjects = GetScenario_concentric('agents',agentVector,...
%                                                     'agentOrbit',sim_agentOrbit,...
%                                                     'agentVelocity',sim_agentVelocity,...
%                                                     'waypointOrbit',sim_waypointOrbit);
        % Opposing lines scenarios
        initialisedObjects = GetScenario_twoLines('agents',agentVector,...
                                                  'agentVelocity',sim_agentVelocity);
        % /////////////////////////////////////////////////////////////////
        sessionSample = studyVector;
        sessionSample(1:numel(initialisedObjects)) = initialisedObjects;
        studyObjects = vertcat(studyObjects,sessionSample);
    end
end

%% ///////////// BEGIN SIMULATING THE MONTE-CARLO INSTANCES ///////////////
fprintf('[SETUP]\t Defining Monte-Carlo Simulation Series...\n');
[monteCarlo] = OMAS_monteCarlo('objects',studyObjects,...
    'duration',sim_maxDuration,...
    'dt',sim_timeStep,...
    'warningDistance',sim_warningDistance,...
    'verbosity',sim_verbosity,...
    'positionSigma',monteCarlo_positionSigma,...
    'velocitySigma',monteCarlo_velocitySigma,...
    'threadPool',monteCarlo_parallel,...
    'shutDownOnComplete',monteCarlo_offOnComplete,...
    'cycles',monteCarlo_cycles,...
    'outputPath',monteCarlo_outputPath);

% EVALUATE ALL OF THE PROPOSED CONDITIONS
monteCarlo.evaluateAllCycles();


function [pnt, tri, srf] = read_bv_srf(filename);

% READ_BV_SRF reads a triangulated surface from a BrainVoyager *.srf file
%
% Use as
%   [pnt, tri] = read_bv_srf(filename) or
%   [pnt, tri, srf] = read_bv_srf(filename)

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

% This documentation originates from
%   http://www.brainvoyager.com/BV2000OnlineHelp/BrainVoyagerWebHelp/mergedProjects/FileFormats/BrainVoyager_File_Formats.htm
%
% BYTES DATA TYPE DEFAULT DESCRIPTION
% 4 float 3 version number
% 4 int 0 reserved, must be '0'
% 4 int  NrOfVertices (number of vertices)
% 4 int  NrOfTriangles (number of triangles)
% 4 float 128.0 MeshCenterX
% 4 float 128.0 MeshCenterY
% 4 float 128.0 MeshCenterZ
% NrOfVertices*4 float  VertexX, sequence of X coordinates of all vertices
% NrOfVertices*4 float  VertexY, sequence of Y coordinates of all vertices
% NrOfVertices*4 float  VertexZ, sequence of Z coordinates of all vertices
% NrOfVertices*4 float  NormalX, sequence of X components of all vertex normals
% NrOfVertices*4 float  NormalY, sequence of Y components of all vertex normals
% NrOfVertices*4 float  NormalZ, sequence of Z components of all vertex normals
% 4 float 0.322 R component of convex curvature color (range: 0.0 - 1-0)
% 4 float 0.733 G component of convex curvature color (range: 0.0 - 1-0)
% 4 float 0.980 B component of convex curvature color (range: 0.0 - 1-0)
% 4 float 0.500 Alpha component of convex curvature color (range: 0.0 - 1-0)
% 4 float 0.100 R component of concave curvature color (range: 0.0 - 1-0)
% 4 float 0.240 G component of concave curvature color (range: 0.0 - 1-0)
% 4 float 0.320 B component of concave curvature color (range: 0.0 - 1-0)
% 4 float 0.500 Alpha component of concave curvature color (range: 0.0 - 1-0)
% NrOfVertices*4 int  MeshColor, sequence of color indices of all vertices (*1)
% 4 int  N, number of nearest neighbors of vertex 1
% 4 int  Nearest neighbor 1 of vertex 1
% : :  :
% 4 int  Nearest neighbor N of vertex 1
% :: ::  ::
% 4 int  N, number of nearest neighbors of vertex 'NrOfVertices'
% 4 int  Nearest neighbor 1 of vertex 'NrOfVertices'
% : :  :
% 4 int  Nearest neighbor N of vertex 'NrOfVertices'
% NrOfTriangels*3*4 int  Sequence of three indices to constituting vertices of each triangle
% 4 int  NrOfTriangleStripElements
% NrOfStripElements*4 int  Sequence of strip elements (if NrOfStripElements > 0)

fid = fopen(filename, 'rb', 'ieee-le');

srf.version_number                                        = fread(fid, 1, 'float');
srf.reserved                                              = fread(fid, 1, 'int'  );
srf.NrOfVertices                                          = fread(fid, 1, 'int'  );
srf.NrOfTriangles                                         = fread(fid, 1, 'int'  );
NrOfVertices  = srf.NrOfVertices;
NrOfTriangles = srf.NrOfTriangles;
srf.MeshCenterX                                           = fread(fid, 1, 'float');
srf.MeshCenterY                                           = fread(fid, 1, 'float');
srf.MeshCenterZ                                           = fread(fid, 1, 'float');
srf.X_coordinates                                         = fread(fid, NrOfVertices, 'float');
srf.Y_coordinates                                         = fread(fid, NrOfVertices, 'float');
srf.Z_coordinates                                         = fread(fid, NrOfVertices, 'float');
srf.X_components                                          = fread(fid, NrOfVertices, 'float');
srf.Y_components                                          = fread(fid, NrOfVertices, 'float');
srf.Z_components                                          = fread(fid, NrOfVertices, 'float');
srf.R_component_of_convex_curvature_color                 = fread(fid, 1, 'float');
srf.G_component_of_convex_curvature_color                 = fread(fid, 1, 'float');
srf.B_component_of_convex_curvature_color                 = fread(fid, 1, 'float');
srf.Alpha_component_of_convex_curvature_color             = fread(fid, 1, 'float');
srf.R_component_of_concave_curvature_color                = fread(fid, 1, 'float');
srf.G_component_of_concave_curvature_color                = fread(fid, 1, 'float');
srf.B_component_of_concave_curvature_color                = fread(fid, 1, 'float');
srf.Alpha_component_of_concave_curvature_color            = fread(fid, 1, 'float');
srf.MeshColor                                             = fread(fid, NrOfVertices, 'int'  );
for i=1:NrOfVertices
  number           = fread(fid, 1, 'int'  );
  srf.neighbour{i} = fread(fid, number, 'int'  );
end
srf.Triangles                                             = fread(fid, [3 NrOfTriangles], 'int'  );
srf.NrOfTriangleStripElements                             = fread(fid, 1, 'int'  );
srf.sequence_of_strip_elements                            = fread(fid, srf.NrOfTriangleStripElements, 'int'  );

fclose(fid);

pnt = [srf.X_coordinates(:) srf.Y_coordinates(:) srf.Z_coordinates(:)];
tri = srf.Triangles' + 1;


function planC = createStapleStruct(structNumV,probCutoff,structureName,planC)
% function planC = createStapleStruct(structNumV,probCutoff,structureName,planC)
%
% Function to create STAPLE agreement structure at the passed probability
% probCutoff.
%
% APA, 11/13/2017

if ~exist('planC','var')
    global planC
end
indexS = planC{end};

scanNum = getStructureAssociatedScan(structNumV(1),planC);
numObs = length(structNumV);
siz = getUniformScanSize(planC{indexS.scan}(scanNum));
rateMatM = false(prod(siz),numObs);
for i=1:numObs
    mask3M = getUniformStr(structNumV(i),planC);
    rateMatM(:,i) = mask3M(:);
end
indV = sum(rateMatM,2) > 0;
rateMatM = rateMatM(indV,:);

iterlim=100;
senstart=0.9999*ones(1,numObs);
specstart=0.9999*ones(1,numObs);
[stapleV, sen, spec, Sall] = staple(rateMatM,iterlim, single(senstart), single(specstart));

staple3M = zeros(siz);
staple3M(indV) = stapleV;
newStrMask3M = staple3M >= probCutoff;

planC = maskToCERRStructure(newStrMask3M, 1, scanNum, structureName, planC);


function [data] = ft_dipolesimulation(cfg)

% FT_DIPOLESIMULATION simulates channel-level time-series data that consists of the
% the spatial distribution of the the field or potential of one or multiple dipoles.
%
% Use as
%   data = ft_dipolesimulation(cfg)
% which will return a raw data structure that resembles the output of
% FT_PREPROCESSING.
%
% The dipoles position and orientation have to be specified with
%   cfg.sourcemodel.pos        = [Rx Ry Rz] (size Nx3)
%   cfg.sourcemodel.mom        = [Qx Qy Qz] (size 3xN)
%   cfg.sourcemodel.unit       = string, can be 'mm', 'cm', 'm' (default is automatic)
%
% The timecourse of the dipole activity is given as a cell-array with one
% dipole signal per trial
%   cfg.sourcemodel.signal     = cell-array with one dipole signal per trial
% or by specifying the parameters of a sine-wave signal
%   cfg.sourcemodel.frequency  =   in Hz
%   cfg.sourcemodel.phase      =   in radians
%   cfg.sourcemodel.amplitude  =   per dipole
%
% The number of trials and the time axes of the trials can be specified by
%   cfg.fsample     = simulated sample frequency (default = 1000)
%   cfg.trllen      = length of simulated trials in seconds (default = 1)
%   cfg.numtrl      = number of simulated trials (default = 10)
%   cfg.baseline    = number (default = 0.3)
% or by
%   cfg.time        = cell-array with one time axis per trial, for example obtained from an existing dataset
%
% Random white noise can be added to the data in each trial, either by
% specifying an absolute or a relative noise level
%   cfg.relnoise    = add noise with level relative to data signal
%   cfg.absnoise    = add noise with absolute level
%   cfg.randomseed  = 'yes' or a number or vector with the seed value (default = 'yes')
%
% Optional input arguments are
%   cfg.channel    = Nx1 cell-array with selection of channels (default = 'all'),
%                    see FT_CHANNELSELECTION for details
%   cfg.dipoleunit = units for dipole amplitude (default nA*m)
%   cfg.chanunit   = Nx1 cell-array with units for the channel data
%
% Optionally, you can modify the leadfields by reducing the rank, i.e. remove the weakest orientation
%   cfg.reducerank    = 'no', or number (default = 3 for EEG, 2 for MEG)
%   cfg.backproject   = 'yes' or 'no',  determines when reducerank is applied whether the
%                       lower rank leadfield is projected back onto the original linear
%                       subspace, or not (default = 'yes')
%
% The volume conduction model of the head should be specified as
%   cfg.headmodel     = structure with volume conduction model, see FT_PREPARE_HEADMODEL
%
% The EEG or MEG sensor positions should be specified as
%   cfg.elec          = structure with electrode positions or filename, see FT_READ_SENS
%   cfg.grad          = structure with gradiometer definition or filename, see FT_READ_SENS
%
% See also FT_SOURCEANALYSIS, FT_DIPOLEFITTING, FT_TIMELOCKSIMULATION,
% FT_FREQSIMULATION, FT_CONNECTIVITYSIMULATION

% Undocumented local options
% cfg.feedback
% cfg.previous
% cfg.version

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

% these are used by the ft_preamble/ft_postamble function and scripts
ft_revision = '$Id$';
ft_nargin   = nargin;
ft_nargout  = nargout;

% do the general setup of the function
ft_defaults
ft_preamble init
ft_preamble debug
ft_preamble provenance
ft_preamble randomseed

% the ft_abort variable is set to true or false in ft_preamble_init
if ft_abort
  return
end

% check if the input cfg is valid for this function
cfg = ft_checkconfig(cfg, 'forbidden',  {'channels'}); % prevent accidental typos, see issue 1729
cfg = ft_checkconfig(cfg, 'renamed',    {'elecfile', 'elec'});
cfg = ft_checkconfig(cfg, 'renamed',    {'gradfile', 'grad'});
cfg = ft_checkconfig(cfg, 'renamed',    {'optofile', 'opto'});
cfg = ft_checkconfig(cfg, 'renamed',    {'hdmfile', 'headmodel'});
cfg = ft_checkconfig(cfg, 'renamed',    {'vol',     'headmodel'});
cfg = ft_checkconfig(cfg, 'renamed',    {'dip',    'sourcemodel'});

% for consistency with FT_TIMELOCKSIMULUATION and FT_FREQSIMULATION
cfg = ft_checkconfig(cfg, 'createsubcfg', 'sourcemodel');
cfg = ft_checkconfig(cfg, 'renamed', {'ntrials', 'numtrl'});
cfg = ft_checkconfig(cfg, 'renamed', {'triallength', 'trllen'});

% set the defaults
cfg.sourcemodel         = ft_getopt(cfg, 'sourcemodel', []);
cfg.sourcemodel.pos     = ft_getopt(cfg.sourcemodel, 'pos', [-5 0 15]);
cfg.sourcemodel.mom     = ft_getopt(cfg.sourcemodel, 'mom', [1 0 0]');
cfg.sourcemodel.time    = ft_getopt(cfg.sourcemodel, 'time', {});
cfg.sourcemodel.signal  = ft_getopt(cfg.sourcemodel, 'signal', {});
cfg.fsample             = ft_getopt(cfg, 'fsample', 250);
cfg.relnoise            = ft_getopt(cfg, 'relnoise', 0);
cfg.absnoise            = ft_getopt(cfg, 'absnoise', 0);
cfg.feedback            = ft_getopt(cfg, 'feedback', 'text');
cfg.channel             = ft_getopt(cfg, 'channel',  'all');
cfg.dipoleunit          = ft_getopt(cfg, 'dipoleunit', 'nA*m');
cfg.chanunit            = ft_getopt(cfg, 'chanunit', {});

% collect and preprocess the electrodes/gradiometer and head model
% this will also update cfg.channel to match the electrodes/gradiometers
[headmodel, sens, cfg] = prepare_headmodel(cfg, []);

% construct the low-level options for the leadfield computation as key-value pairs, these are passed to FT_COMPUTE_LEADFIELD
leadfieldopt = {};
leadfieldopt = ft_setopt(leadfieldopt, 'reducerank',     ft_getopt(cfg, 'reducerank'));
leadfieldopt = ft_setopt(leadfieldopt, 'backproject',    ft_getopt(cfg, 'backproject'));
leadfieldopt = ft_setopt(leadfieldopt, 'normalize',      ft_getopt(cfg, 'normalize'));
leadfieldopt = ft_setopt(leadfieldopt, 'normalizeparam', ft_getopt(cfg, 'normalizeparam'));
leadfieldopt = ft_setopt(leadfieldopt, 'weight',         ft_getopt(cfg, 'weight'));

cfg.sourcemodel = fixdipole(cfg.sourcemodel);
Ndipoles = size(cfg.sourcemodel.pos,1);

% in case no time or signal was given, set some additional defaults
if ~isempty(cfg.sourcemodel.time) && ~isempty(cfg.sourcemodel.signal)
  assert(length(cfg.sourcemodel.signal)==length(cfg.sourcemodel.time)); % these must match
  cfg.numtrl    = length(cfg.sourcemodel.time);
  cfg.fsample   = 1/mean(diff(cfg.sourcemodel.time{1}));  % determine from time-axis
  cfg.trllen    = length(cfg.sourcemodel.time{1})/cfg.fsample;
  cfg.baseline  = -cfg.sourcemodel.time{1}(1);
elseif ~isempty(cfg.sourcemodel.time)
  cfg.numtrl    = length(cfg.sourcemodel.time);
  cfg.fsample   = 1/mean(diff(cfg.sourcemodel.time{1}));  % determine from time-axis
  cfg.trllen    = length(cfg.sourcemodel.time{1})/cfg.fsample;
  cfg.baseline  = -cfg.sourcemodel.time{1}(1);
elseif ~isempty(cfg.sourcemodel.signal)
  cfg.numtrl    = length(cfg.sourcemodel.signal);
  cfg.fsample   = ft_getopt(cfg, 'fsample', 1000);
  cfg.trllen    = length(cfg.sourcemodel.signal{1})/cfg.fsample;
  cfg.baseline  = ft_getopt(cfg, 'baseline', 0);
else
  cfg.numtrl    = ft_getopt(cfg, 'numtrl', 10);
  cfg.fsample   = ft_getopt(cfg, 'fsample', 1000);
  cfg.trllen    = ft_getopt(cfg, 'trllen', 1);
  cfg.baseline  = ft_getopt(cfg, 'baseline', 0);
end

% no signal was given, set some additional defaults
if isempty(cfg.sourcemodel.signal)
  cfg.sourcemodel.frequency   = ft_getopt(cfg, 'frequency', ones(Ndipoles,1)*10);
  cfg.sourcemodel.phase       = ft_getopt(cfg, 'phase', zeros(Ndipoles,1));
  cfg.sourcemodel.amplitude   = ft_getopt(cfg, 'amplitude', ones(Ndipoles,1));
end

if isfield(cfg.sourcemodel, 'frequency')
  % this should be a column vector
  cfg.sourcemodel.frequency = cfg.sourcemodel.frequency(:);
end

if isfield(cfg.sourcemodel, 'phase')
  % this should be a column vector
  cfg.sourcemodel.phase = cfg.sourcemodel.phase(:);
end

if ~isempty(cfg.sourcemodel.time)
  % use the user-supplied time vectors
  diptime = cfg.sourcemodel.time;
else
  % construct a time axis for every trial
  nsample = round(cfg.trllen*cfg.fsample);
  diptime = cell(1, cfg.numtrl);
  for iTr = 1:cfg.numtrl
    diptime{iTr} = (((1:nsample)-1)/cfg.fsample) - cfg.baseline;
  end
end

if ~isempty(cfg.sourcemodel.signal)
  % use the user-supplied signal for the dipoles
  dipsignal = cfg.sourcemodel.signal;
else
  dipsignal = cell(1, cfg.numtrl);
  for iTr = 1:cfg.numtrl
    % compute a cosine signal with the desired frequency, phase and amplitude for each dipole
    for i=1:Ndipoles
      dipsignal{iTr}(i,:) = cos(cfg.sourcemodel.frequency(i)*diptime{iTr}*2*pi + cfg.sourcemodel.phase(i)) * cfg.sourcemodel.amplitude(i);
    end
  end
end

dippos = cfg.sourcemodel.pos;
dipmom = cfg.sourcemodel.mom;

if ~iscell(dipmom)
  dipmom = {dipmom};
end

if ~iscell(dippos)
  dippos = {dippos};
end

if length(dippos)==1
  dippos = repmat(dippos, 1, cfg.numtrl);
elseif length(dippos)~=cfg.numtrl
  ft_error('incorrect number of trials specified in the dipole position');
end

if length(dipmom)==1
  dipmom = repmat(dipmom, 1, cfg.numtrl);
elseif length(dipmom)~=cfg.numtrl
  ft_error('incorrect number of trials specified in the dipole moment');
end

data.time  = diptime;
data.trial = {};

ft_progress('init', cfg.feedback, 'computing data data');
for trial=1:cfg.numtrl
  ft_progress(trial/cfg.numtrl, 'computing data data for trial %d\n', trial);
  if numel(cfg.chanunit) == numel(cfg.channel)
    lf = ft_compute_leadfield(dippos{trial}, sens, headmodel, 'dipoleunit', cfg.dipoleunit, 'chanunit', cfg.chanunit, leadfieldopt{:});
  else
    lf = ft_compute_leadfield(dippos{trial}, sens, headmodel, leadfieldopt{:});
  end
  nsamples = size(dipsignal{trial},2);
  nchannels = size(lf,1);
  data.trial{trial} = zeros(nchannels,nsamples);
  for i = 1:3
    data.trial{trial} = data.trial{trial} + ...
      lf(:,i:3:end) * (repmat(dipmom{trial}(i:3:end),1,nsamples) .* dipsignal{trial});
  end
end
ft_progress('close');

if ft_senstype(sens, 'meg')
  data.grad = sens;
elseif ft_senstype(sens, 'eeg')
  data.elec = sens;
end

% determine RMS value of data data
ss = 0;
sc = 0;
for trial=1:cfg.numtrl
  ss = ss + sum(data.trial{trial}(:).^2);
  sc = sc + length(data.trial{trial}(:));
end
rms = sqrt(ss/sc);
ft_info('RMS value of data data is %g\n', rms);

% add noise to the data data
for trial=1:cfg.numtrl
  relnoise = randn(size(data.trial{trial})) * cfg.relnoise * rms;
  absnoise = randn(size(data.trial{trial})) * cfg.absnoise;
  data.trial{trial} = data.trial{trial} + relnoise + absnoise;
end

data.fsample = cfg.fsample;
data.label   = sens.label;

% do the general cleanup and bookkeeping at the end of the function
ft_postamble debug
ft_postamble randomseed
ft_postamble provenance data
ft_postamble history    data
ft_postamble savevar    data


%CODEGENERATOR.GENSLBLOCKJACOBIAN Generate Simulink block for robot Jacobians
%
% cGen.genslblockjacobian() generates a robot-specific Simulink block to compute
% robot Jacobians (world and tool frame).
%
% Notes::
% - Is called by CodeGenerator.genjacobian if cGen has active flag genslblock
% - The Simulink blocks are generated and stored in a robot specific block
%   library cGen.slib in the directory cGen.basepath.
%
% Author::
%  Joern Malzahn, (joern.malzahn@tu-dortmund.de)
%
% See also CodeGenerator.CodeGenerator, CodeGenerator.genjacobian.

% Copyright (C) 2012-2014, by Joern Malzahn
%
% This file is part of The Robotics Toolbox for Matlab (RTB).
%
% RTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% RTB is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with RTB.  If not, see <http://www.gnu.org/licenses/>.
%
% http://www.petercorke.com
%
% The code generation module emerged during the work on a project funded by
% the German Research Foundation (DFG, BE1569/7-1). The authors gratefully
% acknowledge the financial support.

function genslblockjacobian(CGen)

%% Open or create block library
bdclose('all')                                                              % avoid problems with previously loaded libraries
load_system('simulink');
if ~(exist([CGen.slibpath,simulinkext]) == 2)                                  % Create new block library if none exists
 CGen.createnewblocklibrary;
end
open_system(CGen.slibpath);
set_param(CGen.slib,'lock','off');

q = CGen.rob.gencoords;
%% Jacobian0
CGen.logmsg([datestr(now),'\tGenerating jacobian Embedded Matlab Function Block with respect to the robot base frame']);
%     [datestr(now),'\tGenerating jacobian Embedded Matlab Function Block with respect to the end-effector frame']);
symname = 'jacob0';
fname = fullfile(CGen.sympath,[symname,'.mat']);

if exist(fname,'file')
    tmpStruct = load(fname);
else
    error ('genSLBlockFkine:SymbolicsNotFound','Save symbolic expressions to disk first!')
end

blockaddress = [CGen.slib,'/',symname];          % treat intermediate transformations separately
if ~isempty(find_system(CGen.slib,'SearchDepth',1,'Name',symname))                    % Delete previously generated block
    delete_block(blockaddress);
    save_system;
end

symexpr2slblock(blockaddress,tmpStruct.(symname),'vars',{q});

CGen.logmsg('\t%s\n',' done!');

%% Jacobe
CGen.logmsg([datestr(now),'\tGenerating jacobian Embedded Matlab Function Block with respect to the end-effector frame']);
symname = 'jacobe';
fname = fullfile(CGen.sympath,[symname,'.mat']);

if exist(fname,'file')
    tmpStruct = load(fname);
else
    error ('genSLBlockFkine:SymbolicsNotFound','Save symbolic expressions to disk first!')
end

blockaddress = [CGen.slib,'/',symname];          % treat intermediate transformations separately
if ~isempty(find_system(CGen.slib,'SearchDepth',1,'Name',symname))                    % Delete previously generated block
    delete_block(blockaddress);
    save_system;
end

symexpr2slblock(blockaddress,tmpStruct.(symname),'vars',{q});
CGen.logmsg('\t%s\n',' done!');

%% Cleanup
% Arrange blocks
distributeblocks(CGen.slib);

% Lock, save and close library
set_param(CGen.slib,'lock','on');
save_system(CGen.slib,CGen.slibpath);
close_system(CGen.slib);

end


function pf = loadPoleFigure_rigaku_txt2(fname,varargin)
% import data fom ana file
%
% Syntax
%   pf = loadPoleFigure_rigaku_txt2(fname)
%
% Input
%  fname  - filename
%
% Output
%  pf - @PoleFigure
%
% See also
% ImportPoleFigureData loadPoleFigure

try

  [data,~,~,~,header] = txt2mat(fname,'infoLevel',0);

  rho = data(:,1);
  step = rho(2)-rho(1);
  header = strsplit(header,'\n');
  id = find(~cellfun(@isempty,strfind(header,'Step')),1);
  step2 = cell2mat(textscan(header{id},'Step %d'));
  assert(step2(1) == step);

  data(:,1:2:end) = [];
  theta = ((size(data,2)-2):-1:0)*step;

  r = regularS2Grid('theta',theta*degree,'rho',rho*degree);

  assert(size(data,1)>5 && size(data,2)>5);

  pf = PoleFigure(string2Miller(fname),r,data(:,2:end),varargin{:});

catch
  interfaceError(fname);
end

end


function evalPCKbackproject(expidxs,bUseHeadSize,bSave,bHeadSizeFromRect)

fprintf('evalPCK()\n');

if (nargin < 2)
    bUseHeadSize = true;
end

if (nargin < 3)
    bSave = true;
end

if (nargin < 4)
    bHeadSizeFromRect = true;
end

if (bUseHeadSize)
    prefix = 'pck-head-';
    range = 0:0.05:0.5;
else
    prefix = 'pck-torso-';
    range = 0:0.02:0.2;
end

fontSize = 18;
figure(100); clf; hold on;
legendName = cell(0);
set(0,'DefaultAxesFontSize', fontSize)
set(0,'DefaultTextFontSize', fontSize)

[~,parts] = util_get_parts24();
nJoints = 14;
jidxsUpperBody = 7:12;

for expidx = expidxs
    fprintf('**********************************************************************************\n');
    % load experiment parameters
    p = rcnn_exp_params(expidx);
    % load ground truth
    [annolist, imgidxs_gt, rectidxs_gt, rect_ignore] = getAnnolist(expidx);
    annolist_gt = annolist(imgidxs_gt);

    fnameDist = [fileparts(p.evalTest) '/distAll'];

    mkdir_if_missing(p.latexDir);
    mkdir_if_missing(p.plotsDir);

    try
        assert(false); % no load
        load(fnameDist,'distAll','accAll','pidxs','keypointsAll');
        assert(exist('keypointsAll','var') && length(pidxs) == length(p.pidxs) && ...
               sum(pidxs ~= p.pidxs) == 0 && size(accAll,2) == nJoints+2);
    catch
        assert(length(p.pidxs) == nJoints);
        % load keypoints
        if (exist([p.evalTest '.mat'],'file')>0)
            fprintf('load %s\n',p.evalTest);
            load([p.evalTest '.mat']);
            assert(exist('keypointsAll','var')>0||exist('bboxAll','var')>0)
        else
            warning('file not found: %s\n',[p.evalTest '.mat']);
            keypointsAll = backprojectKeypointsImg(expidx,1,length(annolist_gt),false);
        end

        distAll = nan(sum(cellfun(@length,rectidxs_gt(imgidxs_gt))),nJoints);
        accAll = zeros(length(range),nJoints+2);

        for i = 1:length(p.pidxs)
            pidx = p.pidxs(i);
            % part is a joint
            assert(parts(pidx+1).pos(1) == parts(pidx+1).pos(2));
            jidx = parts(pidx+1).pos(1);

            % compute distance to the ground truth jidx
            distAll(:,i) = getNormGTJointDistBackproject(keypointsAll,annolist_gt,jidx,bUseHeadSize,rectidxs_gt(imgidxs_gt),bHeadSizeFromRect);
        end

        matchPCK = double(distAll <= range(end));

%         if (isfield(p,'singlePerson') && p.singlePerson)
%             issingle = getSinglePersonImages(annolist_gt);
%             distAll(issingle==0,:) = nan;
%         end
        matchPCK(isnan(distAll)) = nan;

        for i = 1:length(p.pidxs)
            dist = distAll(:,i);
            % remove the cases without the ground truth
            dist(isnan(dist)) = [];
            % compute accuracy for each threshold
            for k = 1:numel(range)
                accAll(k,i) = 100*mean(dist<=range(k));
            end
        end

        % compute avg PCKh upper body
        dist = reshape(distAll(:,jidxsUpperBody),size(distAll,1)*length(jidxsUpperBody),1);
        dist(isnan(dist)) = [];
        for k = 1:numel(range)
            accAll(k,end-1) = 100*mean(dist<=range(k));
        end

        % compute avg PCKh full body
        dist = reshape(distAll,size(distAll,1)*size(distAll,2),1);
        dist(isnan(dist)) = [];
        for k = 1:numel(range)
            accAll(k,end) = 100*mean(dist<=range(k));
        end

        pidxs = p.pidxs;
        try
            save(fnameDist,'distAll','accAll','pidxs','keypointsAll','matchPCK');
        catch
            warning('Unable to save %s\n',fnameDist);
        end
    end

    if (bSave)
        tableFilename = [p.latexDir '/' prefix 'expidx' num2str(expidx) '.tex'];
        [row, header] = genTable(accAll(end,:),p.name);
        fid = fopen(tableFilename,'wt');assert(fid ~= -1);
        fprintf(fid,'%s\n',row{1});fclose(fid);
        fid = fopen([p.latexDir '/' prefix 'header.tex'],'wt');assert(fid ~= -1);
        fprintf(fid,'%s\n',header);fclose(fid);
    end
    auc = area_under_curve(scale01(range),accAll(:,end));
    plot(range,accAll(:,end),'color',p.colorName,'LineStyle','-','LineWidth',3);
    legendName{end+1} = sprintf('%s, AUC: %1.1f%%', p.name, auc);

    fprintf('%s\n',legendName{end});
end

legend(legendName,'Location','NorthWest');
set(gca,'YLim',[0 100]);

xlabel('Normalized distance');
ylabel('Detection rate, %');

if (bSave)
    print(gcf, '-dpng', [p.plotsDir '/' prefix 'expidx' num2str(expidx) '.png']);
    printpdf([p.plotsDir '/' prefix 'expidx' num2str(expidx) '.pdf']);
end

end


classdef PTKThresholdLungFiltered < PTKPlugin
    % PTKThresholdLungFiltered. Plugin to detect airlike voxels using thresholding.
    %
    %     This is a plugin for the Pulmonary Toolkit. Plugins can be run using
    %     the gui, or through the interfaces provided by the Pulmonary Toolkit.
    %     See PTKPlugin.m for more information on how to run plugins.
    %
    %     Plugins should not be run directly from your code.
    %
    %     PTKThresholdLungFiltered uses the library routine PTKThresholdAirway to
    %     detect air-like voxels in the lung. Before thresholding, a Gaussian
    %     filter is applied to the image.
    %
    %
    %     Licence
    %     -------
    %     Part of the TD Pulmonary Toolkit. https://github.com/tomdoel/pulmonarytoolkit
    %     Author: Tom Doel, 2012.  www.tomdoel.com
    %     Distributed under the GNU GPL v3 licence. Please see website for details.
    %

    properties
        ButtonText = 'Lung threshold <br>(filtered)'
        ToolTip = 'Detect air-like voxels in the lung through thresholding'
        Category = 'Lungs'

        AllowResultsToBeCached = true
        AlwaysRunPlugin = false
        PluginType = 'ReplaceOverlay'
        HidePluginInDisplay = false
        FlattenPreviewImage = false
        PTKVersion = '1'
        ButtonWidth = 6
        ButtonHeight = 2
        GeneratePreview = true
        Visibility = 'Developer'
        Version = 2
    end

    methods (Static)
        function threshold_image = RunPlugin(dataset, ~)
            if dataset.IsGasMRI
                lung_roi = dataset.GetResult('PTKInvertImage');
                filtered_image = MimGaussianFilter(lung_roi, 2);
            else
                lung_roi = dataset.GetResult('PTKLungROI');
                filtered_image = MimGaussianFilter(lung_roi, 0.5, true);
            end

            if dataset.IsGasMRI
                mri_lung_threshold = dataset.GetResult('PTKMRILungThreshold');
                limits = mri_lung_threshold.Bounds;
                raw_image = filtered_image.RawImage;
                raw_image = (raw_image >= limits(1) & raw_image <= limits(2));
                threshold_image = lung_roi.BlankCopy;
                threshold_image.ChangeRawImage(raw_image);
                threshold_image.ImageType = PTKImageType.Colormap;
            elseif strcmp(dataset.GetImageInfo.Modality, 'MR')
                mri_lung_threshold = dataset.GetResult('PTKMRILungThreshold');
                limits = mri_lung_threshold.Bounds;
                raw_image = filtered_image.RawImage;
                raw_image = (raw_image >= limits(1) & raw_image <= limits(2));
                threshold_image = lung_roi.BlankCopy;
                threshold_image.ChangeRawImage(raw_image);
                threshold_image.ImageType = PTKImageType.Colormap;
            else
                limit_1 = lung_roi.RescaledToGreyscale(-1024);
                limit_2 = lung_roi.RescaledToGreyscale(-775);
                limit_3 = lung_roi.RescaledToGreyscale(-400);

                % Voxles within the wider filtered threshold are given value 2
                filtered_image = uint8(2*(filtered_image.RawImage >= limit_1 & filtered_image.RawImage <= limit_3));

                % Voxles within the narrow unfiltered threshold are given value 1
                filtered_image(lung_roi.RawImage >= limit_1 & lung_roi.RawImage <= limit_2) = 1;

                threshold_image = lung_roi.BlankCopy;
                threshold_image.ChangeRawImage(filtered_image);

                threshold_image.ImageType = PTKImageType.Colormap;
            end
        end
    end
end


function VARopt = VARoption
%========================================================================
% Optional inputs for VAR analysis. This function is run automatically in
% the VARmodel function.
%========================================================================
% VARopt = VARoption
% =======================================================================
% VAR Toolbox 3.0
% Ambrogio Cesa-Bianchi
% ambrogiocesabianchi@gmail.com
% March 2012. Updated November 2020
% -----------------------------------------------------------------------

VARopt.vnames    = [];      % endogenous variables names
VARopt.vnames_ex = [];      % exogenous variables names
VARopt.snames    = [];      % shocks names
VARopt.nsteps    = 40;      % number of steps for computation of IRFs and FEVDs
VARopt.impact    = 0;       % size of the shock for IRFs: 0=1stdev, 1=unit shock
VARopt.shut      = 0;       % forces the IRF of one variable to zero
VARopt.ident     = 'short'; % identification method for IRFs ('short' zero short-run restr, 'long' zero long-run restr, 'sign' sign restr, 'iv' external instrument)
VARopt.recurs    = 'wold';  % method for computation of recursive stuff ('wold' form MA representation, 'comp' for companion form)
VARopt.ndraws    = 1000;    % number of draws for bootstrap or sign restrictions
VARopt.mult      = 10;      % multiple of draws to be printed at screen.
VARopt.pctg      = 95;      % confidence level for bootstrap
VARopt.method    = 'bs';    % methodology for error bands, 'bs' for standard bootstrap, 'wild' wild bootstrap
VARopt.sr_hor    = 1;       % number of periods that sign restrcitions are imposed on
VARopt.sr_rot    = 500;     % max number of rotations for finding sign restrictions
VARopt.sr_draw   = 100000;  % max number of total draws for finding sign restrictions
VARopt.sr_mod    = 1;       % model uncertainty for sign restrictions (1=yes, 0=no)
VARopt.pick      = 0;       % selects one variable for IRFs and FEVDs plots (0 => plot all)
VARopt.quality   = 1;       % quality of exported figures: 1=high (ghostscript required), 0=low
VARopt.suptitle  = 0;       % title on top of figures
VARopt.datesnum  = [];      % numeric vector of dates in the VAR
VARopt.datestxt  = [];      % cell vector of dates in the VAR
VARopt.datestype = 1;       % 1 smart labels; 2 less smart labels
VARopt.firstdate = [];      % initial date of the sample in format 1999.75 => 1999Q4 (both for annual and quarterly data)
VARopt.frequency = 'q';     % frequency of the data: 'm' monthly, 'q' quarterly, 'y' yearly
VARopt.figname   = [];      % string for name of exported figure
VARopt.FigSize   = [26,24]; % size of window for plots

% In progress
%VARopt.maxvd_N   = 1;       % position of variable to maximize variance decomposition
%VARopt.maxvd_H   = 10;      % horizon over which to maximize variance decomposition
%VARopt.maxvd_rot = 1000;    % max number of rotations for maximization of variance decomposition


function this = MrAffineTransformation_transformation(this)
% Unit test for MrAffineTransformation applying transformations
%
%   Y = MrUnitTest()
%   run(Y, 'MrAffineTransformation_transformation')
%
% This is a method of class MrUnitTest.
%
% IN
%
% OUT
%
% EXAMPLE
%   MrAffineTransformation_transformation
%
%   See also MrUnitTest

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

% construct MrAffineTransformation object from sampling points
affineTransformation = this.make_affineTransformation_reference(0);

% define expected solution
expSolution = affineTransformation.copyobj;

% create transformation matrix
transformationMatrix = [-0.2769 0.6948 0.4387 18.69; ...
    0.0462 -0.3171 0.3816 4.898; ...
    0.0971 0.9502 -0.7655 4.456; ...
    -0.8235 0.0344 0.7952 0.6463];
% apply transformation matrix
affineTransformation.apply_transformation(transformationMatrix);
% verify that affine transformation is applied
if affineTransformation.isequal(expSolution)
    this.assertFail('The transformation matrix has not been applied.');
end
% apply inverse transformation matrix
affineTransformation.apply_inverse_transformation(transformationMatrix);

% define actual solution
actSolution = affineTransformation;

% verify equality of expected and actual solution
% import matlab.unittests to apply tolerances for objects
import matlab.unittest.TestCase
import matlab.unittest.constraints.IsEqualTo
import matlab.unittest.constraints.AbsoluteTolerance
import matlab.unittest.constraints.PublicPropertyComparator

this.verifyThat(actSolution, IsEqualTo(expSolution,...
    'Within', AbsoluteTolerance(10e-7),...
    'Using', PublicPropertyComparator.supportingAllValues));


function z = sparse( i, j, x, m, n )

%   Disciplined convex/geometric programming information for SPARSE:
%       For a CVX variable X, SPARSE(X) just returns X. In the three-
%       and five-argument versions SPARSE(I,J,V,M,N), the index
%       arguments I and J and size arguments M and N must be constant.
%       If any of the index pairs (I(k),J(k)) are repeated, then the
%       corresponding elements V(k) will be added together. Therefore,
%       those elements must be compatible with addition; i.e., they
%       must have the same curvature.

switch nargin,
	case 1,
		z = i;
		return
	case {2,4}
		cvx_throw( 'Not enough arguments.' );
end

%
% Check sizes and indices
%

if ( ~isnumeric( i ) && ~ischar( i ) ) || ( ~isnumeric( j ) && ~ischar( j ) ),
    cvx_throw( 'The first two arguments must be numeric.' );
end
nn = [ numel( i ), numel( j ), prod( x.size_ ) ];
nz = max( nn );
if any( nn(nn~=nz) ~= 1 ),
    cvx_throw( 'Vectors must be the same lengths.' );
end
i = i( : ); j = j( : );
if nargin == 3,
    m = max( i );
    n = max( j );
elseif ( ~isnumeric( m ) && ~ischar( m ) ) || ( ~isnumeric( n ) && ~ischar( n ) ) || n < 0 || m < 0 || n ~= floor( n ) || m ~= floor( m ),
    cvx_throw( 'Sparse matrix sizes must be positive integers.' );
elseif any( i > m ) || any( j > n ),
    cvx_throw( 'Index exceeds matrix dimensions.' );
end

%
% Reconstruct basis matrices and indices
%

[ ix, jx, vx ] = find( x.basis_ );
ij = i + m * ( j - 1 );
if length(ij) > 1,
    ij = ij(jx);
end
xb = sparse( ix, ij, vx, max(ix), m * n );
z = cvx( [ m, n ], xb );

%
% Verify vexity is preserved
%

if ~cvx_isvalid(z),
    cvx_throw( 'Disciplined convex programming error:\n    Sparse matrix construction produced invalid sums of convex and concave terms.' );
end

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


function score = grade(board,goal,solutionVector)
modSolutionVector = validateSolutionVector(solutionVector,board);
boardToScore = runSolutionVector(modSolutionVector, board, goal, false);
score = sum(boardToScore(:)) + sum(modSolutionVector);


function predicted=cosmo_classify_libsvm(samples_train, targets_train, samples_test, opt)
% libsvm-based SVM classifier
%
% predicted=cosmo_classify_libsvm(samples_train, targets_train, samples_test, opt)
%
% Inputs
%   samples_train      PxR training data for P samples and R features
%   targets_train      Px1 training data classes
%   samples_test       QxR test data
%   opt                (optional) struct with options for svmtrain
%     .autoscale       If true (default), z-scoring is done on the training
%                      set; the test set is z-scored using the mean and std
%                      estimates from the training set.
%     ?                any option supported by libsvm's svmtrain.
%
% Output
%   predicted          Qx1 predicted data classes for samples_test
%
% Notes:
%  - this function requires libsvm version 3.18 or later:
%    https://github.com/cjlin1/libsvm
%  - by default a linear kernel is used ('-t 0')
%  - this function uses LIBSVM's svmtrain function, which has the same
%    name as matlab's builtin version. Use of this function is not
%    supported when matlab's svmtrain precedes in the matlab path; in
%    that case, adjust the path or use cosmo_classify_matlabsvm instead.
%  - for a guide on svm classification, see
%      http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf
%  - By default this function performs z-scoring of the data. To switch
%    this off, set 'autoscale' to false
%  - cosmo_crossvalidate and cosmo_crossvalidation_measure
%    provide an option 'normalization' to perform data scaling
%
%
% See also svmtrain, svmclassify, cosmo_classify_svm,
%          cosmo_classify_matlabsvm
%
% #   For CoSMoMVPA's copyright information and license terms,   #
% #   see the COPYING file distributed with CoSMoMVPA.           #

    if nargin<4
        opt=struct();
    end

    % support repeated testing on different data after training every time
    % on the same data. This is achieved by caching the training data
    % and associated model
    persistent cached_targets_train;
    persistent cached_samples_train;
    persistent cached_opt;
    persistent cached_model;

    cache_limit=1e5; % avoid caching huge training sets

    if isequal(cached_targets_train, targets_train) && ...
            isequal(cached_opt, opt) && ...
            numel(samples_train) < cache_limit && ...
            isequal(cached_samples_train, samples_train)
        % use cache
        model=cached_model;
    else
        model=train(samples_train,targets_train,opt);

                % store model
        cached_targets_train=targets_train;
        cached_samples_train=samples_train;
        cached_opt=opt;
        cached_model=model;
    end

    predicted=test(model, samples_test);

function model=train(samples_train,targets_train,opt)
    [ntrain, nfeatures]=size(samples_train);

    model=struct();
    model.nfeatures=nfeatures;
    model.normalize=[]; % off by default

    % check input size
    ntrain_=numel(targets_train);
    if ntrain_~=ntrain
        error('illegal input size');
    end

    % construct options string for svmtrain
    opt_str=libsvm_opt2str(opt);

    % auto-scale is the default
    autoscale= ~isstruct(opt) || ...
                ~isfield(opt,'autoscale') || ...
                isempty(opt.autoscale) || ...
                opt.autoscale;

    % perform autoscale if necessary
    if autoscale
        [samples_train, params]=cosmo_normalize(samples_train, ...
                                                    'zscore', 1);
        model.normalize=params;
    end
    train_func=@()svmtrain(targets_train(:), ...
                            samples_train, ...
                            opt_str);

    model.libsvm_model=eval_with_check_external(train_func);

function output=eval_with_check_external(func)
% Evaluates func() in try-catch block. If it fails, this may be due
% to missing libsvm and/or libsvm conflicting with Matlab's svm.
% Therefore first cosmo_check_external is called, which will give an
% informative error message if that is the case. Otherwise the original
% message is shown.

    try
        output=func();
    catch
        cosmo_check_external('libsvm');
        rethrow(lasterror());
    end

function predicted=test(model, samples_test)
    [ntest, nfeatures]=size(samples_test);
    if nfeatures~=model.nfeatures
        error(['Number of features in train set (%d) and '...
                    'test set (%d) do not match'],...
                    model.nfeatures,nfeatures);
    end

    if ~isempty(model.normalize)
        samples_test=cosmo_normalize(samples_test, model.normalize);
    end

    test_opt_str='-q'; % quiet (no output)
    test_func=@()svmpredict(NaN(ntest,1), samples_test, ...
                            model.libsvm_model, test_opt_str);
    predicted=eval_with_check_external(test_func);

function opt_str=libsvm_opt2str(opt)
    persistent cached_opt
    persistent cached_opt_str

    if ~isequal(opt, cached_opt)
        default_opt={'t','q';...
                        '0',''};
        n_default=size(default_opt,2);

        libsvm_opt_keys={'s','t','d','g','r','c','n','p',...
                         'm','e','h','n','wi','v'};
        opt_struct=cosmo_structjoin(opt);

        keys=intersect(fieldnames(opt_struct),libsvm_opt_keys);
        n_keys=numel(keys);

        use_defaults=true(1,n_default);

        libsvm_opt=cell(2,n_keys);
        for k=1:n_keys
            key=keys{k};
            default_pos=find(cosmo_match(default_opt(1,:),(key)),1);

            if ~isempty(default_pos)
                use_defaults(default_pos)=false;
            end

            value=opt_struct.(key);
            if isnumeric(value)
                value=sprintf('%d',value);
            end

            libsvm_opt(:,k)={key;value};
        end

        all_opt=[libsvm_opt default_opt(:, use_defaults)];

        cached_opt_str=sprintf('-%s %s ', all_opt{:});
        cached_opt=opt;
    end

    opt_str=cached_opt_str;


function test_issue2075

% WALLTIME 00:10:00
% MEM 4gb
% DEPENDENCY nanmean

% A user reported an issue related to nanmean, using MATLAB 2022a.
% Operating system unknown. This script tries to reproduce it. On our end,
% running on Linux we cannot reproduce an error (the exact error is as of
% yet still underspecified). The purpose of this function is to document
% it, being aware that the test functions are not necessarily executed in
% their automatic overnight batch in the reported matlab version

[ftver, ftpath] = ft_version;

global ft_default
ft_default.toolbox.signal = 'compat';
ft_default.toolbox.stats= 'compat';
restoredefaultpath;
addpath(ftpath);
ft_defaults;
ft_preproc_bandpassfilter(randn(1,1000), 1000, [230 0.5], [], 'fir');
which nanmean

ft_default.toolbox.signal = 'matlab'; % rather than compat
ft_default.toolbox.stats= 'matlab';
restoredefaultpath;
addpath(ftpath);
ft_defaults;
ft_preproc_bandpassfilter(randn(1,1000), 1000, [230 0.5], [], 'fir');
which nanmean


function [doseBinsV, volsHistV] = loadIVHMatrix(IVHNum, planC)
%"loadIVHMatrix"
%   Return the doseBinsV and volsHistV with the binWidth shift included.
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
% CERR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
% without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% See the GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with CERR.  If not, see <http://www.gnu.org/licenses/>.
%
%Usage:
%   function [doseBinsV, volsHistV] = loadIVHMatrix(IVHNum, planC)

indexS = planC{end};

%Calculate width of bins, use to find middle of each bin.
binWidthsV = diff(planC{indexS.IVH}(IVHNum).IVHMatrix(:,1));
lastBinWidth = binWidthsV(end);
binWidthsV(end+1,1) = lastBinWidth;

%Extract dose bin values, adding half to binwidth to get middle.
doseBinsV = planC{indexS.IVH}(IVHNum).IVHMatrix(:,1) + binWidthsV/2;
volsHistV = planC{indexS.IVH}(IVHNum).IVHMatrix(:,2);
return;


function varargout = plot(v,varargin)
% plot vectors as two dimensional projections on the sphere
%
% Syntax
%   plot(v)
%   plot(v,value)
%   plot(v,rgb)
%   plot(v,'MarkerSize',10)
%   plot(v,'contourf')
%   plot(v,'contour')
%
% Input
%   v - @vector3d
%   value - values to be displayed
%   rgb -
%
% Options
%  Marker           - 'square', 'triangle', 'o','diamond'
%  MarkerSize       -
%  MarkerFaceColor  -
%  MarkerEdgeColor  -
%
% Flags
%  smooth   - plot point cloud as colored density
%  contourf - plot point cloud as filled contours
%  contour  - plot point cloud as contours
%

% maybe we should add this do all subplots
if check_option(varargin,'add2all')
  mtexFig = gcm;
  if isempty(gcm)
    ax = gca;
  else
    ax = mtexFig.children;
  end
  ax = get_option(varargin,'parent',ax);
  varargin = delete_option(varargin,'parent',1);
  varargin = delete_option(varargin,'add2all');

  h = [];
  for i = 1:length(ax)
    h = [h,plot(v,varargin{:},'parent',ax(i),'doNotDraw')]; %#ok<AGROW>
  end

  if nargout >=1, varargout{1} = h; end
  if nargout >=2, varargout{2} = ax; end

  return
end

% extract plot type
plotTypes = {'contour','contourf','smooth','scatter','text','quiver',...
  'line','plane','circle','surf','pcolor','custom','3d','scatter3d'};
plotType = get_flag(varargin,plotTypes);

% default plot type
if isempty(plotType)
  if isOption(v,'plot') && v.opt.plot

    if ~isempty(varargin) && isnumeric(varargin{1}) && all(size(varargin{1}) == [length(v),3])
      plotType = 'surf';
    else
      plotType = 'smooth';
    end

  else
    plotType = 'scatter';
  end
end
varargin = delete_option(varargin,plotTypes(3:end));

% if data is vector3d type is quiver
if ~isempty(varargin) && isa(varargin{1},'vector3d')
  plotType = 'quiver';
end

if any(strcmpi(plotType,{'smooth','contourf','contour','pcolor'}))
  varargin = ensureData(varargin);
end

% call plotting routine according to type
switch lower(plotType)

  case '3d'
    if v.isOption('plot')
      [varargout{1:nargout}] = v.plot3d(varargin{:});
    else
      [varargout{1:nargout}] = v.scatter3d(varargin{:});
    end

  case 'scatter3d'

    [varargout{1:nargout}] = v.plot3d(varargin{:});

  case 'scatter'

    [varargout{1:nargout}] = v.scatter(varargin{:});

  case 'smooth'

    [varargout{1:nargout}] = v.smooth(varargin{:});

  case 'surf'

    [varargout{1:nargout}] = v.surf(varargin{:});

  case 'contourf'

    [varargout{1:nargout}] = v.contourf(varargin{:});

  case 'contour'

    [varargout{1:nargout}] = v.contour(varargin{:});

  case 'pcolor'

    [varargout{1:nargout}] = v.pcolor(varargin{:});

  case 'quiver'

    [varargout{1:nargout}] = v.quiver(varargin{:});

  case 'line'

    [varargout{1:nargout}] = v.line(varargin{:});

  case 'circle'

    [varargout{1:nargout}] = v.circle(varargin{:});

  case 'plane'

    [varargout{1:nargout}] = v.circle(90*degree,varargin{:});

  case 'text'

    [varargout{1:nargout}] = v.text(varargin{:});

  case 'custom'

    [varargout{1:nargout}] = v.plotCustom(varargin{:});

end
end

function v = ensureData(v)
  if ~isempty(v) && ~(islogical(v{1}) ||  isnumeric(v{1}))
    v = [{[]},v];
  end
end


Ts_INS = 1/150;
fprintf('Sample time set: Ts_INS = %f seconds\n',Ts_INS);


function checkxy_N(x, y, function_name, x_var_name, y_var_name, x_pos, y_pos)
%CHECKXY_N Check validity of map x and y vectors
%
%   CHECKXY(X, Y, FUNCTION_NAME, X_VAR_NAME, Y_VAR_NAME, X_POS, X_POS)
%   ensures that X and Y are real vectors of matching size and equal NaN
%   locations.

% Copyright 2006-2011 The MathWorks, Inc.
% $Revision: 1.1.6.3 $  $Date: 2011/05/17 02:12:40 $

% Input arguments are not checked for validity.

if ~isempty(x) || ~isempty(y)
    % Check numeric, 2d, and real.
    validateattributes(x, ...
        {'numeric'}, {'real','2d','vector'}, function_name, x_var_name, x_pos);
    validateattributes(y, ...
        {'numeric'}, {'real','2d','vector'}, function_name, y_var_name, y_pos);

    if ~isequal(isnan(x), isnan(y))
        error(sprintf('map:%s:inconsistentXY', function_name), ...
            'Function %s expected its %s and %s input arguments, %s and %s, to match in size or NaN locations.', ...
            upper(function_name), num2ordinal(x_pos), num2ordinal(y_pos), ...
            x_var_name, y_var_name)
    end
end