%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Copyright 2014 National Renewable Energy Laboratory and National
% Technology & Engineering Solutions of Sandia, LLC (NTESS).
% Under the terms of Contract DE-NA0003525 with NTESS,
% the U.S. Government retains certain rights in this software.
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

classdef constraintClass<handle
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % The ``constraintClass`` creates a ``constraint`` object saved to the MATLAB
    % workspace. The ``constraintClass`` includes properties and methods used
    % to define constraints between the body motion relative to the global reference
    % frame or relative to other bodies.
    %
    %.. autoattribute:: objects.constraintClass.constraintClass
    %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    properties (SetAccess = 'public', GetAccess = 'public') %input file
        hardStops                   = struct(...                    % (`structure`) Defines the constraint hardstop
          'upperLimitSpecify',          'off',...                   % (`string`) Initialize upper stroke limit. ``  'on' or 'off' `` Default = ``off``.
          'upperLimitBound',            1, ...                      % (`float`) Define upper stroke limit in m or deg. Only active if `lowerLimitSpecify` is `on` `` Default = ``1``.
          'upperLimitStiffness',        1e6, ...                    % (`float`) Define upper limit spring stiffness, N/m or N-m/deg. `` Default = ``1e6``.
          'upperLimitDamping',          1e3, ...                    % (`float`) Define upper limit damping, N/m/s or N-m/deg/s.  `` Default = ``1e3``.
          'upperLimitTransitionRegionWidth', 1e-4, ...              % (`float`) Define upper limit transition region, over which spring and damping values ramp up to full values. Increase for stability. m or deg. ``Default = 1e-4``
          'lowerLimitSpecify',          'off',...                   % Initialize lower stroke limit. ``  `on` or `off` `` Default = ``off``.
          'lowerLimitBound',            -1, ...                     % (`float`) Define lower stroke limit in m or deg. Only active if `lowerLimitSpecify` is `on` ``   `` Default = ``-1``.
          'lowerLimitStiffness',        1e6, ...                    % (`float`) Define lower limit spring stiffness, N/m or N-m/deg.  `` Default = ``1e6``.
          'lowerLimitDamping',          1e3, ...                    % (`float`) Define lower limit damping, N/m/s or N-m/deg/s.  `` Default = ``1e3``.
          'lowerLimitTransitionRegionWidth', 1e-4)                  % (`float`) Define lower limit transition region, over which spring and damping values ramp up to full values. Increase for stability. m or deg. ``Default = 1e-4``
        initial                     = struct(...                    %
            'displacement',             [0 0 0])                    % (`structure`) Defines the initial displacement of the constraint. ``displacement`` (`3x1 float vector`) is defined as the initial displacement of the constraint [m] in the following format [x y z], Default = [``0 0 0``].
        name                        = 'NOT DEFINED'                 % (`string`) Specifies the constraint name. For constraints this is defined by the user, Default = ``NOT DEFINED``.
        location                    = [999 999 999]                 % (`3x1 float vector`) Constraint location [m]. Defined in the following format [x y z]. Default = ``[999 999 999]``.
        orientation                 = struct(...                    % (`structure`) Defines the orientation axis of the constraint.
            'z',                        [0, 0, 1], ...              %
            'y',                        [0, 1, 0], ...              %
            'x',                        [], ...                     %
            'rotationMatrix',           [])                         % (`structure`) Defines the orientation axis of the constraint. ``z`` (`3x1 float vector`) defines the direciton of the Z-coordinate of the constraint, Default = [``0 0 1``]. ``y`` (`3x1 float vector`) defines the direciton of the Y-coordinate of the constraint, Default = [``0 1 0``]. ``x`` (`3x1 float vector`) internally calculated vector defining the direction of the X-coordinate for the constraint, Default = ``[]``. ``rotationMatrix`` (`3x3 float matrix`) internally calculated rotation matrix to go from standard coordinate orientation to the constraint coordinate orientation, Default = ``[]``.
    end

    properties (SetAccess = 'private', GetAccess = 'public') %internal
        number                      = []                            % Constraint number
    end

    methods (Access = 'public')
        function obj = constraintClass(name)
            % This method initilizes the ``constraintClass`` and creates a
            % ``constraint`` object.
            %
            % Parameters
            % ------------
            %     filename : string
            %         String specifying the name of the constraint
            %
            % Returns
            % ------------
            %     constraint : obj
            %         contraintClass object
            %
            if exist('name','var')
                obj.name = name;
            else
                error('The constraint class number(s) in the wecSimInputFile must be specified in ascending order starting from 1. The constraintClass() function should be called first to initialize each constraint with a name.')
            end
        end

        function obj = checkLoc(obj,action)
            % This method checks WEC-Sim user inputs and generate an error message if the constraint location is not defined in constraintClass.

            % Checks if location is set and outputs a warning or error. Used in mask Initialization.
            switch action
              case 'W'
                if obj.location == 999 % Because "Allow library block to modify its content" is selected in block's mask initialization, this command runs twice, but warnings cannot be displayed during the first initialization.
                    obj.location = [888 888 888];
                elseif obj.location == 888
                    obj.location = [0 0 0];
                    s1= ['For ' obj.name ': constraint.location was changed from [9999 9999 9999] to [0 0 0]'];
                    warning(s1)
                end
              case 'E'
                try
                    if obj.location == 999
                      s1 = ['For ' obj.name ': constraint.location needs to be specified in the WEC-Sim input file.' ...
                        ' constraint.location is the [x y z] location, in meters, for the pitch constraint.'];
                      error(s1)
                    end
                catch exception
                  throwAsCaller(exception)
                end
            end
        end

        function obj = setOrientation(obj)
            % This method calculates the constraint ``x`` vector and ``rotationMatrix`` matrix in the ``orientation`` structure based on user input.
            obj.orientation.z = obj.orientation.z / norm(obj.orientation.z);
            obj.orientation.y = obj.orientation.y / norm(obj.orientation.y);
            z = obj.orientation.z;
            y = obj.orientation.y;
            if abs(dot(y,z))>0.001
                error('The Y and Z vectors defining the constraint''s orientation must be orthogonal.')
            end
            x = cross(y,z)/norm(cross(y,z));
            x = x(:)';
            obj.orientation.x = x;
            obj.orientation.rotationMatrix  = [x',y',z'];
        end

        function setInitDisp(obj, relCoord, axisAngleList, addLinDisp)
            % Function to set a constraints's initial displacement
            %
            % This function assumes that all rotations are about the same relative coordinate.
            % If not, the user should input a relative coordinate of 0,0,0 and
            % use the additional linear displacement parameter to set the cg or location
            % correctly.
            %
            % Parameters
            % ------------
            %    relCoord : [1 3] float vector
            %        Distance from x_rot to the body center of gravity or the constraint
            %        or pto location as defined by: relCoord = cg - x_rot. [m]
            %
            %    axisAngleList : [nAngle 4] float vector
            %        List of axes and angles of the rotations with the
            %        format: [n_x n_y n_z angle] (angle in rad)
            %        Rotations applied consecutively in order of dimension 1
            %
            %    addLinDisp : [1 3] float vector
            %        Initial linear displacement (in addition to the
            %        displacement caused by rotation) [m]
            %

            % initialize quantities before for loop
            axisList = axisAngleList(:,1:3);
            angleList = axisAngleList(:,4);
            nAngle = size(axisList,1);
            rotMat = eye(3);

            % Loop through all axes and angles.
            for i=1:nAngle
                rotMat = axisAngle2RotMat(axisList(i,:),angleList(i))*rotMat;
            end

            % calculate net axis-angle rotation
%             [netAxis, netAngle] = rotMat2AxisAngle(rotMat);

            % calculate net displacement due to rotation
            rotatedRelCoord = relCoord*(rotMat');
            linDisp = rotatedRelCoord - relCoord;

            % apply rotation and displacement to object
            obj.initial.displacement = linDisp + addLinDisp;

        end

        function listInfo(obj)
            % This method prints constraint information to the MATLAB Command Window.
            fprintf('\n\t***** Constraint Name: %s *****\n',obj.name)
        end

        function setNumber(obj,number)
            % Method to set the private number property
            obj.number = number;
        end
    end
end


%     NeuroSLAM System Copyright (C) 2018-2019
%     NeuroSLAM: A Brain inspired SLAM System for 3D Environments
%
%     Fangwen Yu (www.yufangwen.com), Jianga Shang, Youjian Hu, Michael Milford(www.michaelmilford.com)
%
%     The NeuroSLAM V1.0 (MATLAB) was developed based on the OpenRatSLAM (David et al. 2013).
%     The RatSLAM V0.3 (MATLAB) developed by David Ball, Michael Milford and Gordon Wyeth in 2008.
%
%     Reference:
%     Ball, David, Scott Heath, Janet Wiles, Gordon Wyeth, Peter Corke, and Michael Milford.
%     "OpenRatSLAM: an open source brain-based SLAM system." Autonomous Robots 34, no. 3 (2013): 149-176.
%
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
%
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <http://www.gnu.org/licenses/>.

% Jan 2, 2019
groundTruthFile = 'C:\NeuroSLAM_Datasets\02_NeuroSLAM_Groudtruth\02_SynPanData_GT.txt';
expMapFile = 'C:\NeuroSLAM_Datasets\03_NeuroSLAM_Experiments_Results\SynPanData\01_exp_map_ml.txt';
% plot_3d_multilayer_experience_map(groundTruthFile, expMapFile, xExpMapScaling, yExpMapScaling, zExpMapScaling, xExpMapTrans, yExpMapTrans, zExpMapTrans, xGtScaling, yGtScaling, zGtScaling)
plot_3d_multilayer_experience_map(groundTruthFile, expMapFile, 0.3, -0.35, 0.213, 0.5, 0, 0, 20,20,20);


function [resRates] = ma_getResRates(massLoss)
%getResRates Summary of this function goes here
%   Detailed explanation goes here
    maxNumRes = max(horzcat(massLoss.lossConvert.resLost, massLoss.lossConvert.resConvert));
    resRates = zeros(1,maxNumRes);

    for(i=1:length(massLoss.lossConvert)) %#ok<*NO4LP>
        lossConvert = massLoss.lossConvert(i);
        resRates(lossConvert.resLost) = resRates(lossConvert.resLost) - lossConvert.resLostRates(lossConvert.resLost);

        sumRates = sum(lossConvert.resLostRates);
        resRates(lossConvert.resConvert) = resRates(lossConvert.resConvert) + sumRates*lossConvert.resConvertPercent(lossConvert.resConvert);
    end
end


function w = fix_data_length(w, maxlen)
   %FIX_DATA_LENGTH adjust length of waveform data to allow batch processing
   %   waveform = fix_data_length(waveform)
   %       adjusts all waveforms to the length of the largest, while
   %       zero-padding all shorter waveforms
   %
   %   waveform = fix_data_length(waveform, maxlength)
   %       sets all waveform lengths to maxlength.  This use of the function
   %       has been superceeded by set(waveform,'samplelength',maxlength);
   %
   %  examples
   %       % let inWaves be a 1x2 waveform object
   %       % 3000 samples in inWaves(1)
   %       % 10025 samples in inWaves(2)
   %
   %       % set both waves' data to a length of to 10025 while padding the
   %       % smaller of the two with zeroes.
   %       outWaveforms = fix_data_length(inWaves)
   %
   %       % set both sample lengths to 500 truncating both of them...
   %       outWaveform = fix_data_length(inWaves, 500)
   %
   %       %The above example is nearly the same as
   %       outWaveform = set(inWaves,'sample_length',500)
   %
   %       Behaviorally, this differs from the set command because it
   %       automatically determines the maximum desired length, when not
   %       specified.
   %
   %
   % See also WAVEFORM/EXTRACT, WAVEFORM/DOUBLE, WAVEFORM/SET -- Sample_Length

   % AUTHOR: Celso Reyes, Geophysical Institute, Univ. of Alaska Fairbanks
   % $Date$
   % $Revision$

   % Note: Glenn Thompson 2016 - this function could be simplified by using
   % waveform/get_time_range and waveform/pad
   Wcount = numel(w);

   if ~exist('maxlen','var')
      m(Wcount) = 0;
      for j = Wcount : -1 : 1
         m(j) = numel(w(j).data);
      end
      maxlen = max(m);
   end

   if length(maxlen) == 2
      st = maxlen(1);
      ed = maxlen(2);
   else
      st = 1;
      ed = maxlen(end);
   end

   for j = 1 : Wcount
      D = w(j).data;
      if ed > numel(D)
         D(ed) = 0;
      else
         D = D(st:ed);
      end
      w(j) = set(w(j),'data',D);
   end;
end


function varargout = pm_restore_ramp(varargin)
%
% Restores linear phase-ramps in the x-, y- and z-direction
% that has previously been removed from pm by pm_estimate_ramp.
% FORMAT: pm = pm_estimate_ramp(pm,mask,ramps)
%
% Input:
% pm     : 2 or 3D phasemap that has been unwrapped and
%          that has had its ramps removed by pm_remove_ramp
% mask   : Mask that indicates which voxels are worth
%          bothering with and which are not.
% ramps  : 3x1 vector signifying the slope of the ramps in
%          the x-, y- and z-directions. This SHOULD be the
%          values returned by a previous call to pm_estimate_ramp.
%
% Output:
% pm     : Same as pm in, but with linear ramps restored.
%
% This routine was written on the suggestion of Mark J, and will
% potentially improve performance of subsequent phase-unwrapping.
% I haven't actually found it particularly helpful, and it may
% simply have been a sneaky fMRIB attempt to delay the SPM
% phasemap toolbox.
%__________________________________________________________________
% Jesper Andersson 30/9-03
%_______________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

% Jesper Andersson
% $Id: pm_restore_ramp.m 1317 2008-04-08 16:16:38Z chloe $

error('mex-function pm_restore_ramp.c not compiled');


function getdepthRefined_structureIO(id)
%cd /n/fs/sun3d/code/SiftFuv2StructureIO
%/n/fs/vision/ionicNew/starter.sh getdepthRefined_structureIO 20000mb 120:00:00 1 300 1 /n/fs/modelnet/log/

basicSetup;
interval =20;
OuputPath = '/n/fs/sun3d/data/SUNRGBDv2/';
webtemplate = 'https://sun3d.cs.princeton.edu/player/?name=SUNRGBDv2/%s/&box3D=true&write=true&annotation=annotation3Dfinal&width=640&height=480&R=true&&highlight=false&rect=only';
%directory ='/net/pvd00/p/sunrgbd/mingrub/data_capture/11082015/single_image/2015-11-08T15.25.26.491/';
directory ='/Users/shurans/Downloads/2015-11-08T15.25.26.491/';
load(fullfile(directory,'metadata.mat'))
frameIDtarget = metadata.main_Id;
filename = metadata.main_frame(1:end-4);
folder = [fullfile(OuputPath,filename) '/'];
%% get web page link
webpagelink = sprintf(webtemplate,filename);
display(webpagelink)

if ~metadata.bad
    %% refine the depth
    [depthRefined, image] = SiftFuv2warpFast(directory,frameIDtarget, interval);

    %% put it into folder
    mkdir([folder 'annotation/']);
    mkdir([folder 'annotation3D/']);
    system(sprintf('chmod -R 777 %sannotation/',folder));
    system(sprintf('chmod -R 777 %sannotation3D/',folder));
    mkdir([folder 'depth/']);
    mkdir([folder 'extrinsics/']);
    mkdir([folder 'image/']);
    depth = uint16(depthRefined*1000);
    depth = bitor(bitshift(depth,3), bitshift(depth,-13));
    imwrite(depth,sprintf('%s/depth/%s.png',folder,filename));
    imwrite(image,sprintf('%s/image/%s.jpg',folder,filename));

    data = loadStructureIOdata(directory,[]);
    fid = fopen([folder 'intrinsics.txt'],'w');
    K = data.K';
    fprintf(fid,'%f %f %f\n%f %f %f\n%f %f %f\n',K(1),K(2),K(3),K(4),K(5),K(6),K(7),K(8),K(9));
    fclose(fid);
    %% get extrinsics

    depth = depthRefined;
    [x,y] = meshgrid(1:size(depth,2), 1:size(depth,1));
    XYZcamera(:,:,1) = (x-data.K(1,3)).*depth/data.K(1,1);
    XYZcamera(:,:,2) = (y-data.K(2,3)).*depth/data.K(2,2);
    XYZcamera(:,:,3) = depth;
    XYZcamera(repmat(depth==0,[1,1,3])) = NaN;
    X = XYZcamera(:,:,1);Y = XYZcamera(:,:,3);Z = -XYZcamera(:,:,2);

    [Rtilt,R] = rectify(cat(3,X,Y,Z));
    cameraRt =[eye(3) zeros(3,1)];
    cameraRt(1:3,1:3) =[1 0 0; 0 0 -1 ;0 1 0]*Rtilt*[1 0 0; 0 0 -1 ;0 1 0]';
    timeStamp = clock;
    timeStamp = sprintf('%.4d%.2d%.2d%.2d%.2d%.2d',timeStamp(1),timeStamp(2),timeStamp(3),timeStamp(4),timeStamp(5),round(timeStamp(6)));
    delete([folder '/extrinsics/*.txt'])
    fp = fopen([folder '/extrinsics/' timeStamp '.txt'],'w');
    for rowID=1:size(cameraRt,1)
        fprintf(fp, '%f %f %f %f\n',cameraRt(rowID,:));
    end

    system(sprintf('chmod -R 775 %s',folder));

end

%%
%{
if 0
    rgb = [reshape(image(:,:,1),[],1),reshape(image(:,:,2),[],1),reshape(image(:,:,3),[],1)];
    figure,
    XYZnew = Rtilt*[X(:),Y(:),Z(:)]';
    vis_point_cloud(XYZnew',double(rgb),40,4000);
end
points2ply('refined.ply', [X(:),Y(:),Z(:)], rgb)
%}
end


function x=othertriangle(y);

if y(1,1)==1;
    warning('doesnt work for DIS matrices');
end

x=y*0;
if ndims(y)==2;
    x=y+rot90(flipud(triu(y)),3);
end

if ndims(y)==3;
    for n=1:size(y,3);
        y1=y(:,:,n);
        x(:,:,n)=y1+rot90(flipud(triu(y1)),3);
    end
end

if ndims(y)==4;
    for n=1:size(y,3);
        for n1=1:size(y,4);
            y1=y(:,:,n,n1);
            x(:,:,n,n1)=y1+rot90(flipud(triu(y1)),3);
        end
    end
end


function acq = acqf_vbmc(Xs,vp,gp,optimState,fmu,fs2,fbar,vtot)
%ACQF_VBMC Acquisition fcn. for prospective uncertainty search.

% Xs is in *transformed* coordinates

% Probability density of variational posterior at test points
p = max(vbmc_pdf(vp,Xs,0),realmin);

% Prospective uncertainty search
z = optimState.ymax;
acq = -vtot .* exp(fbar-z) .* p;

end


function [K, P] = biasVardistPsi1Compute(biaskern, vardist, Z)

% BIASVARDISTPSI1COMPUTE one line description
% FORMAT
% DESC description
% RETURN K : description
% RETURN P : description
% ARG biasKern : the kernel structure associated with the white kernel.
% ARG vardist : description
% ARG Z : description
%
%
% SEEALSO : others
%
%
% COPYRIGHT : Michalis K. Titsias, 2009
%

% VARGPLVM

K = repmat(biaskern.variance,size(vardist.means,1),size(Z,1));

P = [];


clear;
clc;

s = iio_sys_obj_matlab; % Constructor
s.ip_address = '10.66.99.200';
s.dev_name = 'ad9361';
s.in_ch_no = 2;
s.out_ch_no = 2;
s.in_ch_size = 8192;
s.out_ch_size = 8192;

s = s.setupImpl();

input = cell(1, s.in_ch_no + length(s.iio_dev_cfg.cfg_ch));
Fs = 30.72e6;
Fc = 1e6;
t = 1/Fs:1/Fs:s.in_ch_size/Fs;
for i=1:s.in_ch_no
    input{i} = sin(2*pi*Fc*t+(i-1)*pi/2)*1024;
end
input{s.getInChannel('RX_LO_FREQ')} = 2.4e9;
input{s.getInChannel('RX_SAMPLING_FREQ')} = 30.72e6;
input{s.getInChannel('RX_RF_BANDWIDTH')} = 18.0e6;
input{s.getInChannel('RX1_GAIN_MODE')} = 'slow_attack';
input{s.getInChannel('RX1_GAIN')} = 0;
input{s.getInChannel('RX2_GAIN_MODE')} = 'slow_attack';
input{s.getInChannel('RX2_GAIN')} = 0;
input{s.getInChannel('TX_LO_FREQ')} = 2.4e9;
input{s.getInChannel('TX_SAMPLING_FREQ')} = 30.72e6;
input{s.getInChannel('TX_RF_BANDWIDTH')} = 18.0e6;

output = cell(1, s.out_ch_no + length(s.iio_dev_cfg.mon_ch));

for i = 1:5
output = stepImpl(s, input);
rssi1 = output{s.out_ch_no+1};
rssi2 = output{s.out_ch_no+2};
end

s.releaseImpl();

figure % new figure
ax1 = subplot(2,1,1); % top subplot
ax2 = subplot(2,1,2); % bottom subplot

plot(ax1,output{1});
title(ax1,'I');
xlabel('Sample');
ylabel('Amplitude');

plot(ax2,output{2});
title(ax2,'Q');
xlabel('Sample');
ylabel('Amplitude');


function res = spm_eeg_artefact_nans(S)
% Plugin for spm_eeg_artefact doing NaN detection
% S            - input structure
% fields of S:
%    S.D       - M/EEG object
%    S.chanind - vector of indices of channels that this plugin will look at
%
%    Additional parameters can be defined specific for each plugin.
%
% Output:
% res -
%    If no input is provided the plugin returns a cfg branch for itself.
%
%    If input is provided the plugin returns a matrix of size D.nchannels x D.ntrials
%    with zeros for clean channel/trials and ones for artefacts.
%__________________________________________________________________________
% Copyright (C) 2011-2017 Wellcome Trust Centre for Neuroimaging

% Vladimir Litvak
% $Id: spm_eeg_artefact_nans.m 7132 2017-07-10 16:22:58Z guillaume $

%-This part if for creating a config branch that plugs into spm_cfg_eeg_artefact
% Any parameters can be specified and they are then passed to the plugin
% when it's called.
%--------------------------------------------------------------------------
if nargin == 0
    nans      = cfg_branch;
    nans.tag  = 'nans';
    nans.name = 'Detect NaNs';
    nans.val  = {};
    nans.help = {''};

    res = nans;

    return
end

SVNrev = '$Rev: 7132 $';

%-Startup
%--------------------------------------------------------------------------
spm('sFnBanner', mfilename, SVNrev);
spm('FigName','M/EEG NaN detection');

D = spm_eeg_load(S.D);

chanind = S.chanind;
res = zeros(D.nchannels, D.ntrials);

if isequal(S.mode, 'reject')
    res = zeros(D.nchannels, D.ntrials);

    %-Artefact detection
    %----------------------------------------------------------------------

    spm_progress_bar('Init', D.ntrials, 'Trials checked');
    if D.ntrials > 100, Ibar = floor(linspace(1, D.ntrials,100));
    else Ibar = [1:D.ntrials]; end

    for i = 1:D.ntrials
        for j = 1:length(chanind)
            if any(isnan(squeeze(D(chanind(j), :, i))))
                res(chanind(j), i) = 1;
            end
        end
        if any(Ibar == i), spm_progress_bar('Set', i); end
    end

    spm_progress_bar('Clear');

elseif isequal(S.mode, 'mark')
    if isequal(D.type, 'continuous')
        spm_progress_bar('Init', length(chanind), 'Channels checked');
        if length(chanind) > 100, Ibar = floor(linspace(1, length(chanind),100));
        else Ibar = [1:length(chanind)]; end
    else
        spm_progress_bar('Init', D.ntrials, 'Trials checked');
        if D.ntrials > 100, Ibar = floor(linspace(1, D.ntrials,100));
        else Ibar = [1:D.ntrials]; end
    end

    for i = 1:D.ntrials
        res = [];
        for j = 1:length(chanind)
            dat  = ~isnan(squeeze(D(chanind(j), :, i)));
            if  sum(dat)/length(dat)<(1-S.badchanthresh)
                res(end+1).type   = 'artefact_nan';
                res(end).value    = char(D.chanlabels(chanind(j)));
                res(end).time     = D.trialonset(i);
                res(end).duration = D.time(end) - D.time(1) + 1;
            else
                tmp  = find(dat);
                diffs = diff([0 tmp D.nsamples]);
                onsets = find(diffs>1);

                onsetsamples = [];
                if any(onsets == 1);
                    onsetsamples = 1;
                    onsets(1)    = [];
                    onsetsamples = [onsetsamples tmp(onsets-1)+1];
                    onsets       = [1 onsets];
                else
                    onsetsamples = [onsetsamples tmp(onsets-1)+1];
                end

                k = 1;
                m = 1;
                while k<=length(onsets)
                    if m <= length(onsets)
                        ind1 = onsetsamples(k);
                        ind2 = onsetsamples(m) + diffs(onsets(m))-2;
                        if ind2 > length(dat)
                            ind2 = length(dat);
                        end
                        if (sum(dat(ind1:ind2))/(ind2-ind1+1))<0.5
                            m = m+1;
                        else
                            if m>k
                                m = m-1;
                            end

                            res(end+1).type   = 'artefact_nan';
                            res(end).value    = char(D.chanlabels(chanind(j)));
                            res(end).time     = D.time(onsetsamples(k)+1) - D.time(1) + D.trialonset(i);
                            res(end).duration = (onsetsamples(m) + diffs(onsets(m))-onsetsamples(k)-1)/D.fsample;

                            k = m+1;
                            m = k;
                        end
                    else
                        ind1 = onsetsamples(k);
                        ind2 = length(dat);
                        if (sum(dat(ind1:ind2))/(ind2-ind1+1))<0.5
                            res(end+1).type   = 'artefact_nan';
                            res(end).value    = char(D.chanlabels(chanind(j)));
                            res(end).time     = D.time(onsetsamples(k)+1) - D.time(1) + D.trialonset(i);
                            res(end).duration = (length(dat)-onsetsamples(k)+2)/D.fsample;
                        else
                            m = m-1;

                            res(end+1).type   = 'artefact_nan';
                            res(end).value    = char(D.chanlabels(chanind(j)));
                            res(end).time     = D.time(onsetsamples(k)+1) - D.time(1) + D.trialonset(i);
                            res(end).duration = (onsetsamples(m) + diffs(onsets(m))-onsetsamples(k)-1)/D.fsample;
                        end
                        break;
                    end
                end
            end

            if isequal(D.type, 'continuous')
                if any(Ibar == j), spm_progress_bar('Set', j); end
            end
        end
        if ~isempty(res)
            ev = D.events(i);
            if iscell(ev)
                ev = ev{1};
            end

            if ~S.append
                ev(strmatch('artefact_nan', {ev.type})) = [];
            end

            D = events(D, i, spm_cat_struct(ev, res));
        end

        if ~isequal(D.type, 'continuous')
            if any(Ibar == i), spm_progress_bar('Set', i); end
        end
    end

    spm_progress_bar('Clear');

    res = D;
end

spm('FigName','M/EEG NaN detection: done');


function [d,fp,dt,tc,t]=v_readhtk(file)
%V_READHTK  read an HTK parameter file [D,FP,DT,TC,T]=(FILE)
%
% Input:
%    FILE = name of HTX file
% Outputs:
%       D = data: column vector for waveforms, one row per frame for other types
%      FP = frame period in seconds
%      DT = data type (also includes Voicebox code for generating data)
%             0  WAVEFORM     Acoustic waveform
%             1  LPC          Linear prediction coefficients
%             2  LPREFC       LPC Reflection coefficients:  -v_lpcar2rf([1 LPC]);LPREFC(1)=[];
%             3  LPCEPSTRA    LPC Cepstral coefficients
%             4  LPDELCEP     LPC cepstral+delta coefficients (obsolete)
%             5  IREFC        LPC Reflection coefficients (16 bit fixed point)
%             6  MFCC         Mel frequency cepstral coefficients
%             7  FBANK        Log Fliter bank energies
%             8  MELSPEC      linear Mel-scaled spectrum
%             9  USER         User defined features
%            10  DISCRETE     Vector quantised codebook
%            11  PLP          Perceptual Linear prediction
%            12  ANON
%      TC = full type code = DT plus (optionally) one or more of the following modifiers
%               64  _E  Includes energy terms
%              128  _N  Suppress absolute energy
%              256  _D  Include delta coefs
%              512  _A  Include acceleration coefs
%             1024  _C  Compressed
%             2048  _Z  Zero mean static coefs
%             4096  _K  CRC checksum (not implemented yet)
%             8192  _0  Include 0'th cepstral coef
%            16384  _V  Attach VQ index
%            32768  _T  Attach delta-delta-delta index
%       T = text version of type code e.g. LPC_C_K

%   Thanks to Dan Ellis (ee.columbia.edu) for sorting out decompression.
%   Thanks to Stuart Anderson (whispersys.com) for making it work on 64 bit machines.

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

fid=fopen(file,'r','b');
if fid < 0
    error(sprintf('Cannot read from file %s',file));
end
nf=fread(fid,1,'int32');             % number of frames
fp=fread(fid,1,'int32')*1.E-7;       % frame interval (converted to seconds)
by=fread(fid,1,'int16');            % bytes per frame
tc=fread(fid,1,'int16');            % type code (see comments above for interpretation)
tc=tc+65536*(tc<0);
cc='ENDACZK0VT';                    % list of suffix codes
nhb=length(cc);                     % number of suffix codes
ndt=6;                              % number of bits for base type
hb=floor(tc*pow2(-(ndt+nhb):-ndt));
hd=hb(nhb+1:-1:2)-2*hb(nhb:-1:1);   % extract bits from type code
dt=tc-pow2(hb(end),ndt);            % low six bits of tc represent data type

% hd(7)=1 CRC check
% hd(5)=1 compressed data
if (dt==5)  % hack to fix error in IREFC files which are sometimes stored as compressed LPREFC
    fseek(fid,0,'eof');
    flen=ftell(fid);        % find length of file
    fseek(fid,12,'bof');
    if flen>14+by*nf        % if file is too long (including possible CRCC) then assume compression constants exist
        dt=2;               % change type to LPREFC
        hd(5)=1;            % set compressed flag
        nf=nf+4;            % frame count doesn't include compression constants in this case
    end
end

if any(dt==[0,5,10])        % 16 bit data for waveforms, IREFC and DISCRETE
    d=fread(fid,[by/2,nf],'int16').';
    if ( dt == 5),
        d=d/32767;                    % scale IREFC
    end
else
    if hd(5)                            % compressed data - first read scales
        nf = nf - 4;                    % frame count includes compression constants
        ncol = by / 2;
        scales = fread(fid, ncol, 'float');
        biases = fread(fid, ncol, 'float');
        d = ((fread(fid,[ncol, nf], 'int16')+repmat(biases,1,nf)).*repmat(1./scales,1,nf)).';
    else                              % uncompressed data
        d=fread(fid,[by/4,nf],'float').';
    end
end;
fclose(fid);
if nargout > 4
    ns=sum(hd);                 % number of suffixes
    kinds={'WAVEFORM' 'LPC' 'LPREFC' 'LPCEPSTRA' 'LPDELCEP' 'IREFC' 'MFCC' 'FBANK' 'MELSPEC' 'USER' 'DISCRETE' 'PLP' 'ANON' '???'};
    t=[kinds{min(dt+1,length(kinds))} reshape(['_'*ones(1,ns);cc(hd>0)],1,2*ns)];
end


function computeAllPredictionTime_HN(pathModels,pathResults,training,param,maxOrder,nBoot,seed)
% -------------------------------------------------------------------------
% function computeAllPrediction_HN(pathModels,pathResults,training,param,maxOrder,nBoot,imbalance,batchNum)
% -------------------------------------------------------------------------
% DESCRIPTION:
% This function computes prediction performance estimation for a given
% feature set type, and for all model orders of all experiments with
% different degrees of freedom. See ref. [1,2] for more details.
% -------------------------------------------------------------------------
% REFERENCE:
% [1] Vallieres, M. et al. (2015). FDG-PET/CT radiomics models for the
%     early prediction of different tumour outcomes in head and neck cancer.
%     The Journal of Nuclear Medicine, aa(bb), xxx-yyy.
%     doi:
% [2] Vallieres, M. et al. (2015). A radiomics model from joint FDG-PET and
%     MRI texture features for the prediction of lung metastases in soft-tissue
%     sarcomas of the extremities. Physics in Medicine and Biology, 60(14),
%     5471-5496. doi:10.1088/0031-9155/60/14/5471
% -------------------------------------------------------------------------
% INPUTS:
% 2. pathModels: Full path to the Models folder of the corresponding experiment.
%                --> Ex: '/myProject/WORKSPACE/COHORT-BASED-RESULTS/Experiment1/MODELS'
% 2. pathResults: Full path to the Results folder of the corresponding experiment.
%                --> Ex: '/myProject/WORKSPACE/COHORT-BASED-RESULTS/Experiment1/RESULTS'
% 3. training: Structure defining all parameters for the given experiment
%              to perform. See masterScript_HN.m for more details.
% 4. param: Cell of two strings, defining 1) The feature set type/name; and
%           2) the outcome to model
% 5. maxOrder: Integer specifying the maximal model order to construct.
%              --> Ex: 10
% 6. nBoot: Number of bootstrap samples to use.
%           --> Ex: 100
% 7. imbalance: String specifying the type of imbalance-adjustement strategy
%               employed. Either 'IABR' for imbalance-adjusted bootstrap
%               resampling (see ref.[1]), or 'IALR' for imbalance-adjusted
%               logistic regression (see ref.[2]).
%               --> Ex: 'IALR'
% 8. batchNum: (optional input). If present, integer that specifies the
%              batch number for parallelization purposes.
%              --> Ex: 6
% -------------------------------------------------------------------------
% OUTPUTS: Prediction performance results are saved in a folder named 'RESULTS' in the
% corresponding folder of each experiment (e.g. 'Experiment1', 'Experiment2', etc.)
% -------------------------------------------------------------------------
% AUTHOR(S): Martin Vallieres <mart.vallieres@gmail.com>
% -------------------------------------------------------------------------
% HISTORY:
% - Creation: July 2015
%--------------------------------------------------------------------------
% STATEMENT:
% This file is part of <https://github.com/mvallieres/radiomics/>,
% a package providing MATLAB programming tools for radiomics analysis.
% --> Copyright (C) 2015  Martin Vallieres
%
%    This package is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    This package is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this package.  If not, see <http://www.gnu.org/licenses/>.
% -------------------------------------------------------------------------

startpath = pwd;
warning off

cd(pathModels)
fSetName = param{1};
outcomeName = param{2};
outcome = training.(outcomeName).timeToEvent;
censoring = 1 - training.(outcomeName).outcome;
models = load(['MODELS_',fSetName,'_',outcomeName]); models = struct2cell(models); models = models{1};

tic
fprintf(['\n --> COMPUTING PREDICTION PERFORMANCE (MODEL ORDERS OF 1 to % u) FOR  "',fSetName,'" FEATURE SET AND "',outcomeName,'" OUTCOME ... '],maxOrder)
for j = 1:maxOrder
    orderName = ['Order',num2str(j)];
    data = models.(orderName).Data;
    [orderResults] = predictionPerformanceEstimationTime_HN(data,outcome,nBoot,censoring,seed);
    results.(orderName) = orderResults;
    results.(orderName).Data = models.(orderName).Data;
    results.(orderName).Name = models.(orderName).Name;
end
cd(pathResults), save(['RESULTS_',fSetName,'_',outcomeName],'results')
fprintf('DONE!\n'), toc

cd(startpath)
end


function [] = anim8_DIC_image_3Dmeasure_points_2n(ImSet,DIC2DpairResults,DIC3DpairResults,faceMeasureString,varargin)
%% function for plotting 2D-DIC results imported from Ncorr in step 2
% called inside plotNcorrPairResults
% plotting the images chosen for stereo DIC (2 views) with the
% correlated points results plotted on top, colored as their correlation
% coefficient.
% on the left side the images from the reference camera (reference image and current images), and on the right side the
% images from the deformed camera
% requirements: GIBBON toolbox
%
%
% INPUT:
% * IMset - a 2nX1 cell array containing 2n grayscale images. The first n
% images are from camera A (the "reference" camera), and the last n images
% are from camera B (the "deformed" camera). The first image in the set is
% considered as the reference image, on which the reference grid of points
% is defined, and all the correlated points and consequent displacements
% and strains, are relative to this image.
% * DIC_2Dpair_results - containig the correlated points, correlation
% coefficients, faces..
% * optional: CorCoeffCutOff - - maximal correlation coefficient to plot
% points
% * optional: CorCoeffDispMax - maximal correlation coefficient in colorbar

%%
DIC2DpairResultsL=DIC2DpairResults{1};
DIC2DpairResultsR=DIC2DpairResults{2};
DIC3DpairResultsL=DIC3DpairResults{1};
DIC3DpairResultsR=DIC3DpairResults{2};

nImages=DIC2DpairResultsL.nImages;
nCam=DIC2DpairResultsL.nCamDef;

PointsL=DIC2DpairResultsL.Points(nImages+1:end);
PointsR=DIC2DpairResultsR.Points(1:nImages);
CorCoeffVecL=DIC2DpairResultsL.CorCoeffVec(nImages+1:end);
CorCoeffVecR=DIC2DpairResultsR.CorCoeffVec(1:nImages);

switch nargin
    case 4 % in case no results were entered
        optStruct=struct;
    case 5
        optStruct=varargin{1};
    otherwise
        error('wrong number of input arguments');
end

%% cut out point with large correlation coefficient
if ~isfield(optStruct,'CorCoeffCutOff')
    CorCoeffCutOff=max([cell2mat(CorCoeffVecL); cell2mat(CorCoeffVecR)]);
else
    CorCoeffCutOff=optStruct.CorCoeffCutOff;
end

for ii=1:nImages
    CorCoeffVecL{ii}(CorCoeffVecL{ii}>CorCoeffCutOff)=NaN;
    CorCoeffVecR{ii}(CorCoeffVecR{ii}>CorCoeffCutOff)=NaN;
end

%%
switch faceMeasureString
    case {'DispMgn'}
        PCL=DIC3DpairResultsL.Disp.DispMgn;
        PCR=DIC3DpairResultsR.Disp.DispMgn;
        cMap='jet';
     case {'DispX'}
         for ii=1:nImages
             PCL{ii,1}=DIC3DpairResultsL.Disp.DispVec{ii}(:,1);
             PCR{ii,1}=DIC3DpairResultsR.Disp.DispVec{ii}(:,1);
         end
         cMap='jet';
    case {'DispY'}
        for ii=1:nImages
            PCL{ii,1}=DIC3DpairResultsL.Disp.DispVec{ii}(:,2);
            PCR{ii,1}=DIC3DpairResultsR.Disp.DispVec{ii}(:,2);
        end
        cMap='jet';
    case {'DispZ'}
        for ii=1:nImages
            PCL{ii,1}=DIC3DpairResultsL.Disp.DispVec{ii}(:,3);
            PCR{ii,1}=DIC3DpairResultsR.Disp.DispVec{ii}(:,3);
        end
        cMap='jet';
    otherwise
        error('unexpected face measure string. plots not created');
end

%%

if ~isfield(optStruct,'PClimits')
    PCmin=0;
    PCmax=0;
    for ii=1:nImages
        PCmin=min([min(PCL{ii}(~isnan(CorCoeffVecL{ii}))) min(PCL{ii}(~isnan(CorCoeffVecL{ii}))) PCmin]);
        PCmax=max([max(PCR{ii}(~isnan(CorCoeffVecR{ii}))) max(PCR{ii}(~isnan(CorCoeffVecR{ii}))) PCmax]);
    end
    PClimits=[PCmin PCmax];
else
    PClimits=optStruct.PClimits;
end

%%
hf=figure; hold all;
hf.Units='normalized'; hf.OuterPosition=[.05 .05 .9 .9]; hf.Units='pixels';

ii=1;
hp1=imagesc(repmat(ImSet{ii},1,1,3)); hold on; axis ij
PL=PointsL{ii}(~isnan(CorCoeffVecL{ii}),:);
PR=PointsR{ii}(~isnan(CorCoeffVecR{ii}),:);
hp2=scatter(PL(:,1),PL(:,2),6,PCL{ii}(~isnan(CorCoeffVecL{ii})),'+');
hp3=scatter(PR(:,1),PR(:,2),6,PCR{ii}(~isnan(CorCoeffVecR{ii})),'+');
pbaspect([size(ImSet{ii},2) size(ImSet{ii},1) 1])
hs1=title(['Cam ' num2str(nCam) ' frame ' num2str(1)]);
colormap(cMap);
hc1=colorbar;
caxis(PClimits)
title(hc1, faceMeasureString);
hc1.FontSize=16;
axis off
drawnow

%Create the time vector
animStruct.Time=linspace(0,1,nImages);

for ii=1:nImages
    xNowL=PointsL{ii}(~isnan(CorCoeffVecL{ii}),1);
    yNowL=PointsL{ii}(~isnan(CorCoeffVecL{ii}),2);
    xNowR=PointsR{ii}(~isnan(CorCoeffVecR{ii}),1);
    yNowR=PointsR{ii}(~isnan(CorCoeffVecR{ii}),2);

    cNowL=PCL{ii};
    cNowR=PCR{ii};

    TitleNow=['Cam ' num2str(nCam) ' frame ' num2str(ii)];

    %Set entries in animation structure
    animStruct.Handles{ii}=[hp1,hp2,hp2,hp2,hp3,hp3,hp3,hs1]; %Handles of objects to animate
    animStruct.Props{ii}={'CData','XData','YData','CData','XData','YData','CData','String'}; %Properties of objects to animate
    animStruct.Set{ii}={repmat(ImSet{ii},1,1,3),xNowL,yNowL,cNowL,xNowR,yNowR,cNowR,TitleNow}; %Property values for to set in order to animate

end

anim8(hf,animStruct);

end

%%
% MultiDIC: a MATLAB Toolbox for Multi-View 3D Digital Image Correlation
%
% License: <https://github.com/MultiDIC/MultiDIC/blob/master/LICENSE.txt>
%
% Copyright (C) 2018  Dana Solav
%
% If you use the toolbox/function for your research, please cite our paper:
% <https://engrxiv.org/fv47e>


dtDirs = {'/biac3/wandell4/data/reading_longitude/dti_adults/ak090724/dti40trilin/'...
    '/biac3/wandell4/data/reading_longitude/dti_adults/am090121/dti06trilinrt/'...
    '/biac3/wandell4/data/reading_longitude/dti_adults/rfd080930/dti06trilinrt/'};

BPFDirs = {'/biac3/wandell5/data/relaxometry/ak090721/trilin_ak_2mms'...
    '/biac3/wandell5/data/relaxometry/am_090126/trilin2mml'...
    '/biac3/wandell5/data/relaxometry/rb_090716/trilin_rb_2mms'};

sub={'ak' 'am' 'rfd'}

for j=1:1%2 %1.5T or 3T anatomy
    for i=2:2%length(sub),
        name3T=sub{i};
        name15T=[sub{i} '1_5'];
        path3=['/biac3/wandell5/data/relaxometry/100405HLF3T/anal/' name3T 'lin_2mms1/'];
        path15=['/biac3/wandell5/data/relaxometry/100405HLF3T/anal/' name15T 'lin_2mms'];%Nbs1

        if j==1,
            path=path15;
        elseif j==2
            path=path3;
        end;
        %%% load maps  %%%
        hlf=niftiRead([path '/HLF_F.nii.gz']);
        t1=niftiRead([path '/T1_LFit_F.nii.gz']);
        T1hWf=niftiRead([path '/T1fh_F.nii.gz']);
        wf=niftiRead([path '/Wf_F.nii.gz']);
        dt = dtiLoadDt6(fullfile(dtDirs{i},'dt6'));
        bpf=niftiRead(fullfile(BPFDirs{i},'f.nii.gz'));
       Class=niftiRead([path15 '/T1_class2mm.nii.gz']);

%        t1=t1.data;
%        hlf=hlf.data;
%        wf=wf.data;
%        T1hWf=T1hWf.data;
%        bpf=bpf.data;
%
      [eigVec,eigVal] = dtiEig(dt.dt6);
    [fa,md,rd] = dtiComputeFA(eigVal);
    [cl, cp, cs] = dtiComputeWestinShapes(eigVal);

%       we will make wm masks for the maps

maskAnat=find(Class.data==3 | Class.data==4);

if(~all(dt.xformToAcpc(:)==Class.qto_xyz(:)))
    maskR= mrAnatResliceSpm(double(Class.data),inv(Class.qto_xyz),dt.bb,dt.mmPerVoxel,1);
    maskDif=find(maskR==3 | maskR==4);
    clear maskR;

else
    maskDif=maskAnat;
end;

%compute means andsd's for each measure within white matter mask
fa_std=std(fa(maskDif(~isnan(fa(maskDif)))));
rd_std=std(rd(maskDif(~isnan(rd(maskDif)))));
md_std=std(md(maskDif(~isnan(md(maskDif)))));
cl_std=std(cl(maskDif(~isnan(cl(maskDif)))));

hlf_std=std(hlf.data(maskAnat(~isnan(hlf.data(maskAnat)))));
wf_std=std(wf.data(maskAnat(~isnan(wf.data(maskAnat)))));
t1_std=std(t1.data(maskAnat(~isnan(t1.data(maskAnat)))));
T1hWf_std=std(T1hWf.data(maskAnat(~isnan(T1hWf.data(maskAnat)))));
bpf_std=std(bpf.data(maskAnat(~isnan(bpf.data(maskAnat)))));

fa_mean=mean(fa(maskDif(~isnan(fa(maskDif)))));
rd_mean=mean(rd(maskDif(~isnan(rd(maskDif)))));
md_mean=mean(md(maskDif(~isnan(md(maskDif)))));
cl_mean=mean(fa(maskDif(~isnan(cl(maskDif)))));

hlf_mean=mean(hlf.data(maskAnat(~isnan(hlf.data(maskAnat)))));
wf_mean=mean(wf.data(maskAnat(~isnan(wf.data(maskAnat)))));
t1_mean=mean(t1.data(maskAnat(~isnan(t1.data(maskAnat)))));
T1hWf_mean=mean(T1hWf.data(maskAnat(~isnan(T1hWf.data(maskAnat)))));
bpf_mean=mean(bpf.data(maskAnat(~isnan(bpf.data(maskAnat)))));

%load morigroups and rois
%fg will contain all mori groups
fbDir=[dtDirs{i} 'fibers/MoriGroups'];

fg=dtiReadFibers(fbDir)

roiDir=[dtDirs{i} 'ROIs'];

fgName(3)={'Left Cortico-Spinal'};
roi1{3}=dtiReadRoi(fullfile(roiDir,'CST_roi1_L'));
roi2{3}=dtiReadRoi(fullfile(roiDir,'CST_roi2_L'));
fgName(4)={'Right Cortico-Spinal'};
roi1{4}=dtiReadRoi(fullfile(roiDir,'CST_roi1_R'));
roi2{4}=dtiReadRoi(fullfile(roiDir,'CST_roi2_R'));
fgName(11)={'Left Inferior Fronto-Occ'};
roi1{11}=dtiReadRoi(fullfile(roiDir,'IFO_roi1_L'));
roi2{11}=dtiReadRoi(fullfile(roiDir,'IFO_roi2_L'));
fgName(12)={'Right Inferior Frontal-Occ'};
roi1{12}=dtiReadRoi(fullfile(roiDir,'IFO_roi1_R'));
roi2{12}=dtiReadRoi(fullfile(roiDir,'IFO_roi2_R'));
fgName(13)={'Left Inferior Longitude'};
roi1{13}=dtiReadRoi(fullfile(roiDir,'ILF_roi1_L'));
roi2{13}=dtiReadRoi(fullfile(roiDir,'ILF_roi2_L'));
fgName(14)={'Right Inferior Longitude'};
roi1{14}=dtiReadRoi(fullfile(roiDir,'ILF_roi1_R'));
roi2{14}=dtiReadRoi(fullfile(roiDir,'ILF_roi2_R'))
fgName(19)={'Left Arcuate'};
roi1{19}=dtiReadRoi(fullfile(roiDir,'SLF_roi1_L'));
roi2{19}=dtiReadRoi(fullfile(roiDir,'SLFt_roi2_L'));
fgName(20)={'Right Arcuate'};
roi1{20}=dtiReadRoi(fullfile(roiDir,'SLF_roi1_R'));
roi2{20}=dtiReadRoi(fullfile(roiDir,'SLFt_roi2_R'));
%compute properties on tract trajectory for the specific fiber goups of
%interest

groups=[3  11  13  19 4 12 14 20];
for ii=groups;
    %compute fa and md along the trajectory of the fiber group as a
    %weighted average of fa and md at each fiber
    [fa_ md_ rd_ d cl_]=dtiComputeDiffusionPropertiesAlongFG(fg(ii), dt, roi1{ii}, roi2{ii}, 30);
    %clip fiber group between 2 rois to obtain core segment
    fgClipped = dtiClipFiberGroupToROIs(fg(ii),roi1{ii},roi2{ii});
    %compute quantitative measures along trajectory of fiber group
    [hlf_, SuperFiber, weightsNormalized] =dtiFiberGroupPropertyWeightedAverage(fgClipped, hlf, 30,'image');
    [wf_, SuperFiber, weightsNormalized] =dtiFiberGroupPropertyWeightedAverage(fgClipped, wf, 30,'image');
    [t1_, SuperFiber, weightsNormalized] =dtiFiberGroupPropertyWeightedAverage(fgClipped, t1, 30,'image');
    [T1hWf_, SuperFiber, weightsNormalized] =dtiFiberGroupPropertyWeightedAverage(fgClipped, T1hWf, 30,'image');
    [bpf_, SuperFiber, weightsNormalized] =dtiFiberGroupPropertyWeightedAverage(fgClipped, bpf, 30,'image');

    %Standardize measures based on variance within white matter mask
    faZ=((fa_-fa_mean)./fa_std);
    rdZ=((rd_-rd_mean)./rd_std);
    mdZ=((md_-md_mean)./md_std);
    clZ=((cl_-cl_mean)./cl_std);

    hlfZ=(hlf_-hlf_mean)./hlf_std;
    T1hWfZ=(T1hWf_-T1hWf_mean)./T1hWf_std;
    t1Z=(t1_-t1_mean)./t1_std;
    wfZ=(wf_-wf_mean)./wf_std;
    bpfZ=(bpf_-bpf_mean)./bpf_std;

    %Make plot for fiber group ii
    figure(ii);
     subplot(2,4,find(groups==ii));

       subplot(2,1,1);
   plot(horzcat(faZ,rdZ,mdZ,clZ),'LineWidth',2);axis([0 30 -2 2]);title([sub{i} 'Dif' fgName{ii}])
         legend('fa', 'rd', 'md', 'cl');ylabel('Z Score');
   subplot(2,1,2);
    plot(horzcat(hlfZ,T1hWfZ,t1Z,wfZ,bpfZ),'LineWidth',2);axis([0 30 -2 2]);title([sub{i} 'Anat' fgName{ii}])
   %if find(groups==ii)==1 | find(groups==ii)==5
        legend( 'hlf', 'T1hWf', 't1', 'wf' ,'bpf'); ylabel('Z Score');
   % end

end

    end

end;


function opts = init_LapSRN_opts(scale, depth, gpu)
% -------------------------------------------------------------------------
%   Description:
%       Generate model options for LapSRN
%
%   Input:
%       - scale : SR upsampling scale
%       - depth : number of conv layers in one pyramid level
%       - gpu   : GPU ID, 0 for CPU mode
%
%   Output:
%       - opts  : options for LapSRN
%
%   Citation:
%       Deep Laplacian Pyramid Networks for Fast and Accurate Super-Resolution
%       Wei-Sheng Lai, Jia-Bin Huang, Narendra Ahuja, and Ming-Hsuan Yang
%       IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 2017
%
%   Contact:
%       Wei-Sheng Lai
%       wlai24@ucmerced.edu
%       University of California, Merced
% -------------------------------------------------------------------------

    %% network options
    opts.scale              = scale;
    opts.depth              = depth;
    opts.weight_decay       = 0.0001;
    opts.init_sigma         = 0.001;
    opts.conv_f             = 3;
    opts.conv_n             = 64;
    opts.loss               = 'L1';

    %% training options
    opts.gpu                = gpu;
    opts.batch_size         = 64;
    opts.num_train_batch    = 100;     % number of training batch in one epoch
    opts.num_valid_batch    = 100;      % number of validation batch in one epoch
    opts.lr                 = 1e-5;     % initial learning rate
    opts.lr_step            = 50;       % number of epochs to drop learning rate
    opts.lr_drop            = 0.5;      % learning rate drop ratio
    opts.lr_min             = 1e-6;     % minimum learning rate
    opts.patch_size         = 128;
    opts.data_augmentation  = 1;
    opts.scale_augmentation = 1;

    %% dataset options
    opts.train_dataset          = {};
    opts.train_dataset{end+1}   = 'T91';
    opts.train_dataset{end+1}   = 'BSDS200';
    %opts.train_dataset{end+1}   = 'General100';
    opts.valid_dataset          = {};
    %opts.valid_dataset{end+1}   = 'Set5';
    %opts.valid_dataset{end+1}   = 'Set14';
    opts.valid_dataset{end+1}   = 'BSDS100';

    %% setup model name
    opts.data_name = 'train';
    for i = 1:length(opts.train_dataset)
        opts.data_name = sprintf('%s_%s', opts.data_name, opts.train_dataset{i});
    end

    opts.net_name = sprintf('LapSRN_x%d_depth%d_%s', ...
                            opts.scale, opts.depth, opts.loss);

    opts.model_name = sprintf('%s_%s_pw%d_lr%s_step%d_drop%s_min%s_bs%d', ...
                            opts.net_name, ...
                            opts.data_name, opts.patch_size, ...
                            num2str(opts.lr), opts.lr_step, ...
                            num2str(opts.lr_drop), num2str(opts.lr_min), ...
                            opts.batch_size);

    %% setup dagnn training parameters
    if( opts.gpu == 0 )
        opts.train.gpus     = [];
    else
        opts.train.gpus     = [opts.gpu];
    end
    opts.train.batchSize    = opts.batch_size;
    opts.train.numEpochs    = 1000;
    opts.train.continue     = true;
    opts.train.learningRate = learning_rate_policy(opts.lr, opts.lr_step, opts.lr_drop, ...
                                                   opts.lr_min, opts.train.numEpochs);

    opts.train.expDir = fullfile('models', opts.model_name) ; % model output dir
    if( ~exist(opts.train.expDir, 'dir') )
        mkdir(opts.train.expDir);
    end

    opts.train.model_name       = opts.model_name;
    opts.train.num_train_batch  = opts.num_train_batch;
    opts.train.num_valid_batch  = opts.num_valid_batch;

    % setup loss
    opts.level = ceil(log(opts.scale) / log(2));
    opts.train.derOutputs = {};
    for s = opts.level : -1 : 1
        opts.train.derOutputs{end+1} = sprintf('level%d_%s_loss', s, opts.loss);
        opts.train.derOutputs{end+1} = 1;
    end

end


function lvPerfTable = getLVPerfTable(lvDef, liftoffUt)
    lvPerfTable = [];
    lvDefCumData = getStageData(lvDef);
    startUt = liftoffUt;
    for(i=1:size(lvDefCumData,1)) %#ok<*NO4LP>
        row = lvDefCumData(i,:);
        coastDur = row(8);
        coastStart = startUt + row(1);
        endUt = startUt + row(1) + coastDur;
        thrust = row(2);
        mdot = row(3);
        massStart = row(4);
        massEnd = row(5);
        dryMassCum = row(6);
        fuMassCum = row(7);
        cDa = row(9);

        lvPerfTable(i,:) = [startUt, endUt, thrust, mdot, massStart, massEnd, dryMassCum, fuMassCum, coastStart, cDa]; %#ok<AGROW>
        startUt = endUt;
    end

    lvPerfTable(end+1,:) = lvPerfTable(end,:);
    lvPerfTable(end, 1) = lvPerfTable(end-1, 2);
    lvPerfTable(end, 2) = Inf;
    lvPerfTable(end, 3) = 0.0;
    lvPerfTable(end, 4) = 0.0;
    lvPerfTable(end, 5) = lvPerfTable(end-1, 6);
    lvPerfTable(end, 6) = lvPerfTable(end, 5);
    lvPerfTable(end, 7) = lvPerfTable(end-1, 7);
    lvPerfTable(end, 8) = 0.0;
    lvPerfTable(end, 9) = Inf;
    lvPerfTable(end, 10) = 0.0;


function [f,model] = penlab_callback_f(x,model)

global latest_x_f
global latest_df

x = x(:);
[f,latest_df] = fmincon_fun(x,model);
latest_x_f = x;


function [rsamobjects, ah]=plotrsam(sta, chan, snum, enum, DATAPATH)
% [rsamobjects, ah]=plotrsam_wrapper(sta, chan, snum, enum, DATAPATH)
%
%   Inputs:
%       sta - station code
%       chan - channel code
%       snum - start datenum
%       enum - end datenum
%       DATAPATH - path to data, including pattern
%
%   Outputs:
%       rsamobjects - vector of rsam objects
%       ah - vector of axes handles
%
%   Examples:
%       1. Data from the digital seismic network, Montserrat
%           DP = fullfile('/raid','data','antelope','mvo','SSSS_CCC_YYYY.DAT');
%           [rsamobjects, ah] = rsam.plotrsam('MBWH','SHZ',datenum(2001,2,24), datenum(2001,3,3), DP);
%       2. Data from the analog seismic network, Montserrat
%           DP = fullfile(DROPBOX, 'DOME', 'SEISMICDATA', 'RSAM_1', 'SSSSYYYY.DAT');
%           [rsamobjects, ah] = rsam.plotrsam('MWHZ','',datenum(1996,7,1), datenum(1996,8,13), DP);
%   Could use the following logic in a wrapper to decide DP:
%       strfind(sta{i},'MB') & ~strcmp(sta{i},'MBET')

    % validate
    if nargin ~= 5
        help rsam>plotrsam()
        return
    end

    % initialise
    if ~iscell(sta)
        sta={sta};
    end
    if ~iscell(chan)
        chan={chan};
    end
    numsta = length(sta);
    numrsams = 0;
    rsamobjects = [];
    ah = [];

    % load data
    for i=1:numsta
        s = rsam('file', DATAPATH, 'snum', snum, 'enum', enum, 'sta', sta{i},'chan',chan{i});
        if ~isempty(s.data)
            numrsams = numrsams + 1;
            rsamobjects = [rsamobjects resample(s.despike(100))];
            %ah(i)=subplot(numsta,1,i),plot(resample(s.despike(10)));
        end
    end

    % plot data
    if numrsams > 0
        figure
        for i=1:numrsams
            ah(i) = subplot(numrsams, 1, i), plot(rsamobjects(i))
        end
        linkaxes(ah, 'x')
        %datetick('x','keeplimits')
    end
end


%==============================================================================
% This code is part of the Matlab-based toolbox
% FAIR - Flexible Algorithms for Image Registration.
% For details see
% - https://github.com/C4IR and
% - http://www.siam.org/books/fa06/
%==============================================================================
% This is a testing environment for the files in the folder kernel/numerics
% 1. Based on data/contents, a list of required files is generated and it
%    is verified, that all files are present; additional files are listed.
% 2. All c-files are compiled.
% 3. All files are executed.
%==============================================================================

FAIRcheckFiles(mfilename);
testEnd;

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


function [c] = datasets_feature(dataset_names, train_lists, test_lists, feature, c)
%
% Copyright Aditya Khosla http://mit.edu/khosla
%
% Please cite this paper if you use this code in your publication:
%   A. Khosla, J. Xiao, A. Torralba, A. Oliva
%   Memorability of Image Regions
%   Advances in Neural Information Processing Systems (NIPS) 2012
%

if(~exist('c', 'var'))
  c = conf();
end

if (~exist('OCTAVE_VERSION','builtin'))
    openPool(c.cores);
end

if(c.common_dictionary)
    c.feature_config.(feature).dictionary = build_dictionary(train_lists, feature, c);
end
cache_folder = c.cache;
idx = randperm(length(train_lists));

for j=1:length(train_lists)
  i = idx(j);
  vprintf(c.verbosity, 0, 'Dataset: %s\n', dataset_names{i});
  c.cache = [cache_folder '/' dataset_names{i} '/'];

  if(~c.common_dictionary)
      c.feature_config.(feature).dictionary = build_dictionary(train_lists{i}, feature, c);
  end

  batch_feature(train_lists{i}, 'train', feature, c);
  batch_feature(test_lists{i}, 'test', feature, c);
end

c.cache = cache_folder;


%% Point Cloud Viewer (OpenCV)
%
% Display point cloud image using OpenCV.
%
% Copyright 2012 The MathWorks, Inc.

%% Input Signals
%
% * Pause (boolean): Pause point cloud image (1: Pause / 0: Not pause).
%
% * Pos (int32): Start position of XYZ and Image input pixel data ([y x]).
% Note that Pos is zero index based.
%
% * XYZ (double): XYZ data of points.
%
% * Image (uint8): RGB data of points.
%
% * View (double): View point ([x y z]). View input is available when "Set view point by input" block parameter was checked.
%

%% Output Signals
%
% * Image (uint8): RGB point cloud image. Image is available when "Image output" block parameter was checked.
%

%% Block Parameters
%
% * Window size: Size of Point Cloud Viewer window
%
% * Frame size: Size of XYZ and Image input data ([rows colums]).
%
% * Full frame size: Size of whole XYZ and Image data ([rows colums]).
%
% * Background color: Background color (R G B).
%
% * Look at point: Look at point of point cloud image ([x y z]).
%
% * Set view point by Input: Configure view point is set by an input signal or keyboard input (ON: Input signal / OFF: Keyboard input).
%
% Note that when this parameter was OFF, view point can be changed by keyboard input while point cloud display window is active.
%
% Note that keyboard input is not case sensitive.
%
% - Press R(r) : Initial view point
%
% - Press K(k) : +y
%
% - Press J(j) : -y
%
% - Press H(h) : +x
%
% - Press L(l) : -x
%
% - Press I(i)  : +z
%
% - Press M(m): -z
%
% * Initial view point: Initial view point when "Set view point by Input" parameter was OFF ([x y z]).
%
% * View point step: View point step for keyboard input. Step value has to be greater than zero.
%
% * Camera distortion coefficients: The input vector of camera distortion coefficients ([k1 k2 p1 p2 k3]) Zero value means no distortion.
%
% * Image output: Configure output of point cloud image (ON: Image output/OFF:No image output).
%


clear all;
close all;
clc;
spx.cluster.ssc.util.bench_subspace_preservation(@ssc_nn_omp, 'ssc_nn_omp');


function camBV2Scheme(bval_filename,bvec_filename,scheme_filename)
%Converts mrVIsta b-values and vectors to the camino scheme format
%
%   camBV2Scheme(bval_filename,bvec_filename,scheme_filename)
%
%
% (c) Stanford Vista, Sherbondy, 2010

bvec_opt = [' -bvecfile ' bvec_filename];
bval_opt = [' -bvalfile ' bval_filename];

% First, guess at what units the bvals are in as camino expects kg,s,m
% units or specifically s/m^2 and we often get them in two other standard
% forms, e.g., b=800 (s/mm^2) or b = 0.8 (ms/micron^2)
b = dlmread(bval_filename);
if any(b>100)
    bscale = '1E6';
else
    bscale = '1E9';
end

xform_opt = [' -bscale ' bscale ' -flipz -flipy -flipx '];

% Has to be scheme2 format so lets strip any provided extension
[pathstr, name, ext] = fileparts(scheme_filename);
scheme_filename = fullfile(pathstr,[name '.scheme2']);
scheme_opt = [' > ' scheme_filename];

cmd = ['fsl2scheme' bvec_opt bval_opt xform_opt  scheme_opt];

display(cmd);
system(cmd,'-echo');

return


load('test_data.mat')
iou_ = compute_dense_overlap(ofx,ofy,stx,sty,vsx,vsy,dx1,dy1,dx2,dy2,gx1,gy1,gx2,gy2,1,1);
err = abs(iou_ - iou);
if all(err(:)) < 1e-12
    fprintf('Test for compute_dense_overlap [passed]\n');
else
    fprintf('Test for compute_dense_overlap [failed]\n');
end


%% t_gifti_4
%

% Download from RDT
%{
 rdt = RdtClient('vistasoft');
 rdt.crp('/vistadata/anatomy/anatomyNIFTI');

 leftMeshFile = rdt.readArtifact('leftMesh',...
    'type','mat',...
    'destinationFolder',fullFolderName);
%}

%%  Set the vista data path and change into the gifti data directory

chdir(fullfile(vistaRootPath,'local'));
%% Create a gifti structure from a mrMesh mesh

% This loads a VISTASOFT msh structure
% First the original mesh
load(fullfile(vistaRootPath,'local','leftMesh.mat'));
g = gifti;
g.faces = int32(meshGet(msh,'triangles')' + 1);

% Choose either the initial unsmoothed vertices, or the smoothed vertices
% g.vertices = single(meshGet(msh,'initVertices')');
g.vertices = single(meshGet(msh,'vertices')');

% We don't know how this is used.
g.mat = eye(4,4);
% g.mat = rand(4,4);
% mrvNewGraphWin; h = plot(g);

% we take the green channel and use a gray scale map.  Their algorithm
% seems to normalize the color list and map it through the color map.
cdata = meshGet(msh,'colors');
cdata = cdata(2,:)';
gg.cdata = single(cdata);
mrvNewGraphWin; clf; colormap(gray); h = plot(g,gg);

%% Change the color map - I had some time on my hands.
colormap(cool); pause(0.5)
colormap(jet); pause(0.5)
colormap(redGreenCmap); pause(0.5)
colormap(blueyellowCmap); pause(0.5)

%% Change lighting and such
daspect([1,1,1]); view(45,30); axis tight
lightangle(45,30);
set(h,'SpecularColorReflectance',0,'SpecularExponent',50)
[az,el] = view;
g.mat = eye(4,4);
% g.mat = rand(4,4);
% mrvNewGraphWin; h = plot(g);

g.private.data{2}.metadata(1).name = 'AnatomicalStructurePrimary';
g.private.data{2}.metadata(1).value = 'CortexLeft';

% Also, DTI-Query will use the AnatomicalStructureSecondary metadata field
% to distinguish the surfaces that have been loaded.  While it's not
% necessary, it may be helpful to set this field as well:
% g.private.data{2}.metadata(2).name = 'AnatomicalStructureSecondary';
% g.private.data{2}.metadata(2).value = 'Pial'; % (or whatever you would like to tag the structure as)

% Then,
% save(g,'dhTest.gii');

% From Guillaume Flandin - storing metadata2
% g = gifti('file.gii');
% g.private.metadata(1).name  = 'AnatomicalStructurePrimary';
% g.private.metadata(1).value = 'CortexLeft';

%% Attach metadata to the gifti so Doug H. can read it. Name it as left.
% Helped by Guillaume Flandin email: gflandin@fil.ion.ucl.ac.uk

% First the left
load(fullfile(mrvDataRootPath,'anatomy','T1andMesh','Left_Mesh_Unsmoothed.mat'));
g = gifti;
g.faces = int32(meshGet(msh,'triangles')' + 1);

% Choose either the initial unsmoothed vertices, or the smoothed vertices
% g.vertices = single(meshGet(msh,'initVertices')');
g.vertices = single(meshGet(msh,'initVertices')');

% Set the flag to indicate this is a left hemisphere
g.private.data{2}.metadata(1).name = 'AnatomicalStructurePrimary';
g.private.data{2}.metadata(1).value = 'CortexLeft';
save(g,'left_gifti.gii');
% mrvNewGraphWin; h = plot(g); axis on; grid on

% Now the right
load(fullfile(mrvDataRootPath,'anatomy','T1andMesh','Right_Mesh_Unsmoothed.mat'));
g = gifti;
g.faces = int32(meshGet(msh,'triangles')' + 1);

% Choose either the initial unsmoothed vertices, or the smoothed vertices
% g.vertices = single(meshGet(msh,'initVertices')');
g.vertices = single(meshGet(msh,'initVertices')');

% Set the flag to indicate this is a left hemisphere
g.private.data{2}.metadata(1).name = 'AnatomicalStructurePrimary';
g.private.data{2}.metadata(1).value = 'CortexRight';

save(g,'right_gifti.gii');
% mrvNewGraphWin; h = plot(g);  axis on; grid on

% and actually, according to the specifications of the file format, you can
% store metadata for the complete file as above or for a given DataArray:
% g.private.data{2}.metadata(1).name = 'AnatomicalStructurePrimary';
% g.private.data{2}.metadata(1).value = 'CortexLeft';
%
% We need to figure out how to save these fields to work with dtiQuery.

%% End


function rgb = cortex

% returns a predefined color as [red green blue] values
%
% skin_surface         = [255 213 119]/255;
% outer_skull_surface  = [140  85  85]/255;
% inner_skull_surface  = [202 100 100]/255;
% cortex = [255 213 119]/255;
% black  = [0   0   0  ]/255;
% white  = [255 255 255]/255;
% red    = [255 0   0  ]/255;
% green  = [0   192 0  ]/255;
% blue   = [0   0   255]/255;
% yellow = [255 255 0  ]/255;
% cortex_light = [199 194 169]/255;
% cortex_dark  = [100 97 85]/255;

rgb = [255 213 119]/255;


function []= prepare_h5_data(data_folder, h5_save_folder,h5_save_list)
% Generate the hdf5 file and a file list used to train the network
% --------------------------------------------------------
% Copyright (c) 2017, Lequan Yu
% Licensed under The MIT License
% --------------------------------------------------------

    % re-sample the data into same resolution, default is False.
    use_isotropic=0;
    patchSize = 64;
    if nargin<3
        data_folder = '../data';
        h5_save_folder = '../h5_data';
        h5_save_list = '../train.list';

    if ~exist(h5_save_folder,'dir')
        mkdir(h5_save_folder);
    end

    addpath('./util');
    fid = fopen(h5_save_list, 'w');

    %% generate the hdf5 file
    for id = 0:0
        tic;
        img_path = [data_folder, '/', 'training_axial_crop_pat', num2str(id), '.nii.gz'];
        seg_path = [data_folder, '/', 'training_axial_crop_pat', num2str(id), '-label.nii.gz'];

        img_nii = load_nii(img_path);
        seg_nii = load_nii(seg_path);

        %pre-process the images (intensity and resize)
        [img,seg] = pre_process_isotropic(img_nii,seg_nii,use_isotropic,id);

        % crop the heart patches (ROI) from whole image and randomly crop patches
        [img,seg,rimgs,rsegs] = Create_ROIs(img, seg,patchSize);

        %% Do data augmentation (permute & rotate & flip)
        % We only do augmentation at axial plane
        % You can do agumentation in all three planes by setting it_p = 1:3
        pp= [1 2 3; 2 3 1; 3 1 2];
        for it_p = 1:1
            permute_img = permute(img,pp(it_p,:));
            permute_seg = permute(seg,pp(it_p,:));
            for it_r = 1:4
                % rotate
                rotate_img = rot90(permute_img, it_r - 1);
                rotate_seg  = rot90(permute_seg, it_r - 1);
                % flip
                for it_f = 0:1
                    if it_f == 0
                        flip_img = rotate_img;
                        flip_seg = rotate_seg;
                    else
                        flip_img = flip(rotate_img, it_f);
                        flip_seg = flip(rotate_seg, it_f);
                    end

                    % h5 file path
                    h5_path    = [h5_save_folder, '/', num2str(id), '_p', num2str(it_p),...
                        '_r', num2str(it_r), 'f', num2str(it_f), '.h5'];
                    if exist(h5_path,'file')
                        delete(h5_path);
                    end

                    [d1, d2, d3, d4, d5] = size(flip_img);
                    data_dims = [d1, d2, d3, d4, d5];
                    [d1, d2, d3, d4, d5] = size(flip_seg);
                    seg_dims = [d1, d2, d3, d4, d5];

                    % store as h5 format
                    h5create(h5_path,'/data',data_dims,'Datatype','single','Deflate',0,'ChunkSize',data_dims);
                    h5create(h5_path,'/label',seg_dims,'Datatype','uint8','Deflate',0,'ChunkSize',seg_dims);
                    h5write(h5_path,'/data', single(flip_img));
                    h5write(h5_path,'/label',uint8(flip_seg));
                    fprintf(fid,'%s\n', h5_path);
                end
            end
        end

        %% save randomly cropped patches.
        % Default, we do not use them to train the model
        for i= 1: 0 %size(random_img, 5)
            h5_path  = [h5_save_folder, '/',num2str(id), '_random_', num2str(i), '.h5'];
            if exist(h5_path,'file')
                delete(h5_path);
            end

            write_img = rimgs{i};
            write_seg  = rsegs{i};
            [d1, d2, d3, d4, d5] = size(write_img);
            data_dims = [d1, d2, d3, d4, d5];
            [d1, d2, d3, d4, d5] = size(write_seg);
            seg_dims = [d1, d2, d3, d4, d5];

            % store as h5 format
            h5create(h5_path,'/data',data_dims,'Datatype','single','Deflate',0,'ChunkSize',data_dims);
            h5create(h5_path,'/label',seg_dims,'Datatype','uint8','Deflate',0,'ChunkSize',seg_dims);
            h5write(h5_path,'/data', single(write_img));
            h5write(h5_path,'/label',uint8(write_seg));
            fprintf(fid,'%s\n', h5_path);
        end
        toc;
    end
    fclose(fid);
end


function view=analyze4d2mrLoadRet3TSeries(view,inFile,scan,volsToSkip,rotateInplanes,scaleFact,flipudFlag,rotateFlag,flipSliceOrder)
% view=4danalyze2mrLoadRet3TSeries(view,inFile,scan,volsToSkip,rotateInplan
% es,scaleFact,flipudFlag,fliplrFlag,flipSliceOrder)
% Converts from 4d analyze functional image data to mrLoadRet TSeries
% format.
% Uses read_avw to read in 4d analyze files. Then saves out the block as
% mlr TSeries while skipping over any initial 'junk frames';
%
% The doRotate param allows to you rotate the functional data by doRotate*90 degrees
% Try to read the the first volume to see if it's there and get the
% dimensions of all the rest
% ARW 032703 : Now saves out data in mrLoadRet3.0 format (.mat as opposed to .dat files)

% AAB 2003.07.08 After the temporal normalization bug, I reconverted the
% Tuebingen data using the Brucker-2-analyze converter downloaded from the
% website. The new time series do not need to be rotated or flipped
% up/down, but do need to be flipped left/right. So, I changed flipFlag to
% flipudFlag (for up/down) and added fliplrFlag (for left/right). I set
% all three values to be off by default.
% ARW : 120805 : This function based on analyze2mrLoadRet3TSeries.

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

if (~exist('scaleFact','var'))
    scaleFact=[1 1]; % No interpolation. (Scaling=1)
end

if (length(scaleFact)~=2) % If we just get a scalar for the scale factor, assume that it applies in both dimensions
    scaleFact=repmat(scaleFact(1),2);
end

if (~exist('rotateInplanes','var'))
    rotateInplanes=0; % This is off by default. Rotates 1*90 degrees
end

if (~exist('flipudFlag','var'))
    flipudFlag=0; % This is off by default. Flips up/down after rotation
end

if (~exist('fliplrFlag','var'))
    fliplrFlag=0; % This is off by default. Flips left/right after rotation
end
if (~exist('flipSliceOrder','var'))
    flipSliceOrder=0; % This is off by default. Flips left/right after rotation
end

disp('Reading volume');
funcVol=read_avw(inFile);
disp('Done');

% Now take care of flipping...

%
% if (mod(doRotate,2)) % When we rotate by 180 degrees the x and y dimensions remain unchanged
%     funcVol=zeros(y,x,nSlices,nVols);
% else
%     funcVol=zeros(x,y,nSlices,nVols);
% end
%
% fprintf('Rotating by %d x 90, flipupFlag=%d, fliplrFlag=%d',doRotate,flipudFlag,fliplrFlag);
%
%
% for t=0:(nVols-1)
%     thisImIndex=t+firstVolIndex;
%     suffix=sprintf('%03d',thisImIndex);
%     fileName=[inFileRoot,suffix];
%     V=spm_vol(fileName);
%     im=spm_read_vols(V);
%
%     % Do the rotation and scaling
%
%     if (mod(doRotate,2)) % When we rotate by 180 degrees the x and y dimensions remain unchanged
%         im2=zeros(y,x,nSlices);
%     else
%         im2=zeros(x,y,nSlices);
%     end
%     fprintf('\nVol=%d',thisImIndex);
%
%     for thisSlice=1:nSlices
%         imSlice=squeeze(im(:,:,thisSlice));
% %         imSlice=imresize(imSlice,[scaleFact(1)*y,scaleFact(2)*x],'nearest');
%
%         im2(:,:,thisSlice)=rot90(imSlice,doRotate);
%
%         if (flipudFlag)
%             im2(:,:,thisSlice)=flipud(im2(:,:,thisSlice));
%         end
%
%         if (fliplrFlag)
%             im2(:,:,thisSlice)=fliplr(im2(:,:,thisSlice));
%         end
%
%     end % next imSlice
%
%
%     if (flipSliceOrder) % We can make it so the slice order is reversed
%         im2=im2(:,:,[thisSlice:-1:1]);
%     end
%
%     funcVol(:,:,:,t+1)=im2;
%     %fprintf('.');
%
% end

% Crop the skipped frames
funcVol=funcVol(:,:,:,(volsToSkip+1):end);

if (rotateInplanes)
disp('Rotating');

[y x nSlices nVols]=size(funcVol)
for thisVol=1:nVols
    for thisSlice=1:nSlices
        funcVol(:,:,thisSlice,thisVol)=rot90(squeeze(funcVol(:,:,thisSlice,thisVol)),rotateInplane);
    end
end
end

% Now write them out in a different format
fprintf('\nDone reading data: Writing now...\n');
for t=1:nSlices

    tSeries=squeeze(funcVol(:,:,t,:));
    tSeries=reshape(tSeries,x*y,nVols);
    tSeries=tSeries';
    view=saveTSeries(tSeries,view,scan,t);

    fprintf('_');
end

fprintf('\nDone\n');


function [net,stats, ders_iter] = cnn_train_dag_ridge(net, imdb, input, getBatch, varargin)
%CNN_TRAIN_DAG Demonstrates training a CNN using the DagNN wrapper
%    CNN_TRAIN_DAG() is similar to CNN_TRAIN(), but works with
%    the DagNN wrapper instead of the SimpleNN wrapper.

% Copyright (C) 2014-16 Andrea Vedaldi.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

% if show test1, please assign true to is_show_test1
is_show_test1 = true;%false;%

addpath(fullfile(vl_rootnn, 'examples'));

opts.expDir = fullfile('data','exp') ;
opts.continue = true ;
opts.batchSize = 256 ;
opts.numSubBatches = 1 ;
opts.train = [] ;
opts.val = [] ;
opts.gpus = [] ;
opts.prefetch = false ;
opts.numEpochs = 300 ;
opts.learningRate = 0.001 ;
opts.weightDecay = 0.0005 ;

opts.solver = @solver.adam; % Empty array - optimised SGD solver
[opts, varargin] = vl_argparse(opts, varargin);
if isempty(opts.solver)
  opts.solverOpts.momentum = 0.9;
else
  assert(isa(opts.solver, 'function_handle') && nargout(opts.solver) == 2,...
    'Invalid solver - a function handle with two outputs expected.');
  % A call without any input arg - def opts
  opts.solverOpts = opts.solver();
end

opts.saveSolverState = true ;
opts.randomSeed = 0 ;
opts.profile = false ;
opts.parameterServer.method = 'mmap' ;
opts.parameterServer.prefix = 'mcn' ;

opts.derOutputs = {'objective_r', 1} ;
opts.extractStatsFn = @extractStats ;
opts.plotStatistics = false;
opts = vl_argparse(opts, varargin) ;

%if ~exist(opts.expDir, 'dir'), mkdir(opts.expDir) ; end
% if isempty(opts.train), opts.train = find(imdb.images.set==1) ; end
% if isempty(opts.val), opts.val = find(imdb.images.set==2) ; end
% if isnan(opts.train), opts.train = [] ; end
% if isnan(opts.val), opts.val = [] ; end

% -------------------------------------------------------------------------
%                                                            Initialization
% -------------------------------------------------------------------------

evaluateMode = isempty(opts.train) ;
if ~evaluateMode
  if isempty(opts.derOutputs)
    error('DEROUTPUTS must be specified when training.\n') ;
  end
end

% -------------------------------------------------------------------------
%                                                        Train and validate
% -------------------------------------------------------------------------

modelPath = @(ep) fullfile(opts.expDir, sprintf('net-epoch-%d.mat', ep));
modelFigPath = fullfile(opts.expDir, 'net-train.pdf') ;

start = opts.continue * findLastCheckpoint(opts.expDir) ;
if start >= 1
  fprintf('%s: resuming by loading epoch %d\n', mfilename, start) ;
  [net, state, stats] = loadState(modelPath(start)) ;
else
  state = [] ;
end

global out;
out=false;

% if is_show_test1
%     act_num = zeros(512,1);%-test1
%     epoch=0;
    ders_iter = zeros(size(input{1},3),opts.numEpochs);
% end
for epoch=start+1:opts.numEpochs

    if out
        break;
    end

  % Set the random seed based on the epoch and opts.randomSeed.
  % This is important for reproducibility, including when training
  % is restarted from a checkpoint.

  rng(epoch + opts.randomSeed) ;
  %prepareGPUs(opts, epoch == start+1) ;

  % Train for one epoch.
  params = opts ;
  params.epoch = epoch ;
  params.learningRate = opts.learningRate(min(epoch, numel(opts.learningRate))) ;
  params.train = opts.train(randperm(numel(opts.train))) ; % shuffle
  params.val = opts.val(randperm(numel(opts.val))) ;
  %params.imdb = imdb ;
  params.getBatch = getBatch ;

  if numel(opts.gpus) <= 1
    [net, state, ders_iter(:,epoch)] = processEpoch(net, input, state, params, 'train') ;
    [net, state] = processEpoch(net, input, state, params, 'val') ;
    if ~evaluateMode
      %saveState(modelPath(epoch), net, state) ;
    end
    lastStats = state.stats ;
  else
    spmd
      [net, state, ders_iter(:,epoch)] = processEpoch(net, input, state, params, 'train') ;
      [net, state] = processEpoch(net, input, state, params, 'val') ;
      if labindex == 1 && ~evaluateMode
        %saveState(modelPath(epoch), net, state) ;
      end
      lastStats = state.stats ;
    end
    lastStats = accumulateStats(lastStats) ;
  end

  stats.train(epoch) = lastStats.train ;
  stats.val(epoch) = lastStats.val ;
  clear lastStats ;
  %saveStats(modelPath(epoch), stats) ;

  if opts.plotStatistics
    switchFigure(1) ; clf ;
    plots = setdiff(...
      cat(2,...
      fieldnames(stats.train)', ...
      fieldnames(stats.val)'), {'num', 'time'}) ;
    for p = plots
      p = char(p) ;
      values = zeros(0, epoch) ;
      leg = {} ;
      for f = {'train', 'val'}
        f = char(f) ;
        if isfield(stats.(f), p)
          tmp = [stats.(f).(p)] ;
          values(end+1,:) = tmp(1,:)' ;
          leg{end+1} = f ;
        end
      end
      subplot(1,numel(plots),find(strcmp(p,plots))) ;
      plot(1:epoch, values','o-') ;
      xlabel('epoch') ;
      title(p) ;
      legend(leg{:}) ;
      grid on ;
    end
    drawnow ;
    print(1, modelFigPath, '-dpdf') ;
  end
end

% if is_show_test1
%     %-test1
%     aa=zeros(epoch,1);
%      for i=1:epoch
%         aa(i) = sum(act_num>i-1 );
%      end
%      figure,plot(aa);
%      xlabel('adjust times');
%      ylabel('channel numbers');
%      title('adjust times vs channel numbers');
%     %-test1
% end
% With multiple GPUs, return one copy
if isa(net, 'Composite'), net = net{1} ; end

% -------------------------------------------------------------------------
function [net, state, ders] = processEpoch(net, input, state, params, mode)
% -------------------------------------------------------------------------
% Note that net is not strictly needed as an output argument as net
% is a handle class. However, this fixes some aliasing issue in the
% spmd caller.

% initialize with momentum 0
if isempty(state) || isempty(state.solverState)
  state.solverState = cell(1, numel(net.params)) ;
end

% move CNN  to GPU as needed
numGpus = numel(params.gpus) ;
if numGpus >= 1
  net.move('gpu') ;
  %state.momentum = cellfun(@gpuArray, state.momentum, 'uniformoutput', false) ;
end
if numGpus > 1
  parserv = ParameterServer(params.parameterServer) ;
  net.setParameterServer(parserv) ;
else
  parserv = [] ;
end

% profile
if params.profile
  if numGpus <= 1
    profile clear ;
    profile on ;
  else
    mpiprofile reset ;
    mpiprofile on ;
  end
end

num = 0 ;
epoch = params.epoch ;
subset = params.(mode) ;
adjustTime = 0 ;

stats.num = 0 ; % return something even if subset = []
stats.time = 0 ;

start = tic ;
for t=1:params.batchSize:numel(subset)
%   fprintf('%s: epoch %02d: %3d/%3d:', mode, epoch, ...
%           fix((t-1)/params.batchSize)+1, ceil(numel(subset)/params.batchSize)) ;
  batchSize = min(params.batchSize, numel(subset) - t + 1) ;

  for s=1:params.numSubBatches
    % get this image batch and prefetch the next
    batchStart = t + (labindex-1) + (s-1) * numlabs ;
    batchEnd = min(t+params.batchSize-1, numel(subset)) ;
    batch = subset(batchStart : params.numSubBatches * numlabs : batchEnd) ;
    num = num + numel(batch) ;
    if numel(batch) == 0, continue ; end

    feats=input{1};
    labels=input{2};

%lx     inputs ={'input1', gpuArray(ims),'input2', ...
%          gpuArray(ims), 'label', gpuArray(labels)};
    inputs ={'input', feats, 'label_gaussian', labels};

    if params.prefetch
      if s == params.numSubBatches
        batchStart = t + (labindex-1) + params.batchSize ;
        batchEnd = min(t+2*params.batchSize-1, numel(subset)) ;
      else
        batchStart = batchStart + numlabs ;
      end
      nextBatch = subset(batchStart : params.numSubBatches * numlabs : batchEnd) ;
      %params.getBatch(params.imdb, nextBatch) ;
    end

    if strcmp(mode, 'train')
      net.mode = 'normal' ;
      net.accumulateParamDers = (s ~= 1) ;
      net.eval(inputs, params.derOutputs, 'holdOn', s < params.numSubBatches) ;
%         if is_show_test1
%               showing gradient value in each depth channel %-test1
              ders = squeeze(gather(sum(sum(net.vars(1).der))));
%                 ders = squeeze(gather(sum(sum(net.params(1).der))));
%               figure(3);
%               plot(a);
%               xlabel('channel number'); ylabel('value');title('gradient weights');
%               [val, ind] = sort(a,'descend');
%               act_num(ind(1:64))= act_num(ind(1:64))+1;  %-test1
%         end
    else
      net.mode = 'test' ;
      net.eval(inputs) ;
    end
  end

  % Accumulate gradient.
  if strcmp(mode, 'train')
    if ~isempty(parserv), parserv.sync() ; end
    state = accumulateGradients(net, state, params, batchSize, parserv) ;
  end

  % Get statistics.
  time = toc(start) + adjustTime ;
  batchTime = time - stats.time ;
  stats.num = num ;
  stats.time = time ;
  stats = params.extractStatsFn(stats,net) ;
  currentSpeed = batchSize / batchTime ;
  averageSpeed = (t + batchSize - 1) / time ;
  if t == 3*params.batchSize + 1
    % compensate for the first three iterations, which are outliers
    adjustTime = 4*batchTime - time ;
    stats.time = time + adjustTime ;
  end

%   fprintf(' %.1f (%.1f) Hz', averageSpeed, currentSpeed) ;
  for f = setdiff(fieldnames(stats)', {'num', 'time'})
    f = char(f) ;
    fprintf(' %s: %.8f', f, stats.(f)) ;

    if strcmp(f,'objective_r')&& stats.(f)<0.02
        global out;
        out=true;
    end
    break;
  end
  fprintf('\n') ;
end

% Save back to state.
state.stats.(mode) = stats ;
if params.profile
  if numGpus <= 1
    state.prof.(mode) = profile('info') ;
    profile off ;
  else
    state.prof.(mode) = mpiprofile('info');
    mpiprofile off ;
  end
end
if ~params.saveSolverState
  state.solverState = [] ;
else
  state.solverState = cellfun(@gather, state.solverState, 'uniformoutput', false) ;
end

net.reset() ;
%net.move('cpu') ;

% -------------------------------------------------------------------------
function state = accumulateGradients(net, state, params, batchSize, parserv)
% -------------------------------------------------------------------------
numGpus = numel(params.gpus) ;
otherGpus = setdiff(1:numGpus, labindex) ;

for p=1:numel(net.params)

  if ~isempty(parserv)
    parDer = parserv.pullWithIndex(p) ;
  else
    parDer = net.params(p).der ;
  end

  switch net.params(p).trainMethod

    case 'average' % mainly for batch normalization
      thisLR = net.params(p).learningRate ;
      net.params(p).value = vl_taccum(...
          1 - thisLR, net.params(p).value, ...
          (thisLR/batchSize/net.params(p).fanout),  parDer) ;

    case 'gradient'
      thisDecay = params.weightDecay * net.params(p).weightDecay ;
      thisLR = params.learningRate * net.params(p).learningRate ;

      if isempty(params.solver)
        if isempty(state.solverState{p})
          state.solverState{p} = zeros(size(parDer), 'like', parDer);
        end

        state.solverState{p} = vl_taccum(...
          params.solverOpts.momentum,  state.solverState{p}, ...
          - (1 / batchSize), parDer) ;
        net.params(p).value = vl_taccum(...
          (1 - thisLR * thisDecay / (1 - params.solverOpts.momentum)),  ...
          net.params(p).value, ...
          thisLR, state.solverState{p}) ;
      else
        grad = (1 / batchSize) * parDer + thisDecay * net.params(p).value;
        % call solver function to update weights
        [net.params(p).value, state.solverState{p}] = ...
          params.solver(net.params(p).value, state.solverState{p}, ...
          grad, params.solverOpts, thisLR) ;
      end

    otherwise
      error('Unknown training method ''%s'' for parameter ''%s''.', ...
        net.params(p).trainMethod, ...
        net.params(p).name) ;
  end
end

% -------------------------------------------------------------------------
function stats = accumulateStats(stats_)
% -------------------------------------------------------------------------

for s = {'train', 'val'}
  s = char(s) ;
  total = 0 ;

  % initialize stats stucture with same fields and same order as
  % stats_{1}
  stats__ = stats_{1} ;
  names = fieldnames(stats__.(s))' ;
  values = zeros(1, numel(names)) ;
  fields = cat(1, names, num2cell(values)) ;
  stats.(s) = struct(fields{:}) ;

  for g = 1:numel(stats_)
    stats__ = stats_{g} ;
    num__ = stats__.(s).num ;
    total = total + num__ ;

    for f = setdiff(fieldnames(stats__.(s))', 'num')
      f = char(f) ;
      stats.(s).(f) = stats.(s).(f) + stats__.(s).(f) * num__ ;

      if g == numel(stats_)
        stats.(s).(f) = stats.(s).(f) / total ;
      end
    end
  end
  stats.(s).num = total ;
end

% -------------------------------------------------------------------------
function stats = extractStats(stats, net)
% -------------------------------------------------------------------------
sel = find(cellfun(@(x) isa(x,'dagnn.Loss'), {net.layers.block})) ;
for i = 1:numel(sel)
  stats.(net.layers(sel(i)).outputs{1}) = net.layers(sel(i)).block.average ;
end

% -------------------------------------------------------------------------
function saveState(fileName, net_, state)
% -------------------------------------------------------------------------
net = net_.saveobj() ;
save(fileName, 'net', 'state') ;

% -------------------------------------------------------------------------
function saveStats(fileName, stats)
% -------------------------------------------------------------------------
if exist(fileName)
  save(fileName, 'stats', '-append') ;
else
  save(fileName, 'stats') ;
end

% -------------------------------------------------------------------------
function [net, state, stats] = loadState(fileName)
% -------------------------------------------------------------------------
load(fileName, 'net', 'state', 'stats') ;
net = dagnn.DagNN.loadobj(net) ;
if isempty(whos('stats'))
  error('Epoch ''%s'' was only partially saved. Delete this file and try again.', ...
        fileName) ;
end

% -------------------------------------------------------------------------
function epoch = findLastCheckpoint(modelDir)
% -------------------------------------------------------------------------
list = dir(fullfile(modelDir, 'net-epoch-*.mat')) ;
tokens = regexp({list.name}, 'net-epoch-([\d]+).mat', 'tokens') ;
epoch = cellfun(@(x) sscanf(x{1}{1}, '%d'), tokens) ;
epoch = max([epoch 0]) ;

% -------------------------------------------------------------------------
function switchFigure(n)
% -------------------------------------------------------------------------
if get(0,'CurrentFigure') ~= n
  try
    set(0,'CurrentFigure',n) ;
  catch
    figure(n) ;
  end
end

% -------------------------------------------------------------------------
function clearMex()
% -------------------------------------------------------------------------
clear vl_tflow vl_imreadjpeg ;

% -------------------------------------------------------------------------
function prepareGPUs(opts, cold)
% -------------------------------------------------------------------------
numGpus = numel(opts.gpus) ;
if numGpus > 1
  % check parallel pool integrity as it could have timed out
  pool = gcp('nocreate') ;
  if ~isempty(pool) && pool.NumWorkers ~= numGpus
    delete(pool) ;
  end
  pool = gcp('nocreate') ;
  if isempty(pool)
    parpool('local', numGpus) ;
    cold = true ;
  end

end
if numGpus >= 1 && cold
  fprintf('%s: resetting GPU\n', mfilename)
  clearMex() ;
  if numGpus == 1
    gpuDevice(opts.gpus)
  else
    spmd
      clearMex() ;
      gpuDevice(opts.gpus(labindex))
    end
  end
end