% Matlab Script: Cum_timeplot.m
% Modified timeplot-script of ZMAP
% ---------------------------------
% Removed buttons "Reset"  and " "Keep as new catalog"
% Author: J. Woessner
%
% This .m file "timeplot" plots the events select by "circle"
% or by other selection button as a cummultive number versus
% time plot in window 2.
% Time of events with a Magnitude greater than minmag will
% be shown on the curve.  Operates on newt2, resets  b  to newt2,
%     newcat is reset to:
%                       - "a" if either "Back" button or "Close" button is         %                          pressed.
%                       - newt2 if "Save as Newcat" button is pressed.
%Last modification 11/95

report_this_filefun(mfilename('fullpath'));

global tmvar                      %for P-Value
global par1 pplot tmp1 tmp2 tmp3 tmp4 difp loopcheck Info_p
global cplot mess til plo2 cum newt2 statime
global magco selt hndl2 wls_button ml_button;;

zmap_message_center.set_info(' ','Plotting cumulative number plot...');

if ~exist('nosort', 'var') ; nosort = 'of'  ; end

if nosort == 'of'
    [s,is] = sort(newt2.Date);
    newt2 = newt2(is(:,1),:) ;
else  % f
    if t3>t2
        l = min(find(newt2.Date > t2))-1;
        newt2 = [newt2(1:l,:) ; newt2(1,:)*nan ; newt2(l+1:newt2.Count,:) ];
    end

end

if ~exist('xt','var')
xt=[]; % time series that will be used
end
if ~exist('as','var')
    as=[]; % z values, maybe? used by the save callback.
end

think
report_this_filefun(mfilename('fullpath'));

% This is the info window text
%
ttlStr='The Cumulative Number Window                  ';
hlpStr1= ...
    ['                                                     '
    ' This window displays the seismicity in the sel-     '
    ' ected area as a cumulative number plot.             '
    ' Options from the Tools menu:                        '
    ' Cuts in magnitude and  depth: Opens input para-     '
    '    meter window                                     '
    ' Decluster the catalog: Will ask for declustering    '
    '     input parameter and decluster the catalog.      '
    ' AS(t): Evaluates significance of seismicity rate    '
    '      changes using the AS(t) function. See the      '
    '      Users Guide for details                        '
    ' LTA(t), Rubberband: dito                            '
    ' Overlay another curve (hold): Allows you to plot    '
    '       one or several more curves in the same plot.  '
    '       select "Overlay..." and then selext a new     '
    '       subset of data in the map window              '
    ' Compare two rates: start a comparison and moddeling '
    '       of two seimicity rates based on the assumption'
    '       of a constant b-value. Will calculate         '
    '       Magnitude Signature. Will ask you for four    '
    '       times.                                        '
    '                                                     '];
hlpStr2= ...
    ['                                                      '
    ' b-value estimation:    just that                     '
    ' p-value plot: Lets you estimate the p-value of an    '
    ' aftershock sequence.                                 '
    ' Save cumulative number cure: Will save the curve in  '
    '        an ASCII file                                 '
    '                                                      '
    ' The "Keep as newcat" button in the lower right corner'
    ' will make the currently selected subset of eartquakes'
    ' in space, magnitude and depth the current one. This  '
    ' will also redraw the Map window!                     '
    '                                                      '
    ' The "Back" button will plot the original cumulative  '
    ' number curve without statistics again.               '
    '                                                      '];

% Find out of figure already exists
%
[existFlag,figNumber]=figure_exists('Cumulative Number',1);
newCumWindowFlag=~existFlag;
cum = figNumber;

% Set up the Cumulative Number window

if newCumWindowFlag
    cum = figure_w_normalized_uicontrolunits( ...
        'Name','Cumulative Number',...
        'NumberTitle','off', ...
        'NextPlot','replace', ...
        'backingstore','on',...
        'Visible','off', ...
        'Position',[ 100 100 (ZmapGlobal.Data.map_len - [100 20]) ]);

    matdraw

    selt='in';
    add_menu_divider();
    options = uimenu('Label','ZTools');

    uimenu(options,'Label','Cuts in time, magnitude and depth', 'Callback','inpu2')
    uimenu(options,'Label','Cut in Time (cursor) ', 'Callback','timesel(4);timeplot;');
    uimenu(options,'Label','Date Ticks in different format', 'Callback','newtimetick');

    uimenu (options,'Label','Decluster the catalog', 'Callback','inpudenew;')
    iwl = ZG.compare_window_yrs*365/par1;
    uimenu(options,'Label','Overlay another curve (hold)', 'Callback','ho2=true; ')
    uimenu(options,'Label','Compare two rates (fit)', 'Callback','dispma2')
    uimenu(options,'Label','Compare two rates ( No fit)', 'Callback','ic=0;dispma3')
    %uimenu(options,'Label','Day/Night split ', 'Callback','daynigt')

    op3D  =   uimenu(options,'Label','Time series ');
    uimenu(op3D,'Label','Time-depth plot ',...
        'Callback',@(~,~)TimeDepthPlotter.plot(newt2));
    uimenu(op3D,'Label','Time magnitude plot ',...
        'Callback',@(~,~)TimeMagnitudePlotter.plot(newt2));

    op4B = uimenu(options,'Label','Rate changes (beta and z-values) ');

    uimenu(op4B, 'Label', 'beta values: LTA(t) function',...
         'Callback', 'sta = ''bet'',newsta')
    uimenu(op4B, 'Label', 'beta values: "Triangle" Plot',...
         'Callback', ';betatriangle')
    uimenu(op4B,'Label','z-values: AS(t)function',...
         'Callback','set(gcf,''Pointer'',''watch'');sta = ''ast'';newsta')
    uimenu(op4B,'Label','z-values: Rubberband function',...
         'Callback','set(gcf,''Pointer'',''watch'');sta = ''rub'';newsta')
    uimenu(op4B,'Label','z-values: LTA(t) function ',...
         'Callback','set(gcf,''Pointer'',''watch'');sta = ''lta'';newsta')

    op4 = uimenu(options,'Label','Mc and b-value estimation');
    uimenu(op4,'Label','automatic', 'Callback','ho=false,selt = ''in'',; bdiff2')
    uimenu(op4,'Label','automatic - overlay existing plot', 'Callback','ho=true,selt = ''in'',;,bdiff2')
 %   uimenu(op4,'Label','manual', 'Callback','bfitnew(newt2)')
    uimenu(op4,'Label','Estimate Mc', 'Callback','mcperc')
    uimenu(op4,'Label','b with depth', 'Callback','bwithde2')
    uimenu(op4,'Label','b with time', 'Callback','selt=''in'';bwithti')
    uimenu(op4,'label','b with magnitude', 'Callback','bwithmag');
    uimenu(op4,'label','Magnitude of completeness (Mc) with time', 'Callback','mcwti');
    uimenu(op4,'label','Create synthetic catalog', 'Callback','synthb');

    pstring=['global freq_field1 freq_field2 freq_field3 freq_field4 freq_field5 tmp1 tmp2 tmp3 tmp4 tmm magn hpndl1 ctiplo mtpl ttcat;ttcat=newt2;'];
    ptstring=[pstring ' cltipval(2);'];
    pmstring=[pstring ' cltipval(1);'];

    op5 = uimenu(options,'Label','p-value estimation');

    %uimenu(op5,'Label','automatic', 'Callback','global hndl1;ttcat =newt2; clpval(3)')
    %The following instruction calls a program for the computation of the parameters in Omori formula, for the catalog of which the cumulative number graph" is
    %displayed (the catalog newt2).
    uimenu(op5,'Label','Completeness in days after mainshock', 'Callback','mcwtidays')
    uimenu(op5,'Label','Define mainshock and estimate p', 'Callback','ho=false;inpu_main')
    uimenu(op5,'Label','Compute p and overlay existing plot', 'Callback','ho=true; pvalcat')
    %In the following instruction the program pvalcat2.m is called. This program computes a map of p in function of the chosen values for the minimum magnitude and
    %initial time.
    uimenu(op5,'Label','p as a function of time and magnitude', 'Callback','pvalcat2')
    %uimenu(op5,'Label','Run aspar3x', 'Callback',' runasp')
    %The previous option is available only under UNIX. The file must contain the mainshock!!
    % uimenu(op5,'Label',' Help/Info on  aspar3x', 'Callback','  do = [ ''web '' hodi ''/help/aspar.htm ;'' ];eval(do) ')
    uimenu(op5,'Label','Cut catalog at mainshock time', 'Callback','l = min(find( newt2.Magnitude == max(newt2.Magnitude) ));newt2 = newt2(l+1:newt2.Count,:);timeplot ')

    op6 = uimenu(options,'Label','Fractal dimension estimation');
    uimenu(op6,'Label','Compute the fractal dimension D', 'Callback',' E = newt2; org = [2]; startfd');
    uimenu(op6,'Label','Compute D for random catalog', 'Callback',' org = [5]; startfd;');
    uimenu(op6,'Label','Compute D with time', 'Callback',' org = [6]; startfd;');
    uimenu(op6,'Label',' Help/Info on  fractal dimension', 'Callback',' showweb(''fractal''); ')

    uimenu(options,'Label','get coordinates with cursor ',...
         'Callback','gi = ginput(1),plot(gi(1),gi(2),''+'');')
    %uimenu(options,'Label','CUSUM ',...
    % 'Callback','cusum(newt2);')
    %uimenu(options,'Label','CUFIT ',...
    % 'Callback','cufit(newt2);')
    uimenu(options,'Label','Cumlative Moment Release ', 'Callback','morel')
    % uimenu(options,'Label','Time to failure  ', 'Callback','savebufe; bufestefan')
    %uimenu(options,'Label','Compute maximum possibe magnitude (Kijko method)', 'Callback','maxmagkijko')

    op7 = uimenu(options,'Label','Stress Tensor Inversion Tools');
    uimenu(op7,'Label','Invert for stress-tensor - Michael''s Method ', 'Callback','doinvers_michael')
    uimenu(op7,'Label','Invert for stress-tensor - Gephart''s Method ', 'Callback','doinversgep_pc')
    uimenu(op7,'Label','Stress tensor with time', 'Callback','stresswtime')
    uimenu(op7,'Label','Stress tensor with depth', 'Callback','stresswdepth')
    uimenu(op7,'Label',' Help/Info on  stress tensor inversions', 'Callback','  showweb(''stress'') ')
    op5C = uimenu(options,'Label','Histograms');

    uimenu(op5C,'Label','Magnitude',...
        'Callback','global histo;hisgra(newt2.Magnitude,stt1);');
    uimenu(op5C,'Label','Depth',...
        'Callback','global histo;hisgra(newt2.Depth,stt2);');
    uimenu(op5C,'Label','Time',...
        'Callback','global histo;hisgra(newt2.Date,''Time '');');
    uimenu(op5C,'Label','Hr of the day',...
        'Callback','global histo;hisgra(newt2.Date.Hour,''Hr '');');

    %uimenu(options,'Label',' Magnitude signature', 'Callback','dispma0')
    uimenu(options,'Label','Save cumulative number curve', 'Callback',{@calSave1, xt, cumu2})

    uimenu(options,'Label','Save cum #  and z value', 'Callback',{@calSave7, xt, cumu2, as})

    %

%     uicontrol('Units','normal','Position',[.0 .0 .1 .05],'String','Reset', 'Callback','nosort = ''of'';newcat = newcat; newt2 = newcat; stri = ['' '']; stri1 = ['' '']; close(cum); timeplot','tooltip','Resets the catalog to the original selection')
%     uicontrol('Units','normal','Position',[.70 .0 .3 .05],'String','Keep as newcat', 'Callback','newcat = newt2;a=newt2;update(mainmap())','tooltip','Plots this subset in the map window')

    ho2=false;

end
%end;    if figure exist

if ho2
    cumu = 0:1:(tdiff*365/par1)+2;
    cumu2 = 0:1:(tdiff*365/par1)-1;
    cumu = cumu * 0;
    cumu2 = cumu2 * 0;
    n = newt2.Count;
    [cumu, xt] = hist(newt2.Date,(t0b:par1/365:teb));
    cumu2 = cumsum(cumu);

    hold on
    axes(ht)
    tiplot2 = plot(newt2.Date,(1:newt2.Count),'r','era','xor');
    set(tiplot2,'LineWidth',2.0)

    ho2=false
    return
end

figure_w_normalized_uicontrolunits(cum)
delete(gca)
delete(gca)
reset(gca)
dele = 'delete(sicum)';er = 'disp('' '')'; eval(dele,er);
cla
hold off
watchon;

set(gca,'visible','off','FontSize',ZmapGlobal.Data.fontsz.s,'FontWeight','normal',...
    'LineWidth',1.5,...
    'Box','on','SortMethod','childorder')

if isempty(newcat), newcat =a; end

% select big events ( > minmag)
%
l = newt2.Magnitude > minmag;
big = newt2(l,:);
%big=[];
%calculate start -end time of overall catalog
%R
statime=[];
par2=par1;
t0b = min(a.Date);
n = newt2.Count;
teb = max(a.Date);
ttdif=(teb - t0b)*365;
if ttdif>10                 %select bin length respective to time in catalog
    %par1 = ceil(ttdif/300);
elseif ttdif<=10  &&  ttdif>1
    %par1 = 0.1;
elseif ttdif<=1
    %par1 = 0.01;
end

if par1>=1
    tdiff = round((teb - t0b)*365/par1);
    %tdiff = round(teb - t0b);
else
    tdiff = (teb-t0b)*365/par1;
end
% set arrays to zero
%
%if par1>=1
cumu = 0:1:((teb-t0b)*365/par1)+2;
cumu2 = 0:1:((teb-t0b)*365/par1)-1;
%else
%  cumu = 0:par1:tdiff+2*par1;
%  cumu2 =  0:par1:tdiff-1;
%end
% cumu = cumu * 0;
% cumu2 = cumu2 * 0;

%
% calculate cumulative number versus time and bin it
%
n = newt2.Count;
if par1 >=1
    [cumu, xt] = hist(newt2.Date,(t0b:par1/365:teb));
else
    [cumu, xt] = hist((newt2.Date-newt2(1,3)+par1/365)*365,(0:par1:(tdiff+2*par1)));
end
cumu2=cumsum(cumu);
% plot time series
%
%orient tall
set(gcf,'PaperPosition',[0.5 0.5 5.5 8.5])
rect = [0.25,  0.18, 0.60, 0.70];
axes('position',rect)
hold on
%tiplo = plot(xt,cumu2,'ob');
set(gca,'visible','off')
%tiplo2 = plot(xt,cumu2,'b');
%set(tiplo2,'LineWidth',2.5)

%d = datenum(ceil(a.Date)+1900,a.Date.Month,a.Date.Day,a.Date.Hour,a.Date.Minute,a.Date.Minute*0);
%tiplo2 = plot(d,(1:length(d)),'r-.');
%datetick('x',2)

nu = (1:newt2.Count); nu(newt2.Count) = newt2.Count;

tiplot2 = plot([newt2.Date ],nu,'b');
set(tiplot2,'LineWidth',2.0)

% plot end of data
% pl = plot(teb,newt2.Count,'rs');
%set(pl,'LineWidth',1.0,'MarkerSize',6,...
%  'MarkerFaceColor','r','MarkerEdgeColor','g');

% plot big events on curve
%
if par1>=1
    if ~isempty(big)
        %if ceil(big(:,3) -t0b) > 0
        %f = cumu2(ceil((big(:,3) -t0b)*365/par1));
        l = newt2.Magnitude > minmag;
        f = find( l  == 1);
        bigplo = plot(big(:,3),f,'hm');
        set(bigplo,'LineWidth',1.0,'MarkerSize',10,...
            'MarkerFaceColor','y','MarkerEdgeColor','k')
        stri4 = [];
        [le1,le2] = size(big);
        for i = 1:le1
            s = sprintf('  M=%3.1f',big(i,6));
            stri4 = [stri4 ; s];
        end   % for i

        %te1 = text(big(:,3),f,stri4);
        %set(te1,'FontWeight','normal','Color','k','FontSize',8)
        %end

        %option to plot the location of big events in the map
        %
        % figure_w_normalized_uicontrolunits(map)
        % plog = plot(big(:,1),big(:,2),'or','EraseMode','xor');
        %set(plog,'MarkerSize',ms10,'LineWidth',2.0)
        %figure_w_normalized_uicontrolunits(cum)

    end
end %if big

if exist('stri', 'var')
    %v = axis;
    %if par1>=1
    % axis([ v(1) ceil(teb) v(3) v(4)+0.05*v(4)]);
    %end
    %tea = text(v(1)+0.5,v(4)*0.9,stri) ;
    % set(tea,'FontSize',ZmapGlobal.Data.fontsz.s,'Color','k')
else
    strib = [file1];
end %% if stri

strib = [name];

title2(strib,'FontWeight','normal',...
    'FontSize',ZmapGlobal.Data.fontsz.s,...
    'Color','k')

if par1>=1
    xlabel('Time in years ','FontSize',ZmapGlobal.Data.fontsz.s)
else
    statime=newt2(1,3)-par1/365;
    xlabel(['Time in days relative to ',num2str(statime)],'FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
end
ylabel('Cumulative Number ','FontSize',ZmapGlobal.Data.fontsz.s)
ht = gca;
set(gca,'Color',color_bg);

%clear strib stri4 s l f bigplo plog tea v
% Make the figure visible
%
set(gca,'visible','on','FontSize',ZmapGlobal.Data.fontsz.s,...
    'LineWidth',1.0,'TickDir','out','Ticklength',[0.02 0.02],...
    'Box','on')
figure_w_normalized_uicontrolunits(cum);
%sicum = signatur('ZMAP','',[0.65 0.98 .04]);
%set(sicum,'Color','b')
axes(ht);
set(cum,'Visible','on');
watchoff(cum)
watchoff(map)
zmap_message_center.clear_message();
%par1=par2;
done


function update_spatial_batch(obj, use_parallel)
%% update the the spatial components for all batches and then summarize the results
% input:
%   use_parallel: boolean, do initialization in patch mode or not.
%       default(true); we recommend you to set it false only when you want to debug the code.

%% Author: Pengcheng Zhou, Columbia University, 2017
%% email: zhoupc1988@gmail.com

%% update spatial components for all batches
nbatches = length(obj.batches);

[d, K] = size(obj.A);
if K==0
    fprintf('You have to initialize neurons first\n');
    return;
end
A = zeros(d, K);
cc = zeros(nbatches, K);

for mbatch=1:nbatches
    batch_k = obj.batches{mbatch};
    neuron_k = batch_k.neuron;

    fprintf('\nprocessing batch %d/%d\n', mbatch, nbatches);

    % update temporal components
    neuron_k.update_spatial_parallel(use_parallel);
    cc(mbatch, :) = sum(neuron_k.C.^2, 2);
    A = A + bsxfun(@times, neuron_k.A, cc(mbatch, :));
end

obj.A = bsxfun(@times, A, 1./sum(cc, 1));
obj.post_process_spatial();

%% spread the same A to all batches and update temporal components
for mbatch=1:(length(obj.batches)-1)
    batch_k = obj.batches{mbatch};
    neuron_k = batch_k.neuron;

    neuron_k.A = obj.A;

    batch_k.neuron = neuron_k;
    obj.batches{mbatch} = batch_k;
end


% function hewma_timeseries_plot
%
% graphic display of significant voxels in whole-brain hewma analysis
% and plotting of timeseries points you click on in the image.
%
% ..
%    tor wager
% ..
if ~exist('overlayimg') == 1, overlayimg = 'hewma_sig.img';,end
disp(['Overlay image is: ' overlayimg])

% used in button-up fcn callback
E2 = EXPT;
clear EXPT

global VOL
global f
global f2
global EXPT
EXPT = E2;

    % -------------------------------------------------------------------
    % * essential stuff for the viewing
    % -------------------------------------------------------------------

    cl = mask2clusters(overlayimg);

% view clusters
cluster_orthviews(cl,'unique');
set(gcf,'WindowButtonUpFcn','[dat,files,stats,mycov] = hewma_plot_coord_btnupfcn;')

% get coordinate mapping matrix
VOL = struct('M',cl(1).M);

% prepare figure
f1 = figure('Color','w','Name','Hewma plots');
f = f1;     % button callback uses figure f

cd ..

%return


function y = minus(X,Y)
%MINUS (overloaded)

global FACTORTRACKING

% Cannot use isa here since blkvar is marked as sdpvar
X_class = class(X);
Y_class = class(Y);
X_is_spdvar = strcmp(X_class,'sdpvar');
Y_is_spdvar = strcmp(Y_class,'sdpvar');

% Convert block objects
if ~X_is_spdvar && ~strcmp(X_class,'double')
    if isa(X,'blkvar')
        X = sdpvar(X);
        X_is_spdvar = isa(X,'sdpvar');
    elseif isa(X,'intval')
        X_is_spdvar = 0;
        Y.basis = intval(Y.basis);
    elseif isa(X,'uint8') || isa(X,'uint16') || isa(X,'uint32') || isa(X,'uint64')
        X = double(X);
    end
end

if ~Y_is_spdvar && ~strcmp(Y_class,'double')
    if isa(Y,'blkvar')
        Y = sdpvar(Y);
        Y_is_spdvar = isa(Y,'sdpvar');
    elseif isa(Y,'intval')
        Y_is_spdvar = 0;
        X.basis = intval(X.basis);
    elseif isa(Y,'uint8') || isa(Y,'uint16') || isa(Y,'uint32') || isa(Y,'uint64')
        Y = double(Y);
    end
end

if X_is_spdvar
    if X.typeflag == 40
        y = X + uminus(Y);
        return
    end
else
    if any(isnan(X))
        error('Adding NaN to an SDPVAR makes no sense.');
    end
end
if Y_is_spdvar
    if Y.typeflag == 40
        y =X + uminus(Y);
        return
    end
else
    if any(isnan(Y))
        error('Adding NaN to an SDPVAR makes no sense.');
    end
end

switch 2*X_is_spdvar+Y_is_spdvar
    case 1
        if isempty(X)
            try
                y = full(X - reshape(Y.basis(:,1),Y.dim(1),Y.dim(2)));
            catch
                error(lasterr);
            end
            return
        end

        y = Y;
        n_Y = Y.dim(1);
        m_Y = Y.dim(2);
        [n_X,m_X] = size(X);
        x_isscalar = (n_X*m_X==1);
        y_isscalar = (n_Y*m_Y==1);
        any_scalar = x_isscalar | y_isscalar;

        % Speeeeeeed
        if x_isscalar && y_isscalar
            y.basis = -y.basis;
            tmp = y.basis(1)+X;
            if (isequal(class(tmp),'gem') || isequal(class(tmp),'sgem')) && ~isequal(class(y.basis), class(tmp))
                y.basis = gemify(y.basis);
            end
            y.basis(1) = tmp;
            % Reset info about conic terms
            y.conicinfo = [0 0];
            y.extra.opname='';
            if FACTORTRACKING, y = addfactors(y,X,-Y);end
            return
        end

        if any_scalar || all([n_Y m_Y]==[n_X m_X])
            if y_isscalar
                y.basis = repmat(y.basis,n_X*m_X,1);
                y.dim(1) = n_X;
                y.dim(2) = m_X;
            end
            y.basis = -y.basis;
            if nnz(X)~=0
                tmp = y.basis(:,1)+X(:);
                if (isequal(class(tmp),'gem') || isequal(class(tmp),'sgem')) && ~isequal(class(y.basis), class(tmp))
                    y.basis = gemify(y.basis);
                end
                y.basis(:,1) = tmp;
            end
        else
            error('Matrix dimensions must agree.');
        end
        % Reset info about conic terms
        y.conicinfo = [0 0];
        y.extra.opname='';
        y.extra.createTime = definecreationtime;
        if FACTORTRACKING, y = addfactors(y,X,-Y);end
    case 2

        if isempty(Y)
            try
                y = full(reshape(X.basis(:,1),X.dim(1),X.dim(2))-Y);
            catch
                error(lasterr);
            end
            return
        end
        y = X;
        n_X = X.dim(1);
        m_X = X.dim(2);
        [n_Y,m_Y] = size(Y);
        x_isscalar = (n_X*m_X==1);
        y_isscalar = (n_Y*m_Y==1);
        any_scalar = x_isscalar | y_isscalar;

        % Silly hack
        % Taking X-scalar(0) takes unnecessary time
        % and is used in most definitions of LMIs
        if (y_isscalar && (Y==0))
            return
        end

        % Speeeeeeed
        if x_isscalar && y_isscalar
            tmp = y.basis(1)-Y;
            if (isequal(class(tmp),'gem') || isequal(class(tmp),'sgem')) && ~isequal(class(y.basis), class(tmp))
                y.basis = gemify(y.basis);
            end
            y.basis(1) = tmp;
            % Reset info about conic terms
            y.conicinfo = [0 0];
            y.extra.opname='';
            if FACTORTRACKING, y = addfactors(y,X,-Y);end
            return
        end

        if any_scalar || all([n_Y m_Y]==[n_X m_X])
            if x_isscalar
                y.basis = repmat(y.basis,n_Y*m_Y,1);
                y.dim(1) = n_Y;
                y.dim(2) = m_Y;
            end
            tmp = y.basis(:,1)-Y(:);
            if (isequal(class(tmp),'gem') || isequal(class(tmp),'sgem')) && ~isequal(class(y.basis), class(tmp))
                y.basis = gemify(y.basis);
            end
            y.basis(:,1) = tmp;
        else
            error('Matrix dimensions must agree.');
        end

        % Update information about conic terms
        % This information is used in DUALIZE to
        % speed up some checks, and to facilitate some
        % advanced dualization features. It also
        % speeds up checking for symmetry in some other code
        % Ugly, but the best way at the moment
        % For a description of this field, check SDPVAR code
        % if (y.conicinfo(1)~=0) && isequal(Y,Y') && (y.conicinfo(2) ~= 2)
        %     y.conicinfo(2) = max(1,y.conicinfo(2));
        % else
        y.conicinfo = [0 0];
        y.extra.opname='';
        if FACTORTRACKING, y = addfactors(y,X,-Y);end
        % end

    case 3

        %	if (X.typeflag~=0) || (Y.typeflag~=0)
        %		error('Relational objects cannot be manipulated')
        %	end

        n_X = X.dim(1);
        m_X = X.dim(2);
        n_Y = Y.dim(1);
        m_Y = Y.dim(2);
        x_isscalar = (n_X*m_X==1);
        y_isscalar = (n_Y*m_Y==1);
        any_scalar = x_isscalar | y_isscalar;

        if ~any_scalar
            if (~((n_X==n_Y) && (m_X==m_Y)))
                error('Matrix dimensions must agree.')
            end
        end

        Xlmi_variables = X.lmi_variables;
        Ylmi_variables = Y.lmi_variables;
        yFirst = 0;
        xFirst = 0;
        if Ylmi_variables(end) < Xlmi_variables(1)
            all_lmi_variables = [Ylmi_variables Xlmi_variables];
            yFirst = 1;
        elseif Xlmi_variables(end) < Ylmi_variables(1)
            all_lmi_variables = [Xlmi_variables Ylmi_variables];
            xFirst = 1;
        else
            all_lmi_variables = uniquestripped([Xlmi_variables Ylmi_variables]);
        end

        y = X;
        %X.basis = []; % Returns memory?
        y.lmi_variables = all_lmi_variables;

        if isequal(all_lmi_variables,Xlmi_variables)
            in_X_logical = ones(1,length(Xlmi_variables));
            in_X = 1:length(Xlmi_variables);
        else
            in_X_logical = ismembcYALMIP(all_lmi_variables,Xlmi_variables);
            in_X = find(in_X_logical);
        end

        if isequal(all_lmi_variables,Ylmi_variables)
            in_Y_logical = ones(1,length(Ylmi_variables));
            in_Y = 1:length(Ylmi_variables);
        else
            in_Y_logical = ismembcYALMIP(all_lmi_variables,Ylmi_variables);
            in_Y = find(in_Y_logical);
        end

        if isequal(Xlmi_variables,Ylmi_variables) && n_Y==n_X && m_Y==m_X
            y.basis = y.basis - Y.basis;
            % Super special case f(scalar)-f(scalar)
            if length(X.lmi_variables)==1
                if all(y.basis(:,2)==0)
                    y = full(reshape(y.basis(:,1),n_Y,m_Y));
                else
                    y.conicinfo = [0 0];
                    y.extra.opname='';
                    if FACTORTRACKING, y = addfactors(y,X,-Y);end
                end
                return
            end
        elseif max(Xlmi_variables) < min(Ylmi_variables) &&  n_Y==n_X && m_Y==m_X
            % Disjoint variables in X - Y
            y.basis = [y.basis(:,1) - Y.basis(:,1) y.basis(:,2:end) -Y.basis(:,2:end)];
        elseif max(Ylmi_variables) < min(Xlmi_variables) &&  n_Y==n_X && m_Y==m_X
            % Disjoint variables in X - Y
            y.basis = [y.basis(:,1) - Y.basis(:,1) -Y.basis(:,2:end) y.basis(:,2:end)];
        else
           % [ix,jx,sx] = find(y.basis);y.basis = [];
           % [iy,jy,sy] = find(Y.basis);%Y.basis = [];
            mapX = [1 1+in_X];
            mapY = [1 1+in_Y];
           % basis_X = sparse(ix,mapX(jx),sx,n_X*m_X,1+length(all_lmi_variables));ix=[];jx=[];sx=[];
           % basis_Y = sparse(iy,mapY(jy),sy,n_Y*m_Y,1+length(all_lmi_variables));iy=[];jy=[];sy=[];
            basis_X = X.basis*(sparse(1:length(mapX),mapX,1,size(X.basis,2),length(all_lmi_variables)+1));
            basis_Y = Y.basis*(sparse(1:length(mapY),mapY,1,size(Y.basis,2),length(all_lmi_variables)+1));

            % Fix addition of matrix+scalar
            if n_X*m_X<n_Y*m_Y
                y.dim(1) = n_Y;
                y.dim(2) = m_Y;
                try
                    y.basis = bsxfun(@plus,basis_X,-basis_Y);
                catch
                    basis_X = repmat(basis_X,n_Y*m_Y,1);
                    y.basis = basis_X - basis_Y;
                end

            elseif n_Y*m_Y<n_X*m_X
                y.dim(1) = n_X;
                y.dim(2) = m_X;
                try
                     y.basis = bsxfun(@minus,basis_X,basis_Y);
                catch
                    basis_Y = repmat(basis_Y,n_X*m_X,1);
                    y.basis = basis_X - basis_Y;
                end
            else
                      y.basis = basis_X - basis_Y;
            end
        end

        y.conicinfo = [0 0];
        y.extra.opname='';
        y.extra.createTime = definecreationtime;
        if FACTORTRACKING, y = addfactors(y,X,-Y);end
        if nnz(in_Y_logical & in_X_logical)>0
            y = clean(y);
        end

    otherwise
end

% Update info on KYP objects
if X_is_spdvar && Y_is_spdvar
  if  X.typeflag==9  && Y.typeflag==9
    error('Substraction of KYP objects currently not supported')
  end
end
if Y_is_spdvar
  if  Y.typeflag==9
    y.extra.M = -Y.extra.M+X;
    y.extra.negated = ~Y.extra.negated;
    return
  end
end
if X_is_spdvar
 if X.typeflag==9
    y.extra.M = y.extra.M-Y;
    return
 end
end


function [hPa] = Pa2hPa(Pa)
% Convert pressure from pascals to hectopascals.
% Chad Greene 2012
hPa = Pa*0.010;


function run_experiment_baseline_conv5(imdb_video)
%% Experiment entry point

	opts.gpus = 1;

	if nargin < 1
	    imdb_video = [];
	end

    opts.join.method = 'xcorr';
    opts.branch.conf.num_out = [96 256 384 384 32];
    opts.branch.conf.num_in = [ 3 48 256 192 192];
    opts.branch.conf.conv_stride = [ 2 1 1 1 1];
    opts.branch.conf.pool_stride = [ 2 1];

    opts.exemplarSize = 127;
   	opts.train.numEpochs = 100;

	experiment(imdb_video, opts);

end


function [net, info] = trainModel(varargin)

opts.batchNormalization = false ;
opts.network = [];
opts.networkType = 'dagnn' ;
opts.database = 'polyu1000';
opts.model = 'vgg16';
opts.downsample = 5;
opts.cdim = 4;
opts.ndim = 1024;
opts.warpsize = 8;
opts.trainNum = 1000;
opts.RoIRoD = 'RoIRoD';
opts.seed = 1;

[opts, varargin] = vl_argparse(opts, varargin) ;

sfx = opts.networkType ;
if opts.batchNormalization, sfx = [sfx '-bnorm'] ; end
[opts, varargin] = vl_argparse(opts, varargin) ;

opts.expDir = fullfile('data',opts.database) ;
opts.train = struct() ;
opts.train.derOutputs = {'losscls', 1} ;
opts = vl_argparse(opts, varargin) ;
if ~isfield(opts.train, 'gpus'), opts.train.gpus = [1]; end;

switch opts.RoIRoD
    case 'RoIOnly'
        opts.expDir = fullfile(opts.expDir,opts.model,'RoIOnly');
    case 'RoDOnly'
        opts.expDir = fullfile(opts.expDir,opts.model,'RoDOnly');
    case 'RoIRoD'
        opts.expDir = fullfile(opts.expDir,opts.model,'RoIRoD');
    otherwise
        error('Unknown RoIRoD choice.');
end

%% prepare the model and data
switch opts.model
    case 'vgg16'
        net = vgg16_intialization(opts.downsample,opts.warpsize,opts.cdim,opts.ndim, opts.RoIRoD);
    case 'resnet50'
        net = resnet50_intialization(opts.downsample,opts.warpsize,opts.cdim,opts.ndim, opts.RoIRoD);
end

opts.minScale = 256;
opts.imdbPath = fullfile(['imdb_' opts.database num2str(opts.minScale) '.mat']);
opts.expDir = fullfile(opts.expDir,[num2str(opts.trainNum) '_down' num2str(opts.downsample)...
              '_warp' num2str(opts.warpsize) 'cdim' num2str(opts.cdim) 'ndim' num2str(opts.ndim) 'seed' num2str(opts.seed)]);

if strcmp(opts.database,'GAIC')
    imdb = setup_database_GAIC(opts.trainNum,opts.seed);
end

gt_scores = cat(2,imdb.bbox.gt_scores{imdb.images.set==1});
gt_scores_means = mean(gt_scores);
gt_scores_stds = std(gt_scores);
for i = 1:length(imdb.bbox.gt_scores)
    imdb.bbox.gt_scores{i} = (imdb.bbox.gt_scores{i} - gt_scores_means) / gt_scores_stds;
end
imdb.gt_scores.means = gt_scores_means;
imdb.gt_scores.stds = gt_scores_stds;

imdb.images.dataMean = net.meta.normalization.averageImage;
net.meta.minScale = opts.minScale;

% --------------------------------------------------------------------
%  Train
% --------------------------------------------------------------------

[net, info] = cnn_train_dag(net, imdb, @(i,b) getBatch_rois(opts,i,b),...
  'expDir', opts.expDir, net.meta.trainOpts, opts.train, ...
  'val', find(imdb.images.set == 3),'solver',@solver.adam);

% --------------------------------------------------------------------
function inputs = getBatch_rois(opts, imdb, batch)
% --------------------------------------------------------------------

imo = vl_imreadjpeg(imdb.meta.img_path(batch),'numThreads',1,'Contrast',0.5,'Saturation',0.5);
num_samples = 64;
for i = 1:length(batch)

    [x1,x2,x3] = size(imo{i});
    imre = imresize(imo{i},opts.minScale/min([x1,x2]),'bilinear');

    [r1,r2,r3] = size(imre);
    r1 = 32*round(r1/32);
    r2 = 32*round(r2/32);
    imre = imresize(imre,[r1,r2],'bilinear');

    imre = bsxfun(@minus,imre,imdb.images.dataMean);

    sel = randperm(numel(imdb.bbox.gt_scores{batch(i)}),min(num_samples,numel(imdb.bbox.gt_scores{batch(i)})));
    rois{i} = imdb.bbox.boxes{batch(i)}(:,sel);

    scale1 = r1/x1;
    scale2 = r2/x2;
    rois{i}(1,:) = max(floor(rois{i}(1,:) * scale1),1);
    rois{i}(2,:) = max(floor(rois{i}(2,:) * scale2),1);
    rois{i}(3,:) = min(ceil(rois{i}(3,:) * scale1),r1);
    rois{i}(4,:) = min(ceil(rois{i}(4,:) * scale2),r2);

    rois{i} = [i*ones(1,length(sel));rois{i}];
    gt_scores{i} = imdb.bbox.gt_scores{batch(i)}(sel);
end

rois = cat(2,rois{:});
gt_scores = cat(2,gt_scores{:});

if numel(opts.train.gpus) > 0
  imre = gpuArray(imre) ;
  rois = gpuArray(single(rois)) ;
end

inputs = {'input', imre, 'label', gt_scores, 'rois', rois} ;


function ms_regular_training(video, method, frames)

opts.expDir = ['net/' method '/' num2str(frames) '/' video] ;

opts.train.batchSize = 5 ;
opts.train.numEpochs = 20;
opts.train.continue = false ;
opts.train.useGpu = true ;
opts.train.learningRate    = 1e-3;
opts.train.expDir = opts.expDir ;

scales = [1, 0.75, 0.5];

%opts = vl_argparse(opts, varargin) ;

% --------------------------------------------------------------------
%                                                         Prepare data
% --------------------------------------------------------------------

imgDir = ['../CDNetDataset/' method '/' num2str(frames) 'frames/' video '/input'];
labelDir = ['../CDNetDataset/' method '/' num2str(frames) 'frames/' video '/GT'];
imdb = getImdb(imgDir,labelDir);

mask = imread(['../CDNetDataset/' method '/' num2str(frames) 'frames/' video '/ROI.bmp']);
mask = mask(:,:,1);
A = max(max(mask));
mask(mask == A) = 1;
if size(mask,1) > 400 || size(mask,2) >400
    mask = imresize(mask, 0.5, 'nearest');
end
imdb.mask = single(double(mask));

imdb.half_size = 15;

%%%%%%Yi%%%%%% redefined the net
load('net');

net.layers{end-1} = struct('type', 'conv', ...
    'filters', 0.1*randn(1,1,64,1, 'single'), ...
    'biases', zeros(1, 1, 'single'), ...
    'stride', 1, ...
    'pad', 0) ;
net.layers{end} = struct('type', 'sigmoidcrossentropyloss');

load('meanPixel.mat');
imdb.meanPixel = meanPixel;
imdb.scales = scales;

[net,info] = cnn_train_adagrad_ms(net, imdb, @getBatch,...
    opts.train,'errorType','euclideanloss',...
    'conserveMemory', true);

end

function [im, labels] = getBatch(imdb, batch)
% --------------------------------------------------------------------

half_size = imdb.half_size;
meanPixel = imdb.meanPixel;

for ii = 1:numel(batch)

    imagename = imdb.images.name{batch(ii)};
    im_ii = single(imread(imagename));
    labelname = imdb.images.labels{batch(ii)};
    roi = imread(labelname);
    labels_ii = zeros(size(roi, 1), size(roi, 2));
    labels_ii( roi == 50 )  = 0.25;       %shade
    labels_ii( roi == 170 ) = 0.75;       %object boundary
    labels_ii( roi == 255 ) = 1;          %foreground

    % resize the image to half size
    if size(im_ii,1) > 400 || size(im_ii,2) >400
        im_ii = imresize(im_ii, 0.5, 'nearest');
        labels_ii = imresize(labels_ii, 0.5, 'nearest');
    end

    im(:,:,:,ii) = im_ii;
    labels(:,:,1,ii) = labels_ii;
end
end

function imdb = getImdb(imgDir, labelDir)

files = dir([imgDir '/*.jpg']);
label_files = dir([labelDir '/*.png']);
names = {};labels = {};

for ii = 1:numel(files)
    names{end+1} = [imgDir '/' files(ii).name];
    labels{end+1} = [labelDir '/' label_files(ii).name];
end

imdb.images.set = ones(1,numel(names));
imdb.images.name = names ;
imdb.images.labels = labels;
end


classdef (Abstract) net_model_ac < mp.net_model% & mp.form_ac
%MP.NET_MODEL_AC Abstract class, explicitly a subclass of MP.NET_MODEL and
%              implicitly assumed to be a subclass of MP.FORM_AC as well

%   MATPOWER
%   Copyright (c) 2019-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
        zr = [];
        zi = [];
    end

    properties (Access=protected)
        inln_list = {};         %% list of indexes of nme's w/inln
        snln_list = {};         %% list of indexes of nme's w/snln
        inln_hess_list = {};    %% list of indexes of nme's w/inln_hess
        snln_hess_list = {};    %% list of indexes of nme's w/snln_hess
    end

    methods
        function obj = def_set_types(obj)
            def_set_types@mp.net_model(obj);    %% call parent first
            obj.set_types.zr = 'NON-VOLTAGE VARS REAL (zr)';
            obj.set_types.zi = 'NON-VOLTAGE VARS IMAG (zi)';
        end

        function obj = build_params(obj, nm, dm)
            %% call parent to build individual element parameters
            build_params@mp.net_model(obj, nm, dm);

            %% aggregate parameters from individual elements
            obj.Y = obj.stack_matrix_params('Y', 1);
            obj.L = obj.stack_matrix_params('L', 0);
            obj.M = obj.stack_matrix_params('M', 1);
            obj.N = obj.stack_matrix_params('N', 0);
            obj.i = obj.stack_vector_params('i');
            obj.s = obj.stack_vector_params('s');

            %% add general nonlinear function if any element has one defined
            for k = 1:length(obj.elements)
                if ~isempty(obj.elements{k}.inln)
                    obj.inln_list{end+1} = k;
                    if ~isempty(obj.elements{k}.inln_hess)
                        obj.inln_hess_list{end+1} = k;
                    end
                end
                if ~isempty(obj.elements{k}.snln)
                    obj.snln_list{end+1} = k;
                    if ~isempty(obj.elements{k}.snln_hess)
                        obj.snln_hess_list{end+1} = k;
                    end
                end
            end
            if ~isempty(obj.inln_list)
                obj.inln = @(x_, sysx, idx)port_inj_nln(obj, 'i', x_, sysx, idx);
                if ~isempty(obj.inln_hess_list)
                    obj.inln_hess = @(x_, lam, sysx, idx)port_inj_nln_hess(obj, 'i', x_, lam, sysx, idx);
                end
            end
            if ~isempty(obj.snln_list)
                obj.snln = @(x_, sysx, idx)port_inj_nln(obj, 's', x_, sysx, idx);
                if ~isempty(obj.snln_hess_list)
                    obj.snln_hess = @(x_, lam, sysx, idx)port_inj_nln_hess(obj, 's', x_, lam, sysx, idx);
                end
            end
        end

        function [g, gv1, gv2, gzr, gzi] = port_inj_nln(obj, si, x_, sysx, idx)
            if nargin < 5
                idx = [];
                if nargin < 4
                    sysx = 1;
                end
            end

            %% current or power
            fcn = [si 'nln'];
            fcn_list = [fcn '_list'];

            %% initialize
            if isempty(idx)
                sel = 0;        %% all ports
                np = obj.np;
            else
                sel = 1;        %% selected ports only
                np = length(idx);
            end
            nv = obj.get_nv_(sysx);
            nz = obj.nz;
            nc = size(x_, 2);   %% num of cols in x_, for evaluating multiple x_
            g = zeros(np, nc);
            gv1 = sparse(np, nv);
            gv2 = sparse(np, nv);
            gzr = sparse(np, nz);
            gzi = sparse(np, nz);

            %% loop through elements w/gen nonlin fcns, evaluate them
            pp = obj.get_idx('port');
            if ~sysx
                ss = obj.get_idx('state');
            end
            for kk = obj.(fcn_list)
                k = kk{1};      %% index into obj.elements
                nme = obj.elements{k};
                i1 = pp.i1.(nme.name)(1);
                iN = pp.iN.(nme.name)(end);

                %% set up port index vector for nme
                if sel
                    apidx = find(idx >= i1 & idx <= iN);   %% aggregate port indices in range
                    if isempty(apidx)  %% skip if selected ports, but none in range
                        continue;
                    end
                    nme_idx = idx(apidx) - i1 + 1;  %% port index vector for nme
                else
                    nme_idx = [];                   %% all ports for nme
                end

                %% set up proper x_ for nme
                if sysx
                    nme_x_ = x_;
                else
                    if isfield(ss.i1, nme.name)
                        j1 = ss.i1.(nme.name)(1);
                        jN = ss.iN.(nme.name)(end);
                    else
                        j1 = 1;
                        jN = 0;
                    end
                    nme_x_ = [  x_(i1:iN, :);
                                x_(nv+j1:nv+jN, :)  ];
                end

                %% call nonlinear function
                gg = cell(1, nargout);
                [gg{:}] = nme.(fcn)(nme_x_, sysx, nme_idx);

                %% insert the results in aggregate output args
                if sel
                    g(apidx, :) = gg{1};
                    if nargout > 1
                        if sysx
                            gv1(apidx, :) = gg{2};
                            gv2(apidx, :) = gg{3};
                            if nargout > 3 && nme.nz
                                gzr(apidx, :) = gg{4};
                                gzi(apidx, :) = gg{5};
                            end
                        else
                            gv1(apidx, i1:iN) = gg{2};
                            gv2(apidx, i1:iN) = gg{3};
                            if nargout > 3 && nme.nz
                                gzr(apidx, j1:jN) = gg{4};
                                gzi(apidx, j1:jN) = gg{5};
                            end
                        end
                    end
                else
                    g(i1:iN, :) = gg{1};
                    if nargout > 1
                        if sysx
                            gv1(i1:iN, :) = gg{2};
                            gv2(i1:iN, :) = gg{3};
                            if nargout > 3 && nme.nz
                                gzr(i1:iN, :) = gg{4};
                                gzi(i1:iN, :) = gg{5};
                            end
                        else
                            gv1(i1:iN, i1:iN) = gg{2};
                            gv2(i1:iN, i1:iN) = gg{3};
                            if nargout > 3 && nme.nz
                                gzr(i1:iN, j1:jN) = gg{4};
                                gzi(i1:iN, j1:jN) = gg{5};
                            end
                        end
                    end
                end
            end     %% for loop
        end

        function H = port_inj_nln_hess(obj, si, x_, lam, sysx, idx)
            % H = obj.port_inj_power_hess(x_, lam)
            % H = obj.port_inj_power_hess(x_, lam, sysx)
            % H = obj.port_inj_power_hess(x_, lam, sysx, idx)
            if nargin < 6
                idx = [];
                if nargin < 5
                    sysx = 1;
                end
            end

            %% current or power
            fcn = [si 'nln_hess'];
            fcn_list = [fcn '_list'];

            %% initialize
            n = 2 * length(x_);
            H = sparse(n, n);

            %% loop through elements w/gen nonlin Hessians, evaluate them
            pp = obj.get_idx('port');
            if ~sysx
                ss = obj.get_idx('state');
            end
            for kk = obj.(fcn_list)
                k = kk{1};      %% index into obj.elements
                nme = obj.elements{k};
                i1 = pp.i1.(nme.name)(1);
                iN = pp.iN.(nme.name)(end);

                %% set up x_ for nme & corresp row/col indices for nme
                if sysx
                    nme_x_ = x_;
                else
                    nv = obj.get_nv_(sysx);
                    nz = obj.nz;
                    if isfield(ss.i1, nme.name)
                        j1 = ss.i1.(nme.name)(1);
                        jN = ss.iN.(nme.name)(end);
                    else
                        j1 = 1;
                        jN = 0;
                    end
                    nme_x_ = [  x_(i1:iN, :);
                                x_(nv+j1:nv+jN, :)  ];

                    %% indices of rows/cols of H corresponding to nme x_
                    h = [(i1:iN) nv+(i1:iN) 2*nv+(j1:jN) 2*nv+nz+(j1:jN)].';
                end

                %% set up port index and lambda vectors for nme
                if ~isempty(idx)    %% selected ports only
                    apidx = find(idx >= i1 & idx <= iN);    %% aggregate port indices in range
                    if isempty(apidx)  %% skip if selected ports, but none in range
                        continue;
                    end
                    nme_idx = idx(apidx) - i1 + 1;  %% port index vector for nme
                    nme_lam = lam(apidx);           %% corresponding lam
                else                %% all ports
                    nme_idx = [];
                    nme_lam = lam(i1:iN);
                end

                %% call nonlinear function
                nme_H = nme.(fcn)(nme_x_, nme_lam, sysx, nme_idx);

                %% accumulate output
                if sysx
                    H = H + nme_H;
                else
                    H(h,h) = H(h,h) + nme_H;
                end
            end
        end

        function [G, Gv1, Gv2, Gzr, Gzi] = nodal_complex_current_balance(obj, x_)
            %% node incidence matrix
            C = obj.C;

            %% get port current injections with derivatives
            if nargout > 1
                [I, Iv1, Iv2, Izr, Izi] = obj.port_inj_current(x_, 1);
                Gv1 = C * Iv1;      %% Gva or Gvr
                Gv2 = C * Iv2;      %% Gvm or Gvi
                Gzr = C * Izr;
                Gzi = C * Izi;
            else
                I = obj.port_inj_current(x_, 1);
            end

            %% nodal current balance
            G = C * I;
        end

        function [G, Gv1, Gv2, Gzr, Gzi] = nodal_complex_power_balance(obj, x_)
            %% node incidence matrix
            C = obj.C;

            %% get port power injections with derivatives
            if nargout > 1
                [S, Sv1, Sv2, Szr, Szi] = obj.port_inj_power(x_, 1);
                Gv1 = C * Sv1;      %% Gva or Gvr
                Gv2 = C * Sv2;      %% Gvm or Gvi
                Gzr = C * Szr;
                Gzi = C * Szi;
            else
                S = obj.port_inj_power(x_, 1);
            end

            %% nodal power balance
            G = C * S;
        end

        function d2G = nodal_complex_current_balance_hess(obj, x_, lam)
            %% get port power injection hessians
            d2G = obj.port_inj_current_hess(x_, obj.C' * lam);
        end

        function d2G = nodal_complex_power_balance_hess(obj, x_, lam)
            %% get port power injection hessians
            d2G = obj.port_inj_power_hess(x_, obj.C' * lam);
        end

        function obj = port_inj_soln(obj)
            %% compute port injections
%             obj.soln.gi_ = obj.port_inj_current(obj.soln.x);
            obj.soln.gs_ = obj.port_inj_power(obj.soln.x);
        end

        function va = get_va(obj, idx)
            if isfield(obj.soln, 'v')           %% solved value
                if nargin < 2 || isempty(idx)
                    va = angle(obj.soln.v);
                else
                    va = angle(obj.soln.v(idx));
                end
            else                                %% initial value
                if nargin < 2 || isempty(idx)
                    va = obj.initial_voltage_angle();
                else
                    va = obj.initial_voltage_angle(idx);
                end
            end
        end
    end     %% methods
end         %% classdef


function vw = percentTSeries(vw, scanNum, sliceNum, detrend,...
    inhomoCorrection, temporalNormalization, noMeanRemove)
%Convert raw time series into percentage change from mean.
% vw = percentTSeries(vw, [scanNum], [sliceNum], [detrend], ...
%           [inhomoCorrection], [temporalNormalization], [noMeanRemove])
%
% Checks the tSeriesScan and tSeriesSlice slots to see if the
% desired tSeries is already loaded. If so, don't do anything.
% Otherwise:
% 1) loads tSeries corresponding to scanNum/sliceNum.
% 2) removes the DC and baseline trend of a tSeries.
% 3) sets:
%    vw.tSeries = resulting percent tSeries
%    vw.tSeriesScan = scanNum
%    vw.tSeriesSlice = sliceNum
%
% INPUTS
% ------
%   vw:             mrVista view structure
%   scanNum:        integer scalar for scan number
%                       [default = viewGet(vw, 'current scan')]
%   sliceNum:       integer scalar or vector for slice number
%                       [default = viewGet(vw, 'current slice')]
%                       0: all slices: [1:viewGet(vw, 'num slices')]
%   detrend:        Options for how to remove the baseline:
%                       0: no trend removal
%                       1: highpass trend removal
%                       2: quadratic removal
%                      -1: linear trend removal
%                       [default: detrend = detrendFlag(vw,scanNum)]
%   inhomoCorrection: How to compensate for distance from the coil:
%                       0 do nothing
%                       1 divide by the mean, independently at each voxel
%                       2 divide by null condition
%                       3 divide by anything you like, e.g., robust
%                         estimate of intensity inhomogeneity
%                       For inhomoCorrection=3, you must compute the
%                           spatial gradient (from the Analysis menu) or
%                           load a previously computed spatial gradient
%                           (from the File/Parameter Map menu).
%   temporalNormalization: Boolean flag. If true, detrend each frame slice
%                           by slice so to that each frame has the same
%                           mean intensity. See doTemporalNormlalization
%                           [default = false]
%   noMeanRemove:       Hmm. Can someone explain this?
%
% OUTPUTS
% -------
%  vw:  Modified vw structure. The following fields get set in the vw:
%               tSeries, tSeriesScan, tSeriesSlice
%
% EXAMPLE
% -------
% dFolder = mrtInstallSampleData('functional', 'mrBOLD_01');
% cd(dFolder);
% vw = initHiddenInplane;
% vw = percentTSeries(vw, 1, 0);

% EDIT HISTORY:
% djh, 1/22/98
% arw, 12/05/99 Added option to remove quadratic function
% dbr, 8/1/00 Added high-pass baseline removal option
% dbr, 11/16/00 Made high-pass trend removal the default (detrendFlag = 1).
%               Linear trend removal is now detrendFlag = -1.
% djh, 11/00  Added option of dividing by spatialGradient
%             (estimate of intensity inhomogeneity) instead
%             of dividing by mean at each pixel.
% djh, 2/2001 Updated to mrLoadRet-3.0
%             Detrending is now done in detrendTSeries.m
%             This function now sets vw.tSeries (loadtSeries used to do this)
% djh, 9/28/2001 Subtract the mean (again) near the end to make sure it's zero
%             Otherwise, it messes up the correlation map.
% djh, 7/12/2002 Changed the options for inhomogeneity correction
%             Used to have only two options (0: divide by mean; 1: divide by robust est)
%             In the current code, current option 1 is the same as what used to be 0
%             and current option 2 is what used to be.
% dhb, 6/3/2003  Comment out code that checks slice and scan numbers and
%             assumes tSeries is cached if they match passed values.  This
%             check did not seem to be bulletproof.
% ras, 3/8/2007		reverted some changes suggested by Mark Schira about
%			  making singles. I agree to use single precision, but will
%			  make the change in loadtSeries and savetSeries, so that this
%			  code doesn't modify the input data type.

%% Argument check
if notDefined('scanNum'),               scanNum               = viewGet(vw,'current scan'); end
if notDefined('sliceNum'),              sliceNum              = viewGet(vw,'current slice'); end
if notDefined('detrend'),               detrend               = detrendFlag(vw,scanNum); end
if notDefined('inhomoCorrection'),      inhomoCorrection      = inhomoCorrectionFlag(vw,scanNum); end
if notDefined('temporalNormalization'), temporalNormalization = 0; end
if notDefined('noMeanRemove'),          noMeanRemove          = 0; end

if sliceNum == 0, sliceNum = 1:viewGet(vw, 'num slices', scanNum); end

%%
% load tSeries
tSeries = loadtSeries(vw, scanNum, sliceNum);

% also, if the tSeries is empty, return w/o erroring
if isempty(tSeries)
	vw = viewSet(vw, 'tSeries', []);
	vw = viewSet(vw, 'tSeriesScan', scanNum);
	vw = viewSet(vw, 'tSeriesSlice', sliceNum);
	return
end

nFrames = size(tSeries,1);

% Added by ARW
if (temporalNormalization)
	disp('Temporal normalization to first frame');
    tSeries=doTemporalNormalization(tSeries);
end

% Make the mean of all other frames the same as this.
% Divide by either the mean or the spatial gradient
%
switch inhomoCorrection
	case 0
		ptSeries = tSeries;
	case 1
		dc = nanmean(tSeries);
		dc(dc==0 | isnan(dc)) = Inf;  % prevents divide-by-zero warnings
		ptSeries = bsxfun(@rdivide, tSeries, dc);
	case 2
		myErrorDlg('Inhomogeneity correction by null condition not yet implement');
	case 3
		if ~isfield(vw, 'spatialGrad') || isempty(vw.spatialGrad)
			try
				vw = loadSpatialGradient(vw);
				updateGlobal(vw); % make sure it stays loaded
			catch                 %#ok<CTCH>
				myErrorDlg(['No spatial gradient map loaded. Either load '...
					'the spatial gradient map from File menu or edit ' ...
					'dataTypes to set inhomoCorrect = 0 or 1']);
			end
		end
		gradientImg = vw.spatialGrad{scanNum}(:,:,sliceNum);
		dc = gradientImg(:)';
		ptSeries = tSeries./(ones(nFrames,1)*dc);
	otherwise
		myErrorDlg(['Invalid option for inhomogeneity correction: ',num2str(inhomoCorrection)]);
end

% Remove trend
%
if detrend
	ptSeries = detrendTSeries(ptSeries,detrend,detrendFrames(vw,scanNum));
end

% Subtract the mean
% Used to just subtract 1 under the assumption that we had already divided by
% the mean, but now with the spatialGrad option the mean may not be exactly 1.
%
if noMeanRemove==0
	ptSeries = bsxfun(@minus, ptSeries, mean(ptSeries));
	% Multiply by 100 to get percent
	%
	ptSeries = 100*ptSeries;
end

% Set fields in view structure
vw = viewSet(vw, 'tSeries', ptSeries);
vw = viewSet(vw, 'tSeriesScan', scanNum);
vw = viewSet(vw, 'tSeriesSlice', sliceNum);

return


function mr = mrReadMag(pth, t, slices);
% Read a P*.7.mag file from Gary's Recon code into
% an mr struct.
%
% Usage: mr = mrReadMag(pth, [time points], [slices]);
%
% ras, 07/05
if notDefined('slices'),	slices = [];			end
if notDefined('t'),			t = [];					end

% init mr struct
[p f ext] = fileparts(pth);
mr = mrCreateEmpty;
mr.path = pth;
mr.name = f;
mr.format = 'pmag';

% first read header file, determine if little endian
% format needs to be used (for Lucas 3T scanner @ Stanford):
[func, mr.hdr] = mrReadMagHeader(pth);
mr.info = mr.hdr;
mr.info.scanner = '';
mr.info.subject = mr.hdr.name;
mr.info.subjectSex = '';
mr.info.subjectAge = [];
[mr.info.date, mr.info.scanStart] = parsePmagDate(mr.hdr.date, mr.hdr.time);
if (mr.info.scanStart(1)<2005) & (mr.info.scanStart(2)<3)  % GE switched from big Endian to little Endian in March 2005
    littleEndian = 0;
else
    littleEndian = 1;
end
mr.info.effectiveResolution = func.effectiveResolution;
mr.info.coil = mr.hdr.coil;

% now read data, get other info:
mr.data = readMagFile(pth, slices, littleEndian);
if ~isempty(t)
	% sub-select time points
	mr.data = mr.data(:,:,:,t);
end
pixdim = mr.hdr.FOV/mr.hdr.equivMatSize;
mr.voxelSize = [pixdim pixdim mr.hdr.sliceThickness mr.hdr.tAcq/1000];
mr.dims = size(mr.data);
mr.dims(3) = size(mr.data, 3);  % in case of 2-D or 3-D data:
mr.dims(4) = size(mr.data, 4);  % enforce 1x4 dims vector
mr.extent = mr.voxelSize .* mr.dims;
mr.spaces = mrStandardSpaces(mr);
mr.dimUnits = {'mm' 'mm' 'mm' 'sec'};
mr.dataUnits = 'T2*-Weighted Intensity';
mr.dataRange = mrvMinmax(mr.data);

% build a space defining the scanner coords, where the
% xform maps from the pixCorners to the R|A|S coords of the
% the three corners from the header:
try
	mr.spaces(end+1).name = 'Scanner';
	mr.spaces(end).xform = mrReadMag_affineScannerXform(mr.hdr);
	mr.spaces(end).xform(1:3,4) = mr.extent(1:3) ./ 2;
	mr.spaces(end).dirLabels = {'L <--> R' 'P <--> A'  'I <--> S'};
	mr.spaces(end).sliceLabels =  {'Sagittal' 'Coronal' 'Axial'};
	mr.spaces(end).units = 'mm';
	mr.spaces(end).coords = [];
	mr.spaces(end).indices = [];

    % NOT YET IMPLEMENTED:
% 	% also update the direction labels on the pixel and L/R flipped spaces,
% 	% using the header info:
% 	dirs = mrEfileDirections(hdrPath);
% 	for i=1:3, mr.spaces(i).dirLabels = dirs; end
% 	mr.spaces(3).dirLabels{2} = dimFlip(mr.spaces(3).dirLabels{2});

catch
	if prefsVerboseCheck
		warning('Couldn''t read E-file header alignment fields.')
	end
end

return
% /-------------------------------------------------------------------/ %

% /-------------------------------------------------------------------/ %
function xform = mrReadMag_affineScannerXform(hdr);
%% given a Mag-file header, compute a 4x4 affine transform mapping from
%% pixel space into the scanner coordinate system.

% E-file headers give us the scanner coordinates of three points from
% each slice:
%	gw_point1 = upper left-hand corner  (x=1, y=1)
%	gw_point2 = lower left-hand corner  (x=1, y=nrows)
%	gw_point3 = upper right-hand corner (x=ncols, y=1)
% We know which points in pixel space coorrespond to these points, so we
% take the combined set of corner coordinates, and the corresponding
% scanner coords, and solve for the best xform to map between them.

% combine the scanner coordinates together
scanCoords = [hdr.gw_point1, hdr.gw_point2, hdr.gw_point3];

% get the corresponding pixel coordinates
[X Y Z] = meshgrid([1 hdr.imgsize], [1 hdr.imgsize], 1:hdr.slquant);
pixCoords = [Y(:) X(:) Z(:)]';

% now we have to clip and resort: every 4th coord here is the
% lower-right-hand corner, which we don't have, so remove these:
pixCoords(:,2:4:end) = [];

% do I have the order of points correct?
pixCoords = pixCoords([1 2 3],:);

% now re-sort to match the order of points in scanCoords:
% [ulhc across slices, llhc across slices, urhc across slices]:
pixCoords = [pixCoords(:,[1:3:end]), ...
			 pixCoords(:,[2:3:end]), ...
			 pixCoords(:,[3:3:end])];

% solve for the xform
xform = affineSolve(pixCoords, scanCoords);

% one last step: we need to account for the shift specified by the start
% location in the header:
xform(1:3,4) = hdr.start_loc;

xform = inv(xform);

return


list_M_species={};

for i=1:2; % reaction
    for t=1:size(list_M(i,:),2) % nubmer of metabolites
        if ~isempty(list_M{i,t})
            met(i,t)=retrieveMet(parsed_fatty_acid_new,list_M(i,t))
            list_M_species(i,2*t-1)={met(i,t).speciesAlliens}

        end
    end
end

for i=1:length(num)

    for r=2:2:length(baseR.(list_nodes{i}))

        list_R(i,r/2)=baseR.(list_nodes{i})(r);
    end

    for d=1:2:length(baseR.(list_nodes{i}))-1
        list_R_M(i,(d+1)/2)=baseR.(list_nodes{i})(d)
    end

    for r=2:2:length(baseP.(list_nodes{i}))

        list_P(i,r/2)=baseP.(list_nodes{i})(r);
    end

    for d=1:2:length(baseP.(list_nodes{i}))-1
        list_P_M(i,(d+1)/2)=baseP.(list_nodes{i})(d)
    end

    for r=2:2:length(baseC_R.(list_nodes{i}))
        list_C_R(i,r/2)=baseC_R.(list_nodes{i})(r); % each reaction has the same color
    end

    for r=2:2:length(baseC_P.(list_nodes{i}))
        list_C_P(i,r/2)=baseC_P.(list_nodes{i})(r); % each reaction has the same color
    end

end


% **********************Zip file 2: AF feature calculation
% AF feature
% calculation code package, which you can use to calculate the 14 AF
% features as the input feature metrix of SVM model. The AF 14 features
% inlcude the NFEn feature I sent you before.
%
% ***********************

clear all
close all
clc

data=load('RR_example.txt');
features = AF_features(data(7,1:53),250);


function [ EMGwhisk ] = GetWhiskFromPiezo( basePath,varargin )
%[ EMGwhisk ] = GetWhiskFromEMG(basePath )
%This is a detector that extracts whisking/nonwhisking epochs from
%implanted EMG in the whisker pad. Extracts also the EMG and EMG envelope.
%
%INPUT
%   Assumes presence of the following files:
%       basePath/baseName.abf    (whisking/camera pulses from clampex)
%       basePath/analogin.dat    (camera pulses to intan)
%   where basePath is a folder of the form:
%       whateverPath/baseName/
%If basePath not specified, tries the current path.
%
%   (options)
%       'PulseChannel'
%       'EMGChannel'
%
%OUTPUT
%Creates file:
%   basePath/baseName.EMGwhisk.states.mat
%
%
%
%To Add: option for no camera pulses, which just align time to intan/pupil
%
%
%DLevenstein 2017
%% DEV
% basePath = '/mnt/proraidDL/Database/WMProbeData/';
% baseName = 'Layers_LFP_Test02_170323_151411';
%%

if ~exist('basePath','var')
    basePath = pwd;
end
baseName = bz_BasenameFromBasepath(basePath);
%%
abfname = fullfile(basePath,[baseName,'.abf']);
analogName = fullfile(basePath,['analogin.dat']);
savefile = fullfile(basePath,[baseName,'.EMGwhisk.states.mat']);
figfolder = fullfile(basePath,'DetectionFigures');

if ~exist(abfname,'file')
    display('No .abf file named basePath/baseName/baseName.abf')
end
if ~exist(analogName,'file')
    display('No analogin.dat in basePath/baseName/')
end

%% Clampex File

[abffile,si,file_info] = abfload(abfname);
sf_abf = 1./(si.*10^-6);

%Prompt user for channel
numabfchans = length(abffile(1,:));
if ~exist('chanNums','var')
    piezochan = listdlg('ListString',file_info.recChNames,...
        'PromptString',['Which channels is Whisker? ']);
    %Replace this with prompt file_info.recChNames
end
%%
EMG = abffile(:,piezochan);
t_abf = [1:length(EMG)]'./sf_abf;

%%
% figure
% plot(t_abf,EMG,'k')
%% Get the whisking envelope
%EMGrange = [400 3000];
%EMG = FiltNPhase(EMG,EMGrange,sf_abf);

downsamplefactor = 16; %Downsample to same as the LFP;
EMG = downsample(EMG,downsamplefactor);
t_EMG = downsample(t_abf,downsamplefactor);
sf_down = sf_abf./downsamplefactor;
%%

EMGparms.gausswidth = 0.05;  %Gaussian width for smoothing (s)
EMGparms.Whthreshold = 3;    %EMG Threshold for Whisking (modSTDs)
EMGparms.NWhthreshold = 0.5;    %EMG Threshold for Whisking (modSTDs)
%EMGparms.threshold = 1;    %EMG Threshold for Whisking (modSTDs)
EMGparms.minwhisk = 0.1;     %Minimum whisking duration (s)
EMGparms.minNWh = 0.1;       %Minimum nonwhisking duration (s)
EMGparms.whiskmerge = 0.1;     %Minimum interwhisking duration (s)
EMGparms.NWhmerge = 0.02;       %Minimum internonwhisking duration (s)

%% Z-Score the EMGZ and get EMG envelope with RMS
EMGz = NormToInt(EMG,'modZ'); %Modified Z score - robust to outliers
EMGsm = RMSEnvelope(EMGz,EMGparms.gausswidth,1/sf_down);
EMGsm = EMGsm-min(EMGsm);
EMGwhisk.EMGenvelope = EMGsm;

%% Set the thresholds by whisking troughs -
%find by "gradient descent"(ish) from initial guess
EMGbins = linspace(-1.5,2,100);
EMGhist = hist(log10(EMGsm),EMGbins);
EMGgrad = smooth(gradient(EMGhist),4);

%Find troughs (gradient crossing from - to +)
troughidx = find(diff(EMGgrad>0)==1);
troughs = 10.^EMGbins(troughidx);

%Get sign of gradient at each of the thresholds and use that to pick trough
Whsign = sign(interp1(EMGbins,EMGgrad,log10(EMGparms.Whthreshold),'nearest'));
if Whsign==-1
    EMGparms.Whthreshold = troughs(find(troughs>EMGparms.Whthreshold,1,'first'));
    if isempty(EMGparms.Whthreshold)
        EMGparms.Whthreshold = troughs(end);
    end
elseif Whsign==1
    EMGparms.Whthreshold = troughs(find(troughs<EMGparms.Whthreshold,1,'last'));
end

NWhsign = sign(interp1(EMGbins,EMGgrad,log10(EMGparms.NWhthreshold),'nearest'));
if NWhsign==-1
    EMGparms.NWhthreshold = troughs(find(troughs>EMGparms.NWhthreshold,1,'first'));
elseif NWhsign==1
    EMGparms.NWhthreshold = troughs(find(troughs<EMGparms.NWhthreshold,1,'last'));
end
%%

% figure
% bar(EMGbins,EMGhist)
% hold on
% plot(EMGbins,EMGgrad)
% plot([1 1].*log10(EMGparms.Whthreshold),get(gca,'ylim'),'g','LineWidth',2)
% plot([1 1].*log10(EMGparms.NWhthreshold),get(gca,'ylim'),'r','LineWidth',2)
%
% axis tight
% xlabel('EMG Envelope (modZ)');
% LogScale('x',10)
% xlim([-1.5 max(log10(EMGsm))])

%% Identify Whisking on/offsets: EMG envelope crosses threshold
wh_thresh = EMGsm > EMGparms.Whthreshold;
wh_on = find(wh_thresh(2:end)>wh_thresh(1:end-1))+1; %whisking onsets (si)
wh_off = find(wh_thresh(2:end)< wh_thresh(1:end-1))+1;%whisking offsets (si)

% If data starts/ends in the middle of an epoch, drop first/last trigger
if wh_off(1)<wh_on(1)
    wh_off = wh_off(2:end);
end
if wh_off(end) < wh_on(end)
    wh_on = wh_on(1:end-1);
end

%% Identify NonWhisking on/offsets: EMG envelope crosses below threshold
nwh_thresh = EMGsm < EMGparms.NWhthreshold;
nwh_on = find(nwh_thresh(2:end)>nwh_thresh(1:end-1))+1; %whisking onsets (si)
nwh_off = find(nwh_thresh(2:end)< nwh_thresh(1:end-1))+1;%whisking offsets (si)

% If data starts/ends in the middle of an epoch, drop first/last trigger
if nwh_off(1)<nwh_on(1)
    nwh_off = nwh_off(2:end);
end
if nwh_off(end) < nwh_on(end)
    nwh_on = nwh_on(1:end-1);
end

%% Merge and Duration Thresholds
%Convert to seconds
wh_on = wh_on./sf_down;
wh_off = wh_off./sf_down;
nwh_on = nwh_on./sf_down;
nwh_off = nwh_off./sf_down;

%Merge brief interruptions
[ NWhints ] = MergeSeparatedInts( [nwh_on,nwh_off],EMGparms.NWhmerge );
[ Whints ] = MergeSeparatedInts( [wh_on,wh_off],EMGparms.whiskmerge );

%Drop nonwhisk epochs smaller than a minimum
[nwh_on,nwh_off] = MinEpochLength(NWhints(:,1),NWhints(:,2),EMGparms.minNWh,1);
%Drop whisking epochs smaller than a minimum
[wh_on,wh_off] = MinEpochLength(Whints(:,1),Whints(:,2),EMGparms.minwhisk,1);

%% Durations
Whdur = wh_off-wh_on;
NWhdur = nwh_off-nwh_on;

numbinst = 25;
durhist.bins = linspace(-1,2,numbinst);
durhist.Wh = hist(log10(Whdur),durhist.bins);
durhist.NWh = hist(log10(NWhdur),durhist.bins);

%% Reset time to align to LFP

%t_EMG = t_EMG-firstpulstime_abf+firstpulstime_lfp;
Whints = [wh_on wh_off];
NWhints = [nwh_on nwh_off];

%% Figure

figure
subplot(4,1,1)
    plot(t_EMG,EMGz,'k')

    hold on
    plot(t_EMG,EMGsm,'b','linewidth',2)
    plot(Whints',EMGparms.Whthreshold.*ones(size(Whints))','g','linewidth',2)
    plot(NWhints',EMGparms.NWhthreshold.*ones(size(NWhints))','r','linewidth',2)
    axis tight
    ylim([-100 100])
    ylabel('EMG (modZ)');

subplot(4,1,2)
    plot(t_EMG,EMGz,'k')

    hold on
    plot(t_EMG,EMGsm,'b','linewidth',2)
    plot(Whints',EMGparms.Whthreshold.*ones(size(Whints))','g','linewidth',2)
    plot(NWhints',EMGparms.NWhthreshold.*ones(size(NWhints))','r','linewidth',2)
    xlim([100 160])
    ylim([-20 40])
    ylabel('EMG (modZ)');

subplot(4,2,6)
hist(log10(EMGsm),100)
hold on
plot([1 1].*log10(EMGparms.Whthreshold),get(gca,'ylim'),'g')
plot([1 1].*log10(EMGparms.NWhthreshold),get(gca,'ylim'),'r')

axis tight
xlabel('EMG Envelope (modZ)');
LogScale('x',10)
xlim([-1.5 max(log10(EMGsm))])

subplot(4,2,8)
plot(durhist.bins,durhist.NWh,'r','linewidth',2)
hold on
plot(durhist.bins,durhist.Wh,'g','linewidth',2)
LogScale('x',10)
xlabel('Duration (s)')
ylabel('# Epochs')
legend('NWh','Wh')

NiceSave('WhiskingDetection',figfolder,baseName)

%%

EMGwhisk.ints.Wh = Whints;
EMGwhisk.ints.NWh = NWhints;
EMGwhisk.detectorparms = EMGparms;
EMGwhisk.detectorname = 'GetWhiskFromEMG';
EMGwhisk.detectiondate = today('datetime');
EMGwhisk.EMG = EMGz;
EMGwhisk.EMGsm = EMGsm;
EMGwhisk.t = t_EMG;

save(savefile,'EMGwhisk')
end


function plot_optfit(a,time,timef,bootloops,maepi)
    % function plot_optfit(a,time,timef,bootloops,maepi);
    % ---------------------------------------------------
    % Plots Ncum observed vs. Ncum modeled for specified time windows
    %
    % Input variables:
    % a         : earthquake catalog (Complete in magnitude!)
    % time      : learning period fo fit Omori parameters
    % timef     : forecast period
    % bootloops : Number of bootstraps
    % maepi     : mainshock
    %
    % Samuel Neukomm
    % last update: 01.03.04

    warning off;

    [fMc] = calc_Mc(a, 1, 0.1)+0.2;
    l = a.Magnitude >= fMc;
    a = a.subset(l);

    if size(a,2) == 9
        date_matlab = datenum(a.Date.Year,a.Date.Month,a.Date.Day,a.Date.Hour,a.Date.Minute,zeros(size(a,1),1));
        date_main = datenum(floor(maepi(3)),maepi(4),maepi(5),maepi(8),maepi(9),0);
    else
        date_matlab = datenum(a.Date.Year,a.Date.Month,a.Date.Day,a.Date.Hour,a.Date.Minute,a(:,10));
        date_main = datenum(floor(maepi(3)),maepi(4),maepi(5),maepi(8),maepi(9),maepi(10));
    end
    time_aftershock = date_matlab-date_main;
    % Select biggest aftershock earliest in time, but more than 1 day after mainshock
    fDay = 1;
    ft_c=fDay/365; % Time not considered to find biggest aftershock
    vSel = (a.Date > maepi(:,3)+ft_c & a.Date<= maepi(:,3)+time/365);
    mCat = a.subset(vSel);
    vSel = mCat(:,6) == max(mCat(:,6));
    vBigAf = mCat(vSel,:);
    if length(mCat(:,1)) > 1
        vSel = vBigAf(:,3) == min(vBigAf(:,3));
        vBigAf = vBigAf(vSel,:);
    end

    if size(a,2) == 9
        date_biga = datenum(floor(vBigAf(3)),vBigAf(4),vBigAf(5),vBigAf(8),vBigAf(9),0);
    else
        date_biga = datenum(floor(vBigAf(3)),vBigAf(4),vBigAf(5),vBigAf(8),vBigAf(9),vBigAf(10));
    end
    fT1 = date_biga - date_main; % Time of big aftershock

    % Aftershock times
    l = time_aftershock(:) > 0;
    tas = time_aftershock(l);
    eqcatalogue = a.subset(l);

    % time_as: Learning period
    l = tas <= time;
    time_as = tas(l);
    time_as = sort(time_as);
    if length(time_as) < 100 % at least 100 events in learning period
        return
    end

    % Times up to the forecast time
    lf = tas <= time+timef ;
    time_asf= [tas(lf) ];
    time_asf=sort(time_asf);

    figure_w_normalized_uicontrolunits('Numbertitle','off','Name','Forecast aftershock occurence')
    hold on

    n = length(time_as);
    loopout = []; nCnt = 0;

    for j = 1:bootloops
        clear newtas
        randnr = ceil(rand(n,1)*n);
        i = (1:n)';
        newtas(i,:) = time_as(randnr(i),:); % bootstrap sample

        % Calculate fits of different models
        mRes = [];
        % Modified Omori law (pck)
        nMod = 1; [pval1, pval2, cval1, cval2, kval1, kval2, fAIC, fL] = bruteforceloglike_a2(newtas,fT1,nMod);
        mRes = [mRes; nMod, pval1, pval2, cval1, cval2, kval1, kval2, fAIC, fL];
        % MOL with secondary aftershock (pckk)
        nMod = 2; [pval1, pval2, cval1, cval2, kval1, kval2, fAIC, fL] = bruteforceloglike_a2(newtas,fT1,nMod);
        mRes = [mRes; nMod, pval1, pval2, cval1, cval2, kval1, kval2, fAIC, fL];
        % MOL with secondary aftershock (ppckk)
        nMod = 3; [pval1, pval2, cval1, cval2, kval1, kval2, fAIC, fL] = bruteforceloglike_a2(newtas,fT1,nMod);
        mRes = [mRes; nMod, pval1, pval2, cval1, cval2, kval1, kval2, fAIC, fL];
        % MOL with secondary aftershock (ppcckk)
        nMod = 4; [pval1, pval2, cval1, cval2, kval1, kval2, fAIC, fL] = bruteforceloglike_a2(newtas,fT1,nMod);
        mRes = [mRes; nMod, pval1, pval2, cval1, cval2, kval1, kval2, fAIC, fL];

        % Select best fitting model by AIC
        vSel = (mRes(:,8)==min(mRes(:,8)));
        mRes = mRes(vSel,:);
        if length(mRes(:,1)) > 1
            vSel = (mRes(:,1)==min(mRes(:,1)));
            mRes = mRes(vSel,:);
        end
        % Model to use for bootstrapping as of lowest AIC to observed data
        nMod = mRes(1,1);
        pval1= mRes(1,2); pval2= mRes(1,3);
        cval1= mRes(1,4); cval2= mRes(1,5);
        kval1= mRes(1,6); kval2= mRes(1,7);

        % Calculate goodness of fit with KS-Test and RMS
        [H,P,KSSTAT,fRMS] = calc_llkstest_a2(newtas,fT1,pval1, pval2, cval1, cval2, kval1, kval2, nMod);
        if H == 1
            nCnt = nCnt + 1;
            if nCnt/bootloops >= 0.5
                return
            end

        else
            cumnr_model = [];

            if nMod == 1
                for i=1:length(time_asf)
                    if pval1 ~= 1
                        nrmod = kval1/(pval1-1)*(cval1^(1-pval1)-(time_asf(i)+cval1)^(1-pval1));
                    else
                        nrmod = kval1*log(time_asf(i)/cval1+1);
                    end
                    cumnr_model = [cumnr_model; nrmod];
                end % END of FOR on length(time_asf)

                if pval1 ~= 1
                    cm = kval1/(pval1-1)*(cval1^(1-pval1)-(max(time_asf)+cval1)^(1-pval1));
                    cl = kval1/(pval1-1)*(cval1^(1-pval1)-(max(time_as)+cval1)^(1-pval1));
                else
                    cm = kval1*log(max(time_asf)/cval1+1);
                    cl = kval1*log(max(time_as)/cval1+1);
                end
            else
                for i=1:length(time_asf)
                    if time_asf(i) <= fT1
                        if pval1 ~= 1
                            nrmod = kval1/(pval1-1)*(cval1^(1-pval1)-(time_asf(i)+cval1)^(1-pval1));
                        else
                            nrmod = kval1*log(time_asf(i)/cval1+1);
                        end
                        cumnr_model = [cumnr_model; nrmod];
                    else
                        if (pval1 ~= 1 & pval2 ~= 1)
                            nrmod = kval1/(pval1-1)*(cval1^(1-pval1)-(time_asf(i)+cval1)^(1-pval1))+ kval2/(pval2-1)*(cval2^(1-pval2)-(time_asf(i)-fT1+cval2)^(1-pval2));
                        elseif (pval1 ~= 1  &&  pval2 == 1)
                            nrmod = kval1/(pval1-1)*(cval1^(1-pval1)-(time_asf(i)+cval1)^(1-pval1))+ kval2*log((time_asf(i)-fT1)/cval2+1);
                        elseif (pval1 == 1  &&  pval2 ~= 1)
                            nrmod = kval1*log(time_asf(i)/cval1+1)+ kval2/(pval2-1)*(cval2^(1-pval2)-(time_asf(i)-fT1+cval2)^(1-pval2));
                        else
                            nrmod = kval1*log(time_asf(i)/cval1+1) + kval2*log((time_asf(i)-fT1)/cval2+1);
                        end
                        cumnr_model = [cumnr_model; nrmod];
                    end %END of IF on fT1
                end % End of FOR length(time_asf)

                if (pval1 ~= 1 & pval2 ~= 1)
                    cm = kval1/(pval1-1)*(cval1^(1-pval1)-(max(time_asf)+cval1)^(1-pval1)) + kval2/(pval2-1)*(cval2^(1-pval2)-(max(time_asf)-fT1+cval2)^(1-pval2));
                    cl = kval1/(pval1-1)*(cval1^(1-pval1)-(max(time_as)+cval1)^(1-pval1)) + kval2/(pval2-1)*(cval2^(1-pval2)-(max(time_as)-fT1+cval2)^(1-pval2));
                elseif (pval1 ~= 1  &&  pval2 == 1)
                    cm = kval1/(pval1-1)*(cval1^(1-pval1)-(max(time_asf)+cval1)^(1-pval1)) + kval2*log((max(time_asf)-fT1)/cval2+1);
                    cl = kval1/(pval1-1)*(cval1^(1-pval1)-(max(time_as)+cval1)^(1-pval1)) + kval2*log((max(time_as)-fT1)/cval2+1);
                elseif (pval1 == 1  &&  pval2 ~= 1)
                    cm = kval1*log(max(time_asf)/cval1+1) + kval2/(pval2-1)*(cval2^(1-pval2)-(max(time_asf)-fT1+cval2)^(1-pval2));
                    cl = kval1*log(max(time_as)/cval1+1) + kval2/(pval2-1)*(cval2^(1-pval2)-(max(time_as)-fT1+cval2)^(1-pval2));
                else
                    cm = kval1*log(max(time_asf)/cval1+1) + kval2*log((max(time_asf)-fT1)/cval2+1);
                    cl = kval1*log(max(time_as)/cval1+1) + kval2*log((max(time_as)-fT1)/cval2+1);
                end
            end % End of if on nMod
            loopout = [loopout; pval1, pval2, cval1, cval2, kval1, kval2, fAIC, fL, cm, cl, nMod];
            pfloop = plot(time_asf,cumnr_model,'color',[0.8 0.8 0.8]);
        end % End of KS-Test
    end

    % 2nd moment of bootstrap number of forecasted number of events
    fStdBst = calc_StdDev(loopout(:,9));

    % plot observed number in learning period
    cumnrf = (1:length(time_asf))';
    cumnr = (1:length(time_as))';
    p2 = plot(time_as,cumnr,'b','Linewidth',2,'Linestyle','--');

    % Plot observed events in forecast period from endpoint of modeled events in learning period
    vSel = time_asf >= max(time_as);
    vCumnr_forecast = cumnrf(vSel,:);
    vTime_forecast = time_asf(vSel,:);
    % Difference of modelled and observed number of events at time_as
    fDiff_timeas = mean(loopout(:,10))-cumnrf(length(time_as));
    vCumnr_forecast = vCumnr_forecast+fDiff_timeas;
    pf3 = plot(vTime_forecast, vCumnr_forecast,'m-.','Linewidth',2);

    xlim([0 max(time_asf)]);
    xlabel('Delay time [days]')
    ylabel('Cumulative number of aftershocks')

    % Plot standard deviation from bootstrap
    ps2=errorbar(max(time_asf),mean(loopout(:,9)),fStdBst,fStdBst);
    set(ps2,'Linewidth',2,'Color',[1 0 0])

    % calculate rate change
    nr_forecast = mean(loopout(:,9));
    nr_learn = mean(loopout(:,10));
    nummod = nr_forecast-nr_learn;
    l = time_asf <= time+timef & time_asf > time;
    numreal = sum(l);
    fRc_Bst = (numreal-nummod)/fStdBst;

    % Set line for learning period
    yy = get(gca,'ylim');
    plot([max(time_as) max(time_as)],[0 yy(2)],'k-.')
    string=['\sigma = ' num2str(fStdBst) '; RC = ' num2str(fRc_Bst) ];
    text(max(time_asf)*0.15,yy(2)*0.15,string,'FontSize',10);

    legend([p2 pf3 min(ps2)],'data','observed','\sigma (Bst)','location', 'NorthWest');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Spherical Harmonic Modeling and Analysis Toolkit (SPHARM-MAT) is a 3D
% shape modeling and analysis toolkit.
% It is a software package developed at Shenlab in Center for Neuroimaging,
% Indiana University (SpharmMat@gmail.com, http://www.iupui.edu/~shenlab/)
% It is available to the scientific community as copyright freeware
% under the terms of the GNU General Public Licence.
%
% Copyright 2009, 2010, ShenLab, Center for Neuroimaging, Indiana University
%
% This file is part of SPHARM-MAT.
%
% SPHARM-MAT 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.
%
% SPHARM-MAT 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 SPHARM-MAT. If not, see <http://www.gnu.org/licenses/>.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Goal: Convert NIfTI image to bim format
% Input:
%       inObjectName - File name of an input object with .nii or .hdr
%       extension
%
%       resampleFactor - Resampling factor to down- or up-sample a binary
%       object
%
% Output:
%       bim - a 3D matrix of binary voxels.
%       mins - lowest coordinate values in x, y, and z axis (1 x 3)
%
% 03/31/2001 - created by Li Shen
% Modified by Sungeun Kim (10-09-08)

function [bim, mins] = NIfTI2bim(inObjectName, resampleFactor)

ni = load_nii(inObjectName);
roi = ni.img;
clear ni;

DIM = size(roi);

if resampleFactor ~= 1   % Upsampling or downsampling
    roi = imresize(roi, resampleFactor, 'nearest');

    space = 1/resampleFactor;  % Interpolate binary volume along z axis
    if space < 1        % Up-sampling
        [xInt, yInt, zInt] = meshgrid(1:size(roi,1), 1:size(roi,2), 1:space:size(roi,3)+space);
    elseif space > 1    % Down-sampling
        [xInt, yInt, zInt] = meshgrid(1:size(roi,1), 1:size(roi,2), 1:space:size(roi,3));
    end
    bim = interp3(roi, xInt, yInt, zInt,'nearest');
else
    bim = roi;
end

% Make binary image
ind = find(bim>0); bim(ind) = 1;
ind = find(bim<1); bim(ind) = 0;

mins = [0 0 0];

return;


% Add path
addpath(genpath('../toolbox_graph/toolbox_graph/'));
addpath(genpath('../icp/'));
addpath(genpath(''));

% Load data
base_path = '';
scan_path = '';

base_name = '';
scan_name = '';
load([base_path base_name]);
base_ver = Ver_3d';
base_tri = Tri';

load([scan_path scan_name]);
scan_ver = Ver_3d';
scan_tri = Tri';

% Select face parts of scan
% base_min = min(base_ver(3, :))-0.015;
% [index, value] = find(scan_ver(3, :)>=base_min*10);
% scan_ver = scan_ver(:, value);
% test_tri = [];
% for i = 1:length(scan_tri)
% 	[judge, ind] = ismember(scan_tri(:, i), value);
% 	if judge(1) && judge(2) && judge(3) == 1
% 		test_tri = [test_tri, ind];
%     end
% end
% scan_tri = test_tri;
% a = scan_ver';
% c = double(scan_tri');
% b = base_ver';
% d = double(base_tri');
% save('output/select_part/points/scan_ver.txt', 'a', '-ascii');
% save('output/select_part/points/scan_tri.txt', 'c', '-ascii');
% save('output/select_part/points/base_ver.txt', 'b', '-ascii');
% save('output/select_part/points/base_tri.txt', 'd', '-ascii');

% Calculation normal
base_norm = NormDirection(base_ver, base_tri);
scan_norm = NormDirection(scan_ver, scan_tri);

% Save mesh struct
field1 = 'faces'; field2 = 'vertices'; field3 = 'normals';
base_s = struct(field1, base_tri', field2, base_ver', field3, base_norm');
scan_s = struct(field1, scan_tri', field2, scan_ver', field3, scan_norm');

% Specify that surface normals are available and can be used.
Options.useNormals = 1;

% Specify that the source deformations should be plotted.
Options.plot = 1;

% Specify that the landmarks term are available and can be used.
Options.landmarks = 0;

% Selected landmarks
ls_source = [];
ls_target = [];
% x = base_ver(1, :); y = base_ver(2, :); z = base_ver(3, :);
% X = scan_ver(1, :); Y = scan_ver(2, :); Z = scan_ver(3, :);
% figure;hold on;
% scatter3(x(:), y(:), z(:) ,'b.');
% scatter3(x(ls_source), y(ls_source), z(ls_source) ,'r*');
% scatter3(X(:), Y(:), Z(:) ,'y.');
% scatter3(X(ls_target), Y(ls_target), Z(ls_target) ,'ro');

% Perform non-rigid ICP
[pointsTransformed, X] = nricp_landmarks(apple_s, scan_s, Options, ls_source, ls_target);
% faces = double(base_s.faces);
% save('output/point_cloud/vertices.txt', 'pointsTransformed', '-ascii');
% save('output/point_cloud/faces.txt', 'faces', '-ascii');


% goes through all matlab files in the folder
% loads file
% saves as CSV file

base_folder_smartmeter = 'data/eco/smartmeter/';
base_folder_plugs = 'data/eco/plugs/';
target_folder_smartmeter = 'data/eco/smartmeter_csv/';
target_folder_plugs = 'data/eco/plugs_csv/';
process_smart_meter = 1;
process_plugs = 0;

% household = [ 2:6 ];
% plugs = [ 1:12 ];
household = [ 4 ];
plugs = [ 3, 8 ];

for h = household

    houseStr = num2str(h, '%02d');

	%% smart meter
    if process_smart_meter == 1
        source_folder = [base_folder_smartmeter, houseStr, '/'];
        target_folder = [target_folder_smartmeter, houseStr, '/'];
        if ~exist(target_folder, 'dir')
            mkdir(target_folder);
        end
        files = dir([source_folder, '*.mat']);
        for day = 1:size(files,1)
            fprintf('Processing smart meter household %s, day %d of %d\n', houseStr, day, size(files,1));
            filename = files(day,1).name;
            source_file = [source_folder, filename];
            vars = whos('-file',source_file);
            load(source_file);
            eval(['smartmeter_data=' vars.name ';']);
            eval(['clear ' vars.name ';']);
            data_to_write = [ ...
                smartmeter_data.powerallphases ...
                smartmeter_data.powerl1 ...
                smartmeter_data.powerl2 ...
                smartmeter_data.powerl3 ...
                smartmeter_data.currentneutral ...
                smartmeter_data.currentl1 ...
                smartmeter_data.currentl2 ...
                smartmeter_data.currentl3 ...
                smartmeter_data.voltagel1 ...
                smartmeter_data.voltagel2 ...
                smartmeter_data.voltagel3 ...
                smartmeter_data.phaseanglevoltagel2l1 ...
                smartmeter_data.phaseanglevoltagel3l1 ...
                smartmeter_data.phaseanglecurrentvoltagel1 ...
                smartmeter_data.phaseanglecurrentvoltagel2 ...
                smartmeter_data.phaseanglecurrentvoltagel3 ...
            ];
            dlmwrite([target_folder, filename(1:end-4), '.csv'], data_to_write, 'precision', 9);
        end
    end

    if process_plugs == 1
        for plug = plugs
            plugStr = num2str(plug, '%02d');
            plug_dir = [ base_folder_plugs, houseStr, '/', plugStr, '/'];
            if ~exist(plug_dir, 'dir')
                continue;
            end
            target_folder = [target_folder_plugs, houseStr, '/', plugStr, '/'];
            if ~exist(target_folder, 'dir')
                mkdir(target_folder)
            end
            files = dir([plug_dir, '*.mat']);
            for day = 1:size(files,1)
                fprintf('Processing plug %s for household %s, day %d of %d\n', plugStr, houseStr, day, size(files,1));
                filename = files(day,1).name;
                source_file = [plug_dir, filename];
                vars = whos('-file',source_file);
                load(source_file);
                eval(['plug_data=' vars.name ';']);
                eval(['clear ' vars.name ';']);
                data_to_write = plug_data.consumption;
                dlmwrite([target_folder, filename(1:end-4), '.csv'], data_to_write, 'precision', 9);
            end
        end
    end
end


function compute_print_results(masks, seg_obj, gt_fldr)
% You can use this function to compute accuracy scores for the segment
% proposals generated against some GT. This function computes the overlap
% for each segment to all GTs. Then prints the results and stores them. The
% results are stored at the path defined by scores_dirpath defined in
% internal_params.m. The file stores some collated scores including
% overlap, and covering (collated_scores). It also stores the number of
% segments generated by parametric min-cut, and the number remaining after
% filtration (init_num_segs and final_num_segs). Also overlaps of all
% segments against the GT is stored (Q). The function finally displays the
% results in a pretty table :)
%
% For instance, if you are working with PASCAL VOC (e.g. stored at
%  ~/pascalvoc12), you can do the following:
%       [masks, seg_obj, total_time] = ...
%           rigor_obj_segments('~/pascalvoc12/JPEGImages/2007_000033.jpg');
%       compute_print_results(masks, seg_obj, ...
%           '~/pascalvoc12/SegmentationObject');
%
% You can also run compute_print_results.m by loading the data saved to
% disk by rigor_obj_segments.m, and supplying masks, and seg_obj to the
% function.
%
% @authors:     Ahmad Humayun
% @contact:     ahumayun@cc.gatech.edu
% @affiliation: Georgia Institute of Technology
% @date:        Fall 2013 - Summer 2014

    img_name = seg_obj.input_info.img_name;

    % compute the quality of each segment given the GT
    [Q, collated_scores] = SvmSegm_segment_quality(img_name, gt_fldr, ...
                                                   masks, 'overlap');

    % collect scores for all segments
    overlap_scores = [Q.q];
    tp = cell2mat(arrayfun(@(q) q.extra_info.tp, Q, 'UniformOutput',false));
    fp = cell2mat(arrayfun(@(q) q.extra_info.fp, Q, 'UniformOutput',false));
    fn = cell2mat(arrayfun(@(q) q.extra_info.fn, Q, 'UniformOutput',false));

    num_gt = numel(Q);
    num_sgmntrs = numel(seg_obj.segm_params.graph_methods);

    % # of segments returned by each segmenter and the remaining number
    % after the filteration step
    init_num_segs = seg_obj.num_segs.init_segs;
    final_num_segs = seg_obj.num_segs.after_clustering_FINAL;

    % get the name of each segmenter
    sgmntr_names = seg_obj.segm_params.graph_methods;
    sgmntr_names = cellfun(@(s) s(1:strfind(s, 'Graph')-1), ...
                           sgmntr_names, 'UniformOutput',false);

    % compute the scores over different segmenters individually
    start_idx = 1;
    avg_best_overlap_segmenters = zeros(1, num_sgmntrs);
    collective_overlap_segmenters = zeros(1, num_sgmntrs);
    best_seg_overlap_segmenters = zeros(num_gt, num_sgmntrs);
    best_seg_idx_segmenters = zeros(num_gt, num_sgmntrs);
    % iterate over each segmenter
    for sgmntr_idx = 1:num_sgmntrs
        % get the scores for just the current segmenter
        segmenter_overlap = ...
            overlap_scores(start_idx:start_idx + ...
                                     final_num_segs(sgmntr_idx)-1,:);
        % compute the best scores for each GT for the current segmenter
        [best_seg_overlap, best_seg_idx] = max(segmenter_overlap);
        avg_best_overlap_segmenters(sgmntr_idx) = mean(best_seg_overlap);
        best_seg_overlap_segmenters(:,sgmntr_idx) = best_seg_overlap;
        best_seg_idx_segmenters(:,sgmntr_idx) = ...
                                            start_idx + best_seg_idx - 1;

        % compute the collective overlap for all GT's for the current
        % segmenter
        best_ind = sub2ind(size(tp), ...
                           best_seg_idx_segmenters(:,sgmntr_idx)', ...
                           1:num_gt);
        total_tp = tp(best_ind);
        total_union = fp(best_ind) + fn(best_ind) + tp(best_ind);
        collective_overlap_segmenters(sgmntr_idx) = ...
            sum(total_tp) / sum(total_union);

        start_idx = start_idx + final_num_segs(sgmntr_idx);
    end

    % store the scores computed
    collated_scores.collective_overlap_segmenters = ...
                                            collective_overlap_segmenters;
    collated_scores.avg_best_overlap_segmenters = ...
                                            avg_best_overlap_segmenters;
    collated_scores.best_seg_overlap_segmenters = ...
                                            best_seg_overlap_segmenters;
    collated_scores.best_seg_idx_segmenters = best_seg_idx_segmenters;

    % print the table of scores
    print_scores_table([Q.gt_seg_szs], sgmntr_names, init_num_segs, ...
                       final_num_segs, collated_scores);

    % save the scores
    scores_filepath = seg_obj.return_scores_filepath();

    dir_name = fileparts(scores_filepath);
    if(~exist(dir_name, 'dir'))
        mkdir(dir_name);
    end
    save(scores_filepath, 'Q', 'sgmntr_names', 'init_num_segs', ...
                          'final_num_segs', 'collated_scores');

    % print a summary line, useful for noting down results/performance
    print_summary(seg_obj, collated_scores);
end

function print_scores_table(gt_seg_szs, sgmntr_names, init_num_segs, ...
                            final_num_segs, cscores)
    % get the row headers
    row_txts = arrayfun(@(i,gt_sz) sprintf('GT %2d (%5d)', i, gt_sz), ...
                        1:length(gt_seg_szs), gt_seg_szs, ...
                        'UniformOutput', false);
    row_txts = [{'', 'Init. # Segs', 'Final # Segs', 'Avg. Best Overlap', ...
                'Collective Overlap'}, row_txts];

    % get the column headers
    col_txts = [{''}, sgmntr_names, {'Overall'}];

    % compute the width based on the header lengths
    first_col_width = max(cellfun(@length, row_txts)) + 1;
    other_col_width = max(cellfun(@length, col_txts)) + 1;

    % create a divider line
    total_width = 2 + first_col_width + ...
                  (length(col_txts) - 1)*(other_col_width + 1);
    divider_line = [repmat('-', 1, total_width), '\n'];

    fprintf(divider_line);

    % printf first column
    print_line(row_txts{1}, col_txts(2:end), 's', ...
               first_col_width, other_col_width, length(sgmntr_names)+1);

    fprintf(divider_line);

    % print initial number of segments
    print_line(row_txts{2}, [init_num_segs, sum(init_num_segs)], 'd', ...
               first_col_width, other_col_width);

    % print final number of segments
    print_line(row_txts{3}, [final_num_segs, sum(final_num_segs)], 'd', ...
               first_col_width, other_col_width, length(sgmntr_names)+1);

    fprintf(divider_line);

    % print average best overlap
    print_line(row_txts{4}, [cscores.avg_best_overlap_segmenters, ...
                             cscores.avg_best_overlap], '.4f', ...
               first_col_width, other_col_width, length(sgmntr_names)+1);

    % print collective best overlap
    print_line(row_txts{5}, [cscores.collective_overlap_segmenters, ...
                             cscores.collective_overlap], '.4f', ...
               first_col_width, other_col_width);

    fprintf(divider_line);

    % print stats for each GT
    for idx = 1:size(cscores.best_seg_overlap_segmenters,1)
        [best_val, best_idx] = ...
            max(cscores.best_seg_overlap_segmenters(idx,:));
        print_line(row_txts{5+idx}, ...
                   [cscores.best_seg_overlap_segmenters(idx,:), ...
                    best_val], '.4f', ...
                   first_col_width, other_col_width, best_idx);
    end

    fprintf(divider_line);
end

function print_line(header, vals, spec, first_col_width, ...
                    other_col_width, strong_idx)
    % controls whether a certain value is going to be bold
    strong = false(1, length(vals));
    if exist('strong_idx','var')
        strong(strong_idx) = true;
    end
    strong_o = repmat({'<strong>'}, 1, length(vals));
    strong_e = repmat({'</strong>'}, 1, length(vals));
    strong_o(~strong) = {''};
    strong_e(~strong) = {''};

    % print header
    eval(['fprintf(''|%-', num2str(first_col_width), 's'', header)']);

    if spec == 's'
        % in case of string
        temp = [strong_o; vals; strong_e];
    else
        temp = [strong_o; num2cell(vals); strong_e];
    end
    eval(['fprintf(''|%s%-', num2str(other_col_width), spec '%s'', temp{:})']);

    fprintf('|\n');
end

function print_summary(seg_obj, cscores)
    for idx = 1:numel(seg_obj.segm_params.graph_methods)
        fprintf(1, '% 4d (% 4d)', ...
                seg_obj.num_segs.init_segs(idx), ...
                seg_obj.num_segs.after_clustering_FINAL(idx));
        if idx < numel(seg_obj.segm_params.graph_methods)
            fprintf(1, ', ');
        else
            fprintf(1, ' - ');
        end
    end
    best_gt_scores = max(cscores.best_seg_overlap_segmenters,[],2);
    for idx = 1:length(best_gt_scores)
        fprintf(1, '%.4f', best_gt_scores(idx));
        if idx < length(best_gt_scores)
            fprintf(1, ' + ');
        else
            fprintf(1, ' => ');
        end
    end
    for idx = 1:length(cscores.avg_best_overlap_segmenters)
        fprintf(1, '%.4f', cscores.avg_best_overlap_segmenters(idx));
        if idx < length(cscores.avg_best_overlap_segmenters)
            fprintf(1, ' + ');
        else
            fprintf(1, ' => ');
        end
    end
    fprintf('%.4f\n', cscores.avg_best_overlap);
end


function [engine, loglik] = enter_evidence(engine, evidence, varargin)
% ENTER_EVIDENCE Add the specified evidence to the network (jtree)
% [engine, loglik] = enter_evidence(engine, evidence, ...)
%
% evidence{i} = [] if X(i) is hidden, and otherwise contains its observed value (scalar or column vector).
%
% The following optional arguments can be specified in the form of name/value pairs:
% [default value in brackets]
%
% soft    - a cell array of soft/virtual evidence;
%           soft{i} is a prob. distrib. over i's values, or [] [ cell(1,N) ]
%
% e.g., engine = enter_evidence(engine, ev, 'soft', soft_ev)

bnet = bnet_from_engine(engine);
ns = bnet.node_sizes(:);
N = length(bnet.dag);

engine.evidence = evidence; % store this for marginal_nodes with add_ev option
engine.maximize = 0;

% set default params
exclude = [];
soft_evidence = cell(1,N);

% parse optional params
args = varargin;
nargs = length(args);
for i=1:2:nargs
  switch args{i},
   case 'soft',    soft_evidence = args{i+1};
   otherwise,
    error(['invalid argument name ' args{i}]);
  end
end

onodes = find(~isemptycell(evidence));
hnodes = find(isemptycell(evidence));
pot_type = determine_pot_type(bnet, onodes);
 if strcmp(pot_type, 'cg')
  check_for_cd_arcs(onodes, bnet.cnodes, bnet.dag);
end

% Evaluate CPDs with evidence, and convert to potentials
pot = cell(1, N);
for n=1:N
  fam = family(bnet.dag, n);
  e = bnet.equiv_class(n);
  if isempty(bnet.CPD{e})
    error(['must define CPD ' num2str(e)])
  else
    pot{n} = convert_to_pot(bnet.CPD{e}, pot_type, fam(:), evidence);
  end
end
clqs = engine.clq_ass_to_node(1:N);

% soft evidence
soft_nodes = find(~isemptycell(soft_evidence));
S = length(soft_nodes);
if S > 0
  assert(pot_type == 'd');
  assert(mysubset(soft_nodes, bnet.dnodes));
end
for i=1:S
  n = soft_nodes(i);
  pot{end+1} = dpot(n, ns(n), soft_evidence{n});
end
clqs = [clqs engine.clq_ass_to_node(soft_nodes)];

[clpot, seppot] = init_pot(engine, clqs, pot, pot_type, onodes);
[clpot, seppot] = collect_evidence(engine, clpot, seppot);
[clpot, seppot] = distribute_evidence(engine, clpot, seppot);

C = length(clpot);
ll = zeros(1, C);
for i=1:C
  [clpot{i}, ll(i)] = normalize_pot(clpot{i});
end
loglik = ll(1); % we can extract the likelihood from any clique

engine.clpot = clpot;


function vw= loadCorAnal(vw, corAnalFile, computeIfNeeded)
% Loads corAnal (coherence analysis) file and fills co, amp, and ph slots
% in the view structure.
%
% vw = loadCorAnal(vw, [corAnalFile], [computeIfNeeded=1])
%
% If you change this function make parallel changes in:
%   loadCorAnal, loadResStdMap, loadStdMap, loadMeanMap
%
% corAnalFile: path to the corAnal file. If it is empty, assumes
%			   it is 'corAnal.mat' in the view's dataDir.
%			   If it's one of 'ask' or 'dialog', pops up a dialog to let
%			   the user select.
%
% computeIfNeeded: if 1, and the corAnalFile is not found, will compute it
%			   for all scans in the view's current data type. Otherwise,
%			   just warns the user and returns an unmodified view.
%			   [Default: 1]
%
% djh, 1/9/98
% dbr, 6/23/99  Modified to use fullfile for NT/Unix platform
%               compatibility.
% djh, 2/2001, mrLoadRet 3.0
% create the full corAnalFile if dataType not original
% sod, 7/2005,  Added option to look for CorAnal file (ask param).
% will be used from fileMenu but other calls will remain the same.
% ras, 7/2007,  added computeIfNeeded argument.
if notDefined('vw'),		vw = getCurView;		end
if notDefined('corAnalFile')
	corAnalFile = fullfile(dataDir(vw), 'corAnal.mat');
end

if notDefined('computeIfNeeded'), computeIfNeeded = 0; end % Making this ==1 breaks a bunch of stuff in the Flat view as far as I can tell ARW 080807
if notDefined('loadMap'), loadMap=0;    end

if ismember(lower(corAnalFile), {'ask' 'dialog' 'select'})
	corAnalFile = getPathStrDialog(dataDir(vw), ...
					['Choose CorAnal map file name'],['*.mat']);
end

if ~exist(corAnalFile,'file')
     corAnalFile = fullfile(dataDir(vw), corAnalFile);
end

verbose = prefsVerboseCheck;

if ~exist(corAnalFile,'file')
	msg = sprintf('corAnal file %s not found. \n', corAnalFile);

	if computeIfNeeded==1
		% compute it
		if verbose > 1,
			fprintf('[%s]: %s\n', mfilename, msg);
			disp('Computing Coherence Analysis ...')
		end
		vw = computeCorAnal(vw, 0);
	else
		% % just warn the user
		% warning(msg);
	end

	return;
end

if verbose > 0
	fprintf('[%s]: Loading from %s ... ', mfilename, corAnalFile);
end

load(corAnalFile); % loads co, amp, ph

if verbose > 0
	fprintf('done.\n');
end

% check that the corAnal fields are the appropriate size
checkSize(vw, co);
checkSize(vw, amp);
checkSize(vw, ph);

% assign to view
vw.co = co;
vw.amp = amp;
vw.ph = ph;
if notDefined('map')~=1, vw.map=map; end
return;