depthfileNamesFile = fopen('sunrgbd_train_depth_fileNames.txt','w');
res_file = fopen('sunrgbd_train_res_fileNames.txt','w');
K_file = fopen('sunrgbd_train_K_fileNames.txt','w');
T_file = fopen('sunrgbd_train_T_fileNames.txt','w');

for i = 1:5285

    i

    k = i+5050;

    fName = mat2str(cell2mat(alltrain(i)));
    fName = strcat('/scratch/SUNRGBD_13',fName(18:end-1),'/depth_bfx/');

    X = dir(fName);

    depth = X(3).name;
    depth = strcat(fName,depth);

    fprintf(depthfileNamesFile,'%s\n',depth);

    Id = double(imread(depth))/10000.0;
%     I = SUNRGBD2Dseg(k).seglabel;

    K = SUNRGBDMeta(k).K;
    Rtilt = SUNRGBDMeta(k).Rtilt;

%     size(Rtilt)

%     X = [1 0 0;
%          0 0 1;
%          0 -1 0];

% %      Rtilt = X * Rtilt * X';

%     Rtilt = X*Rtilt*X';

    fprintf(res_file,'%d %d\n',size(Id,2), size(Id,1));

    fprintf(K_file,'%f %f %f\n',K(1,1),K(1,2),K(1,3));
    fprintf(K_file,'%f %f %f\n',K(2,1),K(2,2),K(2,3));
    fprintf(K_file,'%f %f %f\n\n',K(3,1),K(3,2),K(3,3));

    val_zero = 0.0;

    fprintf(T_file,'%f %f %f %f\n',Rtilt(1,1),Rtilt(1,2),Rtilt(1,3),val_zero);
    fprintf(T_file,'%f %f %f %f\n',Rtilt(2,1),Rtilt(2,2),Rtilt(2,3),val_zero);
    fprintf(T_file,'%f %f %f %f\n\n',Rtilt(3,1),Rtilt(3,2),Rtilt(3,3),val_zero);

%     normals = compute_normals(Id,size(Id,2),size(Id,1),K(1,1), K(2,2), K(1,3), K(2,3), 1);
%
%     [U, V] = meshgrid(1:size(Id,2),1:size(Id,1));
%
%     X = Id.*(U - K(1,3))/K(1,1);
%     Y = Id.*(V - K(2,3))/K(2,2);
%     Z = Id;
%
%     XDash = Rtilt(1,1)*X + Rtilt(1,2)*Y + Rtilt(1,3)*Z;
%     YDash = Rtilt(2,1)*X + Rtilt(2,2)*Y + Rtilt(2,3)*Z;
%     ZDash = Rtilt(3,1)*X + Rtilt(3,2)*Y + Rtilt(3,3)*Z;
%
%     YDash = (YDash - min(min(YDash)));
%
%     normal_x= normals(:,:,1);
%     normal_y= normals(:,:,2);
%     normal_z= normals(:,:,3);
%
%     new_normals_x = Rtilt(1,1)*normal_x + Rtilt(1,2)*normal_y + Rtilt(1,3)*normal_z;
%     new_normals_y = Rtilt(2,1)*normal_x + Rtilt(2,2)*normal_y + Rtilt(2,3)*normal_z;
%     new_normals_z = Rtilt(3,1)*normal_x + Rtilt(3,2)*normal_y + Rtilt(3,3)*normal_z;
%
%     new_normals(:,:,1) = new_normals_x;
%     new_normals(:,:,2) = new_normals_y;
%     new_normals(:,:,3) = new_normals_z;
%
%     angle = acosd(new_normals(:,:,2))/180.0;
%
%     size(normals);
%
%     file1 = fopen(sprintf('train-dha-%04d.bin',i),'wb');
%
%     Id    = imresize(Id,   [224 224],'bilinear');
%     YDash = imresize(YDash,[224 224],'bilinear');
%     angle = imresize(angle,[224 224],'bilinear');
%
%     YDash(isnan(YDash))=0;
%     angle(isnan(angle))=0;
%
%     for i = 1:224
%         for j = 1:224
%             fwrite(file1,single(Id(i,j)),'float');
%             fwrite(file1,single(YDash(i,j)),'float');
%             fwrite(file1,single(angle(i,j)),'float');
%         end
%     end
%
%
%     fclose(file1);

%   [sum(isnan(I(:))), sum(isnan(YDash(:))), sum(isnan(angle(:)))]

end

%     fclose(depthfileNamesFile);
%     fclose(res_file);
%     fclose(T_file);
%     fclose(K_file);


function [] = PSDSInSAR_estimator(Coh,  slcstack, slclist, interfstack, interflist, SHP, reference_ind,  InSAR_path, BroNumthre, Cohthre, Cohthre_slc_filt, InSAR_processor)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   This file is part of TomoSAR.
%
%   TomoSAR is distributed in the hope that it will be useful,
%   but without warranty of any kind; without even the implied
%   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
%   See the Apache License for more details.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Author : Dinh Ho Tong Minh (INRAE) and Yen Nhi Ngo, Jan. 2022
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% This function provides the combination of PS and DS targets
% see more detail in section 2 of [1]:
% [1] Dinh Ho Tong Minh and Yen Nhi Ngo.
% "Compressed SAR Interferometry in the Big Data Era". Remote Sensing.
% 2022, 14, 390. https://doi.org/10.3390/rs14020390
%
% This file can be used only for research purposes, you should cite
% the aforementioned papers in any resulting publication.
%

% Phase Linking
[phi_PL,Coh_cal] =  Intf_PL(Coh, 10,reference_ind);

% Phase filtering
[infstack_filt] = Intf_filt(interfstack,SHP,phi_PL,Coh_cal,reference_ind,BroNumthre,Cohthre);

% DeSpeckle
mli_despeckle = Image_DeSpeckle(abs(slcstack),SHP);
[SLCstack] = SLC_filt(mli_despeckle,slcstack,SHP,Coh_cal,BroNumthre,Cohthre_slc_filt);

% Export
switch InSAR_processor
    case 'snap' %
        Intf_export(infstack_filt,interflist,[InSAR_path,'/diff0'],'.psds');
        SLC_export(SLCstack,slclist,[InSAR_path,'/rslc'],'.psar');
    case 'isce'
        Intf_export(infstack_filt,interflist,InSAR_path,'.psds',InSAR_processor);
        SLC_export(SLCstack,slclist,InSAR_path,'.psar',InSAR_processor,reference_ind);
    otherwise
        disp('not yet support')
end

return


function [media,density,medname,xbound,ybound,zbound] = dicomrt_readegs4phant(patient_position,filename)
% dicomrt_readegs4phant(patient_position,filename)
%
% Read a ct phantom which comply to BEAM/DOSXYZ file format
% Return media matrix and density matrix.
%
% patient_position is a code which correspond to one of the supported
% patient position cases
% Filename is an character string which contain the name of the egs4phantom file (no extension).
%
% Example:
%
% [A,B,medname]=dicomrt_readegs4phant(1,'demo')
%
% will store in A the medium number and in B the density read from the egs4phantom demo.egs4phant;
% Materials name are stored in medname. This information is required when converting
% dose2medium <-> dose2water.
%
% See also dicomrt_ctcreate, dicomrt_getPatientPosition
%
% Copyright (C) 2002 Emiliano Spezi (emiliano.spezi@physics.org)

filename=[filename,'.egs4phant'];
fid=fopen(filename);
nummedia = fscanf(fid,'%i');
medname=cell(nummedia,1);

for i=1:nummedia
    medname{i,1}=fgetl(fid);
end

for i=1:nummedia
    estepe(i,:) = fscanf(fid,'%f',1);
end

global xnum;
global ynum;
global znum;

xnum = fscanf(fid,'%i',1);
ynum = fscanf(fid,'%i',1);
znum = fscanf(fid,'%i',1);

xbound = fscanf(fid,'%f',xnum+1);
ybound = fscanf(fid,'%f',ynum+1);
zbound = fscanf(fid,'%f',znum+1);

xbound = dicomrt_mmdigit(xbound,7,10,'fix');
ybound = dicomrt_mmdigit(ybound,7,10,'fix');
zbound = dicomrt_mmdigit(zbound,7,10,'fix');

if patient_position == 1
    % 1st case: supported Patient Position is HFS
    %load the media matrix
    media=[];
    for k=1:znum
        media_temp = fscanf(fid,'%1i',[xnum, ynum]);
        media(:,:,k) = media_temp';
        line = fgets(fid);
    end
    % load the density matrix
    for k = 1:znum
        density_temp = fscanf(fid,'%f',[xnum, ynum]);
        density(:,:,k) = density_temp';
    end
elseif patient_position == 2
    % 2nd case: supported Patient Position is FFS
    %load the media matrix
    media=[];
    for k=1:znum
        media_temp = fscanf(fid,'%1i',[xnum, ynum]);
        media(:,:,k) = media_temp';
        line = fgets(fid);
    end
    % load the density matrix
    for k = 1:znum
        density_temp = fscanf(fid,'%f',[xnum, ynum]);
        density(:,:,k) = density_temp';
    end
end
fclose(fid);


function out = spm_shoot_warp(job)
% Register images with template
% format spm_shoot_warp(job)
% Fields of job:
%     job.images{1} first set of images (eg rc1*.nii)
%     job.images{2} second set of images (eg rc2*.nii)
%     etc
%     job.templates template files
% Other settings are defined in spm_shoot_defaults.m
%
% The outputs are flow fields (v*.nii), deformation fields (y*.nii) and
% Jacobian determinants (j*.nii)
%_______________________________________________________________________
% Copyright (C) Wellcome Trust Centre for Neuroimaging (2009)

% John Ashburner
% $Id: spm_shoot_warp.m 7389 2018-08-06 13:35:48Z john $

%_______________________________________________________________________
d       = spm_shoot_defaults;
tname   = d.tname;   % Base file name for templates

cyc_its = d.cyc_its; % No. multigrid cycles and inerations
sched   = d.sched;   % Schedule for coarse to fine
nits    = numel(sched)-1;
rparam  = d.rparam;  % Regularisation parameters for deformation
eul_its = d.eul_its; % Start with fewer steps
scale   = d.scale;   % Fraction of Gauss-Newton update step to use

bs_args = d.bs_args; % B-spline settings for interpolation
%_______________________________________________________________________

spm_diffeo('boundary',0); % Set boundary condition

% Sort out handles to images
n1 = numel(job.images);
n2 = numel(job.images{1});
NF = struct('NI',[],'vn',[1 1]);
NF(n1,n2) = struct('NI',[],'vn',[1 1]);

% Pick out individual volumes within NIfTI files
for i=1:n1
    if numel(job.images{i}) ~= n2
        error('Incompatible number of images');
    end
    for j=1:n2
        [pth,nam,ext,num] = spm_fileparts(job.images{i}{j});
        NF(i,j).NI        = nifti(fullfile(pth,[nam ext]));
        num               = [str2num(num) 1 1];
        NF(i,j).vn        = num(1:2);
    end
end

dm = [size(NF(1,1).NI.dat) 1];
dm = dm(1:3);

% Sort out which template for each iteration
tmpl_no = round(((1:nits)-1)/(nits-1)*(numel(job.templates)-0.51))+1;

ok = true(n2,1);

NU     = nifti;
NU(n2) = nifti;
NY     = nifti;
NY(n2) = nifti;
NJ     = nifti;
NJ(n2) = nifti;

for i=1:n2 % Loop over subjects

    % Generate files for flow fields, deformations and Jacobian determinants.
    [pth,nam,ext]   = fileparts(NF(1,i).NI.dat.fname);
    if ~isempty(tname), nam = [nam '_' tname]; end
    offs  = 352;

    NU(i) = nifti;
    NU(i).dat = file_array(fullfile(pth,['v_' nam '.nii']),[dm 1 3], 'float32-le', offs, 1, 0);
    NU(i).descrip = sprintf('Velocity (%d %.4g %.4g %.4g)', rparam(1), rparam(2), rparam(3), rparam(4));
    NU(i).mat     = NF(1,i).NI.mat;
    NU(i).mat0    = NF(1,i).NI.mat0;
    create(NU(i)); NU(i).dat(:,:,:,:,:) = 0;

    NY(i) = nifti;
    NY(i).dat = file_array(fullfile(pth,['y_' nam '.nii']),[dm 1 3], 'float32-le', offs, 1, 0);
    NY(i).descrip = 'Deformation (templ. to. ind.)';
    NY(i).mat     = NF(1,i).NI.mat;
    create(NY(i)); NY(i).dat(:,:,:,:,:) = reshape(affind(spm_diffeo('Exp',zeros([dm,3],'single'),[0 1]),NU(i).mat0),[dm,1,3]);

    NJ(i) = nifti;
    NJ(i).dat = file_array(fullfile(pth,['j_' nam '.nii']),[dm 1 1], 'float32-le', offs, 1, 0);
    NJ(i).descrip = 'Jacobian det (templ. to. ind.)';
    NJ(i).mat     = NF(1,i).NI.mat;
    create(NJ(i)); NJ(i).dat(:,:,:)     = 1;

    drawnow
end

for i=1:n2 % Loop over subjects. Can replace FOR with PARFOR.

    % Load image data for this subject
    f  = loadimage(NF(:,i));
    u  = squeeze(single(NU(i).dat(:,:,:,:,:)));
    y  = affind(squeeze(single(NY(i).dat(:,:,:,:,:))),inv(NU(i).mat0));
    dt = squeeze(single(NJ(i).dat(:,:,:)));

    % Re-load first template
    [g,vx] = load_template(job.templates{tmpl_no(1)}, n1, bs_args);

    % The actual work
    for it=1:nits

        % Load template appropriate for this iteration
        if (it>1) && (tmpl_no(it)~=tmpl_no(it-1))
            [g,vx] = load_template(job.templates{tmpl_no(it)}, n1, bs_args);
        end

        % More regularisation in the early iterations, as well as a
        % a less accurate approximation in the integration.
        prm      = [vx, rparam*sched(it+1)*prod(vx)];
        int_args = [eul_its(it), cyc_its];
        drawnow

        fprintf(' %-5d %-3d\t| ',i,it);

        % Gauss-Newton iteration to re-estimate deformations for this subject
        u      = spm_shoot_update(g,f,u,y,dt,prm,bs_args,scale); drawnow
        [y,dt] = defdet(u,prm,int_args);

        if any(~isfinite(dt(:)) | dt(:)>100 | dt(:)<1/100)
            ok(i) = false;
            fprintf('Problem with %s (dets: %g .. %g)\n', NU(i).dat.fname, min(dt(:)), max(dt(:)));
           %clear dt
            break
        end

        drawnow
        NU(i).dat(:,:,:,:,:) = reshape(u,[dm 1 3]);
        NY(i).dat(:,:,:,:,:) = reshape(affind(y,NU(i).mat0),[dm 1 3]);
        NJ(i).dat(:,:,:)     = dt;

    end
    fprintf('\n');

    drawnow
end

if any(~ok)
    fprintf('Problems with:\n');
    for i=find(~ok)'
        fprintf('\t%s\n', NU(i).dat.fname);
    end
end

% Finish off
out.vel = cell(n2,1);
out.def = cell(n2,1);
out.jac = cell(n2,1);
for i=1:n2
    out.vel{i} = NU(i).dat.fname;
    out.def{i} = NY(i).dat.fname;
    out.jac{i} = NJ(i).dat.fname;
end
%=======================================================================

%=======================================================================
function y1 = affind(y0,M)
% Affine transform of deformation
y1 = zeros(size(y0),'single');
for d=1:3
    y1(:,:,:,d) = y0(:,:,:,1)*M(d,1) + y0(:,:,:,2)*M(d,2) + y0(:,:,:,3)*M(d,3) + M(d,4);
end
%=======================================================================

%=======================================================================
function f = loadimage(NF)
n1      = size(NF,1);
f       = cell(n1+1,1);
dm      = [NF(1).NI.dat.dim 1 1 1];
dm      = dm(1:3);
f{n1+1} = ones(dm,'single');
for j=1:n1
    vn      = NF(j,1).vn;
    f{j}    = single(NF(j,1).NI.dat(:,:,:,vn(1),vn(2)));
    msk     = ~isfinite(f{j});
    f{j}(msk) = 0;
    f{n1+1} = f{n1+1} - f{j};
    drawnow
end
f{n1+1}(msk) = 0.00001;
%=======================================================================

%=======================================================================
function [g,vx] = load_template(template, n1, bs_args)
g  = cell(n1+1,1);
NG = nifti(template);
if size(NG.dat,4) < n1+1
    error('Not enough tissues in template (%d < %d+1).', size(NG.dat,4),n1);
end

bg = ones([size(NG.dat,1), size(NG.dat,2), size(NG.dat,3)]);
for j=1:n1
    tmp  = NG.dat(:,:,:,j);
    g{j} = spm_bsplinc(log(tmp), bs_args);
    bg   = bg - tmp;
    clear tmp;
end
g{n1+1}  = log(max(bg,eps));
clear bg

vx = sqrt(sum(NG.mat(1:3,1:3).^2));
%=======================================================================

%=======================================================================
function [y,dt] = defdet(u,prm,int_args)
% Generate deformation
[y,J] = spm_shoot3d(u,prm,int_args);
dt    = spm_diffeo('det',J);
%=======================================================================

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


function [Ef, Varf, lpy, Ey, Vary] = gpmc_loopreds(gp, x, y, varargin)
%GPMC_LOOPREDS  Leave-one-out predictions with Gaussian Process MCMC approximation
%
%  Description
%    [EFT, VARFT, LPYT, EYT, VARYT] = GPMC_LOOPREDS(RECGP, X, Y)
%    takes a Gaussian processes record structure RECGP (returned by
%    gp_mc) together with a matrix X of training inputs and vector
%    Y of training targets, and evaluates the leave-one-out
%    predictive distribution at inputs X and returns means EFT and
%    variances VARFT of latent variables, the logarithm of the
%    predictive densities PYT, and the predictive means EYT and
%    variances VARYT of observations at input locations X.
%
%    OPTIONS is optional parameter-value pair
%      z      - optional observed quantity in triplet (x_i,y_i,z_i)
%               Some likelihoods may use this. For example, in case of
%               Poisson likelihood we have z_i=E_i, that is, expected value
%               for ith case.
%    Note:
%      - the hyperparameters, hp, are sampled from the full
%        posterior p(hp|x,y) by gp_mc
%      - in case of Gaussian likelihood or non-Gaussian likelihood
%        and latent method Laplace/EP, the conditonal LOO-CV
%        distributions p(f_i | x_\i, y_\i, z_\i, hp_s) are computed
%        for each hyperparameter sample hp_s
%      - use gp_loopred to evaluate p(f_i | x_\i, y_\i, z_\i)
%
%  See also
%   GP_LOOPRED
%
% Copyright (c) 2008-2010,2012 Jarno Vanhatalo
% Copyright (c) 2010,2012 Aki Vehtari

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.

% Nothing to parse, but check the arguments anyway
ip=inputParser;
ip.FunctionName = 'GPMC_LOOPREDS';
ip.addRequired('gp',@isstruct);
ip.addRequired('x', @(x) ~isempty(x) && isreal(x) && all(isfinite(x(:))))
ip.addRequired('y', @(x) ~isempty(x) && isreal(x) && all(isfinite(x(:))))
ip.addParamValue('z', [], @(x) isreal(x) && all(isfinite(x(:))))
ip.parse(gp, x, y, varargin{:});
z=ip.Results.z;

if isfield(gp,'meanf') & ~isempty(gp.meanf)
  error('GPMC_LOOPREDS: Mean functions not yet supported');
end

nmc=size(gp.jitterSigma2,1);

if isfield(gp, 'latentValues') && ~isempty(gp.latentValues)
  % Non-Gaussian likelihood. The latent variables should be used in
  % place of observations
  lv = gp.latentValues';
end

for i1=1:nmc
  Gp = take_nth(gp,i1);
  if isfield(Gp,'latent_method') && isequal(Gp.latent_method,'MCMC')
    Gp = rmfield(Gp,'latent_method');
  end

  if isfield(gp, 'latentValues') && ~isempty(gp.latentValues)
    % latent values have been sampled with MCMC
    [Ef(:,i1), Varf(:,i1)] = gp_loopred(Gp, x, lv(:,i1), varargin{:});
    if nargout >=4
      [lpy(:,i1), Ey(:,i1), Vary(:,i1)] = Gp.lik.fh.predy(Gp.lik, Ef(:,i1), Varf(:,i1), y, z);
    else
      lpy(:,i1) = Gp.lik.fh.predy(Gp.lik, Ef(:,i1), Varf(:,i1), y, z);
    end
  else
    % Gaussian likelihood or Laplace/EP for latent values
    if nargout <= 2
      [Ef(:,i1), Varf(:,i1)] = gp_loopred(Gp, x, y, varargin{:});
    elseif nargout <=3
      [Ef(:,i1), Varf(:,i1), lpy(:,1)] = gp_loopred(Gp, x, y, varargin{:});
    else
      [Ef(:,i1), Varf(:,i1), lpy(:,1), Ey(:,i1), Vary(:,i1)] = gp_loopred(Gp, x, y, varargin{:});
    end
  end
end


% this is a demo low-performance EPI sequence;
% it doesn't use ramp-samping and is only good for educational purposes.
% in addition, it demonstrated how LABEL extension can be used to set data
% header values, which can be used either in combination with integrated
% image reconstruction or to guide the off-line reconstruction tools
%
seq=mr.Sequence();              % Create a new sequence object
fov=220e-3; Nx=96; Ny=Nx;       % Define FOV and resolution
thickness=3e-3;                 % slice thinckness
Nslices=7;
Nreps = 4;
Navigator = 3;

% Set system limits
lims = mr.opts('MaxGrad',32,'GradUnit','mT/m',...
               'MaxSlew',130,'SlewUnit','T/m/s', ...
               'rfRingdownTime', 30e-6, 'rfDeadTime', 100e-6);

% Create 90 degree slice selection pulse and gradient
[rf, gz] = mr.makeSincPulse(pi/2,'system',lims,'Duration',3e-3,...
    'SliceThickness',thickness,'apodization',0.5,'timeBwProduct',4);

% define the trigger to play out
trig=mr.makeTrigger('physio1','duration', 2000e-6); % duration after

% Define other gradients and ADC events
deltak=1/fov;
kWidth = Nx*deltak;
dwellTime = 4e-6; % I want it to be divisible by 2
readoutTime = Nx*dwellTime;
flatTime=ceil(readoutTime*1e5)*1e-5; % round-up to the gradient raster
gx = mr.makeTrapezoid('x',lims,'Amplitude',kWidth/readoutTime,'FlatTime',flatTime);
adc = mr.makeAdc(Nx,'Duration',readoutTime,'Delay',gx.riseTime+flatTime/2-(readoutTime-dwellTime)/2);

% Pre-phasing gradients
preTime=8e-4;
gxPre = mr.makeTrapezoid('x',lims,'Area',-gx.area/2,'Duration',preTime); % removed -deltak/2 to aligh the echo between the samples
gzReph = mr.makeTrapezoid('z',lims,'Area',-gz.area/2,'Duration',preTime);
gyPre = mr.makeTrapezoid('y',lims,'Area',+Ny/2*deltak,'Duration',preTime); % phase area should be Kmax for clin=0 and -Kmax for clin=Ny... strange

% Phase blip in shortest possible time
dur = ceil(2*sqrt(deltak/lims.maxSlew)/10e-6)*10e-6;
gy = mr.makeTrapezoid('y',lims,'Area',-deltak,'Duration',dur); % phase area should be Kmax for clin=0 and -Kmax for clin=Ny... strange

gz_spoil=mr.makeTrapezoid('z',lims,'Area',deltak*Nx*4);

% Define sequence blocks
for r=1:Nreps
    seq.addBlock(trig, mr.makeLabel('SET','SLC', 0));
    for s=1:Nslices
        rf.freqOffset=gz.amplitude*thickness*(s-1-(Nslices-1)/2);
        rf.phaseOffset=-rf.freqOffset*mr.calcRfCenter(rf); % compensate for the slice-offset induced phase
        seq.addBlock(rf,gz);
        seq.addBlock(gxPre,gzReph, ...
                     mr.makeLabel('SET','NAV',1),...
                     mr.makeLabel('SET','LIN', round(Ny/2)));
        for n=1:Navigator
            seq.addBlock(gx,adc, ...
                         mr.makeLabel('SET','REV', gx.amplitude<0), ...
                         mr.makeLabel('SET','SEG', gx.amplitude<0), ...
                         mr.makeLabel('SET','AVG',n==3));
            if (n~=Navigator)
                seq.addBlock(mr.makeDelay(mr.calcDuration(gy))); % we need this dummy blip pulse to maintain ientical RO gradient timing anf the correspnding eddy currents
            end
            gx.amplitude = -gx.amplitude;   % Reverse polarity of read gradient
        end
        %seq.addBlock(gxPre,gyPre,gzReph);
        seq.addBlock(gyPre, ...
                     mr.makeLabel('SET','LIN', 0), ...
                     mr.makeLabel('SET','NAV', 0), ...
                     mr.makeLabel('SET','AVG', 0) );% lin/nav/avg reset
        for i=1:Ny
            seq.addBlock(mr.makeLabel('SET','REV', gx.amplitude<0), ...
                         mr.makeLabel('SET','SEG', gx.amplitude<0));
            seq.addBlock(gx,adc);   % Read one line of k-space
            seq.addBlock(gy,mr.makeLabel('INC','LIN', 1));  % Phase blip
            gx.amplitude = -gx.amplitude;   % Reverse polarity of read gradient
        end
        seq.addBlock(gz_spoil,mr.makeDelay(0.1),mr.makeLabel('INC','SLC', 1));
        if rem(Navigator+Ny,2)~=0
            gx.amplitude = -gx.amplitude;
        end
    end
    seq.addBlock(mr.makeLabel('INC','REP', 1)); % zero-duration block, but it's OK
end

%% check whether the timing of the sequence is correct
[ok, error_report]=seq.checkTiming;

if (ok)
    fprintf('Timing check passed successfully\n');
else
    fprintf('Timing check failed! Error listing follows:\n');
    fprintf([error_report{:}]);
    fprintf('\n');
end

%% prepare sequence export
seq.setDefinition('FOV', [fov fov thickness*Nslices]);
seq.setDefinition('Name', 'epi_lbl');

seq.write('epi_label.seq');   % Output sequence for scanner

return

%% plots, etc.
seq.plot('TimeRange',[0 0.1], 'TimeDisp', 'ms', 'Label', 'SEG,LIN,SLC');
% trajectory calculation
[ktraj_adc, t_adc, ktraj, t_ktraj, t_excitation, t_refocusing] = seq.calculateKspacePP();

% plot k-spaces
figure; plot(t_ktraj, ktraj'); % plot the entire k-space trajectory
hold; plot(t_adc,ktraj_adc(1,:),'.'); % and sampling points on the kx-axis
figure; plot(ktraj(1,:),ktraj(2,:),'b'); % a 2D plot
axis('equal'); % enforce aspect ratio for the correct trajectory display
hold; plot(ktraj_adc(1,:),ktraj_adc(2,:),'r.');

% seq.sound(); % simulate the seq's tone
% test read-write
%seq.read('epi_label.seq');
%seq.write('epi_label2.seq');


function colorsurface( ptch, cameras )
%COLORSURFACE: color in a surface based on image data
%
%   COLORSURFACE(PTCH,CAMERAS) colors-in each vertex of the patch PTCH
%   using the nearest image pixel in one of the cameras in CAMERAS.

%   Copyright 2005-2009 The MathWorks, Inc.
%   $Revision: 1.0 $    $Date: 2006/06/30 00:00:00 $

error( nargchk( 2, 2, nargin ) );

if ~ishandle( ptch ) || ~strcmpi( get( ptch, 'Type' ), 'patch' )
    error( 'COLORSURFACE:BadPatch', 'First argument must the handle to a patch object created using the PATCH command' );
end

vertices = get( ptch, 'Vertices' );
normals = get( ptch, 'VertexNormals' );
num_vertices = size( vertices, 1 );

% Get the view vector for each camera
num_cameras = numel( cameras );
cam_normals = zeros( 3, num_cameras );
for ii=1:num_cameras
    cam_normals(:,ii) = spacecarving.getcameradirection( cameras(ii) );
end

% For each vertex, use the normal to find the best camera and then lookup
% the value.
vertexcdata = zeros( num_vertices, 3 );
for ii=1:num_vertices
    % Use the dot product to find the best camera
    angles = normals(ii,:)*cam_normals./norm(normals(ii,:));
    [~,cam_idx] = min( angles );
    % Now project the vertex into the chosen camera
    [imx,imy] = spacecarving.project( cameras(cam_idx), ...
        vertices(ii,1), vertices(ii,2), vertices(ii,3) );
    vertexcdata(ii,:) = double( cameras(cam_idx).Image( round(imy), round(imx), : ) )/255;
end

% Set it into the patch
set( ptch, 'FaceVertexCData', vertexcdata, 'FaceColor', 'interp' );


function Q = cost(V,t,tc,Run)
%
% Least-squares cost function for the IL model
%
% INPUT:
% Run = stick function
% tc = time course
% t = vector of time points
% V = parameters
%
% OUTPUT:
% Q = cost
%
% By Martin Lindquist and Tor Wager
% Edited 12/12/06
%

len = length(Run);

h1 = Get_Logit(V(1:7),t);           % Get IL model corresponding to parameters V
yhat = conv(Run, h1);               % Convolve IL model with stick function
yhat = yhat(1:len);

Q = sum((yhat-tc).^2);              % Calculate cost function

return


function plot_pcolor(vResults,j)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% example: plot_pcolor(vResults,85)
%
%  vResults : result matrix
%  i : position in result matrix
%  j : no of simulation to plot
%
%
figure;
set(gca,'LineWidth',2);
set(gca,'FontSize',14);
set(get(gca,'XLabel'),'FontSize',16);
set(get(gca,'YLabel'),'FontSize',16);

string=sprintf('load mCatBkgr%03.0f.mat',j);eval(string);
mBkgr=mCatalog;
string=sprintf('load vMain%03.0f.mat',j);eval(string);
vMain=logical(vMain);
string=sprintf('load mCatETAS%03.0f.mat',j);eval(string);
mETAS=mCatalog;
string=sprintf('load vDeclus%03.0f.mat',j);eval(string);
vDeclus=logical(vDeclus);

vTmp = ones(length(vResults(1).vX) * length(vResults(1).vY), 1) * nan;

for i=1:3
vTmp(vResults(i).vUsedNodes) = vResults(i).mValueGrid(:,j);
mPlotValues = reshape(vTmp, length(vResults(i).vY), length(vResults(i).vX));

mX=repmat(vResults(i).vX,length(vResults(i).vY),1);
mY=repmat(vResults(i).vY',1,length(vResults(i).vX));
% plot pcolor
subplot(3,1,i);
pcolor(mX,mY,mPlotValues);
shading interp;
xlabel('Lon');ylabel('Lat');

set(gca,'CLim',[-4 4]);
if i==3
    colorbar('location','southoutside')
end

switch i
    case 1
        hold on;plot(mETAS(vMain,1),mETAS(vMain,2),'k.');
    case 2
        hold on;plot(mETAS(vDeclus,1),mETAS(vDeclus,2),'k.');
    case 3
        hold on;plot(mETAS(vDeclus,1),mETAS(vDeclus,2),'k.');
        hold on;plot(mETAS(~vDeclus,1),mETAS(~vDeclus,2),'rx');
end
end


function [peakOutputStat] = computePeakStatistics(inputSignals,varargin)
	% Get slope ratio, the average trace from detected peaks, and other peak-related statistics
	% Biafra Ahanonu
	% started: 2013.12.09
	% inputs
		% inputSignals = [n m] matrix where n={1....N}
	% outputs
		% slopeRatio
		% traceErr
		% fwhmSignal
		% avgPeakAmplitude
		% spikeCenterTrace
		% pwelchPxx
		% pwelchf

	[peakOutputStat] = ciapkg.signal_processing.computePeakStatistics(inputSignals,'passArgs', varargin);
end


function [baseScanNum,filtScanNum,planC] = createFilteredScanForDLS(identifierS,filtS,planC)
% createFilteredScanForDLS.m
%------------------------------------------------------------------------
% INPUTS
% identifierS : Dictionary of scan identifiers.
% filtS       : Dictionary of filter parameters acccepted by processImage.m
% planC
%------------------------------------------------------------------------
% AI 1/5/22

indexS = planC{end};

%% Get scan array from identifiers
%identifierS.filtered = 0;           %Identify base scan
%identifierS.warped = 0;             %Identify base scan
origFlag = 1;                       %Identify base scan
baseScanNum = getScanNumFromIdentifiers(identifierS,planC,origFlag);
scan3M = double(getScanArray(baseScanNum,planC));
scan3M = scan3M - double(...
    planC{indexS.scan}(baseScanNum).scanInfo(1).CTOffset);
mask3M = ones(size(scan3M));

%% Apply filter
imType = fieldnames(filtS.imageType);
imType = imType{1};
filterParS = filtS.imageType.(imType);
outS = processImage(imType, scan3M, mask3M, filterParS);
fieldName = fieldnames(outS);
filtScan3M = outS.(fieldName{1});

%% Add filtered scan to planC
filtScanNum = length(planC{indexS.scan}) + 1;
[xValsV, yValsV, zValsV] = getScanXYZVals(planC{indexS.scan}(baseScanNum));
if yValsV(1) > yValsV(2)
    yValsV = fliplr(yValsV);
end
dx = median(diff(xValsV));
dy = median(diff(yValsV));
sliceThicknessV = diff(zValsV);
scanInfoS.horizontalGridInterval = dy;
scanInfoS.verticalGridInterval = dx;
scanInfoS.coord1OFFirstPoint = xValsV(1);
scanInfoS.coord2OFFirstPoint = yValsV(1);
scanInfoS.zValues = zValsV;
scanInfoS.sliceThickness = [sliceThicknessV,sliceThicknessV(end)];
scanType = ['Filt_scan',num2str(baseScanNum)];
planC = scan2CERR(filtScan3M,scanType,'',scanInfoS,'',planC);
planC{indexS.scan}(filtScanNum).assocBaseScanUID = ...
    planC{indexS.scan}(baseScanNum).scanUID;

end


function varargout = stlread(file)
% STLREAD imports geometry from an STL file into MATLAB.
%    FV = STLREAD(FILENAME) imports triangular faces from the binary STL file
%    indicated by FILENAME, and returns the patch struct FV, with fields 'faces'
%    and 'vertices'.
%
%    [F,V] = STLREAD(FILENAME) returns the faces F and vertices V separately.
%
%    [F,V,N] = STLREAD(FILENAME) also returns the face normal vectors.
%
%    The faces and vertices are arranged in the format used by the PATCH plot
%    object.

%    Eric C. Johnson, 11-Dec-2008
%    Copyright 1999-2008 The MathWorks, Inc.

    if ~exist(file,'file')
        error(['File ''%s'' not found. If the file is not on MATLAB''s path' ...
               ', be sure to specify the full path to the file.'], file);
    end

    fid = fopen(file,'r');
    if ~isempty(ferror(fid))
        error(lasterror); %#ok
    end

    M = fread(fid,inf,'uint8=>uint8');
    fclose(fid);

    if( isbinary(M) )
       [f,v,n] = stlbinary(M);
    else
       [f,v,n] = stlascii(M); % Not currently supported
    end

    varargout = cell(1,nargout);
    switch nargout
        case 2
            varargout{1} = f;
            varargout{2} = v;
        case 3
            varargout{1} = f;
            varargout{2} = v;
            varargout{3} = n;
        otherwise
            varargout{1} = struct('faces',f,'vertices',v);
    end

end

function [F,V,N] = stlbinary(M)

    F = [];
    V = [];
    N = [];

    if length(M) < 84
        error('MATLAB:stlread:incorrectFormat', ...
              'Incomplete header information in binary STL file.');
    end

    % Bytes 81-84 are an unsigned 32-bit integer specifying the number of faces
    % that follow.
    numFaces = typecast(M(81:84),'uint32');
    %numFaces = double(numFaces);
    if numFaces == 0
        warning('MATLAB:stlread:nodata','No data in STL file.');
        return
    end

    T = M(85:end);
    F = NaN(numFaces,3);
    V = NaN(3*numFaces,3);
    N = NaN(numFaces,3);

    numRead = 0;
    while numRead < numFaces
        % Each facet is 50 bytes
        %  - Three single precision values specifying the face normal vector
        %  - Three single precision values specifying the first vertex (XYZ)
        %  - Three single precision values specifying the second vertex (XYZ)
        %  - Three single precision values specifying the third vertex (XYZ)
        %  - Two unused bytes
        i1    = 50 * numRead + 1;
        i2    = i1 + 50 - 1;
        facet = T(i1:i2)';

        n  = typecast(facet(1:12),'single');
        v1 = typecast(facet(13:24),'single');
        v2 = typecast(facet(25:36),'single');
        v3 = typecast(facet(37:48),'single');

        n = double(n);
        v = double([v1; v2; v3]);

        % Figure out where to fit these new vertices, and the face, in the
        % larger F and V collections.
        fInd  = numRead + 1;
        vInd1 = 3 * (fInd - 1) + 1;
        vInd2 = vInd1 + 3 - 1;

        V(vInd1:vInd2,:) = v;
        F(fInd,:)        = vInd1:vInd2;
        N(fInd,:)        = n;

        numRead = numRead + 1;
    end

end

function [F,V,N] = stlascii(A) %#ok
    warning('MATLAB:stlread:ascii','ASCII STL files currently not supported.');
    F = [];
    V = [];
    N = [];
end

function tf = isbinary(A)
% ISBINARY determines if an STL file is binary or ASCII.

    % Look for the string 'endsolid' near the end of the file
    if isempty(A) || length(A) < 16
        error('MATLAB:stlread:incorrectFormat', ...
              'File does not appear to be an ASCII or binary STL file.');
    end

    % Read final 16 characters of M
    i2  = length(A);
    i1  = i2 - 15;
    str = char( A(i1:i2)' );

    k = strfind(lower(str), 'endsolid');
    if ~isempty(k)
        tf = false; % ASCII
    else
        tf = true;  % Binary
    end
end


function [w]=iwtt(v,wtt_transform)
%Inverse WTT transform with previously computed filters
%   W=IWTT(V,WTT_TRANSFORM) computes the inverse WTT tranformation of a
%   given tensor with filters, stored in the WTT_TRANSFORM structure.
%
%
% TT-Toolbox 2.2, 2009-2012
%
%This is TT Toolbox, written by Ivan Oseledets et al.
%Institute of Numerical Mathematics, Moscow, Russia
%webpage: http://spring.inm.ras.ru/osel
%
%For all questions, bugs and suggestions please mail
%ivan.oseledets@gmail.com
%---------------------------

u=wtt_transform.u;
r=wtt_transform.rks;
sz=wtt_transform.sz;
w=iwtt_loc(v,u,r,sz);
return
end
function [w]=iwtt_loc(v,u,r,sz)
%[W]=IWTT(V,U,R,SZ)
%Applies Inverse WTT transform to vector V with linear filters U
%and ranks R
%SZ is optional
if ( nargin == 1 )
  sz=size(v);% d=numel(sz);
else
 % d=numel(sz);
end
%Apply one transform back
  N=numel(v);
  v=reshape(v,[r(1)*sz(1),N/(r(1)*sz(1))]);
if ( numel(u) == 1 )
   w=u{1}*v;
    w=reshape(w,[r(1),N/(r(1))]);
else
  %Simplest one is recursion
  w=v;
  w0=v(1:r(2),:);
  unew=u(2:numel(u)); rnew=r(2:numel(r)); sznew=[sz(2),sz(3:numel(sz))];
  w0=iwtt_loc(w0,unew,rnew,sznew);
  w(1:r(2),:)=w0;
  m=size(u{1},1);
  w=reshape(w,[m,N/m]);
  w=u{1}*w;
  w=reshape(w,[r(1),N/r(1)]);
end
  return
end


classdef Symmetrizer < handle

    properties (Access = public)
        symmetricMesh
    end

    properties (Access = private)
        symmetricPoint
        meshMerger
    end

    properties (Access = private)
        mesh
        symmetrizedMesh
        symmetricLine
    end

    methods (Access = public)

        function obj = Symmetrizer(cParams)
            obj.init(cParams);
            obj.createSymmetricPointComputer();
            obj.createSymmetrizedMesh();
            obj.createMeshMerger();
        end

        function m = computeSymmetricMesh(obj)
            m = obj.meshMerger.compute();
        end

        function sF = symmetrizeScalarField(obj,f)
            nodes = obj.meshMerger.computeRemainingNodes();
            fS = f;
            fD = [f;fS];
            sF   = fD(nodes,:);
        end

        function sF = symmetrizeVectorField(obj,f)
            nodes = obj.meshMerger.computeRemainingNodes();
            fS = obj.computeFsymmetric(f);
            fD   = [f;fS];
            sF   = fD(nodes,:);
        end

    end

    methods (Access = private)

        function init(obj,cParams)
            obj.mesh          = cParams.mesh;
            obj.symmetricLine = cParams.symmetricLine;
        end

        function fSym = computeFsymmetric(obj,f)
            s.vector = f;
            s.line  = obj.symmetricLine;
            s.line.point = [0,0];
            sP = SymmetricPointComputer(s);
            fSym = sP.computeSymmetricVector();
        end

        function createSymmetricPointComputer(obj)
            s.vector = obj.mesh.coord;
            s.line   = obj.symmetricLine;
            sP = SymmetricPointComputer(s);
            obj.symmetricPoint = sP;
        end

        function createSymmetrizedMesh(obj)
            sConnec(:,[1 3 2]) = obj.mesh.connec(:,[1 2 3]);
            sCoord = obj.symmetricPoint.computeSymmetricVector();
            s.connec = sConnec;
            s.coord  = sCoord;
            m = Mesh(s);
            obj.symmetrizedMesh = m;
        end

        function createMeshMerger(obj)
            isInSymLine = obj.symmetricPoint.isNodeInLine;
            s.meshA  = obj.mesh;
            s.meshB  = obj.symmetrizedMesh;
            s.isMergedNodeA = isInSymLine;
            s.isMergedNodeB = isInSymLine;
            obj.meshMerger = MeshMerger(s);
        end

    end

end


function [m,n,newE] = grValidation(E);
% The validation of array E - auxiliary function for GrTheory Toolbox.
% Author: Sergiy Iglin
% e-mail: siglin@yandex.ru
% personal page: http://iglin.exponenta.ru

if ~isnumeric(E),
  error('The array E must be numeric!')
end
if ~isreal(E),
  error('The array E must be real!')
end
se=size(E); % size of array E
if length(se)~=2,
  error('The array E must be 2D!')
end
if (se(2)<2),
  error('The array E must have 2 or 3 columns!')
end
if ~all(all(E(:,1:2)>0))
  error('1st and 2nd columns of the array E must be positive!')
end
if ~all(all((E(:,1:2)==round(E(:,1:2))))),
  error('1st and 2nd columns of the array E must be integer!')
end
m=se(1);
if se(2)<3, % not set the weight
  E(:,3)=1; % all weights =1
end
newE=E(:,1:3);
n=max(max(newE(:,1:2))); % number of vertexes
return


function [StencilC, CenterC] = stencilCrop(Stencil, Center)
%------------------------------------------------------------------------------
%
% This function crops a stencil at its bounds, in case all values are
% zero on the bounds and the center remains within the stencil.
% For dimensions <=3 no (more) cropping is performed.
%
% Stencil  = input stencil
%
% Center   = center of Stencil
%
% StencilC = output stencil (cropped)
%
% CenterC  = center of StencilC
%
% See also: stencilR2Q
%
% Design and implementation by:
% Dr. Paul M. de Zeeuw <Paul.de.Zeeuw@cwi.nl>  http://homepages.cwi.nl/~pauldz/
% Last Revision: January 24, 2001.
% (c) 1999-2002 Stichting CWI, Amsterdam.
%------------------------------------------------------------------------------
o=[0 0];
if ~all(size(o) == size(Center))
  error(' stencilCrop - unexpected dimensions of Center ')
else
  clear o;
end
StencilC = Stencil;
CenterC = Center;
%
[n, m] = size(Stencil);
for j = n:-1:4
   [nC, mC] = size(StencilC);
   v = StencilC(nC,:);
   if any(v) || CenterC(1)>=nC
     break;
   else
     StencilC = StencilC(1:(nC-1),:);
   end
end
for j = m:-1:4
   [nC, mC] = size(StencilC);
   v = StencilC(:,mC)';
   if any(v) || CenterC(2)>=mC
     break;
   else
     StencilC = StencilC(:,1:(mC-1));
   end
end
%
[n, m] = size(StencilC);
for j = 1:(n-3)
   [nC, mC] = size(StencilC);
   v = StencilC(1,:);
   if any(v) || CenterC(1)<=1
     break;
   else
     StencilC = StencilC(2:nC,:);
     CenterC = [(CenterC(1)-1) CenterC(2)];
   end
end
for j = 1:(m-3)
   [nC, mC] = size(StencilC);
   v = StencilC(:,1)';
   if any(v) || CenterC(2)<=1
     break;
   else
     StencilC = StencilC(:,2:mC);
     CenterC = [CenterC(1) (CenterC(2)-1)];
   end
end
%


% Profiler extension template.
%
% Profiler extension for [algorithm]
%
% This file is part of the Kernel Adaptive Filtering Toolbox for Matlab.
% https://github.com/steven2358/kafbox/

classdef kafbox_template_profiler < kafbox_template

    properties (GetAccess = 'public', SetAccess = 'private')
        elapsed = 0; % elapsed time
    end

    methods

        function kaf = kafbox_template_profiler(parameters) % constructor
            if nargin<1, parameters = struct(); end
            kaf = kaf@kafbox_template(parameters);
        end

        function flops = lastflops(kaf) % flops for last iteration
            % numbers of operations
            m1 = 1;
            m2 = 1;
            m3 = 1;
            m4 = 1;

            floptions = struct(...
                'sum', m1, ...
                'mult', m2, ...
                'div', m3, ...
                sprintf('%s_kernel',kaf.kerneltype), [m4,1,size(kaf.dict,2)]);

            flops = kflops(floptions);
        end

        %% flops breakdown

        % [space for remarks on number of operations used above]

        %%

        function train_profiled(kaf,x,y)
            t1 = tic;
            kaf.train(x,y);
            t2 = toc(t1);
            kaf.elapsed = kaf.elapsed + t2;
        end

        function bytes = lastbytes(kaf) % bytes used in last iteration
            m = size(kaf.dict,1);
            m2 = 1;
            bytes = (m2 + m*size(kaf.dict,2)); % 8 bytes for double precision
            % [list variables]
        end

    end
end


% -*- INTERNAL UNDOCUMENTED FUNCTION -*-
function [geometry, msh, sp, u, gnum] = ...
                    mp_solve_linear_elasticity_3d (problem_data, method_data)

warning ('geopdes:obsolete', 'Function MP_SOLVE_LINEAR_ELASTICITY_3D is obsolete. Using MP_SOLVE_LINEAR_ELASTICITY instead')

[geometry, msh, sp, u, gnum] = mp_solve_linear_elasticity (problem_data, method_data);


function varargout = process_aec1n( varargin )
% PROCESS_PLV1N: Compute amplitude envelope correlation between all the pairs of signals, in one file.

% @=============================================================================
% 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: Francois Tadel, 2012-2014
%          Peter Donhauser, 2017

eval(macro_method);
end

%% ===== GET DESCRIPTION =====
function sProcess = GetDescription() %#ok<DEFNU>
    % Description the process
    sProcess.Comment     = 'Amplitude Envelope Correlation NxN';
    sProcess.Category    = 'Custom';
    sProcess.SubGroup    = 'Connectivity';
    sProcess.Index       = 682;
    sProcess.Description = 'https://neuroimage.usc.edu/brainstorm/Tutorials/Connectivity';
    % Definition of the input accepted by this process
    sProcess.InputTypes  = {'data',     'results',  'matrix'};
    sProcess.OutputTypes = {'timefreq', 'timefreq', 'timefreq'};
    sProcess.nInputs     = 1;
    sProcess.nMinFiles   = 1;

    % === CONNECT INPUT
    sProcess = process_corr1n('DefineConnectOptions', sProcess, 1);
    % === FREQ BANDS
    sProcess.options.freqbands.Comment = 'Frequency bands for the Hilbert transform:';
    sProcess.options.freqbands.Type    = 'groupbands';
    sProcess.options.freqbands.Value   = bst_get('DefaultFreqBands');
    % === KEEP TIME
    sProcess.options.isorth.Comment = 'Orthogonalize signal pairs before envelope computation';
    sProcess.options.isorth.Type    = 'checkbox';
    sProcess.options.isorth.Value   = 0;
    % === OUTPUT MODE
    sProcess.options.outputmode.Comment = {'Save individual results (one file per input file)', 'Concatenate input files before processing (one file)', 'Save average connectivity matrix (one file)'};
    sProcess.options.outputmode.Type    = 'radio';
    sProcess.options.outputmode.Value   = 1;
    sProcess.options.outputmode.Group   = 'output';
end

%% ===== FORMAT COMMENT =====
function Comment = FormatComment(sProcess) %#ok<DEFNU>
    Comment = sProcess.Comment;
end

%% ===== RUN =====
function OutputFiles = Run(sProcess, sInputA) %#ok<DEFNU>
    % Input options
    OPTIONS = process_corr1n('GetConnectOptions', sProcess, sInputA);
    if isempty(OPTIONS)
        OutputFiles = {};
        return
    end
    OPTIONS.Method = 'aec';
    % Filtering bands options
    OPTIONS.Freqs = sProcess.options.freqbands.Value;
    OPTIONS.isOrth = sProcess.options.isorth.Value;

    % Compute metric
    OutputFiles = bst_connectivity({sInputA.FileName}, [], OPTIONS);
end


  function xrs = xray_read_spectra(stype, varargin)
%|function xrs = xray_read_spectra(stype, [options])
%|
%| Read X-ray spectra data and initialize a structure that describes "M"
%| piecewise constant polyenergetic X-ray spectra, where M=2 for dual-kVp case.
%|
%| in
%|	stype		char	which spectrum model:
%|				'mono,60,100' dual mono-energetic
%|				'poly1,kvp1[,kvp2][,...]' polyenergetic
%|		or:	cell	{en [ne 1], sp [ne M]} sampled spectra
%|
%| option
%|	'en'		[ne 1]	specify energy sampling
%|	'filters'	cell{M} optional additional filtration of each spectrum
%|		{{mtype11, thick11, mtype12, thick12, ...}, ...
%|		 {mtypeM1, thickM1, mtypeM2, thickM2, ...}}
%|	'units'		''	'cm' (default) or 'mm' for filter thicknesses
%|	'show'		1|0	plot?
%|	'name'		{char}	names for each spectrum
%|	'kvp'		[M 1]
%|	'dir_spectra'	char	directory with spectra.  default:
%|				[path_find_dir('ct') filesep 'xray-spectra'];
%| out
%|	xrs		strum
%| data:
%|	xrs.en		[ne 1]	energy list
%|	xrs.sp		[ne M]	M spectra, for M kVp settings: I_m(E)
%|	xrs.Ide		[ne M]	differential array for "integrating": I_m(E) dE
%|	xrs.I		[M 1]	total intensity: sum(Ide)
%|	xrs.kvp		[M 1]	tube potentials (voltage in kVp)
%|	xrs.eff		[M 1]	mean energies (incident)
%| methods:
%|		.plot	plot spectra
%|
%| Note: xrs.eff perhaps should be named xrs.mean because it is a mean energy
%| of the incident spectrum.  It is not the "effective energy" as defined
%| e.g., on p56 of 4th edition of W. R. Hendee's "Medical Imaging Physics"
%| because that definition depends on the attenuation of a particular material.
%|
%| Copyright 2001-04-27, Jeff Fessler, University of Michigan

if ~nargin, ir_usage, end
if streq(stype, 'test'), xray_read_spectra_test, return, end

% defaults
arg.en = [];
arg.filters = {};
arg.show = false;
arg.name = {};
arg.kvp = [];
arg.units = 'cm';
arg.dir_spectra = [path_find_dir('ct') filesep 'xray-spectra'];
arg = vararg_pair(arg, varargin);

xrs.kvp = arg.kvp;

if ischar(stype)
	xrs = xray_read_spectra_char(stype, arg.en, arg.filters, arg.dir_spectra);
	xrs.type = stype;

elseif iscell(stype) && numel(stype) == 2
	xrs.en = stype{1};
	xrs.sp = stype{2};
	xrs.type = '';
	xrs.filters = arg.filters;
	if ~isequal(size(xrs.en,1), size(xrs.sp,1))
		error 'bad stype as cell usage'
	end
else
	error 'bad stype'
end

MM = size(xrs.sp, 2);

%
% apply filtration, if any
%
if ~isempty(xrs.filters)
	if numel(xrs.filters) ~= 1 && numel(xrs.filters) ~= MM
		error 'should be 1 or M sets of filters'
	end
	for mm=1:MM
		xrs.sp(:,mm) = xray_apply_filters(xrs.sp(:,mm), xrs.en, ...
			xrs.filters{min(mm,end)}, arg.units);
	end
end

%
% precompute some aspects of the spectra
%
xrs.Ide = xrs.sp .* repmat(difff(xrs.en), 1, MM); % [N M] I(E) dE
xrs.I = sum(xrs.Ide); % [1 M] spectrum integral
xrs.eff = xrs.en' * xrs.Ide ./ xrs.I;
for mm=1:MM
	xrs.sp_at_eff(mm) = interp1(xrs.en, xrs.sp(:,mm), xrs.eff(mm));
end

if isempty(arg.name)
	if ischar(stype)
		xrs.name = cat(2, {stype}, cell(1,MM-1));
	else
		xrs.name = '';
	end
else
	xrs.name = arg.name;
end
xrs = strum(xrs, {'plot', @xray_plot_spectra});

if arg.show
	xrs.plot;
end

%
% xray_read_spectra_char()
%
function xrs = xray_read_spectra_char(stype, en, filters, dir_spectra)
xrs.en = en;
xrs.filters = filters;

%
% simplest option is mono-energetic (for testing)
% usage: mono,kvp1,kvp2,...
%
if streq(stype, 'mono', 4)
	xrs.kvp = str2num(strrep(stype(6:end), ',', ' '));
	for mm=1:numel(xrs.kvp)
		xrs.en = [20:140]';
		xrs.sp(:,mm) = xrs.en == xrs.kvp(mm);
	end

%
% polyenergetic spectra
% usage: poly1,kvp1,kvp2,...
%
elseif streq(stype, 'poly1', 5)
	if ~exist(dir_spectra, 'dir')
		fail('spectra dir "%s" not in path', dir_spectra)
	end
	xrs.kvp = str2num(strrep(stype(7:end), ',', ' ')); % [M]

	% read raw data
	MM = numel(xrs.kvp);
	for mm=1:MM
		kvp = xrs.kvp(mm);
		raw = sprintf('spectra.%d', kvp);
		raw = [dir_spectra filesep raw];
		tmp = load_ascii_skip_header(raw);
		sr.enc{mm} = tmp(:,1);
		sr.spc{mm} = tmp(:,2);

		% The Wilderman/Sukovic spectra must be scaled by energy!
		sr.spc{mm} = sr.spc{mm} .* sr.enc{mm};
	end

	% interpolate onto same energy sampling
	[xrs.en xrs.sp] = xray_sp_interp(xrs.en, sr.enc, sr.spc);

%
% 1st spectra from predrag sukovic
%
elseif streq(stype, 'ps1')
	if ~exist(dir_spectra, 'dir')
		fail('spectra dir "%s" not in path', dir_spectra)
	end

	xrs.kvp = [80 140];

	for mm=1:numel(xrs.kvp)
		file = sprintf('xray%03d.mat', xrs.kvp(mm));
		file = [dir_spectra filesep file];
		if ~exist(file, 'file')
			error(sprintf('file "%s" not found', file))
		end
		raw = load(file);
		ie = raw.energy >= 20 & raw.energy <= 140;
		sr.enc{mm} = raw.energy(ie);
		sr.spc{mm} = raw.spe(ie) .* raw.energy(ie);
	end

	[xrs.en xrs.sp] = xray_sp_interp(xrs.en, sr.enc, sr.spc);

%
% spectra used for 2002 SPIE talk (fix: or did i just use 'ps1' ???)
%
elseif streq(stype, 'spie02')
	xrs = xray_read_spectra('poly1,80,140');
%	xrs.filters = { {{'aluminum', 0.25}, {'copper', 0.05}} };
	xrs.filters = {{'aluminum', 0.25, 'copper', 0.05}};
%	xrs.filters = {{'aluminum', 0.10}, {'copper', 0.05}};
%	xrs.filters = {{'aluminum', 0.5, 'copper', 0.04, 'csi', 0.1}};
%	xrs.filters = {{'aluminum', 0.5, 'copper', 0.04, 'gadolinium', 0.1}};

else
	fail('bad stype "%s"', stype)
end

%
% interpolate onto same energy sampling
%
function [en, sp] = xray_sp_interp(en, enc, spc)
MM = numel(spc);
if isempty(en)
	tmp = zeros(MM,1);
	for mm=1:MM
		tmp(mm) = max(enc{mm});
	end
	mm = imax(tmp); % find col with largest max
	en = enc{mm};
end
sp = zeros(numel(en), MM);
for mm=1:MM
	sp(:,mm) = interp1(enc{mm}, spc{mm}, ...
		en, 'linear', 0); % extrapolate with zeros
end

%
% xray_apply_filters()
%
function sp = xray_apply_filters(sp, en, filters, units);
% {mtype1, thick1, mtype2, thick2, ...}, ...
if ~iscell(filters)
	error 'filtration arguments must be cells'
end
for ii=1:2:numel(filters)
	sp = sp .* xray_filters(filters{ii}, filters{ii+1}, en, 'units', units);
end

%
% xray_plot_spectra()
% plot routine
%
function dummy = xray_plot_spectra(xrs, varargin)
dummy = [];

arg.title = xrs.type;
arg.kmin = min(xrs.en);
arg.kmax = max(xrs.en);
arg.spike = false;
arg.threshold = 1.2;
arg.hold = false;
arg.linetype = 'y.-';
arg = vararg_pair(arg, varargin);

MM = size(xrs.sp,2);
if ~im, return, end

if ~arg.hold, clf, end
pl=@(m) subplot(MM*100+10+m);
for mm=1:MM
	pl(mm)
	if arg.hold, hold on, end
	plot(xrs.en, xrs.sp(:,mm), arg.linetype, ...
		xrs.eff(mm) * [1 1], [0 xrs.sp_at_eff(mm)], 'm--')
	if arg.hold
		hold off
	else
		axis([arg.kmin arg.kmax [-0.00 1.05]*max(xrs.sp(:,mm))])
	end
	xt = [arg.kmin round(xrs.eff(mm)) arg.kmax];
	if arg.spike
		where = xrs_find_spike(xrs.sp(:,mm), arg.threshold);
		xt = [xt col(xrs.en(where))'];
	end
	xtick(sort(xt)), ytick([0])
	ylabelf('I%d(E)', mm)
	if mm == 1
		title(arg.title)
	end
	if ~isempty(xrs.name) && ~isempty(xrs.name{mm})
		title(xrs.name{mm})
	end

	if ~isempty(xrs.kvp)
		t = sprintf('%g kVp Spectrum', xrs.kvp(mm));
		texts(0.5, 0.8, t, 'color', 'green')
	end
end
xlabel 'Energy [keV]'

%
% xrs_find_spike()
% find spikes in spectrum
%
function where = xrs_find_spike(sp, threshold)
local = (sp(1:end-2) + sp(3:end)) / 2;
where = (sp(2:end-1) - local) > threshold * local;
where = 1 + find(where);

%
% xray_read_spectra_test()
% test routine
%
function xray_read_spectra_test

stype = 'mono,60,100';
stype = 'poly1,80,100';
stype = 'spie02';
stype = 'ps1';
stype = 'poly1,160,100,60';
filts = {{}, {}, {}};
xrs1 = xray_read_spectra(stype, 'filters', filts);
filts = {{'aluminum', 0.1}, {'copper', 0.2}, {}};
xrs2 = xray_read_spectra(stype, 'filters', filts);
xrs1.plot;
xrs2.plot('hold', true, 'linetype', 'c-');
%clf, plot(xrs1.en, xrs1.sp, '-', xrs2.en, xrs2.sp, '--')


function d =  testing(a,d)

  %K = get_kernel(a.child,d,a.X); %% OLD CODE

  if a.use_kernels
    K = test(a.child, d);  K=K.X;
  else
    K=d.X;
  end

  if(a.use_b & ~a.use_kernels) K=[K ; ones(1,size(K,2))]; end;
  Yest = K'*a.alpha;

  if a.algorithm.use_signed_output==1
    Yest=sign(Yest);
  end
  d=set_x(d,Yest);
  d=set_name(d,[get_name(d) ' -> ' get_name(a)]);


function display(a)
% function display(A)
%
% DESCRIPTION
%   Displays a polynomial.
%
% INPUTS
%   A: polynomial
%
% OUTPUTS
%   NONE
%
% SYNTAX
%   display(A);

% 6/7/2002: PJS  Initial Coding
% 6/9/2002: PJS  Use char conversion and display matrices

%   Get String Representation of a
s = char(a);
sza = size(a);

%   Display the Polynomial
if ~isequal(get(0,'FormatSpacing'),'compact')
    disp(' ');
end

% Compute sizes of character arrays and max size
nchar = cellfun('size',s,2);
maxr = max(nchar,[],1);
numc = sum(maxr);
rootprops = fieldnames(get(0));
if any(strcmp(rootprops,'CommandWindowSize'))
    ws = get(0,'CommandWindowSize');
else
    % Older Versions of matlab don't allow access to the
    % window size.  Modify window size (ws) if polynomial
    % line breaks are not in the right spot.
    ws = 80;
end
maxchar=ws(1)-6-3*(sza(2)-1);

if isempty(a)
    disp([inputname(1) ' = ']);
    disp([' ' s{1}]);

elseif max(numc) < maxchar
    % Display as matrix if all rows can fit on screen
    disp([inputname(1) ' = ']);
    for i1 = 1:sza(1);
        if all(sza==[1 1])
            d = '  ';
        else
            d = '  [ ';
        end
        for i2 = 1:sza(2);
            d = [d blanks(maxr(i2)-nchar(i1,i2)) s{i1,i2}];
            if i2~=sza(2)
                d = [d ', '];
            elseif ~all(sza==[1 1])
                d = [d ']'];
            end
        end
        disp(d);
    end

else
    % Else display entry-by-entry going down columns
    for i2 = 1:sza(2);
        if min(sza) > 1
            disp(['----  Column ' int2str(i2) ' ----------'])
            disp(' ')
        end
        for i1 = 1:sza(1);
            % Display the (i1,i2) entry
            if ~all(sza==[1 1]);
                disp([inputname(1) '(' int2str(i1) ',' int2str(i2) ')  = ']);
            else
                disp([inputname(1) ' = ']);
            end

            % Break lines at +,-, or *
            sr = s{i1,i2};
            while ~isempty(sr) %length(sr)>0
                if length(sr) < (ws(1)-6)
                    disp(['  ' sr]);
                    sr = [];
                else
                    idx1 = sort([strfind(sr,'-') strfind(sr,'+') strfind(sr,'*')]);
                    idx1 = [setdiff(idx1,1) length(sr)];
                    %idx2 = max(find(idx1< (ws(1)-6) ));
                    idx2 = find(idx1< (ws(1)-6), 1, 'last' );
                    if isempty(idx2)
                        disp(['  ' sr(1:idx1(1)-1)]);
                        sr = sr(idx1(1):end);
                    else
                        disp(['  ' sr(1:idx1(idx2)-1)]);
                        sr = sr(idx1(idx2):end);
                    end
                end
            end
            if ~all([i1 i2]==sza)
                disp(' ');
            end
        end
    end

end

if ~isequal(get(0,'FormatSpacing'),'compact')
    disp(' ');
end


function [pc, fvecm2, p, c] = gp_predcm(gp,x,y,varargin)
%GP_PREDCM  Corrections for latent marginal posterior
%
%  Description
%    [PC, FVEC, P, C] = GP_PREDCM(GP, X, Y, XT, OPTIONS) Evaluates the
%    corrected marginal posterior of latent variable at given indices
%    of XT or X if XT is empty or not given. Marginal posterior
%    corrections are evaluated in 9 Gauss-Hermite points, after which
%    piecewise cubic Hermite interpolation is used interpolate
%    logarithm of the correction terms to a finer grid. Returns tilted
%    distribution P if XT is empty or equal to X, otherwise predictive
%    distribution, corrected predictive/tilted distribution PC and
%    correction terms C, where PC_i = P_i*C_i for every grid point i
%    in grid FVEC. FVEC is linearly spaced grid from predictive
%    distribution between mean minus/plus 4 standard deviations
%
%
%   OPTIONS is optional parameter-value pair
%      z      - optional observed quantity in triplet (x_i,y_i,z_i)
%               Some likelihoods may use this. For example, in case of
%               Poisson likelihood we have z_i=E_i, that is, expected value
%               for ith case.
%      ind    - Index vector or scalar defining the indices of data
%               points at which the marginal posterior corrections are
%               done. Default = 1.
%      fcorr  - Method used for evaluating correction terms C. Possible
%               methods are 'fact' (default) for EP and either 'fact'
%               or 'cm2' (default) for Laplace. If method is 'on',
%               the default methods are used.
%      ng     - Number of grid points evaluated from the spline. Default is 50.
%
%   Reference
%     Cseke & Heskes (2011). Approximate Marginals in Latent Gaussian
%     Models. Journal of Machine Learning Research 12 (2011), 417-454
%
%   See also
%     DEMO_IMPROVEDMARGINALS
%
% Copyright (c) 2011,2013 Ville Tolvanen

% This software is distributed under the GNU General Public
% License (version 3 or later); please refer to the file
% License.txt, included with the software, for details.

ip=inputParser;
ip.addRequired('gp',@isstruct);
ip.addRequired('x', @(x) ~isempty(x) && isreal(x) && all(isfinite(x(:))))
ip.addRequired('y', @(x) ~isempty(x) && isreal(x) && all(isfinite(x(:))))
%ip.addRequired('fvec',  @(x) ~isempty(x) && isreal(x) && all(isfinite(x(:))))
ip.addOptional('xt', [], @(x) isreal(x) && all(isfinite(x(:))))
ip.addParamValue('z', [], @(x) isreal(x) && all(isfinite(x(:))))
ip.addParamValue('ind', 1, @(x) isreal(x) && all(isfinite(x(:))))
ip.addParamValue('ng', 50, @(x) isreal(x) && all(isfinite(x(:))) && x > 1)
ip.addParamValue('fcorr', 'on', @(x) ismember(x, {'fact', 'cm2', 'on','lr'}))
ip.addParamValue('tstind', [], @(x) isempty(x) || iscell(x) ||...
                   (isvector(x) && isreal(x) && all(isfinite(x)&x>0)))
if rem(size(varargin,2), 2) == 0
  ip.parse(gp, x, y, [],varargin{:});
else
  ip.parse(gp, x, y, varargin{:});
end
tstind = ip.Results.tstind;
z = ip.Results.z;
ind = ip.Results.ind;
xt = ip.Results.xt;
ng = ip.Results.ng;
predictive=false;
gplik=gp.lik;
n=size(x,1);
[Ef, Covf] = gp_jpred(gp,x,y,x, 'z', z, 'tstind', 1:n);
Covf=full(Covf);
if ismember('fcorr', ip.UsingDefaults)
  if isequal(gp.latent_method, 'Laplace')
    % Default for Laplace
    fcorr='cm2';
  else
    % Default for EP
    fcorr='fact';
  end
else
  fcorr=ip.Results.fcorr;
end
ind=ind(:);
if ~isempty(xt) && ~isequal(xt, x)
  % Predictive equations if given xt, mind that if xt(ind) is in training
  % input x, predictive equations might not work correctly.
  predictive = true;
  [Ef2, Varf2]=gp_pred(gp,x,y,xt,'z',z,'tstind',tstind);
%   [Ef2, Covf2] = gp_jpred(gp,x,y,xt,'z',z, 'tstind', tstind);
%   Covf2=full(Covf2);
end
nin = 11;
fvecm=zeros(nin,length(ind));
fvecm2=zeros(ng,length(ind));
for i1=1:length(ind)
  i2=ind(i1);
  % Form evaluation points for spline formation & grid points to be
  % evaluated from the spline
  minf = 6;
  maxf = 6;
  if ~predictive
    fvecm(:,i1)=Ef(i2)+[-3.668 -2.783 -2.026 -1.326 -0.657 0 0.657 1.326 2.026 2.783 3.668].*sqrt(Covf(i2,i2));
%     fvecm(:,i1)=Ef(i2)+[-3.191 -2.267 -1.469 -0.724 0 0.724 1.469 2.267 3.191].*sqrt(Covf(i2,i2));
    fvecm2(:,i1)=linspace(Ef(i2)-minf.*sqrt(Covf(i2,i2)), Ef(i2)+maxf.*sqrt(Covf(i2,i2)),ng)';
  else
    fvecm(:,i1)=Ef2(i2)+[-3.668 -2.783 -2.026 -1.326 -0.657 0 0.657 1.326 2.026 2.783 3.668].*sqrt(Varf2(i2));
%     fvecm(:,i1)=Ef2(i2)+[-3.191 -2.267 -1.469 -0.724 0 0.724 1.469 2.267 3.191].*sqrt(Covf2(i2,i2));
    fvecm2(:,i1)=linspace(Ef2(i2)-minf.*sqrt(Varf2(i2)), Ef2(i2)+maxf.*sqrt(Varf2(i2)),ng)';
  end
end
lc = zeros(nin, length(ind));
pc = zeros(ng, size(ind,1)); lp = zeros(ng,size(ind,1)); c = zeros(ng,size(ind,1));
lp2 = zeros(nin,size(ind,1)); p = zeros(ng,size(ind,1));

switch gp.latent_method
  case 'EP'

    if isequal(fcorr, 'lr')
        [Efloo,Varfloo]=gpep_loopred(gp,x,y,'z',z);
    end

    switch fcorr
      case {'fact', 'lr'}
        [tmp, tmp, tmp, param] = gpep_e(gp_pak(gp), gp, x,y,'z',z);
        [tautilde, nutilde, muvec_i, sigm2vec_i] = ...
              deal(param.tautilde, param.nutilde, param.muvec_i, param.sigm2vec_i);

        % Compute tilted moments
        logM02 = gp.lik.fh.tiltedMoments(gp.lik, y, 1:n, sigm2vec_i, muvec_i, z);

        if predictive
          K_ff = gp_trcov(gp, x);
        end

        % Loop through grid indices
        for i1=1:size(ind,1)
          fvec = fvecm(:,i1);
          if ~predictive
            inds=[1:(ind(i1)-1) (ind(i1)+1):n];
            cii = Covf(ind(i1),ind(i1));
            if isempty(z)
              z_ind = [];
            else
              z_ind = z(ind(i1));
            end

            % Here we keep track of normalizing constants so we dont have to
            % normalize distributions at any point.
            %     Z_q = sqrt(2*pi*cii);
%             logM0 = gp.lik.fh.tiltedMoments(gp.lik, y, ind(i1), sigm2vec_i(ind(i1)), muvec_i(ind(i1)), z);
%             Z_p = exp(logM0)*sqrt(2*pi)*sqrt(sigm2vec_i(ind(i1))+1./tautilde(ind(i1)))*exp(0.5*(muvec_i(ind(i1))-nutilde(ind(i1))./tautilde(ind(i1))).^2/(sigm2vec_i(ind(i1))+1./tautilde(ind(i1))));

            % Function handle to marginal distribution without any fcorr parameters
            if isequal(fcorr, 'fact')
                cav = @(f) norm_lpdf(f,Ef(ind(i1)),sqrt(cii)) - norm_lpdf(f, nutilde(ind(i1))/tautilde(ind(i1)), 1/sqrt(tautilde(ind(i1))));
            else
                cav = @(f) norm_lpdf(f, Efloo(ind(i1)), sqrt(Varfloo(ind(i1))));
            end
            fh_p = @(f) (arrayfun(@(a) gplik.fh.ll(gplik, y(ind(i1)), a, z_ind), f)) + cav(f);
          else
            inds=1:n;
            cii = Varf2(ind(i1));
            fh_p = @(f) norm_lpdf(f,Ef2(ind(i1)),sqrt(cii));
          end

          % Loop through grid points
          for i=1:nin

            % Variance and mean for global Gaussian approximation conditioned on
            % other data grid points, q(x_j|x_i) or in predictive case, q(x_j,
            % x_*)
            if ~predictive
              cji = Covf(ind(i1),:);% cji(ind(i1)) = [];
              cjj = Covf;% cjj(ind(i1),:) = []; cjj(:,ind(i1)) = [];
              ci = diag(cjj)-(cji'*(1/cii)).*cji';
              mf = Ef; %mf(ind(i1)) = [];
              mu = mf+cji'./cii.*(fvec(i)-Ef(ind(i1)));
            else
              K_fstar = gp_cov(gp,  x, xt(ind(i1),:));
              cjj = Covf;
              cji = (K_fstar'/K_ff)*cjj;
              ci = diag(cjj)-cji'.*(1/cii).*cji';
              mu = Ef+cji'./cii.*(fvec(i)-Ef2(ind(i1)));
            end
            % Loop through other points in x, exclude point to which current latent grid
            % corresponds to (if not predictive).
            lZtilde=logM02 + log(sqrt(2*pi)) + log(sqrt(sigm2vec_i+1./tautilde)) + 0.5*(muvec_i-nutilde./tautilde).^2./(sigm2vec_i+1./tautilde);
            m1 = nutilde./tautilde;
            s1 = 1./sqrt(tautilde);
            m2 = mu;
            s2 = sqrt(ci);

            s = sqrt(1./(1./s2.^2 - 1./s1.^2));
            m = (m2./s2.^2 - m1./s1.^2).*s.^2;
            lZ = log(s1) - log(s2) - 1./(2*(-s1.^2+s2.^2)).*(m1-m2).^2 +log(sqrt(2*pi*s.^2));
            lc_ii = lZ(inds) - lZtilde(inds) + gp.lik.fh.tiltedMoments(gplik, y(inds), 1:length(inds), s(inds).^2, m(inds), z);
            lc(i,i1) = sum(lc_ii);
            %p(i,i1) = fh_p(fvec(i,i1));

          end
          lp(:,i1) = fh_p(fvecm2(:,i1));
          lp2(:,i1) = fh_p(fvecm(:,i1));
          lp(:,i1) = lp(:,i1)-max(lp(:,i1));
          lp2(:,i1) = lp2(:,i1)-max(lp2(:,i1));
        end
      otherwise
        error('Invalid method for EP, use fact');
    end
  case 'Laplace'

    [tmp, tmp, tmp, param] = gpla_e(gp_pak(gp), gp, x,y,'z',z);
    f_mode = param.f;
    if ~isempty(z)
      ll = arrayfun(@(f,yy, zz) gplik.fh.ll(gplik, yy, f, zz), f_mode, y, z);
    else
      ll = arrayfun(@(f,yy) gplik.fh.ll(gplik, yy, f, z), f_mode, y);
    end
    llg = gplik.fh.llg(gplik, y, f_mode, 'latent', z);
    llg2 = gplik.fh.llg2(gplik, y, f_mode, 'latent', z);
    K_ff = gp_trcov(gp, x);
    if isequal(fcorr, 'lr')
        [Efloo,Varfloo]=gpla_loopred(gp,x,y,'z',z,'method','lrs');
    end

    switch fcorr
      case 'fact'
        % Loop through grid indices
        for i1=1:size(ind,1)
          fvec = fvecm(:,i1);
          if ~predictive
            cii = Covf(ind(i1),ind(i1));
            if isempty(z)
              z_ind = [];
            else
              z_ind = z(ind(i1));
            end

            % Function handle to marginal distribution without any fcorr parameters
            t_tilde = @(f)  (ll(ind(i1)) + (f-f_mode(ind(i1)))*llg(ind(i1)) + 0.5*(f-f_mode(ind(i1))).^2*llg2(ind(i1)));
            fh_p = @(f) (arrayfun(@(a) gplik.fh.ll(gplik, y(ind(i1)), a, z_ind), f)) - t_tilde(f) + norm_lpdf(f,Ef(ind(i1)),sqrt(cii));
          else
            cii = Varf2(ind(i1));
            fh_p = @(f) norm_lpdf(f,Ef2(ind(i1)),sqrt(cii));
          end

          if ~predictive
            cji = Covf(ind(i1),:); %cji(ind(i1)) = [];
            cjj = Covf; %cjj(ind(i1),:) = []; cjj(:,ind(i1)) = [];
            ci = diag(cjj)-(cji'*(1/cii)).*cji';
            mf = Ef; %mf(ind(i1)) = [];
            inds=[1:(ind(i1)-1) (ind(i1)+1):n];
          else
            K_fstar = gp_cov(gp,  x, xt(ind(i1),:));
            cjj = Covf;
            cji = (K_fstar'/K_ff)*cjj;
            ci = diag(cjj)-cji'.*(1/cii).*cji';
            inds=1:n;
          end
          % Loop through grid points
          for i=1:nin

            % Variance and mean for global gaussian approximation conditioned on
            % other data grid poins, q(x_j|x_i) or in predictive case, q(x_j,
            % x_*)
            if ~predictive
              mu = mf+cji'./cii.*(fvec(i)-Ef(ind(i1)));
            else
              mu = Ef+cji'./cii.*(fvec(i)-Ef2(ind(i1)));
            end
            m1 = (f_mode-llg./llg2);
            s1 = sqrt(-1./llg2);
            lC1 = ll+llg2.*f_mode.^2-llg2.*m1.^2 - llg.*f_mode;
            m2 = mu;
            s2 = sqrt(ci);
            lC2 = log(1./sqrt(2*pi*s2.^2));

            s = sqrt(1./(1./s2.^2 - 1./s1.^2));
            m = (m2./s2.^2 - m1./s1.^2).*s.^2;

            lZ = lC1 - lC2 - 1./(2*(-s1.^2+s2.^2)).*(m1-m2).^2 + log(sqrt(2*pi*s.^2));
            lc_ii = lZ(inds) + gp.lik.fh.tiltedMoments(gplik, y(inds), 1:length(inds), s(inds).^2, m(inds), z);

            %c(i,i1) = prod(c_ii);
            lc(i,i1) = sum(lc_ii);
            %p(i,i1) = fh_p(fvec(i,i1));

          end
          lp(:,i1) = fh_p(fvecm2(:,i1));
          lp2(:,i1) = fh_p(fvecm(:,i1));
          lp(:,i1) = lp(:,i1)-max(lp(:,i1));
          lp2(:,i1) = lp2(:,i1)-max(lp2(:,i1));
        end

      case {'cm2', 'lr'}
        % Loop through grid indices
        for i1=1:size(ind,1)
          fvec = fvecm(:,i1);
          if ~predictive
            cii = Covf(ind(i1),ind(i1));
            if isempty(z)
              z_ind = [];
            else
              z_ind = z(ind(i1));
            end

            % Function handle to marginal distribution without any fcorr parameters
            if isequal(fcorr, 'cm2')
%                t_tilde(f) = @(f) (ll(ind(i1)) + (f-f_mode(ind(i1)))*llg(ind(i1)) + 0.5*(f-f_mode(ind(i1))).^2*llg2(ind(i1)));
                cav = @(f) norm_lpdf(f,Ef(ind(i1)),sqrt(cii)) - (ll(ind(i1)) + (f-f_mode(ind(i1)))*llg(ind(i1)) + 0.5*(f-f_mode(ind(i1))).^2*llg2(ind(i1)));
            else
                cav = @(f) norm_lpdf(f, Efloo(ind(i1)), sqrt(Varfloo(ind(i1))));
            end
            fh_p = @(f) arrayfun(@(a) gplik.fh.ll(gplik, y(ind(i1)), a, z_ind), f) + cav(f);
%             fh_p = @(f) (arrayfun(@(a) gplik.fh.ll(gplik, y(ind(i1)), a, z_ind), f)) - t_tilde(f) + norm_lpdf(f,Ef(ind(i1)),sqrt(cii));
          else
            cii = Varf2(ind(i1));
            fh_p = @(f) norm_lpdf(f,Ef2(ind(i1)),sqrt(cii));
          end

          if ~predictive
            cji = Covf(ind(i1),:);
            cji(ind(i1)) = [];
            inds=[1:(ind(i1)-1) (ind(i1)+1):n];
          else
            K_fstar = gp_cov(gp,  x, xt(ind(i1),:));
            cji = (K_fstar'/K_ff)*Covf;
            inds=1:n;
          end
          mf = Ef(inds);
          cjj = Covf(inds,inds);
          y_tmp = y(inds);
          ci = cjj - cji'*(1/cii)*cji;
          f_mode_tmp=f_mode(inds);
          llg2_mode=diag(llg2(inds));
          llg_mode=llg(inds);
          ll_mode=sum(ll(inds));

          lnZ0 = -1/cii - ll_mode + 0.5*log(cii);
          icW = -eye(size(ci))/ci  - llg2_mode;
          % Loop through grid points
          for i=1:nin

            if isempty(z)
              z_tmp = [];
            else
              z_tmp = z(inds);
            end
            % Compute conditional covariance matrices and mean vector
            if ~predictive
              mu = mf+cji'./cii.*(fvec(i)-Ef(ind(i1)));
            else
              mu = mf+cji'./cii.*(fvec(i)-Ef2(ind(i1)));
            end
            W = -diag(gplik.fh.llg2(gplik, y_tmp, mu, 'latent', z_tmp));
            deriv = gplik.fh.llg(gplik, y_tmp, mu, 'latent', z_tmp);
            logll = gplik.fh.ll(gplik,y_tmp, mu, z_tmp);

            % Computation of correction term by integrating the second order Taylor
            % expansion of product of global Gaussian approximation conditioned on latent
            % value x_i, q(x_-i|x_i), and t_-i(x_-i)/ttilde_-i(x_-i)
            mu1=mu-f_mode_tmp;
            lnZ = lnZ0 + logll - mu1'*llg_mode - 0.5*mu1'*llg2_mode*mu1;
            mu2=deriv-llg_mode-(mu1'*llg2_mode)';
            lnZ = lnZ - (0.5*mu2'/(icW - W))*mu2;
            lnZ = lnZ  - evaluate_q(diag(W+llg2_mode), ci);

            lc(i,i1) = lnZ;
            %p(i,i1) = fh_p(fvec(i,i1));

          end
          lp(:,i1) = fh_p(fvecm2(:,i1));
          lp2(:,i1) = fh_p(fvecm(:,i1));
          lp(:,i1) = lp(:,i1)-max(lp(:,i1));
          lp2(:,i1) = lp2(:,i1)-max(lp2(:,i1));

        end
    end

end

for i1=1:length(ind)
  fvec = fvecm(:,i1);

  % Interpolate correction to these grid points
  % using piecewise cubic Hermite interpolation
  fvec2 = fvecm2(:,i1);
  lc(:,i1)=lc(:,i1)-lc(6,i1);

  % Check that the corrected distribution has decreasing tails
  lctmp=lc(:,i1);
  lptmp=(lp2(:,i1)+lc(:,i1));
  fvectmp=fvec;
  while lptmp(end)-lptmp(end-1) > 0
    lctmp=lctmp(1:end-1);
    lptmp=lptmp(1:end-1);
    fvectmp=fvectmp(1:end-1);
  end
  while lptmp(1)-lptmp(2) > 0
    lctmp=lctmp(2:end);
    lptmp=lptmp(2:end);
    fvectmp=fvectmp(2:end);
  end

  if (sum(isnan(lctmp))>0)
    warning('NaNs in moment computations')
    lctmp(isnan(lctmp))=0;
  end
  lc2(:,i1) = interp1(fvectmp, lctmp, fvec2, 'pchip');

  % Make correction
  pc(:,i1)=exp(lc2(:,i1) + lp(:,i1));

  if any(isnan(pc(:,i1))) || any(isinf(pc(:,i1)))
    warning('NaNs in moment computations')
    pc(isnan(pc(:,i1)),i1)=0;
    pc(isinf(pc(:,i1)),i1)=0;
  end
  if any(pc(:,i1)<eps)
    pc(pc(:,i1)<eps,i1)=0;
    iz1=find(pc(1:ceil(0.5*ng),i1)==0,1);
    iz2=ceil(0.5*ng)+find(pc(ceil(0.5*ng):ng,i1)==0,1,'last');
    pc([1:iz1 iz2:ng],i1)=0;
  end

  % Form corrected distribution & normalize
  p(:,i1) = exp(lp(:,i1))./trapz(fvec2,exp(lp(:,i1)));
  pc(:,i1) = pc(:,i1)./trapz(fvec2, pc(:,i1));
  c(:,i1) = pc(:,i1)./p(:,i1);

end
if isequal(fcorr, 'lr')
    pc=p;
end
end

function [lnZ_q,L1,L2]=evaluate_q(tau_q,K)

%%%%%%%%%%%%%%%%
% q-distribution

%   n=length(nu_q);
ii1=find(tau_q>0); n1=length(ii1); W1=sqrt(tau_q(ii1));
ii2=find(tau_q<0); n2=length(ii2); W2=sqrt(abs(tau_q(ii2)));

if ~isempty(ii1)
  % Cholesky decomposition for positive sites
  L1=(W1*W1').*K(ii1,ii1);
  L1(1:n1+1:end)=L1(1:n1+1:end)+1;
  L1=chol(L1);

else
  L1=1;
end

if ~isempty(ii2)
  % Cholesky decomposition for negative sites
  V=bsxfun(@times,K(ii2,ii1),W1')/L1;
  L2=(W2*W2').*(V*V'-K(ii2,ii2));
  L2(1:n2+1:end)=L2(1:n2+1:end)+1;

  L2=chol(L2);

else
  L2=1;
end

% log normalization
lnZ_q = sum(log(diag(L1))) + sum(log(diag(L2)));
end


function cr = slcorrectrate_blks(scores, blocks, clabels, qlabels, op, varargin)
%SLCORRECTRATE_BLKS Computes the correct rate based on blockwise scores
%
% $ Syntax $
%   - cr = slcorrectrate_blks(scores, blocks, clabels, qlabels, op, ...)
%
% $ Arguments $
%   - scores:       the score matrix
%   - blocks:       the cell array of block limits
%   - clabels:      the class labels of reference samples
%   - qlabels:      the query labels of query samples
%   - op:           the score attribute
%   - cr:           the computed classification correct rate
%
% $ Remarks $
%   - An extension of slcorrectrate to support blockwise scores
%
% $ History $
%   - Created by Dahua Lin, on Aug 9th, 2006
%   - Modified by Dahua Lin on Aug 16th, 2006
%     - Based on new slclassify to support multiple schemes
%

%% parse and verify input arguments

if nargin < 5
    raise_lackinput('slcorrectrate_blks', 5);
end

%% Make decision

n = length(qlabels);
decisions = slclassify_blks(scores, n, blocks, clabels, op, varargin{:});

%% Evaluate correct rate

qlabels = qlabels(:)';
cr = sum(decisions == qlabels) / length(qlabels);


classdef LevelSetCircle < LevelSetSphereNdim

    methods (Access = public)

        function obj = LevelSetCircle(cParams)
            obj.fracRadius = cParams.fracRadius;
            obj.compute(cParams);
        end
    end

    methods (Access = protected)
        function computeLevelSetValue(obj)
            ls = obj.dist - 1;
            obj.levelSet = ls;
        end
    end

end


function [out, lengthFuns] = length(F)
%LENGTH   Length of a Chebfun.
%   LENGTH(F) returns the length of a scalar-valued CHEBFUN object F, which is
%   defined as the sum of the length of F.funs. If F is a quasimatrix, then
%   LENGTH(F) returns the maximum length of the columns.
%
%   [LEN, LENFUNS] = LENGTH(F) also returns the length of each of the piecewise
%   components of the scalar-valued CHEBFUN object F. If F is array-valued
%   LENFUNS = NaN.
%
% See also SIZE.

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

if ( isempty(F) )
    out = 0;
else
    out = zeros(1, numel(F));
    for k = 1:numel(F)
        out(k) = sum(cellfun(@length, F(k).funs));
    end
    out = max(out);
end

if ( nargout > 1 && (numColumns(F) == 1) )
    lengthFuns = cellfun(@length, F(1).funs).';
    if ( F(1).isTransposed )
        lengthFuns = lengthFuns.';
    end
else
    lengthFuns = NaN;
end

end


function [K,w_jk,mu_jk,sigma_jk,A1] = estimate_num_comp(Y, A, ...
    sizes, shrink_size, max_num_comp, options)
%ESTIMATE_NUM_COMP Summary of this function goes here
%   Detailed explanation goes here
if nargin < 6
    options = [];
end

thresh = 0.99;
ignore_small_prior = 0.1;

[N,M] = size(A);
K = ones(1,M);
w_jk = cell(1,M);
mu_jk = cell(1,M);
sigma_jk = cell(1,M);

A1 = trim_abundance(A, sizes, shrink_size, thresh);

for j = 1:M
    X = Y(A1(:,j), :);
    num = CVIC(X, max_num_comp, options);
    K(j) = num;

    while true
        try % fit_GMM has a small probability to fail
            obj = fit_GMM(X, num, []);
            break;
        catch me
            disp('Failed to perform fit_GMM.');
        end
    end
    w_jk{j} = obj.PComponents;
    mu_jk{j} = obj.mu;
    sigma_jk{j} = obj.Sigma;
end

disp(['The number of components after CVIC are ',num2str(K)]);

%% remove the components that have too smaller priors
for j = 1:M
    X = Y(A1(:,j), :);
    ignore_masks = w_jk{j} < ignore_small_prior;
    w_jk{j}(ignore_masks) = [];
    mu_jk{j}(ignore_masks,:) = [];
    sigma_jk{j}(:,:,ignore_masks) = [];

    K(j) = length(w_jk{j});
    obj = struct('PComponents',w_jk{j},'mu',mu_jk{j},'Sigma',sigma_jk{j});
    obj = fit_GMM(X, K(j), obj);
    w_jk{j} = obj.PComponents;
    mu_jk{j} = obj.mu;
    sigma_jk{j} = obj.Sigma;
end

disp(['The number of components after removing small priors are ',num2str(K)]);
disp(['Total number of combinations is ',num2str(prod(K))]);

function num = CVIC(X, max_num_comp, options)
[N,B] = size(X);
if N/2 < B % number of samples is too small to allow 2 components
    num = 1;
    return;
end

warning('off','stats:gmdistribution:FailedToConverge');

% p = randperm(N);
% X = X(p,:);
likelihoods = zeros(N,1);
total_lh = zeros(max_num_comp,1);

num_fold = 5;
% set_size = round(N / num_fold);

for K = 1:max_num_comp
    if (N*(num_fold-1)/num_fold) / K < B % number of samples is too small
        total_lh(K) = -Inf;
        continue;
    end
    for i = 1:num_fold
        X1 = X;
%         indices = (i-1)*set_size+1 : min(i*set_size,N);
        indices = i:num_fold:N;
        test_X = X1(indices,:);
        X1(indices,:) = [];
        try
            obj = fit_GMM(X1, K, []);
            value = calc_log_gmm(test_X, obj.PComponents, obj.mu, obj.Sigma);
            likelihoods(indices) = value;
        catch me
            likelihoods(indices) = -Inf;
%             disp(['Error in CVIC: ',me.message]);
        end
    end
    total_lh(K) = sum(likelihoods);
end

[max_lh,num] = max(total_lh);
thresh_CVIC = parse_param(options,'thresh_CVIC',[]);
if ~isempty(thresh_CVIC)
    num = find(abs(total_lh - max_lh) <= max_lh * thresh_CVIC, 1);
end

warning('on','stats:gmdistribution:FailedToConverge');

function obj = fit_GMM(X, num, s)
if num > 1
    if isempty(s)
%         s = kmeans(X, num, 'start', 'cluster');
        s = kmeans(X, num);
    end
    options = statset('Display','off');
    obj = gmdistribution.fit(X, num, 'Start', s, 'Options', options);
else % one Gaussian
    [N,B] = size(X);
    obj = [];
    obj.PComponents = 1;
    obj.mu = mean(X,1);
    X1 = X - repmat(obj.mu, N, 1);
    obj.Sigma = (1/N)*(X1'*X1); % same as in EM (not 1/(N-1))
    if N < B % if the number of samples is too small
        obj.Sigma = obj.Sigma + 1e-9*eye(B);
    end
end

function A_new = trim_abundance(A, sizes, shrink_size, thresh)
if shrink_size == 0
    A_new = A > thresh;
    return
end

[N,M] = size(A);
A_new = false(N,M);
for j = 1:M
    A1 = reshape(A(:,j)>thresh, sizes);
    se = strel('disk', shrink_size);
    erodedBW = imerode(A1, se);

    shrink_size_r = shrink_size;
    while all(erodedBW(:) == 0) % reduce size of structure element
        shrink_size_r = shrink_size_r - 1;
        se_r = strel('disk', shrink_size_r);
        erodedBW = imerode(A1, se_r);
    end

    A_new(:,j) = erodedBW(:);
end

function A_new = trim_abundance1(A, sizes, pure_perc, thresh)
if pure_perc == 1
    A_new = A > thresh;
    return
end

[N,M] = size(A);
A_new = false(N,M);
disk_sizes = (1:100);
for j = 1:M
    A1 = reshape(A(:,j)>thresh, sizes);
    for k = 1:length(disk_sizes)
        se = strel('disk', disk_sizes(k));
        erodedBW = imerode(A1, se);
        if length(find(erodedBW)) / length(find(A1)) <= pure_perc
            A_new(:,j) = erodedBW(:);
            break;
        end
    end
end


function plot_path(map, path)
% PLOT_PATH Visualize a path through an environment
%   PLOT_PATH(map, path) creates a figure showing a path through the
%   environment.  path is an N-by-3 matrix where each row corresponds to the
%   (x, y, z) coordinates of one point along the path.

path = points_to_idx(map, path);

[x,y,z] = meshgrid(1:size(map.map3d,1),1:size(map.map3d,2),1:size(map.map3d,3));
x = x(:); y = y(:); z = z(:);

xyz = [];
for i = 1:numel(x)
    if map.map3d(x(i),y(i),z(i),1)~= 255 | map.map3d(x(i),y(i),z(i),2)~= 255 | map.map3d(x(i),y(i),z(i),2)~= 255
        xyz = [xyz; x(i),y(i),z(i)];
    end
end
rgb = zeros(size(xyz,1),3);
for i = 1:size(xyz,1)
    rgb(i,:) = map.map3d(xyz(i,1),xyz(i,2),xyz(i,3),:);
end
if size(xyz,1) > 0
pcshow(xyz, rgb, 'MarkerSize', 200);
end
hold on;
if size(path,1) > 0
pcshow(path, [0,0,0],'MarkerSize', 20);
end
hold off;
end


function parse_data_int(filename, max_memo_GB)
% max_memo_GB is an idea of the number of GB allocated for the data to be
% stored in RAM, so it is used to compute the number of segments in which
% the data should be split for processing
% Based in read_intan_data.m version 1.1, June 26, 2010
% (c) 2010, Intan Technologies, LLC
% For more information, see http://www.intantech.com
% For updates and latest version, see http://www.intantech.com/software.html

[unused, fname, ext] = fileparts(filename);
ext = lower(ext(2:end));

if strcmp(ext,'.int')
    error('Incorrect extension.');
end

with_memory=true;
try
	memory;
catch
	with_memory=false;
end
if with_memory
	[userview,systemview] = memory;
	memo_avaible = floor(systemview.PhysicalMemory.Available*0.80);
	if exist('max_memo_GB','var') && ~isempty(max_memo_GB)
        max_memo = max_memo_GB*(1024)^3;
		if max_memo > memo_avaible
			error('max_memo_GB > 80% of Physical Memory Available')
		end
	else
		max_memo = memo_avaible;
	end
else
	max_memo = max_memo_GB*(1024)^3;
end

fid = fopen(filename, 'r');

% Read first three header bytes encoding file version
for i=1:3
    header(i) = fread(fid, 1, 'uint8');
end

if (header(1) ~= 128)
    error('Improper data file format.');
end

if (header(2) ~= 1 || header(3) ~= 1)
    warning('Data file version may not be compatible with this m-file.');
end

% Now see which amplifier channels are saved in this file.

for i=1:64
    amp_on(i) = fread(fid, 1, 'uint8');
end

num_amps = sum(amp_on);
channels = find(amp_on);
s = dir(filename);
filesize = s.bytes;

lts = (filesize - 67)/(num_amps*4 + 1);

sr = 25000;
save('intan_meta_data','sr','lts','channels')

%-----------------------------------

fprintf(1, '\nData file contains %0.2f seconds of data from %d amplifier channels.\n', lts/sr, num_amps);
fprintf(1, 'Channels: %s \n',num2str(channels));

%--------------------------------------

% Go back to the beginning of the file...
frewind(fid);
% ...skip the header this time...
fread(fid, 3+64, 'uint8');

samples_per_channel = ceil(max_memo/(num_amps*4+1));
num_segments = ceil(lts/samples_per_channel);

outfile_handles = cell(1,num_amps);

for i = 1:num_amps
    outfile_handles{i} = fopen([fname '_' num2str(channels(i)) '.intch'],'w','l');
end

for j=1:num_segments
    ini = (j-1)*samples_per_channel;
    fin = min(j*samples_per_channel,lts);
    data2 = fread(fid,(fin-ini)*(num_amps*4+1),'uint8=>uint8');
    data2((num_amps*4)+1:num_amps*4+1:end) = [];
    data2 = typecast(data2,'single');
    for ind = 1:num_amps
        fwrite(outfile_handles{ind},data2(ind:num_amps:end),'single');
    end
    fprintf('Segment %d out of %d processed.\n',j,num_segments);
end

fclose('all');


% ------------------------------------------------------------------------
% Copyright (C) 2016 University of Southern California, SAIL, U.S.
% Author: Maarten Van Segbroeck
% Mail: mvansegbroeck@gmail.com
% Date: 2016-20-12
% ------------------------------------------------------------------------
% vadout = apply_vad(audiodir,p1,p2);
%
%      Apply Voice Activity Detection to all files in a specified audio directory
%
%      --IN--
%      audiodir: directory of audio files (WAV format)
%      p1: speech/non-speech threshold [default:0.1]
%      p2: speech region smoothing [default:20]
%
%      --OUT--
%      vadout: VAD labels at frame level (10 ms)
%
%      When using please cite:
%
%      @article{van2013robust,
%       title={A Robust Frontend for VAD: Exploiting Contextual, Discriminative and Spectral Cues of Human Voice},
%       author={Van Segbroeck, Maarten and Tsiartas, Andreas and Narayanan, Shrikanth},
%       year={2013}
%     }

function vadout=apply_vad(audiodir,p1,p2)

if ~exist('audiodir','var')
  fprintf('Please specify an audio directory\n')
  return
end

% ---vad parameters (to tune)---
% speech noise threshold
if ~exist('p1','var')
  p1=0.1;
end
% speech region smoothing
if ~exist('p2','var')
  p2=20;
end

% set path
addpath mfiles/

filenames=dir(sprintf('%s/*.wav',audiodir));
fs=8000;

% ---feature---
% GT
NbCh=64;
% Gabor
nb_mod_freq=2;
% LTSV
R=50; % context
M=10; % smoothing
ltsvThr=0.5;
ltsvSlope=0.2;
% vprob2 and ltsv2
K=30; order=4;
% -------------

% ---vad model---
load('models/model.mat')

% ---visualize---
visualize=true;

for k = 1 : length(filenames)

 % read in audio
 [sam,fs_orig]=audioread(fullfile(audiodir,filenames(k).name));
 sam_8k=downsample(sam(:,1),fs_orig/fs);

 % [1] extract cochleagram
 gt=FE_GT(sam_8k,fs,NbCh);

 % [2] Gabor filtering applied on mel
 gbf=FE_GBF(sam_8k,fs,nb_mod_freq,false);
 gbf= [gbf gbf(:,ones(1,10)*size(gbf,2))];
 gbf = gbf(:,1:size(gt,2));

 % [3] LTSV
 ltsv=FE_LTSV(sam_8k,fs,R,M,gt,ltsvThr,ltsvSlope);
 ltsv2 = convert_to_context_stream(ltsv, K, order);
 ltsv2= [ltsv2 ltsv2(:,ones(1,10)*size(ltsv,2))];
 ltsv2 = ltsv2(:,1:size(gt,2));

 % [4] vprob prob
 vprob=voicingfeature(sam_8k,fs);
 vprob2 = convert_to_context_stream(vprob, K, order);
 vprob2 = [vprob2 vprob2(:,ones(1,10)*size(vprob,2))];
 vprob2 = vprob2(:,1:size(gt,2));

 % feature for VAD
 test_x = [gt;gbf;ltsv2;vprob2];
 test_x_norm = mvn(test_x);

 % VAD decoding
 [~,~,output] = nntest(dnn, test_x_norm');
 outprob=double(output(:,1));
 vadout=medfilt1(outprob.^2,p2)>p1;

 if visualize
  imagesc(mvn(gt));axis xy;hold on;
  plot(10*vadout,'m','LineWidth',3); zoom xon; hold off
 end
end


classdef math_model_cpf_accs < mp.math_model_cpf_acc & mp.mm_shared_pfcpf_accs
%MP.MATH_MODEL_CPF_ACCS  MATPOWER mathematical model for continuation power flow (CPF) problem.
%   ?
%
%   MP.MATH_MODEL_CPF_ACCS ... power flow ...
%
%   Properties
%       ? - ?
%
%   Methods
%       ?

%   MATPOWER
%   Copyright (c) 2021-2022, Power Systems Engineering Research Center (PSERC)
%   by Ray Zimmerman, PSERC Cornell
%
%   This file is part of MATPOWER.
%   Covered by the 3-clause BSD License (see LICENSE file for details).
%   See https://matpower.org for more info.

%     properties
%     end

    methods
        function tag = form_tag(obj)
            tag = 'accs';
        end

        function name = form_name(obj)
            name = 'AC-cartesian-power';
        end

        function obj = add_node_balance_constraints(obj, nm, dm, mpopt)
            %% power balance constraints
            ad = obj.aux_data;
            fcn = @(x)node_balance_equations_cpf(obj, x, nm);
            obj.add_nln_constraint({'Pmis', 'Qmis', 'Vmis'}, [ad.npv+ad.npq;ad.npq;ad.npv], 1, fcn, []);
        end
    end     %% methods
end         %% classdef


addpath('D:\CODE\MariusBox\SpikeDetection')

f0      = 30; % sampling frequencys

mname   = 'M150329_MP009';
datExp  = '2015-04-27';
root    = 'D:\DATA\F\';
plane_um = 0;
pix_um  = 2;
npl     = 1;

%% load the procesed data
[Ff, res] = loadPROC(root, mname, datExp, npl, plane_um, pix_um, f0);

%% ITeRATIVE OPTIMIZATION OF PARAMETERS
% load('D:\CODE\MariusBox\BigNeuralCode\results\driv1112F.mat')
load('D:\CODE\MariusBox\SpikeDetection\kernel.mat')

[dcell, Ffr, kinterp] = run_deconvolution(Ff, f0, kernel);

%%
NN = numel(dcell);
iNN = ceil(rand *NN);
clf
plot(my_conv2(Ff(:,iNN) - dcell{iNN}.B, 2, 1))
hold all
plot(conv(kinterp, Ffr(:,iNN)))
hold off