%function dtiGenerateNormalizedData
% Generate a spatially-normalized set of summary data for two groups (boys
% and girls).

bd = '/biac3/wandell4/data/reading_longitude/dti_y1234/';
[sd,sc] = findSubjects([bd '*'],'dti06trilinrt');
behaveData = dtiGetBehavioralDataStruct(sc, '/biac3/wandell4/data/reading_longitude/read_behav_measures_longitude.csv', sd);
clear sd sc;
outDir = '/biac3/wandell4/data/reading_longitude/logNorm_analysis';
sumFile = fullfile(outDir,'sum_090715');

n = numel(behaveData);
templateName = 'SIRL54';
templateDir = fullfile(fileparts(which('mrDiffusion.m')),'templates');
template = fullfile(templateDir, [templateName '_EPI.nii.gz']);
t1Template = fullfile(templateDir, [templateName '_T1.nii.gz']);
desc = ['Normalized to ' templateName ' using B0.'];
clear templateName templateDir;
mT1 = 0;
mB0 = 0;
mBm = 0;
mDt6 = 0;
clear sn t1Sn;
for(ii=116:n)
    tic;
    fprintf('Processing %d of %d (%s)...\n',ii, n, behaveData(ii).dataDir);
    dtiRawFixDt6File(behaveData(ii).dataDir);
    [dt,t1] = dtiLoadDt6(behaveData(ii).dataDir);
    im = mrAnatHistogramClip(double(dt.b0),0.4,0.98);
    dt.b0 = im;
    im(bwareaopen(im==0,10000,6)) = NaN;
    evalc('sn{ii} = mrAnatComputeSpmSpatialNorm(im, dt.xformToAcpc, template);');
    evalc('dt_sn = dtiSpmDeformer(dt,sn{ii});');
    sn{ii}.VG.dat = [];
    dtXformToAcpc = dt_sn.xformToAcpc;
    adcUnits = dt_sn.adcUnits;
    mB0 = mB0 + dt_sn.b0;
    % We'll exclude non-PD tensors by removing them from the brain mask
    [vec,val] = dtiEig(dt_sn.dt6);
    mBm = mBm + double(dt_sn.brainMask & all(val>0,4));
    mDt6 = mDt6 + dt_sn.dt6;
    dt6(:,:,:,:,ii) = single(dt_sn.dt6);
    b0(:,:,:,ii) = single(dt_sn.b0);
    clear dt im dt_sn vec val;
    im = mrAnatHistogramClip(double(t1.img),0.4,0.98);
    evalc('t1Sn{ii} = mrAnatComputeSpmSpatialNorm(im, t1.xformToAcpc, t1Template);');
    t1Sn{ii}.VG.dat = [];
    [im,t1XformToAcpc] = mrAnatResliceSpm(im, t1Sn{ii}, mrAnatXformCoords(t1Sn{ii}.VG.mat,[1 1 1; t1Sn{ii}.VG.dim]), [1 1 1], 7, false);
    % mrAnatOverlayMontage(dt_sn.b0,dt_sn.xformToAcpc, im, t1Sn.VG.mat, autumn(256), [.8 1], [-20:2:60])
    mT1 = mT1 + im;
    clear im t1;
    toc
end
tmpFile = [tempname '.mat'];
save(tmpFile,'-v7.3');

clear vec val im ii tmpFile;
brainMask = mBm>=ceil(n*.95) & all(dt6(:,:,:,1,:)~=0,5);
b0 = dtiImgToInd(b0,brainMask);
dt6 = dtiImgToInd(dt6, brainMask);
mBm = single(mBm);
mB0 = single(mB0);
mDt6 = single(mDt6);
mT1 = single(mT1);
clear ans;

save(sumFile);

%return

dtiWriteTensorsToNifti(mDt6, dtXformToAcpc, desc, adcUnits, fullfile(outDir,'dti06','bin','tensors.nii.gz'));
dtiWriteNiftiWrapper(mB0, dtXformToAcpc, fullfile(outDir,'dti06','bin','b0.nii.gz'), 1, desc);
dtiWriteNiftiWrapper(uint8(brainMask), dtXformToAcpc, fullfile(outDir,'dti06','bin','brainMask.nii.gz'), 1, desc);
dtiWriteNiftiWrapper(mT1, t1XformToAcpc, fullfile(outDir,'dti06','t1.nii.gz'), 1, desc);


function copyOrbitToClipboardFromText(hEpoch, hSMA, hEcc, hInc, hRAAN, hArg, hAnomaly, isTrueAnomaly, bodyID)
%copyOrbitToClipboardFromText Summary of this function goes here
%   Detailed explanation goes here
    global GLOBAL_OrbitClipboard;

    if(~isempty(hEpoch))
        GLOBAL_OrbitClipboard(1) = str2double(get(hEpoch, 'String'));
    else
        GLOBAL_OrbitClipboard(1) = 0;
    end

    GLOBAL_OrbitClipboard(2) = str2double(get(hSMA, 'String'));
    GLOBAL_OrbitClipboard(3) = str2double(get(hEcc, 'String'));
    GLOBAL_OrbitClipboard(4) = deg2rad(str2double(get(hInc, 'String')));
    GLOBAL_OrbitClipboard(5) = deg2rad(str2double(get(hRAAN, 'String')));
    GLOBAL_OrbitClipboard(6) = deg2rad(str2double(get(hArg, 'String')));

    if(~isempty(hAnomaly))
        anomaly = deg2rad(str2double(get(hAnomaly, 'String')));
        if(isTrueAnomaly == true)
            tru = anomaly;
        else
            mean = anomaly;
            ecc = str2double(get(hEcc, 'String'));
            tru = computeTrueAnomFromMean(mean, ecc);
        end
        GLOBAL_OrbitClipboard(7) = tru;
    else
        GLOBAL_OrbitClipboard(7) = 0;
    end

    GLOBAL_OrbitClipboard(8) = bodyID;
end


function m_utmgrid(varargin)
% M_UTMGRID Draws a UTM grid on a map.
%        M_UTMGRID('parameter','value',...) with any number (or no)
%        optional parameters is used to draw a UTM grid (i.e. with
%        grid lines at 1 km intervals) for a map using the UTM
%        coordinate system. This can be used instead of, or in addition
%        to, the latitude/longitude grid drawn by M_GRID.
%
%        The optional parameters allow the user
%        to control the look of the grid. These parameters are listed
%        by M_UTMGRID('get'), with default parameters in M_UTMGRID('set');
%
%        This is probably useful only for maps less than a few km across.
%
%        see also M_PROJ, M_GRID

% Rich Pawlowicz (rich@eoas.ubc.ca) 25/April/2018

% These structures are initialized by m_proj()

global MAP_PROJECTION MAP_VAR_LIST

% Have to have initialized a map first

if isempty(MAP_PROJECTION)
  disp('No Map Projection initialized - call M_PROJ(''UTM'',... first!');
  return;
elseif ~strcmp(MAP_PROJECTION.name,'UTM')
  disp('Not a UTM projection');
  return;
elseif strcmp(MAP_VAR_LIST.ellipsoid,'normal')
  disp('Cannot show UTM coordinates using the ``normal'' (earth radius=1) ellipsoid in the m_proj call');
  return;
end

gcolor=get(gca,'gridcolor');
gxcolor=get(gca,'xcolor');
gycolor=get(gca,'ycolor');
glinestyle=get(gca,'gridlinestyle');
glinewidth=get(gca,'linewidth');
gfontsize=get(gca,'fontsize');
gfontname=get(gca,'fontname');
gxaxisloc=get(gca,'xaxislocation');
gyaxisloc=get(gca,'yaxislocation');
gtickdir=get(gca,'tickdir');
gticklen=get(gca,'ticklength'); gticklen=gticklen(1);

k=1;
while k<=length(varargin)
  switch lower(varargin{k}(1:3))
    case 'gri'
      gcolor=varargin{k+1};
    case 'lin'
      switch lower(varargin{k}(1:5))
         case 'linew'
           glinewidth=varargin{k+1};
         case 'lines'
           glinestyle=varargin{k+1};
      end
    case 'fon'
       switch lower(varargin{k}(1:5))
         case 'fonts'
           gfontsize=varargin{k+1};
         case 'fontn'
           gfontname=varargin{k+1};
       end
    case 'xco'
      gxcolor=varargin{k+1};
    case 'yco'
      gycolor=varargin{k+1};
    case 'xax'
      gxaxisloc=varargin{k+1};
    case 'yax'
      gyaxisloc=varargin{k+1};
    case 'tic'
      switch lower(varargin{k}(1:5))
        case 'tickl'
           gticklen=varargin{k+1};
        case 'tickd'
           gtickdir=varargin{k+1};
      end
    case {'get','usa'}

      disp('      ''ticklength'',value');
      disp('      ''tickdir'',( ''in'' | ''out'' )');
      disp('      ''gridcolor'',colorspec');
      disp('      ''linewidth'', value');
      disp('      ''linestyle'', ( linespec | ''none'' )');
      disp('      ''fontsize'',value');
      disp('      ''fontname'',name');
      disp('      ''Xcolor'',colorspec');
      disp('      ''Ycolor'',colorspec');
      disp('      ''XaxisLocation'',( ''bottom'' | ''top'' ) ');
      disp('      ''YaxisLocation'',( ''left'' | ''right'' ) ');
      return;
    case 'set'
      disp(['      ticklength = ' num2str(gticklen)]);
      disp(['      tickdir = ' gtickdir]);
      disp(['      gridcolor = ' gcolor]);
      disp(['      linewidth = ' num2str(glinewidth)]);
      disp(['      linestyle = ' glinestyle]);
      disp(['      fontsize = ' num2str(gfontsize)]);
      disp(['      fontname = ' gfontname]);
      disp(['      Xcolor = ' gxcolor]);
      disp(['      Ycolor = ' gycolor]);
      disp(['      XaxisLocation = ' gxaxisloc]);
      disp(['      YaxisLocation = ' gyaxisloc]);
      return;
  end
  k=k+2;
end

% Bring the grid back!

set(gca,'visible','on','layer','top','tickdir',gtickdir,...
   'gridcolor',gcolor,'gridlinestyle',glinestyle,'linewidth',glinewidth,...
   'xaxislocation',gxaxisloc,'yaxislocation',gyaxisloc,'xcolor',gxcolor',...
   'ycolor',gycolor,'fontname',gfontname,'ticklength',[gticklen .025],...
   'fontsize',gfontsize,'xgrid','on','ygrid','on');

fnt=gfontsize;
fnt2=fnt*0.8;

% Do the x axis

tk=get(gca,'xtick');
% Nothing smaller than 1 km squares
tk(rem(tk,1e3)~=0)=[];

tk1=fix(tk/1e5);
tk2=fix((tk-1e5*tk1)/1e3);
tk3=rem(tk,1e3);

for k=1:length(tk)-1,
    lab{k}=sprintf('\\fontsize{%d}%02d',fnt,tk2(k));
end
k=length(tk);
lab{k}=sprintf('{\\fontsize{%d}%2d}\\fontsize{%d}%02d{\\fontsize{%d}%03d} E',fnt2,tk1(k),fnt,tk2(k),fnt2,tk3(k));
set(gca,'xtick',tk,'xticklabel',lab);

% Do the y axis

tk=get(gca,'ytick');
% Nothing smaller than 1 km squares
tk(rem(tk,1e3)~=0)=[];

tk1=fix(tk/1e5);
tk2=fix((tk-1e5*tk1)/1e3);
tk3=rem(tk,1e3);

for k=1:length(tk)-1,
    lab{k}=sprintf('\\fontsize{%d}%02d',fnt,tk2(k));
end
k=length(tk);
lab{k}=sprintf('{\\fontsize{%d}%2d}\\fontsize{%d}%02d{\\fontsize{%d}%03d} N',fnt2,tk1(k),fnt,tk2(k),fnt2,tk3(k));
set(gca,'ytick',tk,'yticklabel',lab','yticklabelrotation',90);

set(gca,'tag','m_utmgrid');


function fem = line_swap(fem_struct,j,k);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Line_swap is mesh refining tool that swaps an edge that two elements
% share. It reconnects the elements so that the edge they share has been
% flipped. This routine only operates on one line at a time and can only be
% used if the two elements share an edge. This routine can operate on any
% elemnet, even boundry elements, unless the new elements formed by the line
% swap would overlap existing elements. No nodes are moved by this routine.
% The fem.e and fem.ar are the only fields that are updated. If no .nei file
% is present then none will be generated; however, if one is present then
% it will be updated to reflect the new connectivity.
%
% Calls: is_valid_struct.m
%
% Usage: fem = line_swap(fem_struct,j,k);
%
% Variables:
%  fem -- the new split finite element mesh.
%  fem_struct -- the finite element grid structure from the opnml suite.
%          Note: fem_struct.nei will not be generated if not present
%  j -- element number for one element used in the line swap.
%  k -- element number for one element used in the line swap.
%          Note: j and k can be interchanged.
%
% Filename: line_swap.m
% Created by: Ben Holladay
% Date: June 8, 2005
% Last Modified:
%       Oct. 26, 2007 -- Chris Massey, NRL 7322
%       Changed when line swap can not be performed due to mesh tangling,
%       from an error call to a display message and return original fem.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%Ensure the apropriate number of input arguements is given, checks that the
%fem_struct is valid.
if nargin == 0
    error('Not enough input arguments; need a fem_struct and two element numbers.');
end
if ~is_valid_struct(fem_struct)
   error('Input argument to line swap must be a valid fem_struct.');
end
if nargin == 1
    error(['Input arguments must include a valid fem_struct and two element ' , ...
    'numbers that share an edge.']);
elseif nargin == 2
    error('Two element numbers must be given.');
elseif nargin == 3
    if j <= 0 | j > size(fem_struct.e,1) | j ~= floor(j)
        error(['Element numbers must positive integers that are less than ',...
            'the maximum number of elements.']);
    end
    if k <= 0 | k > size(fem_struct.e,1) | k ~= floor(k)
        error(['Element numbers must positive integers that are less than ',...
            'the maximum number of elements.']);
    end
else
    error('Too many input arguments.');
end

%Sets the intial fem_struct variables.
x = fem_struct.x;
y = fem_struct.y;
enodes = fem_struct.e;
ar = fem_struct.ar;

%Determine if the elements share a common edge.
elems = enodes([j;k],:);
comp = unique(intersect(elems(1,:),elems(2,:)));
if length(comp) < 2
    error('The elements do not share a common edge.');
end

%Indentify each node for swapping.
[nodes,ti,tj] = unique(elems);
temp1 = setdiff((1:6),ti);
temp1 = elems(temp1);
temp2 = setdiff(nodes,temp1);

%Determine if the angle between the elements is too big for line_swap to
%effectively operate on it.
a2 = (x(enodes([j;k],3))-x(enodes([j;k],2))).^2+(y(enodes([j;k],3))-y(enodes([j;k],2))).^2;
b2 = (x(enodes([j;k],1))-x(enodes([j;k],3))).^2+(y(enodes([j;k],1))-y(enodes([j;k],3))).^2;
c2 = (x(enodes([j;k],2))-x(enodes([j;k],1))).^2+(y(enodes([j;k],2))-y(enodes([j;k],1))).^2;
A = (180/pi)*acos((b2+c2-a2)./(2*sqrt(b2).*sqrt(c2)));
B = (180/pi)*acos((c2+a2-b2)./(2*sqrt(c2).*sqrt(a2)));
C = (180/pi)*acos((a2+b2-c2)./(2*sqrt(a2).*sqrt(b2)));
ang = [A,B,C];
temp3 = find(temp1(1) == elems);
temp4 = find(temp1(2) == elems);
temp5 = ang(temp3);
temp6 = ang(temp4);
temp5 = sum(temp5);
temp6 = sum(temp6);
if temp5 >= 180 | temp6 >= 180
    disp(['The line cannot be swapped because the new elements would '...
        'create overlapping elements.']);
    fem = fem_struct;
    return
elseif temp5 >= 135 | temp6 >= 135
    disp(['Warning: The elements created will contain large angles.']);
end
clear a2 b2 c2 A B C ang

%Swap the lines in the enodes list.
temp3 = setdiff(elems(1,:),temp1);
temp4 = setdiff(elems(2,:),temp1);
temp5 = find(elems(1,:) == temp1(1));
elems(1,temp5) = temp4;
temp6 = find(elems(2,:) == temp1(2));
elems(2,temp6) = temp3;
clear temp5 temp6;

%Recomputes the areas for the new elements.
xnodes = x(elems);
ynodes = y(elems);
temparea = 0.5*(xnodes(:,1).*(ynodes(:,2)-ynodes(:,3))+xnodes(:,2).*...
(ynodes(:,3)-ynodes(:,1))+xnodes(:,3).*(ynodes(:,1)-ynodes(:,2)));
clear xnodes ynodes x y;

%Addes the new elements and areas to the global lists.
enodes([j;k,],:) = elems;
ar([j;k]) = temparea(:);
clear elems temparea;

%Create the output structure.
fem = fem_struct;
fem.e = enodes;
fem.ar = ar;

%Updates the nei if present.
try
    nei = fem_struct.nei;
    nei = [nei,zeros((size(nei,1)),1)];
    tempnei = nei([temp1(:);temp2(:)],:);
    temp3 = find(tempnei(1,:) == temp1(2));
    temp4 = setdiff(1:(size(tempnei,2)),temp3);
    tempnei(1,:) = ([tempnei(1,temp4),0]);
    temp3 = find(tempnei(2,:) == temp1(1));
    temp4 = setdiff(1:(size(tempnei,2)),temp3);
    tempnei(2,:) = ([tempnei(2,temp4),0]);
    temp3 = find(tempnei(3,:) == temp1(1) | tempnei(3,:) == temp1(2));
    if abs(temp3(1)-temp3(2)) == 1
		tempnei(3,:) = [tempnei(3,(1:temp3(1))),temp2(2),tempnei(3,((temp3(2)):(end-1)))];
    else
        tempnei(3,:) = [temp2(2),tempnei(3,(1:end-1))];
    end
    temp3 = find(tempnei(4,:) == temp1(1) | tempnei(4,:) == temp1(2));
    if abs(temp3(1)-temp3(2)) == 1
        tempnei(4,:) = [tempnei(4,(1:temp3(1))),temp2(1),tempnei(4,((temp3(2)):(end-1)))];
    else
        tempnei(4,:) = [temp2(1),tempnei(4,(1:end-1))];
    end
    nei([temp1(:);temp2(:)],:) = tempnei;
    temp3 = find(nei(:,end) ~= 0);
    if isempty(temp3) == 1
        nei = nei(:,(1:end-1));
    end
    temp3 = find(nei(:,end) ~= 0);
    if isempty(temp3) == 1
        nei = nei(:,(1:end-1));
    end
    fem.nei = nei;
catch
end

return


function [in] = au2in(au)
% Convert length from astronomical units to inches.
% Chad A. Greene 2012
in = au*5889679948464;


classdef UnfittedMesh_Builder_Factory < handle

    methods (Access = public, Static)

        function concreteBuilder = create(type,ndim)
            switch ndim
                case 1
                    concreteBuilder = UnfittedMesh_StraightLine();
                case 2
                    switch type
                        case 'INTERIOR'
                            concreteBuilder = UnfittedMesh_FlatSurface();
                        case 'BOUNDARY'
                            concreteBuilder = UnfittedMesh_FlatCurve();
                    end
                case 3
                    switch type
                        case 'INTERIOR'
                            concreteBuilder = UnfittedMesh_Volumetric();
                        case 'BOUNDARY'
                            concreteBuilder = UnfittedMesh_3DSurface();
                    end
            end
        end

    end

end


function [Fao,Fso] = blockframepairaccel(Fa, Fs, Lb, varargin)
%BLOCKFRAMEPAIRACCEL Precompute structures for block processing
%   Usage: F = blockframepairaccel(Fa,Fs,Lb);
%
%   `[Fao,Fso]=blockframepairaccel(Fa,Fs,Lb)` works similar to
%   |blockframeaccel| with a pair of frames. The only difference from
%   calling |blockframeaccel| separatelly for each frame is correct
%   default choice of the slicing windows. Frame objects `Fa,Fs` will be
%   accelerated for length `2*Lb`.
%
%   The following optional arguments are recognized:
%
%      `'anasliwin',anasliwin`  : Analysis slicing window. `sliwin` have to
%                                 be a window of length *2Lb* or a string
%                                 accepted by the |firwin| function. It is
%                                 used only in the slicing window approach.
%                                 The default is `'hann'`.
%
%      `'synsliwin',synsliwin`  : Synthesis slicing window. The same as the
%                                 previous one holds. The default is `'rect'`.
%
%      `'zpad',zpad`   : Number of zero samples the block will be padded
%                        after it is windowed by a slicing window. Note the
%                        frames will be accelerated for length
%                        `2*Lb+2*kv.zpad`.
%

complainif_notenoughargs(nargin,3,'BLOCKFRAMEPAIRACCEL');
complainif_notvalidframeobj(Fa,'BLOCKFRAMEPAIRACCEL');
complainif_notvalidframeobj(Fs,'BLOCKFRAMEPAIRACCEL');

definput.flags.blockalg = {'naive','sliced','segola'};
definput.keyvals.anasliwin = [];
definput.keyvals.synsliwin = [];
definput.keyvals.zpad = 0;
[flags,kv]=ltfatarghelper({},definput,varargin);

isSliProp = ~isempty(kv.anasliwin) || ~isempty(kv.synsliwin) || kv.zpad~=0;
assert(~(~flags.do_sliced && isSliProp),...
   sprintf(['%s: Definig slicing window properties without setting the',...
            ' ''sliced'' flag.'], mfilename));

if flags.do_sliced
   if isempty(kv.anasliwin)
      kv.anasliwin = 'hann';
   end

   if isempty(kv.synsliwin)
      kv.synsliwin = 'hann';
   end

   Fao = blockframeaccel(Fa,Lb,'sliced','sliwin',kv.anasliwin,...
                         'zpad',kv.zpad);
   Fso = blockframeaccel(Fs,Lb,'sliced','sliwin',kv.synsliwin,...
                         'zpad',kv.zpad);
else
   Fao = blockframeaccel(Fa,Lb,flags.blockalg);
   Fso = blockframeaccel(Fs,Lb,flags.blockalg);
end


function drawCartPoleTraj(t,p1,p2,nFrame)
% drawCartPoleTraj(t,p1,p2,nFrame)
%
% INPUTS:
%   t =  [1,n] = time stamp for the data in p1 and p2
%   p1 = [2,n] = [x;y] = position of center of the cart
%   p2 = [2,n] = [x;y] = position of tip of the pendulum
%   nFrame = scalar integer = number of "freeze" frames to display
%

clf; hold on;

Cart_Width = 0.15;
Cart_Height = 0.05;

Pole_Width = 4;  %pixels

%%%% Figure out the window size:

[xLow, xUpp, yLow, yUpp] = getBounds(p1,p2);

xLow = xLow - 0.7*Cart_Width;
xUpp = xUpp + 0.7*Cart_Width;

yLow = yLow - 0.7*Cart_Height;
yUpp = yUpp + 0.7*Cart_Height;

Limits = [xLow,xUpp,yLow,yUpp];

%%%% Get color map for the figure
map = colormap;
tMap = linspace(t(1),t(end),size(map,1))';

%%%% Plot Rails
plot([Limits(1) Limits(2)],-0.5*Cart_Height*[1,1],'k-','LineWidth',2)

%%%% Draw the trace of the pendulum tip  (continuously vary color)

nTime = length(t);
for i=1:(nTime-1)
    idx = i:(i+1);
    x = p2(1,idx);
    y = p2(2,idx);
    c = interp1(tMap,map,mean(t(idx)));
    plot(x,y,'Color',c);
end

%%%% Compute the frames for plotting:
tFrame = linspace(t(1), t(end), nFrame);
cart = interp1(t',p1',tFrame')';
pole = interp1(t',p2',tFrame')';

for i = 1:nFrame

    % Compute color:
    color = interp1(tMap,map,tFrame(i));

    %Plot Cart
    x = cart(1,i) - 0.5*Cart_Width;
    y = -0.5*Cart_Height;
    w = Cart_Width;
    h = Cart_Height;
    hCart = rectangle('Position',[x,y,w,h],'LineWidth',2);
    set(hCart,'FaceColor',color);
    set(hCart,'EdgeColor',0.8*color);

    %Plot Pendulum
    Rod_X = [cart(1,i), pole(1,i)];
    Rod_Y = [cart(2,i), pole(2,i)];
    plot(Rod_X,Rod_Y,'k-','LineWidth',Pole_Width,'Color',color)

    %Plot Bob and hinge
    plot(pole(1,i),pole(2,i),'k.','MarkerSize',40,'Color',color)
    plot(cart(1,i),cart(2,i),'k.','MarkerSize',60,'Color',color)

end

%These commands keep the window from automatically rescaling in funny ways.
axis(Limits);
axis('equal');
axis manual;
axis off;

end

function [xLow, xUpp, yLow, yUpp] = getBounds(p1,p2)
%
% Returns the upper and lower bound on the data in val
%

val = [p1,p2];
xLow = min(val(1,:));
xUpp = max(val(1,:));
yLow = min(val(2,:));
yUpp = max(val(2,:));

end


function [ vertex_coordinate, vertex_label, edge_vertex, edge_label, ...
  triangle_vertex, triangle_label, quadrilateral_vertex, ...
  quadrilateral_label, tetrahedron_vertex, tetrahedron_label, ...
  hexahedron_vertex, hexahedron_label ] = mesh_data_read ( filename, dim, ...
  vertices, edges, triangles, quadrilaterals, tetrahedrons, hexahedrons )

%*****************************************************************************80
%
%% MESH_READ reads a MESH file defining a mesh and returns the data.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 November 2014
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Pascal Frey,
%    MEDIT: An interactive mesh visualization software,
%    Technical Report RT-0253,
%    Institut National de Recherche en Informatique et en Automatique,
%    03 December 2001.
%
%  Parameters:
%
%    Input, string FILENAME, the name of the MESH file.
%
%    Input, integer DIM, the spatial dimension, which should be 2 or 3.
%
%    Input, integer VERTICES, the number of vertices.
%
%    Input, integer EDGES, the number of edges (may be 0).
%
%    Input, integer TRIANGLES, the number of triangles (may be 0).
%
%    Input, integer QUADRILATERALS, the number of quadrilaterals (may be 0).
%
%    Input, integer TETRAHEDRONS, the number of tetrahedrons (may be 0).
%
%    Input, integer HEXAHEDRONS, the number of hexahedrons (may be 0).
%
%    Output, real VERTEX_COORDINATE(DIM,VERTICES), the coordinates
%    of each vertex.
%
%    Output, integer VERTEX_LABEL(VERTICES), a label for each vertex.
%
%    Output, integer EDGE_VERTEX(2,EDGES), the vertices that form each edge.
%
%    Output, integer EDGE_LABEL(EDGES), a label for each edge.
%
%    Output, integer TRIANGLE_VERTEX(3,TRIANGLES), the vertices that form
%    each triangle.
%
%    Output, integer TRIANGLE_LABEL(TRIANGLES), a label for each triangle.
%
%    Output, integer QUADRILATERAL_VERTEX(4,QUADRILATERALS), the vertices that
%    form each quadrilateral.
%
%    Output, integer QUADRILATERAL_LABEL(QUADRILATERALS), a label for
%    each quadrilateral.
%
%    Output, integer TETRAHEDRON_VERTEX(4,TETRAHEDRONS), the vertices that
%    form each tetrahedron.
%
%    Output, integer TETRAHEDRON_LABEL(TETRAHEDRONS), a label for
%    each tetrahedron.
%
%    Output, integer HEXAHEDRON_VERTEX(8,HEXAHEDRONS), the vertices that form
%    each hexahedron.
%
%    Output, integer HEXAHEDRON_LABEL(HEXAHEDRONS), a label for each hexahedron.
%

%
%  Initialize everything to nothing.
%
  vertex_coordinate = [];
  vertex_label = [];
  edge_vertex = [];
  edge_label = [];
  triangle_vertex = [];
  triangle_label = [];
  quadrilateral_vertex = [];
  quadrilateral_label = [];
  tetrahedron_vertex = [];
  tetrahedron_label = [];
  hexahedron_vertex = [];
  hexahedron_label = [];
%
%  Open the file.
%
  unit = fopen ( filename, 'rt' );

  if ( unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'MESH_DATA_READ - Error!\n' );
    fprintf ( 1, '  Could not open the input file "%s".\n', filename );
    error ( 'MESH_DATA_READ - Error!' );
    return
  end
%
%  Read lines til you get alphanumerics and determine a "mode"
%
  line_num = 0;
  keyword = 'NONE';

  while ( 1 )

    text = fgetl ( unit );

    if ( text == -1 )
      break
    end

    line_num = line_num + 1;

    if ( s_len_trim ( text ) == 0 )
      keyword = 'NONE';
      continue
    end

    if ( text(1) == '#' )
      continue
    end
%
%  Remove initial blanks.
%

%
%  Expecting a keyword.
%
        if ( s_eqi ( text, 'CORNERS' ) )

      keyword = 'SKIP';

    elseif ( s_eqi ( text, 'DIMENSION' ) )

      keyword = 'DIMENSION';

    elseif ( s_eqi ( text, 'EDGES' ) )

      keyword = 'EDGES';

    elseif ( s_eqi ( text, 'END' ) )

      fprintf ( 1, '\n' );
      fprintf ( 1, '  END statement encountered.\n' );
      break

    elseif ( s_eqi ( text, 'HEXAHEDRA' ) || s_eqi ( text, 'HEXAHEDRONS' ) )

      keyword = 'HEXAHEDRONS';

    elseif ( s_begin ( text, 'MESHVERSIONFORMATTED' ) )

    elseif ( s_eqi ( text, 'NORMALATQUADRILATERALVERTICES' ) )

      keyword = 'SKIP';

    elseif ( s_eqi ( text, 'NORMALATTRIANGLEVERTICES' ) )

      keyword = 'SKIP';

    elseif ( s_eqi ( text, 'NORMALATVERTICES' ) )

      keyword = 'SKIP';

    elseif ( s_eqi ( text, 'NORMALS' ) )

      keyword = 'SKIP';

    elseif ( s_eqi ( text, 'QUADRILATERALS' ) )

      keyword = 'QUADRILATERALS';

    elseif ( s_eqi ( text, 'REQUIREDEDGES' ) )

      keyword = 'SKIP';

    elseif ( s_eqi ( text, 'REQUIREDVERTICES' ) )

      keyword = 'SKIP';

    elseif ( s_eqi ( text, 'RIDGES' ) )

      keyword = 'SKIP';

    elseif ( s_eqi ( text, 'TANGENTATEDGES' ) )

      keyword = 'SKIP';

    elseif ( s_eqi ( text, 'TANGENTS' ) )

      keyword = 'SKIP';

    elseif ( s_eqi ( text, 'TETRAHEDRA' ) || s_eqi ( text, 'TETRAHEDRONS' ) )

      keyword = 'TETRAHEDRONS';

    elseif ( s_eqi ( text, 'TRIANGLES' ) )

      keyword = 'TRIANGLES';

    elseif ( s_eqi ( text, 'VERTICES' ) )

      keyword = 'VERTICES';
%
%  Presumably, numeric data to be processed by keyword.
%
    elseif ( s_eqi ( keyword, 'DIMENSION' ) )

      [ value, count ] = sscanf ( text, '%d' );

      if ( count == 1 )
%       dim = value;
      end

      keyword = 'NONE';

    elseif ( s_eqi ( keyword, 'EDGES' ) )

      [ value, count ] = sscanf ( text, '%d' );

      if ( count == 1 )
%       edges = value;
      end

      keyword = 'EDGE_VERTEX';
      edge = 0;
      edge_vertex = zeros ( 2, edges );
      edge_label = zeros ( 1, edges );

    elseif ( s_eqi ( keyword, 'EDGE_VERTEX' ) )

      [ value, count ] = sscanf ( text, '%d  %d  %d' );

      edge = edge + 1;
      edge_vertex(1:2,edge) = value(1:2);
      edge_label(edge) = value(3);

    elseif ( s_eqi ( keyword, 'HEXAHEDRONS' ) )

      [ value, count ] = sscanf ( text, '%d' );

      if ( count == 1 )
%       hexahedrons = value;
      end

      keyword = 'HEXAHEDRON_VERTEX';
      hexahedron = 0;
      hexahedron_vertex = zeros ( 8, hexahedrons );
      hexahedron_label = zeros ( 1, hexahedrons );

    elseif ( s_eqi ( keyword, 'HEXAHEDRON_VERTEX' ) )

      [ value, count ] = sscanf ( text, '%d  %d  %d  %d  %d  %d  %d  %d  %d' );

      hexahedron = hexahedron + 1;
      hexahedron_vertex(1:8,hexahedron) = value(1:8);
      hexahedron_label(hexahedron) = value(9);

    elseif ( s_eqi ( keyword, 'QUADRILATERALS' ) )

      [ value, count ] = sscanf ( text, '%d' );

      if ( count == 1 )
%       quadrilaterals = value;
      end

      keyword = 'QUADRILATERAL_VERTEX';
      quadrilateral = 0;
      quadrilateral_vertex = zeros ( 4, quadrilateral );
      quadrilateral_label = zeros ( 1, quadrilateral );

    elseif ( s_eqi ( keyword, 'QUADRILATERAL_VERTEX' ) )

      [ value, count ] = sscanf ( text, '%d  %d  %d  %d  %d' );

      quadrilateral = quadrilateral + 1;
      quadrilateral_vertex(1:4,quadrilateral) = value(1:4);
      quadrilateral_label(quadrilateral) = value(5);

    elseif ( s_eqi ( keyword, 'TETRAHEDRONS' ) )

      [ value, count ] = sscanf ( text, '%d' );

      if ( count == 1 )
%       tetrahedrons = value;
      end

      keyword = 'TETRAHEDRON_VERTEX';
      tetrahedron = 0;
      tetrahedron_vertex = zeros ( 4, tetrahedron );
      tetrahedron_label = zeros ( 1, tetrahedron );

    elseif ( s_eqi ( keyword, 'TETRAHEDRON_VERTEX' ) )

      [ value, count ] = sscanf ( text, '%d  %d  %d  %d  %d' );

      tetrahedron = tetrahedron + 1;
      tetrahedron_vertex(1:4,tetrahedron) = value(1:4);
      tetrahedron_label(tetrahedron) = value(5);

    elseif ( s_eqi ( keyword, 'TRIANGLES' ) )

      [ value, count ] = sscanf ( text, '%d' );

      if ( count == 1 )
%       triangles = value;
      end

      keyword = 'TRIANGLE_VERTEX';
      triangle = 0;
      triangle_vertex = zeros ( 3, triangle );
      triangle_label = zeros ( 1, triangle );

    elseif ( s_eqi ( keyword, 'TRIANGLE_VERTEX' ) )

      [ value, count ] = sscanf ( text, '%d  %d  %d  %d' );

      triangle = triangle + 1;
      triangle_vertex(1:3,triangle) = value(1:3);
      triangle_label(triangle) = value(4);

    elseif ( s_eqi ( keyword, 'VERTICES' ) )

      [ value, count ] = sscanf ( text, '%d' );

      if ( count == 1 )
%       vertices = value;
      end

      keyword = 'VERTEX_COORDINATE';
      vertex = 0;
      vertex_coordinate = zeros ( dim, vertices );
      vertex_label = zeros ( 1, vertices );

    elseif ( s_eqi ( keyword, 'VERTEX_COORDINATE' ) )

      if ( dim == 2 )
        [ value, count ] = sscanf ( text, '%f  %f  %d' );
      elseif ( dim == 3 )
        [ value, count ] = sscanf ( text, '%f  %f  %f  %d' );
      end

      vertex = vertex + 1;
      vertex_coordinate(1:dim,vertex) = value(1:dim);
      vertex_label(vertex) = value(dim+1);

    elseif ( s_eqi ( keyword, 'SKIP' ) )

    else

      fprintf ( 1, '\n' );
      fprintf ( 1, 'MESH_DATA_READ - Fatal error!\n' );
      fprintf ( 1, '  Could not find keyword while reading line %d:\n', line_num );
      fprintf ( 1, '"%s"\n', text );
      error ( 'MESH_DATA_READ - Fatal error!\n' );

    end
  end
%
%  Close the file.
%
  fclose ( unit );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Read %d lines from "%s".\n', line_num, filename );

  return
end


function kern = ouKernExpandParam(kern, params)

% OUKERNEXPANDPARAM Create kernel structure from OU kernel's parameters
% (see ouKernCompute or ouKernParamInit for a more detailed description of
% the OU kernel).
% FORMAT
% DESC returns a Ornstein-Uhlenbeck kernel kernel structure filled with the
% parameters in the given vector. This is used as a helper function to
% enable parameters to be optimised in, for example, the NETLAB
% optimisation functions.
% ARG kern : the kernel structure in which the parameters are to be
% placed.
% ARG param : vector of parameters which are to be placed in the
% kernel structure.
% RETURN kern : kernel structure with the given parameters in the
% relevant locations.
%
% SEEALSO : ouKernParamInit, ouKernExtractParam, kernExpandParam
%
% COPYRIGHT : David Luengo, 2009

% KERN

kern.decay = params(1);
kern.variance = params(2);


function test_external_images

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

filelist = {'hsv2rgb'};

% NOTE: hsv2rgb was part of standard matlab in older matlab versions

[ftver, ftpath] = ft_version;
restoredefaultpath

% ensure that the the 'compat' (i.e. external/signal) is used
global ft_default
ft_default.toolbox.signal = 'compat';
addpath(ftpath);
ft_defaults;

for k = 1:numel(filelist)
  assert(exist(filelist{k}, 'file')==2);

  fprintf('testing the functionality of %s\n', filelist{k});
  switch filelist{k}
    case 'hsv2rgb'
      assert(isequal(hsv2rgb([0 1 1]),[1 0 0]));
      assert(isequal(hsv2rgb([1 0 1]),[1 1 1]));
    otherwise
      ft_error('function %s is not part of the official external/images directory', filelist{k});
  end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% compare the external/images output with the matlab version
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tmp = rand(10,10,3);
for k = 1:numel(filelist)
  try
    % this only works for the functions that create a window
    funhandle = str2func(filelist{k});
    output1.(filelist{k}) = funhandle(tmp);
  end
end

restoredefaultpath

% ensure that the the matlab version is used
ft_default.toolbox.imagesc = 'matlab';
addpath(ftpath);
ft_defaults;

for k = 1:numel(filelist)
  try
    funhandle = str2func(filelist{k});
    output2.(filelist{k}) = funhandle(tmp);
  end
end

fn1 = fieldnames(output1);
fn2 = fieldnames(output2);
assert(isequal(sort(fn1), sort(fn2)));
for k = 1:numel(fn1)
  assert(isalmostequal(output1.(fn1{k}), output2.(fn1{k}), 'abstol', 10*eps));
end


function  display(grains,varargin)
% standard output

displayClass(grains,inputname(1));

disp(' ')
%disp(char(dynOption(grains)));

% generate phase table
matrix = cell(numel(grains.phaseMap),6);

for ip = 1:numel(grains.phaseMap)

  ind = grains.phaseId == ip;

  % phase
  matrix{ip,1} = num2str(grains.phaseMap(ip)); %#ok<*AGROW>

  % grains
  matrix{ip,2} = int2str(nnz(ind));

  % grains
  matrix{ip,3} = int2str(sum(grains.grainSize(ind)));

  % abort in special cases
  if isempty(grains.CSList{ip})
    continue
  elseif ischar(grains.CSList{ip})
    matrix{ip,4} = grains.CSList{ip};
    continue
  else
    % mineral
    matrix{ip,4} = char(grains.CSList{ip}.mineral);
  end

  % symmetry
  matrix{ip,5} = grains.CSList{ip}.pointGroup;

  % reference frame
  matrix{ip,6} = option2str(grains.CSList{ip}.alignment);

end

% remove empty rows
matrix(accumarray(full(grains.phaseId),1,[size(matrix,1) 1])==0,:) = [];

if ~isempty(grains)
  cprintf(matrix,'-L',' ','-Lc',...
    {'Phase' 'Grains' 'Pixels' 'Mineral'  'Symmetry' 'Crystal reference frame'},...
    '-d','  ','-ic',true);
else
  disp('  no grains here!')
end

disp(' ')

% show boundary and triple points
disp([' ' varlink([inputname(1),'.boundary'],'boundary segments') ': ',int2str(length(grains.boundary))])
disp([' ' varlink([inputname(1),'.innerBoundary'],'inner boundary segments') ': ',int2str(length(grains.innerBoundary))])
disp([' ' varlink([inputname(1),'.triplePoints'],'triple points') ': ',int2str(length(grains.triplePoints))])
disp(' ');

if isempty(grains), return; end

% show properties
disp(char(dynProp(grains.prop),...
  'Id',grains.id,'Phase',grains.phase,'Pixels',grains.grainSize))
disp(' ')


function display(x)
%DISP Display TT/MPS tensor as a tensor network
%
    %   TTeMPS Toolbox.
    %   Michael Steinlechner, 2013-2016
    %   Questions and contact: michael.steinlechner@epfl.ch
    %   BSD 2-clause license, see LICENSE.txt

    disp( x, inputname(1));
end


function x = optimiMinimize(objectiveGradient, params, options, varargin);

% OPTIMIMINIMIZE Wrapper for Carl Rasmussen's minimize function.
% FORMAT
% DESC is a nother wrapper for Carl Rasmussen's minimize function,
% but this time using functions which return the gradient and the
% function value together (such as gpObjectiveGradient).
% ARG objectiveGradient : function that returns the value (as a
% ARG params : the initial parameters to be optimised.
% scalar) and the gradients (as a row vector) of the function to be
% optimised.
% ARG options : a NETLAB style options vector.
% ARG P1, P2, P3 ... : further arguments to be passed to
% OBJECTIVEGRADIENT.
% RETURN params : row vector of optimised parameters.
%
% SEEALSO : minimize, cgcarl
%
% COPYRIGHT : Neil D. Lawrence, 2006

% OPTIMI

x = minimize(params', objectiveGradient, options(14), ...
             varargin{:})';


classdef MrGlm < MrCopyData
    % Class providing General Linear Model of fMRI data
    % (for mass-univariate analysis, i.e. per-voxel regression)
    %
    %
    % EXAMPLE
    %   MrGlm
    %
    %   See also

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

    properties

        % Multiple regressors, i.e. confounds that will be regressed directly,
        % without convolution with the hemodynamic response function(s).
        % fields:
        %      realign     Realignment parameters
        regressors = struct( ...
            'realign', [], ...
            'physio', [], ...
            'other', [] ...
            );

        % Multiple conditions, i.e. behavioral/neuronal regressors that will be
        % convolved with the hemodynamic response function(s).
        conditions = struct( ...
            'names', [], ...
            'onsets', [], ...
            'durations', [] ...
            );

        % The final design matrix used for the voxel-wise regression
        designMatrix = [];

        % timing parameters
        timingUnits = '';
        repetitionTime = '';

        % HRF derivatives
        hrfDerivatives = '';

        % SPM Directory
        parameters = struct( ...
            'save', struct( ...
            'path', '', ... % path where the SPM file is stored, e.g. the MrSeries path
            'spmDirectory', '')... % name of the SPM Directory for the SPM file
            );

        % masking threshold, defined as proportion of globals
        maskingThreshold = 0.8;

        % explicit mask for the analysis, e.g. the segmentation results for a
        % whithin brain mask
        explicitMasking = '';

        % serial correlations, AR(1) or FAST
        serialCorrelations = 'AR(1)';

        % estimation method (classical or Bayesian)
        estimationMethod = 'classical'

        % AR model order (for Bayesian estimation only)
        ARModelOrderBayes = 3;

        % contrasts need to be specified before hand as well
        gcon = struct(...
            'name', {'main_positive', 'main negative'}, ...
            'convec', {1, -1});

    end % properties

    methods

        % Constructor of class
        function this = MrGlm()
        end

        % NOTE: Most of the methods are saved in separate function.m-files in this folder;
        %       except: constructor, delete, set/get methods for properties.

    end % methods

end


function [StopFlag, Status] = StopCritDuplo(nfxk,Niter, Nmap, T, MaxNumIter, MaxNumMapEval, TimeLimit, epsilon, Stopping_Crit)
% Function checking that one of the stopping criteria
% holds to terminate LLM and GLM. It perepares the status determining why
% the algorithm is stopped.
%
% USAGE:
%
%    [StopFlag, Status] = StopCritDuplo(nfxk,Niter, Nmap, T, MaxNumIter, MaxNumMapEval, TimeLimit, epsilon, Stopping_Crit)
%
% INPUTS:
%    nhxk:             the norm 2 of `h(xk)`
%    Niter:            the number of iterations
%    Nmap:             the number of mapping calls
%    T:                the running time
%    MaxNumIter:       maximum number of iterations
%    MaxNumMapEval:    maximum number of function evaluations
%    TimeLimit:        maximum running time
%    epsilon:          accuracy parameter
%    Stopping_Crit:    stopping criterion:
%
%                        1. stop if :math:`||nfxk|| \leq \epsilon`
%                        2. stop if `MaxNumIter` is reached
%                        3. stop if `MaxNumMapEval` is reached
%                        4. stop if `TimeLimit` is reached
%                        5. stop if (default) :math:`||hxk|| \leq \epsilon` or `MaxNumIter` is reached
% OUTPUTS:
%    StopFlag:         1: if one of the stopping criteria holds, 0: if none of the stopping criteria holds
%    Status:           the reason of the scheme termination

switch Stopping_Crit

  case 1
    if nhxk <= epsilon
      StopFlag = 1;
      Status   = 'A solution of nonlinear system is found.';
    else
      StopFlag = 0;
      Status   = [];
    end

  case 2
    if Niter >= MaxNumIter
      StopFlag = 1;
      Status   = 'Maximum number of iterations is reached.';
    else
      StopFlag = 0;
      Status   = [];
    end

  case 3
    if Nmap >= MaxNumMapEval
      StopFlag = 1;
      Status   = 'Maximum number of mapping evaluations is reached.';
    else
      StopFlag = 0;
      Status   = [];
    end

  case 4
    if T >= TimeLimit
      StopFlag = 1;
      Status   = 'Time limit is reached.';
    else
      StopFlag = 0;
      Status   = [];
    end

  case 5
    if (nfxk <= epsilon || Niter >= MaxNumIter)
      StopFlag = 1;
      if Niter < MaxNumIter
          Status = 'a solution is found.';
      else
          Status = 'Maximum number of iterations is reached.';
      end
    else
      StopFlag = 0;
      Status   = [];
    end

end

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%% End of StopCritDuplo.m %%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


function [n, nm, nl, ts, names, m] = nex_marker(filename, varname)
% nex_marker(filename, varname): Read a marker variable from a .nex file
%
% [n, nm, nl, ts, names, m] = nex_marker(filename, varname)
%
% INPUT:
%   filename - if empty string, will use File Open dialog
%   varname - variable name
%
%           continuous (a/d) data come in fragments. Each fragment has a timestamp
%           and a number of a/d data points. The timestamp corresponds to
%           the time of recording of the first a/d value in this fragment.
%           All the data values stored in the vector d.
% OUTPUT:
%   n - number of markers
%   nm - number of fields in each marker
%   nl - number of characters in each marker field
%   ts - array of marker timestamps (in seconds)
%   names - names of marker fields ([nm 64] character array)
%   m - character array of marker values [n nl nm]

n = 0;
nm = 0;
nl = 0;
ts = 0;
m = 0;
names = 0;

if(nargin ~= 2)
   disp('2 input arguments are required')
   return
end

if(ischar(filename) == 0)
   disp('input arguments should be character arrays')
   return
end

if(ischar(varname) == 0)
   disp('input arguments should be character arrays')
   return
end

if(isempty(filename))
   [fname, pathname] = uigetfile('*.nex', 'Select a Nex file');
	filename = strcat(pathname, fname);
end

fid = fopen(filename, 'r');
if(fid == -1)
	disp('cannot open file');
   return
end

disp(strcat('file = ', filename));
magic = fread(fid, 1, 'int32');
version = fread(fid, 1, 'int32');
comment = fread(fid, 256, 'char');
freq = fread(fid, 1, 'double');
tbeg = fread(fid, 1, 'int32');
tend = fread(fid, 1, 'int32');
nvar = fread(fid, 1, 'int32');
fseek(fid, 260, 'cof');
name = zeros(1, 64);
found = 0;
for i=1:nvar
	type = fread(fid, 1, 'int32');
	var_version = fread(fid, 1, 'int32');
	name = fread(fid, [1 64], 'char');
	offset = fread(fid, 1, 'int32');
	n = fread(fid, 1, 'int32');
	dummy = fread(fid, 32, 'char');
	adfreq = fread(fid, 1, 'double');
	adtomv = fread(fid, 1, 'double');
	npw = fread(fid, 1, 'int32');
	nm = fread(fid, 1, 'int32');
	nl = fread(fid, 1, 'int32');
	dummy = fread(fid, 68, 'char');
	name = char(name);
	name = deblank(name);
	k = strcmp(name, deblank(varname));
	if(k == 1)
		if type ~= 6
			disp(sprintf('%s is not a marker variable', deblank(varname)));
			return;
		end
		found = 1;
		fseek(fid, offset, 'bof');
		ts = fread(fid, [1 n], 'int32');
		names = zeros(1,64);
		m = zeros(n, nl, nm);
		for j=1:nm
			names(j, :) = fread(fid, [1 64], 'char');
			for p = 1:n
				m(p, :, j) = fread(fid, [1 nl], 'char');
			end
		end
		break
	end
end

fclose(fid);

if found == 0
	disp('did not find variable in the file');
else
	names = char(names);
	m = char(m);
	ts = ts/freq;
	disp(strcat('number of markers = ', num2str(n)));
end


classdef LineSegmentDetector < handle
    %LINESEGMENTDETECTOR  Line segment detector class
    %
    % Following the algorithm described at [Rafael12].
    %
    % ## References
    % [Rafael12]:
    % > Rafael Grompone von Gioi, Jeremie Jakubowicz, Jean-Michel Morel,
    % > and Gregory Randall. Lsd: a line segment detector. 2012.
    %
    % See also: cv.LineSegmentDetector.LineSegmentDetector, cv.HoughLines,
    %  cv.FastLineDetector, houghlines
    %

    properties (SetAccess = private)
        % Object ID
        id
    end

    methods
        function this = LineSegmentDetector(varargin)
            %LINESEGMENTDETECTOR  Creates a LineSegmentDetector object and initializes it
            %
            %     lsd = cv.LineSegmentDetector()
            %     lsd = cv.LineSegmentDetector('OptionName', optionValue, ...)
            %
            % ## Options
            % * __Refine__ The way found lines will be refined, one of:
            %   * __None__ No refinement applied.
            %   * __Standard__ (default) Standard refinement is applied. E.g.
            %     breaking arches into smaller straighter line approximations.
            %   * __Advanced__ Advanced refinement. Number of false alarms is
            %     calculated, lines are refined through increase of precision,
            %     decrement in size, etc.
            % * __Scale__ The scale of the image that will be used to find the
            %   lines. In the range `[0,1)`. default 0.8
            % * __SigmaScale__ Sigma for Gaussian filter. It is computed as
            %   `sigma = SigmaScale/Scale`. default 0.6
            % * __QuantError__ Bound to the quantization error on the gradient
            %   norm. default 2.0
            % * __AngleTol__ Gradient angle tolerance in degrees. default 22.5
            % * __DetectionThreshold__ Detection threshold:
            %   `-log10(NFA) > DetectionThreshold`. Used only when advanced
            %   refinement is chosen. default 0
            % * __MinDensity__ Minimal density of aligned region points in the
            %   enclosing rectangle. default 0.7
            % * __NBins__ Number of bins in pseudo-ordering of gradient
            %   modulus. default 1024
            %
            % The cv.LineSegmentDetector algorithm is defined using the
            % standard values. Only advanced users may want to edit those, as
            % to tailor it for their own application.
            %
            % See also: cv.LineSegmentDetector.detect
            %
            this.id = LineSegmentDetector_(0, 'new', varargin{:});
        end

        function delete(this)
            %DELETE  Destructor
            %
            %     obj.delete()
            %
            % See also: cv.LineSegmentDetector
            %
            if isempty(this.id), return; end
            LineSegmentDetector_(this.id, 'delete');
        end
    end

    methods
        function clear(this)
            %CLEAR  Clears the algorithm state
            %
            %     obj.clear()
            %
            % See also: cv.LineSegmentDetector.empty
            %
            LineSegmentDetector_(this.id, 'clear');
        end

        function b = empty(this)
            %EMPTY  Checks if algorithm object is empty
            %
            %     b = obj.empty()
            %
            % ## Output
            % * __b__ Returns true if the algorithm object is empty
            %   (e.g. in the very beginning or after unsuccessful read).
            %
            % See also: cv.LineSegmentDetector.clear
            %
            b = LineSegmentDetector_(this.id, 'empty');
        end

        function name = getDefaultName(this)
            %GETDEFAULTNAME  Returns the algorithm string identifier
            %
            %     name = obj.getDefaultName()
            %
            % ## Output
            % * __name__ This string is used as top level XML/YML node tag
            %   when the object is saved to a file or string.
            %
            % See also: cv.LineSegmentDetector.save, cv.LineSegmentDetector.load
            %
            name = LineSegmentDetector_(this.id, 'getDefaultName');
        end

        function save(this, filename)
            %SAVE  Saves the algorithm to a file
            %
            %     obj.save(filename)
            %
            % ## Input
            % * __filename__ Name of the file to save to.
            %
            % This method stores the algorithm parameters in a file storage.
            %
            % See also: cv.LineSegmentDetector.load
            %
            LineSegmentDetector_(this.id, 'save', filename);
        end

        function load(this, fname_or_str, varargin)
            %LOAD  Loads algorithm from a file or a string
            %
            %     obj.load(fname)
            %     obj.load(str, 'FromString',true)
            %     obj.load(..., 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __fname__ Name of the file to read.
            % * __str__ String containing the serialized model you want to
            %   load.
            %
            % ## Options
            % * __ObjName__ The optional name of the node to read (if empty,
            %   the first top-level node will be used). default empty
            % * __FromString__ Logical flag to indicate whether the input is a
            %   filename or a string containing the serialized model.
            %   default false
            %
            % This method reads algorithm parameters from a file storage.
            % The previous model state is discarded.
            %
            % See also: cv.LineSegmentDetector.save
            %
            LineSegmentDetector_(this.id, 'load', fname_or_str, varargin{:});
        end
    end

    methods
        function [lines, width, prec, nfa] = detect(this, img)
            %DETECT  Finds lines in the input image
            %
            %     lines = lsd.detect(img)
            %     [lines, width, prec, nfa] = lsd.detect(img)
            %
            % ## Input
            % * __img__ A grayscale (`uint8`) input image.
            %
            % ## Output
            % * __lines__ A cell-array of 4-element vectors of the form
            %   `{[x1, y1, x2, y2], ..}` specifying the beginning and ending
            %   point of a line. Where point 1 `[x1,y1]` is the start, point 2
            %   `[x2,y2] the end. Returned lines are strictly oriented
            %   depending on the gradient.
            % * __width__ Vector of widths of the regions, where the lines are
            %   found. E.g. Width of line.
            % * __prec__ Vector of precisions with which the lines are found.
            % * __nfa__ Vector containing number of false alarms in the line
            %   region, with precision of 10%. The bigger the value,
            %   logarithmically better the detection. This vector will be
            %   calculated only when the object refine type is 'Advanced',
            %   empty otherwise.
            %   * -1 corresponds to 10 mean false alarms
            %   * 0 corresponds to 1 mean false alarm
            %   * 1 corresponds to 0.1 mean false alarms
            %
            % See also: cv.LineSegmentDetector.drawSegments
            %
            [lines, width, prec, nfa] = LineSegmentDetector_(this.id, 'detect', img);
        end

        function img = drawSegments(this, img, lines)
            %DRAWSEGMENTS  Draws the line segments on a given image
            %
            %     img = lsd.drawSegments(img, lines)
            %
            % ## Input
            % * __img__ The image, where the lines will be drawn. Should be
            %   bigger or equal to the image, where the lines were found.
            % * __lines__ A vector of the lines that needed to be drawn.
            %
            % ## Output
            % * __img__ Output image with drawn line segments.
            %
            % See also: cv.LineSegmentDetector.compareSegments
            %
            img = LineSegmentDetector_(this.id, 'drawSegments', img, lines);
        end

        function [img, count] = compareSegments(this, sz, lines1, lines2, varargin)
            %COMPARESEGMENTS  Draws two groups of lines in blue and red, counting the non overlapping (mismatching) pixels
            %
            %     [img, count] = lsd.compareSegments(sz, lines1, lines2)
            %     [...] = lsd.compareSegments(..., 'OptionName', optionValue, ...)
            %
            % ## Input
            % * __sz__ The size of the image, where `lines1` and `lines2` were
            %   found `[w,h]`.
            % * __lines1__ The first group of lines that needs to be drawn. It
            %   is visualized in blue color.
            % * __lines2__ The second group of lines. They visualized in red
            %   color.
            %
            % ## Output
            % * __img__ color image with the two groups of lines drawn.
            % * __count__ count of non overlapping (mismatching) pixels.
            %
            % ## Options
            % * __Image__ Optional image, where the lines will be drawn. The
            %   image should be color (3-channel) in order for `lines1` and
            %   `lines2` to be drawn in the above mentioned colors.
            %
            % See also: cv.LineSegmentDetector.drawSegments
            %
            [img, count] = LineSegmentDetector_(this.id, 'compareSegments', ...
                sz, lines1, lines2, varargin{:});
        end
    end
end


function t_opf_dc_mips(quiet)
%T_OPF_DC_MIPS  Tests for DC optimal power flow using MIPS solver.

%   MATPOWER
%   Copyright (c) 2004-2021, 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.

if nargin < 1
    quiet = 0;
end

num_tests = 43;

t_begin(num_tests, quiet);

[PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
    VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
[GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
    MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
    QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
[F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
    TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
    ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;

casefile = 't_case9_opf';
if quiet
    verbose = 0;
else
    verbose = 0;
end
if have_feature('octave')
    if have_feature('octave', 'vnum') >= 4
        file_in_path_warn_id = 'Octave:data-file-in-path';
    else
        file_in_path_warn_id = 'Octave:load-file-in-path';
    end
    s1 = warning('query', file_in_path_warn_id);
    warning('off', file_in_path_warn_id);
    sing_matrix_warn_id = 'Octave:singular-matrix';
else
    sing_matrix_warn_id = 'MATLAB:singularMatrix';
    near_sing_matrix_warn_id = 'MATLAB:nearlySingularMatrix';
    s3 = warning('query', near_sing_matrix_warn_id);
    warning('off', near_sing_matrix_warn_id);
end
s2 = warning('query', sing_matrix_warn_id);

t0 = 'DC OPF (MIPS): ';
mpopt = mpoption('out.all', 0, 'verbose', verbose);
mpopt = mpoption(mpopt, 'opf.dc.solver', 'MIPS', 'mips.comptol', 1e-9);

%% reveals a bug introduced with summer 2017 OPF refactorization
if have_feature('pdipmopf')
    mpopt = mpoption(mpopt, 'opf.ac.solver', 'PDIPM');
end

    %% set up indices
    ib_data     = [1:BUS_AREA BASE_KV:VMIN];
    ib_voltage  = [VM VA];
    ib_lam      = [LAM_P LAM_Q];
    ib_mu       = [MU_VMAX MU_VMIN];
    ig_data     = [GEN_BUS QMAX QMIN MBASE:APF];
    ig_disp     = [PG QG VG];
    ig_mu       = (MU_PMAX:MU_QMIN);
    ibr_data    = (1:ANGMAX);
    ibr_flow    = (PF:QT);
    ibr_mu      = [MU_SF MU_ST];
    ibr_angmu   = [MU_ANGMIN MU_ANGMAX];

    %% get solved DC power flow case from MAT-file
    load soln9_dcopf;       %% defines bus_soln, gen_soln, branch_soln, f_soln

    %% run OPF
    t = t0;
    [baseMVA, bus, gen, gencost, branch, f, success, et] = rundcopf(casefile, mpopt);
    t_ok(success, [t 'success']);
    t_is(f, f_soln, 3, [t 'f']);
    t_is(   bus(:,ib_data   ),    bus_soln(:,ib_data   ), 10, [t 'bus data']);
    t_is(   bus(:,ib_voltage),    bus_soln(:,ib_voltage),  3, [t 'bus voltage']);
    t_is(   bus(:,ib_lam    ),    bus_soln(:,ib_lam    ),  3, [t 'bus lambda']);
    t_is(   bus(:,ib_mu     ),    bus_soln(:,ib_mu     ),  2, [t 'bus mu']);
    t_is(   gen(:,ig_data   ),    gen_soln(:,ig_data   ), 10, [t 'gen data']);
    t_is(   gen(:,ig_disp   ),    gen_soln(:,ig_disp   ),  3, [t 'gen dispatch']);
    t_is(   gen(:,ig_mu     ),    gen_soln(:,ig_mu     ),  3, [t 'gen mu']);
    t_is(branch(:,ibr_data  ), branch_soln(:,ibr_data  ), 10, [t 'branch data']);
    t_is(branch(:,ibr_flow  ), branch_soln(:,ibr_flow  ),  3, [t 'branch flow']);
    t_is(branch(:,ibr_mu    ), branch_soln(:,ibr_mu    ),  2, [t 'branch mu']);

    %%-----  test OPF with angle difference limits  -----
    t = [t0 'w/angle diff lims : '];
    mpc = loadcase(casefile);
    mpc.branch(4, ANGMAX) = 3;
    mpc.branch(7, ANGMIN) = -4.5;
    r = rundcopf(mpc, mpopt);
    [bus, gen, branch, f, success] = deal(r.bus, r.gen, r.branch, r.f, r.success);
    t_ok(success, [t 'success']);
    t_is(   f, 6456.7213, 3, [t 'f']);
    t_is(   bus(:,ib_data   ),    bus_soln(:,ib_data   ), 10, [t 'bus data']);
    t_is(   gen(:,ig_data   ),    gen_soln(:,ig_data   ), 10, [t 'gen data']);
    t_is(   gen(:,PG        ),    [99.98497;89.35133;125.66371], 4, [t 'gen dispatch']);
    t_is(branch(:,ibr_data  ), mpc.branch(:,ibr_data   ), 10, [t 'branch data']);
    e = zeros(size(branch, 1), 1);
    e(4) = 297.83776;
    e(7) = -26.94788;
    t_is(branch(:,MU_ANGMAX )-branch(:,MU_ANGMIN ), e, 4, [t 'branch ang diff mu']);

    t = [t0 'w/ignored angle diff lims : '];
    mpopt1 = mpoption(mpopt, 'opf.ignore_angle_lim', 1);
    r = rundcopf(mpc, mpopt1);
    [bus, gen, branch, f, success] = deal(r.bus, r.gen, r.branch, r.f, r.success);
    t_ok(success, [t 'success']);
    t_is(f, f_soln, 3, [t 'f']);
    t_is(   bus(:,ib_data   ),    bus_soln(:,ib_data   ), 10, [t 'bus data']);
    t_is(   bus(:,ib_voltage),    bus_soln(:,ib_voltage),  3, [t 'bus voltage']);
    t_is(   bus(:,ib_lam    ),    bus_soln(:,ib_lam    ),  3, [t 'bus lambda']);
    t_is(   bus(:,ib_mu     ),    bus_soln(:,ib_mu     ),  2, [t 'bus mu']);
    t_is(   gen(:,ig_data   ),    gen_soln(:,ig_data   ), 10, [t 'gen data']);
    t_is(   gen(:,ig_disp   ),    gen_soln(:,ig_disp   ),  3, [t 'gen dispatch']);
    t_is(   gen(:,ig_mu     ),    gen_soln(:,ig_mu     ),  3, [t 'gen mu']);
    t_is(branch(:,ibr_data  ), mpc.branch(:,ibr_data   ), 10, [t 'branch data']);
    t_is(branch(:,ibr_flow  ), branch_soln(:,ibr_flow  ),  3, [t 'branch flow']);
    t_is(branch(:,ibr_mu    ), branch_soln(:,ibr_mu    ),  2, [t 'branch mu']);

    %%-----  run OPF with extra linear user constraints & costs  -----
    %% two new z variables
    %%      0 <= z1, P3 - P1 <= z1
    %%      0 <= z2, P3 - P2 <= z2
    %% with A and N sized for DC opf
    mpc = loadcase(casefile);
    mpc.A = sparse([1;1;1;2;2;2],[10;12;13;12;11;14],[-1;1;-1;1;-1;-1],2,14);
    mpc.u = [0; 0];
    mpc.l = [-Inf; -Inf];
    mpc.zl = [0; 0];

    mpc.N = sparse([1;2], [13;14], [1;1], 2, 14);   %% new z variables only
    mpc.fparm = ones(2,1) * [1 0 0 1];              %% w = r = z
    mpc.H = sparse(2,2);                            %% no quadratic term
    mpc.Cw = [1000;1];

    t = [t0 'w/extra constraints & costs 1 : '];
    [r, success] = rundcopf(mpc, mpopt);
    t_ok(success, [t 'success']);
    t_is(r.gen(1, PG), 116.15974, 4, [t 'Pg1 = 116.15974']);
    t_is(r.gen(3, PG), 116.15974, 4, [t 'Pg3 = 116.15974']);
    t_is(r.var.val.z, [0; 0.3348], 4, [t 'user vars']);
    t_is(r.cost.usr, 0.3348, 3, [t 'user costs']);

    %% with A and N sized for AC opf
    mpc = loadcase(casefile);
    mpc.A = sparse([1;1;1;2;2;2],[19;21;25;21;20;26],[-1;1;-1;1;-1;-1],2,26);
    mpc.u = [0; 0];
    mpc.l = [-Inf; -Inf];
    mpc.zl = [0; 0];

    mpc.N = sparse([1;2], [25;26], [1;1], 2, 26);   %% new z variables only
    mpc.fparm = ones(2,1) * [1 0 0 1];              %% w = r = z
    mpc.H = sparse(2,2);                            %% no quadratic term
    mpc.Cw = [1000;1];

    t = [t0 'w/extra constraints & costs 2 : '];
    [r, success] = rundcopf(mpc, mpopt);
    t_ok(success, [t 'success']);
    t_is(r.gen(1, PG), 116.15974, 4, [t 'Pg1 = 116.15974']);
    t_is(r.gen(3, PG), 116.15974, 4, [t 'Pg3 = 116.15974']);
    t_is(r.var.val.z, [0; 0.3348], 4, [t 'user vars']);
    t_is(r.cost.usr, 0.3348, 3, [t 'user costs']);

    t = [t0 'infeasible : '];
    warning('off', sing_matrix_warn_id);
    %% with A and N sized for DC opf
    mpc = loadcase(casefile);
    mpc.A = sparse([1;1], [10;11], [1;1], 1, 14);   %% Pg1 + Pg2
    mpc.u = Inf;
    mpc.l = 600;
    [r, success] = rundcopf(mpc, mpopt);
    t_ok(~success, [t 'no success']);

    %% OPF with all buses isolated
    t = [t0 'all buses isolated : '];
    mpc = loadcase(casefile);
    mpc.bus(:, BUS_TYPE) = NONE;
    try
        r = rundcopf(mpc, mpopt);
        t_is(r.success, 0, 12, [t 'success = 0']);
    catch
        t_ok(0, [t 'unexpected fatal error']);
    end

if have_feature('octave')
    warning(s1.state, file_in_path_warn_id);
else
    warning(s3.state, near_sing_matrix_warn_id);
end
warning(s2.state, sing_matrix_warn_id);

t_end;


function prepareFsetVASARI(pathWORK,pathSTUDY)
% -------------------------------------------------------------------------
% function prepareFsetVASARI(pathWORK,pathSTUDY)
% -------------------------------------------------------------------------
% DESCRIPTION:
% This function prepares feature sets for multivariable modeling
% experiments with VASARI features
% -------------------------------------------------------------------------
% INPUTS:
% 1. pathWORK: Full path to the WORKSPACE of the LGG study. Defined in
%              masterScript_LGG.m.
%              --> Ex: '/myProject/WORKSPACE/'
% 2. pathSTUDY: Full path to where the organized data will be saved.
%               Defined in masterScript_LGG.m
%               --> Ex: '/myProject/WORKSPACE/STUDY_DATA'
% -------------------------------------------------------------------------
% OUTPUTS: Organized 'feature sets data in
% '/myProject/WORKSPACE/VASARI/FSET
% -------------------------------------------------------------------------
% AUTHOR(S):
% - Martin Vallieres <mart.vallieres@gmail.com>
% -------------------------------------------------------------------------
% HISTORY:
% - Creation: January 2017
%--------------------------------------------------------------------------
% STATEMENT:
% This file is part of <https://github.com/mvallieres/radiomics/>,
% a package providing MATLAB programming tools for radiomics analysis.
% --> Copyright (C) 2015-2017  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;

cd(pathSTUDY), load('outcomes')
nameOutcomes = fieldnames(outcomes); nOutcomes = numel(nameOutcomes);

cd(pathWORK), mkdir('VASARI'), cd('VASARI'), save('outcomes','outcomes'), mkdir('FSET'), cd('FSET'), pathFset = pwd;

for o = 1:nOutcomes
    outcomeName = nameOutcomes{o};
    cd(pathSTUDY), load(['vasari_',outcomeName]) % Variable 'vasari' now in MATLAB workspace
    outcome = outcomes.(outcomeName);
    vasari(isnan(vasari)) = 0; nVas = size(vasari,2); nameVas = cell(nVas,1);
    for i = 1:nVas
        nameVas{i} = ['F',num2str(i)];
    end
    delete = [];
    for i = 1:nVas
        if numel(unique(vasari(:,i))) < 3 % Deleted, not enough variation
            delete = [delete,i];
        end
    end
    vasari(:,delete) = []; nameVas(delete) = [];

    fSet = struct;
    fSet.Data = vasari;
    fSet.Info = nameVas;
    cd(pathFset), save(['FSET_VASARI_',outcomeName],'fSet')
end

cd(startpath)
end


% trainScript2

imdir = '../images/all_images';
outdir = '/IUS/vmr20/dhoiem/data/mcmcdata';
ncv = 5;

%nsegments = [3 5 7 9 11 13 15 20 25 30 35 40 50 60 70 80 90 100];
nsegments = [3 5 6 6 7 8 9 10 11 12 13 14 15 17 18 20 23 27 32 45 50 75 100];
%nsegments = [3 4 5 6 7 7 8 8 9 9 10 11 11 12 12 13 13 14 14 15 16 16 17 19 20 21 23 25 28 31 37 51];

if ~exist('efeaturesdj')
    [efeaturesdj, adjlistdj] = mcmcGetAllDisjointEdgeData(spfeatures, imsegs, adjlist);
    save([outdir '/mcmcEdgeDataDj.mat'], 'efeaturesdj', 'adjlistdj');
end

if ~exist('eclassifierdj')
    eclassifierdj = mcmcTrainEdgeClassifier(efeaturesdj(cluster_images), ...
        adjlistdj(cluster_images), imsegs(cluster_images));
    save([outdir '/mcmcEdgeClassifierDj.mat'], 'eclassifierdj');
end

if ~exist('labdata')
    % gather data
    for tf = 1:numel(cv_images)

        f = cv_images(tf);

        disp([num2str(tf) ': ' imsegs(f).imname])

        [pvSP{tf}, phSP{tf}, pE{tf}] = mcmcInitialize(spfeatures{f}, efeatures{f}, ...
            adjlist{f}, imsegs(f), vclassifierSP, hclassifierSP, eclassifier, 'labels');
        pEdj{tf} =1./(1+exp(-test_boosted_dt_mc(eclassifierdj, efeaturesdj{f})));
        smaps{tf} = generateMultipleSegmentations2([pE{tf} ; pEdj{tf}], ...
            [adjlist{f} ; adjlistdj{f}], imsegs(f).nseg, nsegments);

        im = im2double(imread([imdir '/' imsegs(f).imname]));
        imdata = mcmcComputeImageData(im, imsegs(f));
%         imdata.pvSP = pvSP;
%         imdata.phSP = phSP;

        for k = 1:numel(nsegments)
            smapk = smaps{tf}(:, k);
            labdata{tf, k} = mcmcGetSegmentFeatures(imsegs(f), spfeatures{f}, imdata, smapk, 1:max(smapk));
            segdata{tf, k} = mcmcGetSegmentationFeatures(pvSP{tf}, phSP{tf}, ...
                [pE{tf} ; pEdj{tf}], [adjlist{f} ; adjlistdj{f}], imsegs(f).npixels, smapk, 1:max(smapk));
            [mclab{tf, k}, mcprc{tf, k}, allprc{tf, k}, trainw{tf, k}] = ...
                segmentation2labels(imsegs(f), smapk);
            unilabel{tf, k} = mclab{tf, k}.*(mcprc{tf, k}>0.99);
            seglabel{tf,k} =  1*(mcprc{tf, k}>0.99) + (-1)*(mcprc{tf, k}<0.90);

            if k==8
                figure(1), imagesc(label2rgb(smapk(imsegs(f).segimage))), axis image
                drawnow; pause(1);
            end
        end
    end
    save([outdir '/traindataDj.mat'], 'smaps', 'labdata', 'segdata', ...
        'mclab', 'mcprc', 'allprc', 'seglabel', 'unilabel', 'trainw', ...
        'pvSP', 'phSP', 'pE', 'pEdj');
end

for k = 1:ncv
    disp(['Iteration: ' num2str(k)]);
    testind{k} = (floor((k-1)*numel(cv_images)/ncv)+1):(floor(k*numel(cv_images)/ncv));
    trainind{k} = setdiff([1:numel(cv_images)], testind{k});
    sclassifier(k) = mcmcTrainSegmentationClassifier2(segdata(trainind{k}, :), seglabel(trainind{k}, :), trainw(trainind{k}, :));
    [vclassifier(k), hclassifier(k)] = ...
        mcmcTrainSegmentClassifier2(labdata(trainind{k}, :), unilabel(trainind{k}, :), trainw(trainind{k}, :));
    %[vregressor(k), hregressor(k)] = ...
    %    trainRegressorLR(labdata(trainind, :), allprc(trainind, :), trainw(trainind, :));
    %[sregressor(k)] = ...
    %    trainRegressorLR(labdata(trainind{k}, :), mcprc(trainind{k}, :), trainw(trainind{k}, :));
end
[vacc, hacc, vcm, hcm, pg] = testMultipleSegmentationsCV2(imsegs(cv_images), ...
    labdata, segdata, smaps, vclassifier, hclassifier, sclassifier, pvSP, phSP, ncv);

save([outdir '/resultsdj.mat'], 'vclassifier', 'hclassifier', 'sclassifier', 'vacc', 'hacc', 'vcm', 'hcm', 'pg');


% written by Jianxiong Xiao http://mit.edu/jxiao/

function svm_prune(alwaysKeep)

global n;
global X;
global Y;
global D;
global SV;

SV = unique([SV; alwaysKeep(:)]);
SV = SV(SV<=n);
n = numel(SV);

X(1:n,:) = X(SV,:);
Y(1:n) = Y(SV,:);
D(1:n) = D(SV);


%GETVALUEOFASSIGNMENT Gets the value of a variable assignment in a factor.
%
%   v = GETVALUEOFASSIGNMENT(F, A) returns the value of a variable assignment,
%   A, in factor F. The order of the variables in A are assumed to be the
%   same as the order in F.var.
%
%   v = GETVALUEOFASSIGNMENT(F, A, VO) gets the value of a variable assignment,
%   A, in factor F. The order of the variables in A are given by the vector VO.
%
%   See also SETVALUEOFASSIGNMENT

% Copyright (C) Daphne Koller, Stanford University, 2012

function v = GetValueOfAssignment(F, A, VO)

if (nargin == 2),
    indx = AssignmentToIndex(A, F.card);
else
    map = zeros(length(F.var), 1);
    for i = 1:length(F.var),
        map(i) = find(VO == F.var(i));
    end;
    indx = AssignmentToIndex(A(map), F.card);
end;

v = F.val(indx);


function w = rbfpak(net)
%RBFPAK	Combines all the parameters in an RBF network into one weights vector.
%
%	Description
%	W = RBFPAK(NET) takes a network data structure NET and combines the
%	component parameter matrices into a single row vector W.
%
%	See also
%	RBFUNPAK, RBF
%

%	Copyright (c) Ian T Nabney (1996-2001)

errstring = consist(net, 'rbf');
if ~errstring
  error(errstring);
end

w = [net.c(:)', net.wi, net.w2(:)', net.b2];


function [zgMax, bgMax, bgOriented] = getLocalGradients(imName)
	paths = getPaths();
	typ = {'bgOriented', 'bgMax', 'zgMax'};
	for t = 1:3,
		fileName = fullfile(paths.gradientsForRecognition, typ{t}, strcat(imName, '.mat'));
		dt = load(fileName);
		eval(sprintf('%s = dt.signal;', typ{t}));
	end
	ng1 = zgMax(:,:,[1:4 4]);
	ng2 = zgMax(:,:,[5:8 8]);
	dg = zgMax(:,:,[9:12 12]);
	zgMax = cat(3, ng1, ng2, dg);
end


function g = fgplvmSequenceGradient(xvec, model, Y, varargin)

% FGPLVMSEQUENCEGRADIENT Wrapper function for gradient of a latent sequence.
% FORMAT
% DESC is a wrapper function for the gradient of the log probability
% of a sequence under the posterior distribution induced by the
% training data with respect to the latent positions.  The GP-LVM
% model is one that is already trained with a specific data set.
% ARG vecx : the positions in the latent space that are being
% optimised as a row vector using the matlab X(:)' notation.
% ARG model : the trained GP-LVM model that is being optimised.
% ARG Y : the position in data space for which the latent sequence is
% being optimised.
% ARG P1, P2, P3 ... : optional additional arguments to be passed
% to the model sequence log likelihood gradient.
% RETURN g : the gradient of the log likelihood with respect to the
% latent positions.
%
% SEEALSO : fgplvmSequenceLogLikeGradient, fgplvmOptimiseSequence
%
% COPYRIGHT Neil D. Lawrence, 2006

% FGPLVM

X = reshape(xvec, size(Y, 1), model.q);
g = - fgplvmSequenceLogLikeGradient(model, X, Y, varargin{:});

g = g(:)';


%% clear the workspace and select data
% clear; clc; close all;

%% choose data
neuron = Sources2D();
nam = get_fullname('./data_1p.tif');          % this demo data is very small, here we just use it as an example
nam = neuron.select_data(nam);  %if nam is [], then select data interactively

%% parameters
% -------------------------    COMPUTATION    -------------------------  %
pars_envs = struct('memory_size_to_use', 8, ...   % GB, memory space you allow to use in MATLAB
    'memory_size_per_patch', 0.6, ...   % GB, space for loading data within one patch
    'patch_dims', [64, 64]);  %GB, patch size

% -------------------------      SPATIAL      -------------------------  %
gSig = 3;           % pixel, gaussian width of a gaussian kernel for filtering the data. 0 means no filtering
gSiz = 13;          % pixel, neuron diameter
ssub = 1;           % spatial downsampling factor
with_dendrites = false;   % with dendrites or not
if with_dendrites
    % determine the search locations by dilating the current neuron shapes
    updateA_search_method = 'dilate';  %#ok<UNRCH>
    updateA_bSiz = 5;
    updateA_dist = neuron.options.dist;
else
    % determine the search locations by selecting a round area
    updateA_search_method = 'ellipse'; %#ok<UNRCH>
    updateA_dist = 5;
    updateA_bSiz = neuron.options.dist;
end
spatial_constraints = struct('connected', true, 'circular', false);  % you can include following constraints: 'circular'
spatial_algorithm = 'hals_thresh';

% -------------------------      TEMPORAL     -------------------------  %
Fs = 10;             % frame rate
tsub = 1;           % temporal downsampling factor
deconv_flag = true;     % run deconvolution or not
deconv_options = struct('type', 'ar1', ... % model of the calcium traces. {'ar1', 'ar2'}
    'method', 'foopsi', ... % method for running deconvolution {'foopsi', 'constrained', 'thresholded'}
    'smin', -5, ...         % minimum spike size. When the value is negative, the actual threshold is abs(smin)*noise level
    'optimize_pars', true, ...  % optimize AR coefficients
    'optimize_b', true, ...% optimize the baseline);
    'max_tau', 100);    % maximum decay time (unit: frame);

nk = 3;             % detrending the slow fluctuation. usually 1 is fine (no detrending)
% when changed, try some integers smaller than total_frame/(Fs*30)
detrend_method = 'spline';  % compute the local minimum as an estimation of trend.

% -------------------------     BACKGROUND    -------------------------  %
bg_model = 'ring';  % model of the background {'ring', 'svd'(default), 'nmf'}
nb = 1;             % number of background sources for each patch (only be used in SVD and NMF model)
ring_radius = 18;  % when the ring model used, it is the radius of the ring used in the background model.
%otherwise, it's just the width of the overlapping area
num_neighbors = []; % number of neighbors for each neuron
bg_ssub = 2;        % downsample background for a faster speed

% -------------------------      MERGING      -------------------------  %
show_merge = false;  % if true, manually verify the merging step
merge_thr = 0.65;     % thresholds for merging neurons; [spatial overlap ratio, temporal correlation of calcium traces, spike correlation]
method_dist = 'max';   % method for computing neuron distances {'mean', 'max'}
dmin = 5;       % minimum distances between two neurons. it is used together with merge_thr
dmin_only = 2;  % merge neurons if their distances are smaller than dmin_only.
merge_thr_spatial = [0.8, 0.4, -inf];  % merge components with highly correlated spatial shapes (corr=0.8) and small temporal correlations (corr=0.1)

% -------------------------  INITIALIZATION   -------------------------  %
K = [];             % maximum number of neurons per patch. when K=[], take as many as possible.
min_corr = 0.8;     % minimum local correlation for a seeding pixel
min_pnr = 8;       % minimum peak-to-noise ratio for a seeding pixel
min_pixel = gSig^2;      % minimum number of nonzero pixels for each neuron
bd = 0;             % number of rows/columns to be ignored in the boundary (mainly for motion corrected data)
frame_range = [];   % when [], uses all frames
save_initialization = false;    % save the initialization procedure as a video.
use_parallel = true;    % use parallel computation for parallel computing
show_init = true;   % show initialization results
choose_params = true; % manually choose parameters
center_psf = true;  % set the value as true when the background fluctuation is large (usually 1p data)
% set the value as false when the background fluctuation is small (2p)

% -------------------------  Residual   -------------------------  %
min_corr_res = 0.7;
min_pnr_res = 6;
seed_method_res = 'auto';  % method for initializing neurons from the residual
update_sn = true;

% ----------------------  WITH MANUAL INTERVENTION  --------------------  %
with_manual_intervention = false;

% -------------------------  FINAL RESULTS   -------------------------  %
save_demixed = true;    % save the demixed file or not
kt = 3;                 % frame intervals

% -------------------------    UPDATE ALL    -------------------------  %
neuron.updateParams('gSig', gSig, ...       % -------- spatial --------
    'gSiz', gSiz, ...
    'ring_radius', ring_radius, ...
    'ssub', ssub, ...
    'search_method', updateA_search_method, ...
    'bSiz', updateA_bSiz, ...
    'dist', updateA_bSiz, ...
    'spatial_constraints', spatial_constraints, ...
    'spatial_algorithm', spatial_algorithm, ...
    'tsub', tsub, ...                       % -------- temporal --------
    'deconv_flag', deconv_flag, ...
    'deconv_options', deconv_options, ...
    'nk', nk, ...
    'detrend_method', detrend_method, ...
    'background_model', bg_model, ...       % -------- background --------
    'nb', nb, ...
    'ring_radius', ring_radius, ...
    'num_neighbors', num_neighbors, ...
    'bg_ssub', bg_ssub, ...
    'merge_thr', merge_thr, ...             % -------- merging ---------
    'dmin', dmin, ...
    'method_dist', method_dist, ...
    'min_corr', min_corr, ...               % ----- initialization -----
    'min_pnr', min_pnr, ...
    'min_pixel', min_pixel, ...
    'bd', bd, ...
    'center_psf', center_psf);
neuron.Fs = Fs;

%% distribute data and be ready to run source extraction
neuron.getReady(pars_envs);

%% initialize neurons from the video data within a selected temporal range
if choose_params
    % change parameters for optimized initialization
    [gSig, gSiz, ring_radius, min_corr, min_pnr] = neuron.set_parameters();
end

[center, Cn, PNR] = neuron.initComponents_parallel(K, frame_range, save_initialization, use_parallel);
neuron.compactSpatial();
if show_init
    figure();
    ax_init= axes();
    imagesc(Cn, [0, 1]); colormap gray;
    hold on;
    plot(center(:, 2), center(:, 1), '.r', 'markersize', 10);
end

%% estimate the background components
neuron.update_background_parallel(use_parallel);
neuron_init = neuron.copy();

%%  merge neurons and update spatial/temporal components
neuron.merge_neurons_dist_corr(show_merge);
neuron.merge_high_corr(show_merge, merge_thr_spatial);

%% update spatial components

%% pick neurons from the residual
[center_res, Cn_res, PNR_res] =neuron.initComponents_residual_parallel([], save_initialization, use_parallel, min_corr_res, min_pnr_res, seed_method_res);
if show_init
    axes(ax_init);
    plot(center_res(:, 2), center_res(:, 1), '.g', 'markersize', 10);
end
neuron_init_res = neuron.copy();

%% udpate spatial&temporal components, delete false positives and merge neurons
% update spatial
if update_sn
    neuron.update_spatial_parallel(use_parallel, true);
    udpate_sn = false;
else
    neuron.update_spatial_parallel(use_parallel);
end
% merge neurons based on correlations
neuron.merge_high_corr(show_merge, merge_thr_spatial);

for m=1:2
    % update temporal
    neuron.update_temporal_parallel(use_parallel);

    % delete bad neurons
    neuron.remove_false_positives();

    % merge neurons based on temporal correlation + distances
    neuron.merge_neurons_dist_corr(show_merge);
end

%% add a manual intervention and run the whole procedure for a second time
neuron.options.spatial_algorithm = 'nnls';
if with_manual_intervention
    show_merge = true;
    neuron.orderROIs('snr');   % order neurons in different ways {'snr', 'decay_time', 'mean', 'circularity'}
    neuron.viewNeurons([], neuron.C_raw);

    % merge closeby neurons
    neuron.merge_close_neighbors(true, dmin_only);

    % delete neurons
    tags = neuron.tag_neurons_parallel();  % find neurons with fewer nonzero pixels than min_pixel and silent calcium transients
    ids = find(tags>0);
    if ~isempty(ids)
        neuron.viewNeurons(ids, neuron.C_raw);
    end
end
%% run more iterations
neuron.update_background_parallel(use_parallel);
neuron.update_spatial_parallel(use_parallel);
neuron.update_temporal_parallel(use_parallel);

K = size(neuron.A,2);
tags = neuron.tag_neurons_parallel();  % find neurons with fewer nonzero pixels than min_pixel and silent calcium transients
neuron.remove_false_positives();
neuron.merge_neurons_dist_corr(show_merge);
neuron.merge_high_corr(show_merge, merge_thr_spatial);

if K~=size(neuron.A,2)
    neuron.update_spatial_parallel(use_parallel);
    neuron.update_temporal_parallel(use_parallel);
    neuron.remove_false_positives();
end

%% save the workspace for future analysis
neuron.orderROIs('snr');
cnmfe_path = neuron.save_workspace();

%% show neuron contours
Coor = neuron.show_contours(0.6);

%% create a video for displaying the
amp_ac = 140;
range_ac = 5+[0, amp_ac];
multi_factor = 10;
range_Y = 1300+[0, amp_ac*multi_factor];

avi_filename = neuron.show_demixed_video(save_demixed, kt, [], amp_ac, range_ac, range_Y, multi_factor);

%% save neurons shapes
neuron.save_neurons();


function [state,Energy,TotalEnergy1MCS,ColorMatrix] = InitializeMatricesQPOTTS(x,MonteCarloSteps,Q);

state=zeros(size(x,1),size(x,1));
Energy=zeros(size(x,1),size(x,1),MonteCarloSteps);
TotalEnergy1MCS=zeros(1,MonteCarloSteps);
ColorMatrix=rand(Q,3);

github-repos/MATLAB/Sable-mcbench-benchmarks/mcbench-benchmarks-ba13b2f0296ef49491b95e3f984c7c41fccdb6d8/34784-monte-carlo-simulation-of-two-dimensional-grain-growth-code-version-no-1-basic/Monte Carlo Simulation Q-state Potts model 2D square-lattice - microstructure/InitializeMatricesQPOTTS.m


function varargout = mapc(values, fcns, varargin)

% varargout = mapc(value, fcns, varargin)
%
% See functional_programming_examples.m for a discussion of this function.
%
% Pass all of the inputs in |values| (a cell array of arguments) to each
% function handle in the cell array |fcns|, allowing output size to vary.
% The output is therefore a cell array instead of an array. Any additional
% arguments are passed to the |cellfun| function, such as the
% 'ErrorHandler' property.
%
% >> mapc({1}, {@(x) 2*x, @asin, @(x) char(x+[115 110 108 96 115 110])})
% ans =
%     [2]    [1.5708]    'tomato'
%
% Tucker McClure
% Copyright 2013 The MathWorks, Inc.

    [varargout{1:nargout}] = cellfun(@(f) f(values{:}), fcns, ...
                                     'UniformOutput', false, varargin{:});

end


function [surf, labels] = imSurfaceEstimate(img, varargin)
% Estimate surface area of a binary 3D structure
%
%   Deprecated, use 'imSurfaceAreaEstimate' instead.
%
%   Usage
%   S = imSurfaceEstimate(IMG)
%   Estimate the surface area of the structure within the image, without
%   measuring surface area of borders.
%   The aim of this function is to be called by the "imSurfaceDensity"
%   function, for providing an estimate of surface area density within a
%   representative volume of interest.
%
%
%   Example
%   imSurfaceEstimate
%
%   See also
%   imSurfaceAreaEstimate, imSurfaceDensity
%

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2010-07-26,    using Matlab 7.9.0.529 (R2009b)
% Copyright 2010 INRA - Cepia Software Platform.

%% Process input arguments

warning('MatImage:deprecated', ...
    'function imSurfaceEstimate is obsolete, use imSurfaceAreaEstimate instead');

% check image dimension
if ndims(img) ~= 3
    error('first argument should be a 3D image');
end

% in case of a label image, return a vector with a set of results
if ~islogical(img)
    labels = unique(img);
    labels(labels==0) = [];
    surf = zeros(length(labels), 1);
    for i=1:length(labels)
        surf(i) = imSurfaceEstimate(img==labels(i), varargin{:});
    end
    return;
end

%% Process input arguments

% in case of binary image, compute only one label...
labels = 1;

% default number of directions
nDirs = 13;

% default image resolution
delta = [1 1 1];

% Process user input arguments
while ~isempty(varargin)
    var = varargin{1};
    if ~isnumeric(var)
        error('option should be numeric');
    end

    % option is either connectivity or resolution
    if isscalar(var)
        nDirs = var;
    else
        delta = var;
    end
    varargin(1) = [];
end

%% Use the LUT to estimate surface area

lut = imSurfaceLut(delta, nDirs);
bch = imBinaryConfigHisto(img);
surf = sum(bch .* lut);


% icaproj() - project ICA component activations through the
%             associated weight matrices to reconstitute the
%             observed data using only the selected ICA components.
% Usage:
%   >> [icaprojdata] = icaproj(data,weights,compindex,[datameans],chansout);
%
% Inputs:
%   data        - data matrix (chans, frames*epochs)
%   weights     - unmixing weight matrix (e.g., weights*sphere from runica())
%   compindex   - vector of ICA component indices to project
%
% Optional inputs:
%   datamean    - Optional ICA row means (for each epoch) from runica()
%                 {default 0 -> distribute data offsets among the ICA components}
%   chansout    - Optional vector of channel indices to output {default: all}
%
%
% Author: Scott Makeig, SCCN/INC/UCSD, La Jolla, 11-30-96
%
% See also: icavar(), runica()

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

% 11-30-96 Scott Makeig CNL / Salk Institute, La Jolla as icaproject.m
% 12-24-96 added define for verbose -sm (V1.3)
% 2-11-97  use outer product math when only one component in compindex -sm
% 3-11-97  remove row means instead of grand mean -sm
% 3-19-97  used datamean argument instead of frames/baseframes -sm
% 4-03-97  changed name to icaproj() -sm
% 6-07-97  changed order of args to conform to runica -sm
% 6-10-97  fixed data mean handling -sm
% 6-23-97  trying pseudo-inverse for non-square weights -sm
% 7-23-97  distributed baseline offset (if any) among the activations -sm
% 10-31-97 removed errcode -sm
% 12-19-00 removed sphere, shifted order of args -sm
% 05-29-01 added chansout, made more efficient -sm
% 01-25-02 reformated help & license, added links -ad

function  [icaprojdata] = icaproj(data,weights,compindex,datamean,chansout)

verbose = 0;   % default no-verbose

if nargin<3   % need 3 args
    help icaproj
    return
end
if nargin<4
  datamean = 0;  % default
end
if isempty(datamean)
  datamean = 0;  % default
end

[chans,framestot] = size(data);
if nargin<5
  chansout = [];
end
if isempty(chansout) | chansout(1) == 0
  chansout = 1:chans;
end
if min(chansout)<1 | max(chansout)> chans
  fprintf('icaproj(): chansout variable out of 1:chans range.\n')
  return
end

[mchans,epochs] = size(datamean);
frames = floor(framestot/epochs);
if epochs*frames ~= framestot | frames < 1,
    fprintf(...
        'icaproj(): frames (%d) does not divide data length (%d)\n.',...
                frames,framestot);
    return
end

[ncomps,cols] = size(compindex);
if cols>1,
  if ncomps==1,    % if row vector,
      compindex = compindex';    % make col vector
      ncomps = cols;
  else
      fprintf('icaproj(): compindex must be a vector\n');
      return
  end
end
if ncomps>chans,
  fprintf('icaproj(): compindex must have <= %d entries\n',chans);
  return
end
for a=1:ncomps-1
  for b=a+1:ncomps
      if compindex(a,1)==compindex(b,1),
            fprintf('icaproj(): component index repeated in compindex\n.');
          return
      end
  end
end
for a=1:ncomps
    if compindex(a)>chans | compindex(a)<1
      fprintf('icaproj(): component index %d out of range!\n',compindex(a));
      return
      break
    end
end

if nargin<4
  datamean = 0; % default
end

if datamean ~= 0,
  %
  % Remove row means, e.g. those subtracted prior to ICA training by runica()
  %
  if verbose==1,
     fprintf('Removing data means of each channel and data epoch...\n');
  end
  for e=1:epochs
      data(:,(e-1)*frames+1:e*frames) = ...
         data(:,(e-1)*frames+1:e*frames) - datamean(:,e)*ones(1,frames);
  end;
end
if verbose == 1
  fprintf('Final input data range: %g to %g\n', ...
                min(min(data)),max(max(data)));
end

if size(weights,1) == size(weights,2)
  iweights    = inv(weights);             % inverse weight matrix
else
  iweights    = pinv(weights);            % pseudo-inverse weight matrix
end

activations = weights(compindex,:)*data;  % activation waveforms
                                          % at desired components
if ncomps==1,  % compute outer product only for single component projection
  if verbose==1,
    fprintf('icaproj(): Projecting data for ICA component %d\n',...
                     compindex(1));
  end
else % if ncomps > 1
  if verbose==1,
    fprintf('icaproj(): Projecting data for ICA components ');
    if ncomps<32
     for n=1:ncomps % for each included component
      fprintf('%d ',compindex(n));
     end
    else
      fprintf('specified.');
    end
    fprintf('\n');         % copy selected activations
  end
end

icaprojdata = iweights(chansout,compindex)*activations;
% reconstitute selected scalp data channels from selected ICA components