function [opts,imdb] = DeepInstCoseg(imdb, varargin)
opts.GPUID = 1;
opts.DatasetDir = [];
opts.DatasetName = [];
opts.expDir = [];
opts.ClassName = [];
opts.Resolution = 448;
opts.Lambda = [1 1];
opts.learningRate = 0.000001 * ones(1, 20);
opts.InitModelPath = [];
opts.RootDir = [];
opts.SalDir = [];
opts.solver = @adam;
opts.InitNetPath = [];
opts.RemoveLayerIndex = 34;
[opts, varargin] = vl_argparse(opts, varargin) ;
assert(~isempty(opts.SalDir), 'Provide Sal Data!!!')
if isempty(opts.expDir)
    opts.expDir = [opts.RootDir opts.DatasetName '/' opts.ClassName '/'];
end

if isempty(opts.InitModelPath)
    opts.InitModelPath = [opts.RootDir 'models/'];
end
New_mkdir(opts.expDir);
New_mkdir(opts.InitModelPath);
opts.InitModelName = [opts.InitModelPath '/InitModel.mat'];
opts.ImageDir = [opts.DatasetDir '/' opts.DatasetName '/Image/' opts.ClassName];
opts.ClassifierPath = [opts.RootDir '/models/imagenet-vgg-verydeep-16.mat'];

% training options (SGD)
opts.train.numSubBatches = 1;
opts.train.batchSize = 6;
opts.train.continue = false ;
opts.train.gpus = opts.GPUID;
opts.train.expDir = opts.expDir ;
opts.train.learningRate = opts.learningRate;
opts.train.SaveEachEpoch = false;
opts.train.numEpochs = numel(opts.train.learningRate);
opts.train.derOutputs = {'SalLoss', 1, 'CopeakLoss', opts.Lambda(1), 'AffinityLoss', opts.Lambda(2)};
% the balanced weights presented in Eq. (1)

opts.train.solver = opts.solver;
opts = vl_argparse(opts, varargin) ;

IsModelExist = exist([opts.expDir '/' sprintf('net-epoch-%d.mat', numel(opts.train.learningRate))], 'file');

if ~IsModelExist || nargout == 2
    if isempty(imdb)
        imdb = SetupTrainDataset(opts);
    end
    if length(imdb.images.set) == 1
        return
    end
    train = find(imdb.images.set == 1);
    val = train;

    if IsModelExist
        return;
    end
    if ~exist(opts.InitModelName, 'file')
        Net = ModifyNet(opts);
        Net = Net.saveobj();
        save(opts.InitModelName, '-struct', 'Net', '-v7.3');
    end
    Net = load(opts.InitModelName);
    Net = dagnn.DagNN.loadobj(Net);
    AllImageIndex = train;
    AvgImage = imresize(single(Net.meta.normalization.averageImage), [opts.Resolution opts.Resolution]);
    FunHand = @(imdb,batch)getBatch(imdb, batch, AvgImage, AllImageIndex);
    if length(opts.Lambda) == 3
        Sel = cellfun(@(x) isa(x,'dagnn.AffinityLoss'), {Net.layers.block});
        Net.layers(Sel).block.Alpha = opts.Lambda(end);
    end
    save([opts.expDir '/opts.mat'], 'opts');
    cnn_train_dag(Net, imdb, FunHand, ...
        opts.train, ....
        'train', train, ...
        'val', val, ...
        opts.train);
end
end

function net = ModifyNet(opts)
if isempty(opts.InitNetPath)
    [net, FeatOutput] = fcnInitializeSaliencyModel('sourceModelPath', opts.ClassifierPath, 'RemoveLayerIndex', opts.RemoveLayerIndex) ;
    Sel = cellfun(@(x) isa(x,'dagnn.Loss'), {net.layers.block}) | cellfun(@(x) isa(x,'dagnn.DropOut'), {net.layers.block});
    net.removeLayer({net.layers(Sel).name})
    net.renameVar('prediction', 'SalScore');
    net.addLayer('SigmoidNormalization', dagnn.Sigmoid(), 'SalScore', 'SalMap');
    net.addLayer('SalLoss', dagnn.WeightEuclidLoss, {'SalMap', 'SalImg'}, 'SalLoss');
    net.addLayer('SigmoidNormalization_2', dagnn.Sigmoid(), 'SmallScoreMap', 'SmallSalMap');
    net.rebuild();
    InputStr = 'SmallScoreMap';
else
    net = load(opts.InitNetPath);
    net = dagnn.DagNN.loadobj(net.net);
end
Sel = cellfun(@(x) isa(x,'dagnn.PlanePeakGen'), {net.layers.block});
if all(~Sel)
    net.addLayer('PlanePeakMapsGen', ...
        dagnn.PlanePeakGen(), InputStr, {'PosPlainPeakValues'});
end
net.addLayer('FeatNorm', dagnn.LPNormalization(), FeatOutput, 'FeatNorm');

net.addLayer('SelfFeatCorrelation', dagnn.CorrelateCross, 'FeatNorm', 'PixelAffinity');
net.addLayer('SelfSalCorrelation', dagnn.CorrelateCross, 'SmallSalMap', 'SalAffinity');
net.addLayer('SelfSalDiff', dagnn.SalDiffCross(), 'SmallSalMap', 'SalDiff');
net.addLayer('WeightPixelAffinityLoss', dagnn.AffinityLoss, {'SalAffinity', 'PixelAffinity', 'SalDiff'}, 'AffinityLoss');

net.addLayer('WeightFeatNorm', dagnn.FeatMultication(), {'FeatNorm', 'SmallSalMap'}, 'WeightFeatNorm');
net.addLayer('FeatCorrelation', dagnn.Correlate, {'WeightFeatNorm'}, 'FourDTensor');
net.addLayer('CoPeakGen', dagnn.CoPeakGen, {'FourDTensor'}, 'CoPeakValues');
net.addLayer('CopeakLoss', dagnn.CopeakLoss, {'CoPeakValues'}, 'CopeakLoss');
net.rebuild();
end

function y = getBatch(imdb, images, AvgImage, AllImageIndex)
if mod(length(images), 2) == 1
    ImageIndex = find(~ismember(AllImageIndex, images));
    RandomIndex= randperm(length(AllImageIndex) - length(images));
    images = [images ImageIndex(RandomIndex(1))];
end
AvgImage = gpuArray(AvgImage);
ImageList = bsxfun(@minus, single(gpuArray(imdb.images.images(:,:,:,images))), AvgImage);
SalImgList = im2single(gpuArray(imdb.images.SalImg(:,:,:,images)));
y = {'input', ImageList, 'SalImg', SalImgList};
end

function imdb = SetupTrainDataset(opts)
ImageList = dir([opts.ImageDir '/*.jpg']);
SalDir = [opts.SalDir '/' opts.ClassName '/'];
NumImages = length(ImageList);
imdb.images.images = zeros([opts.Resolution opts.Resolution 3 NumImages], 'uint8');
imdb.images.SalImg = zeros([opts.Resolution opts.Resolution 1 NumImages], 'uint8');
for i = 1:NumImages
    disp(['Reading Image: ' num2str(i)])
    Image = imread([opts.ImageDir '/' ImageList(i).name]);
    if size(Image, 3) == 1
        Image = repmat(Image, [1 1 3]);
    end
    imdb.images.images(:,:,:,i) = imresize(Image, [opts.Resolution opts.Resolution]);
    [~,ImgName,~] = fileparts(ImageList(i).name);
    SaImg = load([SalDir ImgName '.mat']);
    imdb.images.SalImg(:,:,:,i) = imresize(SaImg.SalMap, [opts.Resolution opts.Resolution]);

end
imdb.images.set = true(1, NumImages);
imdb.images.name = {ImageList.name};
end

function [net, FeatOutput] = fcnInitializeSaliencyModel(varargin)
NumClasses = 1;
opts.sourceModelUrl = 'http://www.vlfeat.org/matconvnet/models/imagenet-vgg-verydeep-16.mat' ;
opts.sourceModelPath = 'data/models/imagenet-vgg-verydeep-16.mat' ;
opts.RemoveLayerIndex = [];
opts = vl_argparse(opts, varargin) ;

if ~exist(opts.sourceModelPath,'file')
  fprintf('%s: downloading %s\n', opts.sourceModelUrl) ;
  mkdir(fileparts(opts.sourceModelPath)) ;
  urlwrite('http://www.vlfeat.org/matconvnet/models/imagenet-vgg-verydeep-16.mat', opts.sourceModelPath) ;
end
net = vl_simplenn_tidy(load(opts.sourceModelPath)) ;

net.meta.cudnnOpts = {'cudnnworkspacelimit', 512 * 1024^3} ;

if ~isempty(opts.RemoveLayerIndex)
    net.layers = net.layers(1:opts.RemoveLayerIndex-1);
end

net = dagnn.DagNN.fromSimpleNN(net, 'canonicalNames', true) ;

net.layers(5).block.pad = [0 1 0 1] ;
net.layers(10).block.pad = [0 1 0 1] ;
net.layers(17).block.pad = [0 1 0 1] ;
net.layers(24).block.pad = [0 1 0 1] ;
if opts.RemoveLayerIndex > 31
    net.layers(31).block.pad = [0 1 0 1] ;
end
if opts.RemoveLayerIndex > 32
    net.layers(32).block.pad = [3 3 3 3] ;
end

% remove the last layers to reduce the model size
switch opts.RemoveLayerIndex
    case 32
        InputDim = 512;
        FeatOutput = 'x31';
    case 34
        InputDim = 4096;
        FeatOutput = 'x33';
end
for i = 1:numel(net.layers)
  if (isa(net.layers(i).block, 'dagnn.Conv') && net.layers(i).block.hasBias)
    filt = net.getParamIndex(net.layers(i).params{1}) ;
    bias = net.getParamIndex(net.layers(i).params{2}) ;
    net.params(bias).learningRate = 2 * net.params(filt).learningRate ;
  end
end

net.addLayer('Conv1X1', dagnn.Conv('size', [1 1 InputDim 1]), net.layers(end).outputs, 'SmallScoreMap', {'Conv1X1_f', 'Conv1X1_b'});
f = net.getParamIndex('Conv1X1_f') ;
net.params(f).value = zeros(1, 1, InputDim, 1, 'single');
net.params(f).learningRate = 1;
net.params(f).weightDecay = 1 ;
f = net.getParamIndex('Conv1X1_b') ;
net.params(f).value = zeros(1, 1, 1, 1, 'single');
net.params(f).learningRate = 2;
net.params(f).weightDecay = 1 ;

upsample = 32;
filters = single(bilinear_u(upsample * 2, NumClasses, NumClasses)) ;
net.addLayer('deconv32', ...
  dagnn.ConvTranspose(...
  'size', size(filters), ...
  'upsample', upsample, ...
  'crop', [upsample/2 upsample/2 upsample/2 upsample/2], ...
  'numGroups', NumClasses, ...
  'hasBias', false, ...
    'opts', net.meta.cudnnOpts), ...
  'SmallScoreMap', 'prediction', 'deconvf') ;

f = net.getParamIndex('deconvf') ;
net.params(f).value = filters ;
net.params(f).learningRate = 0 ;
net.params(f).weightDecay = 1 ;
net.vars(net.getVarIndex('prediction')).precious = 1 ;

net.addLayer('objective', ...
  dagnn.Loss('loss', 'softmaxlog'), ...
  {'prediction', 'label'}, 'objective') ;

net.addLayer('accuracy', ...
   dagnn.Loss(), ...
  {'prediction', 'label'}, 'accuracy') ;
end


function net = load_cnn(fparams, im_size)

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

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

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

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

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

net.info = vl_simplenn_display(net);
end


function [result, M] = ft_warp_optim(input, target, method)

% FT_WARP_OPTIM determine intermediate positions using warping (deformation)
% the input cloud of points is warped to match the target.
% The strategy is to start with simpelest linear warp, followed by a more
% elaborate linear warp, which then is followed by the nonlinear warps up
% to the desired order.
%
% [result, M] = ft_warp_pnt(input, target, method)
%     input          contains the Nx3 measured 3D positions
%     target         contains the Nx3 template 3D positions
%     method         should be any of
%                     'rigidbody'
%                     'globalrescale'
%                     'traditional' (default)
%                     'nonlin1'
%                     'nonlin2'
%                     'nonlin3'
%                     'nonlin4'
%                     'nonlin5'
%
% The default warping method is a traditional linear warp with individual
% rescaling in each dimension. Optionally you can select a nonlinear warp
% of the 1st (affine) up to the 5th order.
%
% When available, this function will use the MATLAB optimization toolbox.
%
% See also FT_WARP_APPLY, FT_WARP_ERRROR

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

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

% this can be used for printing detailled user feedback
fb = false;

if nargin<3
  method='traditional';
end

pos1 = input;
pos2 = target;

% The ft_warp_error function might be located in the private subdirectory of
% FieldTrip, i.e. only available to functions in the FieldTrip toolbox.
% The following line ensures that the function can also be found by the
% feval that is executed by the optimalization toolbox.
errorfun = str2func('ft_warp_error');

% determine whether the MATLAB Optimization toolbox is available and can be used
if ft_hastoolbox('optim')
  optimfun = @fminunc;
else
  optimfun = @fminsearch;
end

% set the options for the minimalisation routine
if isequal(optimfun,  @fminunc)
  options  = optimset('fminunc');
  options  = optimset(options, 'Display', 'off');
  options  = optimset(options, 'MaxIter', 1500);
  % options  = optimset(options, 'MaxFunEvals', '1000*numberOfVariables');
  options  = optimset(options, 'TolFun', 1e-4);
  options  = optimset(options, 'LargeScale', 'off');
elseif isequal(optimfun, @fminsearch)
  options  = optimset('fminsearch');
  options  = optimset(options, 'Display', 'off');
  options  = optimset(options, 'MaxIter', 4500);
else
  ft_warning('unknown optimization function "%s", using default parameters', func2str(optimfun));
end

if fb; fprintf('distance = %f\n', errorfun([0 0 0 0 0 0], pos1, pos2, 'rigidbody')); end

if isempty(method)
  ft_error('incorrect warping method specified');
end

% the warp is done in steps, starting simple and progressively getting more complex
level = find(strcmp(method, {
  'rigidbody'         % 1
  'globalrescale'     % 2
  'traditional'       % 3
  'nonlin1'           % 4
  'nonlin2'           % 5
  'nonlin3'           % 6
  'nonlin4'           % 7
  'nonlin5'           % 8
  }));

if isempty(level)
  ft_error('incorrect warping method specified');
end

if level>=1
  % do a rigid-body transformation (6 parameters)
  if fb; disp('rigidbody...'); end
  ri = [0 0 0 0 0 0];
  rf = optimfun(errorfun, ri, options, pos1, pos2, 'rigidbody');
  if fb; fprintf('distance = %f\n', errorfun(rf, pos1, pos2, 'rigidbody')); end
end

if level>=2
  % do a rigid-body + global rescaling transformation (7 parameters)
  if fb; disp('rigidbody + global rescaling...'); end
  gi = [rf 1];
  gf = optimfun(errorfun, gi, options, pos1, pos2, 'globalrescale');
  if fb; fprintf('distance = %f\n', errorfun(gf, pos1, pos2, 'globalrescale')); end
end

if level>=3
  % do a rigid-body + individual rescaling transformation (9 parameters)
  if fb; disp('rigidbody + individual rescaling...'); end
  ti = [gf gf(7) gf(7)];
  tf = optimfun(errorfun, ti, options, pos1, pos2, 'traditional');
  if fb; fprintf('distance = %f\n', errorfun(tf, pos1, pos2, 'traditional')); end
end

if level>=4
  % do a first order nonlinear transformation,
  if fb; disp('1st order nonlinear...'); end
  e1i = traditional(tf);
  e1i = [e1i(1:3,4) e1i(1:3,1:3)];  % reshuffle from homogenous into nonlinear
  e1f = optimfun(errorfun, e1i, options, pos1, pos2);
  if fb; fprintf('distance = %f\n', errorfun(e1f, pos1, pos2, 'nonlinear')); end
end

if level>=5
  % do a second order nonlinear transformation,
  if fb; disp('2nd order nonlinear...'); end
  e2i = [e1f zeros(3,6)];
  e2f = optimfun(errorfun, e2i, options, pos1, pos2);
  if fb; fprintf('distance = %f\n', errorfun(e2f, pos1, pos2, 'nonlinear')); end
end

if level>=6
  % do a third order nonlinear transformation,
  if fb; disp('3rd order nonlinear...'); end
  e3i = [e2f zeros(3,10)];
  e3f = optimfun(errorfun, e3i, options, pos1, pos2);
  if fb; fprintf('distance = %f\n', errorfun(e3f, pos1, pos2, 'nonlinear')); end
end

if level>=7
  % do a fourth order nonlinear transformation,
  if fb; disp('4th order nonlinear...'); end
  e4i = [e3f zeros(3,15)];
  e4f = optimfun(errorfun, e4i, options, pos1, pos2);
  if fb; fprintf('distance = %f\n', errorfun(e4f, pos1, pos2, 'nonlinear')); end
end

if level>=8
  % do a fifth order nonlinear transformation,
  if fb; disp('5th order nonlinear...'); end
  e5i = [e4f zeros(3,21)];
  e5f = optimfun(errorfun, e5i, options, pos1, pos2);
  if fb; fprintf('distance = %f\n', errorfun(e5f, pos1, pos2, 'nonlinear')); end
end

% return the estimated parameters of the highest level warp
% and compute the warped points
switch level
  case 1
    M = rf;
  case 2
    M = gf;
  case 3
    M = tf;
  case 4
    M = e1f;
  case 5
    M = e2f;
  case 6
    M = e3f;
  case 7
    M = e4f;
  case 8
    M = e5f;
end
result = ft_warp_apply(M, input, method);


function [ix] = spm_fieldindices(X,varargin)
% Returns the indices of fields in a structure (and vice versa)
% FORMAT [i]     = spm_fieldindices(X,field1,field2,...)
% FORMAT [field] = spm_fieldindices(X,i)
%
% X         - structure
% field1,.. - fields
%
% i         - vector of indices or fieldname{s}
%
% Note: Fields are returned in column order of X, regardless of the order
% of fields specified in the input.
%
%__________________________________________________________________________
% Copyright (C) 2010-2013 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_fieldindices.m 7031 2017-02-27 19:46:48Z karl $

% if varargin is a vector simply return fieldnames
%--------------------------------------------------------------------------
if isnumeric(varargin{1})
    if numel(varargin{1}) > 1
        for j = 1:length(varargin{1})
            ix{j} = spm_fieldindices(X,varargin{1}(j));
        end
        return
    end
end

% create structure of zeros
%--------------------------------------------------------------------------
X0    = spm_zeros(X);
ix    = spm_vec(X0);

% and add one to specified fields
%--------------------------------------------------------------------------
for i = 1:length(varargin)

    if ischar(varargin{i})

        field = varargin{i};
        x  = X0;
        try
            % field is a field name
            %--------------------------------------------------------------
            f  = x.(field);
            f  = spm_unvec(spm_vec(f) + 1,f);
            x.(field) = f;
            ix = ix + spm_vec(x);

        catch
            try
                % field is an expression
                %----------------------------------------------------------
                eval(['x.' field ' = x.' field ' + 1;']);
                ix = ix + spm_vec(x);
            end
        end

        % or return the name of the field
        %----------------------------------------------------------------------
    elseif isnumeric(varargin{i})

        ind    = varargin{i};
        x      = ix;
        x(ind) = 1;
        x      = spm_unvec(x,X);
        name   = fieldnames(x);

        for j = 1:length(name)
            if any(spm_vec(x.(name{j})))
                if iscell(x.(name{j}))
                    for k = 1:numel(x.(name{j}))
                        xv = spm_vec(x.(name{j}){k});
                        if any(xv)
                            if isstruct(x.(name{j}){k})
                                s     = spm_fieldindices(x.(name{j}){k},find(xv));
                                ix    = sprintf('%s{%i}.%s',name{j},k,s);
                            else
                                [p,q] = find(x.(name{j}){k});
                                ix    = sprintf('%s{%i}(%i,%i)',name{j},k,p,q);
                            end
                            return
                        end
                    end
                elseif isnumeric(x.(name{j}))
                    s   = size(x.(name{j}));
                    if numel(s) < 3
                        if min(s) == 1
                            p    = find(x.(name{j}));
                            ix   = sprintf('%s(%i)',name{j},p);
                            return
                        else
                            [p,q] = find(x.(name{j}));
                            ix    = sprintf('%s(%i,%i)',name{j},p,q);
                            return
                        end
                    else
                        [p,q,r] = ind2sub(s,find(x.(name{j})));
                        ix      = sprintf('%s(%i,%i,%i)',name{j},p,q,r);
                        return
                    end
                end
            end
        end
    end
end

% find indices
%--------------------------------------------------------------------------
ix = find(ix);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%                                                                  %%%%%
%%%%    IEEE PES Power Grid Library - Optimal Power Flow - v21.07     %%%%%
%%%%          (https://github.com/power-grid-lib/pglib-opf)           %%%%%
%%%%             Benchmark Group - Active Power Increase              %%%%%
%%%%                         29 - July - 2021                         %%%%%
%%%%                                                                  %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mpc = pglib_opf_case30_ieee__api
mpc.version = '2';
mpc.baseMVA = 100.0;

%% bus data
%	bus_i	type	Pd	Qd	Gs	Bs	area	Vm	Va	baseKV	zone	Vmax	Vmin
mpc.bus = [
	1	 3	 0.0	 0.0	 0.0	 0.0	 1	    1.00000	    0.00000	 132.0	 1	    1.06000	    0.94000;
	2	 2	 36.08	 12.70	 0.0	 0.0	 1	    1.00000	    0.00000	 132.0	 1	    1.06000	    0.94000;
	3	 1	 3.99	 1.20	 0.0	 0.0	 1	    1.00000	    0.00000	 132.0	 1	    1.06000	    0.94000;
	4	 1	 12.64	 1.60	 0.0	 0.0	 1	    1.00000	    0.00000	 132.0	 1	    1.06000	    0.94000;
	5	 2	 156.64	 19.00	 0.0	 0.0	 1	    1.00000	    0.00000	 132.0	 1	    1.06000	    0.94000;
	6	 1	 0.0	 0.0	 0.0	 0.0	 1	    1.00000	    0.00000	 132.0	 1	    1.06000	    0.94000;
	7	 1	 37.91	 10.90	 0.0	 0.0	 1	    1.00000	    0.00000	 132.0	 1	    1.06000	    0.94000;
	8	 2	 49.89	 30.00	 0.0	 0.0	 1	    1.00000	    0.00000	 132.0	 1	    1.06000	    0.94000;
	9	 1	 0.0	 0.0	 0.0	 0.0	 1	    1.00000	    0.00000	 1.0	 1	    1.06000	    0.94000;
	10	 1	 9.64	 2.00	 0.0	 19.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	11	 2	 0.0	 0.0	 0.0	 0.0	 1	    1.00000	    0.00000	 11.0	 1	    1.06000	    0.94000;
	12	 1	 18.62	 7.50	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	13	 2	 0.0	 0.0	 0.0	 0.0	 1	    1.00000	    0.00000	 11.0	 1	    1.06000	    0.94000;
	14	 1	 10.31	 1.60	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	15	 1	 13.64	 2.50	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	16	 1	 5.82	 1.80	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	17	 1	 14.97	 5.80	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	18	 1	 5.32	 0.90	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	19	 1	 15.80	 3.40	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	20	 1	 3.66	 0.70	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	21	 1	 29.10	 11.20	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	22	 1	 0.0	 0.0	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	23	 1	 5.32	 1.60	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	24	 1	 14.47	 6.70	 0.0	 4.3	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	25	 1	 0.0	 0.0	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	26	 1	 5.82	 2.30	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	27	 1	 0.0	 0.0	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	28	 1	 0.0	 0.0	 0.0	 0.0	 1	    1.00000	    0.00000	 132.0	 1	    1.06000	    0.94000;
	29	 1	 3.99	 0.90	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
	30	 1	 17.63	 1.90	 0.0	 0.0	 1	    1.00000	    0.00000	 33.0	 1	    1.06000	    0.94000;
];

%% generator data
%	bus	Pg	Qg	Qmax	Qmin	Vg	mBase	status	Pmax	Pmin
mpc.gen = [
	1	 175.5	 0.0	 176.0	 -176.0	 1.0	 100.0	 1	 351	 0.0; % NG
	2	 171.0	 0.0	 171.0	 -171.0	 1.0	 100.0	 1	 342	 0.0; % NG
	5	 0.0	 0.0	 40.0	 -40.0	 1.0	 100.0	 1	 0	 0.0; % SYNC
	8	 0.0	 0.0	 230.4	 -230.4	 1.0	 100.0	 1	 0	 0.0; % SYNC
	11	 0.0	 3.0	 24.0	 -18.0	 1.0	 100.0	 1	 0	 0.0; % SYNC
	13	 0.0	 9.0	 24.0	 -6.0	 1.0	 100.0	 1	 0	 0.0; % SYNC
];

%% generator cost data
%	2	startup	shutdown	n	c(n-1)	...	c0
mpc.gencost = [
	2	 0.0	 0.0	 3	   0.000000	  18.421528	   0.000000; % NG
	2	 0.0	 0.0	 3	   0.000000	  52.182254	   0.000000; % NG
	2	 0.0	 0.0	 3	   0.000000	   0.000000	   0.000000; % SYNC
	2	 0.0	 0.0	 3	   0.000000	   0.000000	   0.000000; % SYNC
	2	 0.0	 0.0	 3	   0.000000	   0.000000	   0.000000; % SYNC
	2	 0.0	 0.0	 3	   0.000000	   0.000000	   0.000000; % SYNC
];

%% branch data
%	fbus	tbus	r	x	b	rateA	rateB	rateC	ratio	angle	status	angmin	angmax
mpc.branch = [
	1	 2	 0.0192	 0.0575	 0.0528	 138.0	 138.0	 138.0	 0.0	 0.0	 1	 -30.0	 30.0;
	1	 3	 0.0452	 0.1652	 0.0408	 152.0	 152.0	 152.0	 0.0	 0.0	 1	 -30.0	 30.0;
	2	 4	 0.057	 0.1737	 0.0368	 139.0	 139.0	 139.0	 0.0	 0.0	 1	 -30.0	 30.0;
	3	 4	 0.0132	 0.0379	 0.0084	 135.0	 135.0	 135.0	 0.0	 0.0	 1	 -30.0	 30.0;
	2	 5	 0.0472	 0.1983	 0.0418	 144.0	 144.0	 144.0	 0.0	 0.0	 1	 -30.0	 30.0;
	2	 6	 0.0581	 0.1763	 0.0374	 139.0	 139.0	 139.0	 0.0	 0.0	 1	 -30.0	 30.0;
	4	 6	 0.0119	 0.0414	 0.009	 148.0	 148.0	 148.0	 0.0	 0.0	 1	 -30.0	 30.0;
	5	 7	 0.046	 0.116	 0.0204	 127.0	 127.0	 127.0	 0.0	 0.0	 1	 -30.0	 30.0;
	6	 7	 0.0267	 0.082	 0.017	 140.0	 140.0	 140.0	 0.0	 0.0	 1	 -30.0	 30.0;
	6	 8	 0.012	 0.042	 0.009	 148.0	 148.0	 148.0	 0.0	 0.0	 1	 -30.0	 30.0;
	6	 9	 0.0	 0.208	 0.0	 142.0	 142.0	 142.0	 0.978	 0.0	 1	 -30.0	 30.0;
	6	 10	 0.0	 0.556	 0.0	 53.0	 53.0	 53.0	 0.969	 0.0	 1	 -30.0	 30.0;
	9	 11	 0.0	 0.208	 0.0	 142.0	 142.0	 142.0	 1.0	 0.0	 1	 -30.0	 30.0;
	9	 10	 0.0	 0.11	 0.0	 267.0	 267.0	 267.0	 1.0	 0.0	 1	 -30.0	 30.0;
	4	 12	 0.0	 0.256	 0.0	 115.0	 115.0	 115.0	 0.932	 0.0	 1	 -30.0	 30.0;
	12	 13	 0.0	 0.14	 0.0	 210.0	 210.0	 210.0	 1.0	 0.0	 1	 -30.0	 30.0;
	12	 14	 0.1231	 0.2559	 0.0	 29.0	 29.0	 29.0	 0.0	 0.0	 1	 -30.0	 30.0;
	12	 15	 0.0662	 0.1304	 0.0	 29.0	 29.0	 29.0	 0.0	 0.0	 1	 -30.0	 30.0;
	12	 16	 0.0945	 0.1987	 0.0	 30.0	 30.0	 30.0	 0.0	 0.0	 1	 -30.0	 30.0;
	14	 15	 0.221	 0.1997	 0.0	 20.0	 20.0	 20.0	 0.0	 0.0	 1	 -30.0	 30.0;
	16	 17	 0.0524	 0.1923	 0.0	 38.0	 38.0	 38.0	 0.0	 0.0	 1	 -30.0	 30.0;
	15	 18	 0.1073	 0.2185	 0.0	 29.0	 29.0	 29.0	 0.0	 0.0	 1	 -30.0	 30.0;
	18	 19	 0.0639	 0.1292	 0.0	 29.0	 29.0	 29.0	 0.0	 0.0	 1	 -30.0	 30.0;
	19	 20	 0.034	 0.068	 0.0	 29.0	 29.0	 29.0	 0.0	 0.0	 1	 -30.0	 30.0;
	10	 20	 0.0936	 0.209	 0.0	 30.0	 30.0	 30.0	 0.0	 0.0	 1	 -30.0	 30.0;
	10	 17	 0.0324	 0.0845	 0.0	 33.0	 33.0	 33.0	 0.0	 0.0	 1	 -30.0	 30.0;
	10	 21	 0.0348	 0.0749	 0.0	 30.0	 30.0	 30.0	 0.0	 0.0	 1	 -30.0	 30.0;
	10	 22	 0.0727	 0.1499	 0.0	 29.0	 29.0	 29.0	 0.0	 0.0	 1	 -30.0	 30.0;
	21	 22	 0.0116	 0.0236	 0.0	 29.0	 29.0	 29.0	 0.0	 0.0	 1	 -30.0	 30.0;
	15	 23	 0.1	 0.202	 0.0	 29.0	 29.0	 29.0	 0.0	 0.0	 1	 -30.0	 30.0;
	22	 24	 0.115	 0.179	 0.0	 26.0	 26.0	 26.0	 0.0	 0.0	 1	 -30.0	 30.0;
	23	 24	 0.132	 0.27	 0.0	 29.0	 29.0	 29.0	 0.0	 0.0	 1	 -30.0	 30.0;
	24	 25	 0.1885	 0.3292	 0.0	 27.0	 27.0	 27.0	 0.0	 0.0	 1	 -30.0	 30.0;
	25	 26	 0.2544	 0.38	 0.0	 25.0	 25.0	 25.0	 0.0	 0.0	 1	 -30.0	 30.0;
	25	 27	 0.1093	 0.2087	 0.0	 28.0	 28.0	 28.0	 0.0	 0.0	 1	 -30.0	 30.0;
	28	 27	 0.0	 0.396	 0.0	 75.0	 75.0	 75.0	 0.968	 0.0	 1	 -30.0	 30.0;
	27	 29	 0.2198	 0.4153	 0.0	 28.0	 28.0	 28.0	 0.0	 0.0	 1	 -30.0	 30.0;
	27	 30	 0.3202	 0.6027	 0.0	 28.0	 28.0	 28.0	 0.0	 0.0	 1	 -30.0	 30.0;
	29	 30	 0.2399	 0.4533	 0.0	 28.0	 28.0	 28.0	 0.0	 0.0	 1	 -30.0	 30.0;
	8	 28	 0.0636	 0.2	 0.0428	 140.0	 140.0	 140.0	 0.0	 0.0	 1	 -30.0	 30.0;
	6	 28	 0.0169	 0.0599	 0.013	 149.0	 149.0	 149.0	 0.0	 0.0	 1	 -30.0	 30.0;
];

% INFO    : === Translation Options ===
% INFO    : Load Model:                  from file ./pglib_opf_case30_ieee.m.api.sol
% INFO    : Gen Active Capacity Model:   stat
% INFO    : Gen Reactive Capacity Model: al50ag
% INFO    : Gen Active Cost Model:       stat
% INFO    :
% INFO    : === Load Replacement Notes ===
% INFO    : Bus 2	: Pd=21.7, Qd=12.7 -> Pd=36.08, Qd=12.70
% INFO    : Bus 3	: Pd=2.4, Qd=1.2 -> Pd=3.99, Qd=1.20
% INFO    : Bus 4	: Pd=7.6, Qd=1.6 -> Pd=12.64, Qd=1.60
% INFO    : Bus 5	: Pd=94.2, Qd=19.0 -> Pd=156.64, Qd=19.00
% INFO    : Bus 7	: Pd=22.8, Qd=10.9 -> Pd=37.91, Qd=10.90
% INFO    : Bus 8	: Pd=30.0, Qd=30.0 -> Pd=49.89, Qd=30.00
% INFO    : Bus 10	: Pd=5.8, Qd=2.0 -> Pd=9.64, Qd=2.00
% INFO    : Bus 12	: Pd=11.2, Qd=7.5 -> Pd=18.62, Qd=7.50
% INFO    : Bus 14	: Pd=6.2, Qd=1.6 -> Pd=10.31, Qd=1.60
% INFO    : Bus 15	: Pd=8.2, Qd=2.5 -> Pd=13.64, Qd=2.50
% INFO    : Bus 16	: Pd=3.5, Qd=1.8 -> Pd=5.82, Qd=1.80
% INFO    : Bus 17	: Pd=9.0, Qd=5.8 -> Pd=14.97, Qd=5.80
% INFO    : Bus 18	: Pd=3.2, Qd=0.9 -> Pd=5.32, Qd=0.90
% INFO    : Bus 19	: Pd=9.5, Qd=3.4 -> Pd=15.80, Qd=3.40
% INFO    : Bus 20	: Pd=2.2, Qd=0.7 -> Pd=3.66, Qd=0.70
% INFO    : Bus 21	: Pd=17.5, Qd=11.2 -> Pd=29.10, Qd=11.20
% INFO    : Bus 23	: Pd=3.2, Qd=1.6 -> Pd=5.32, Qd=1.60
% INFO    : Bus 24	: Pd=8.7, Qd=6.7 -> Pd=14.47, Qd=6.70
% INFO    : Bus 26	: Pd=3.5, Qd=2.3 -> Pd=5.82, Qd=2.30
% INFO    : Bus 29	: Pd=2.4, Qd=0.9 -> Pd=3.99, Qd=0.90
% INFO    : Bus 30	: Pd=10.6, Qd=1.9 -> Pd=17.63, Qd=1.90
% INFO    :
% INFO    : === Generator Setpoint Replacement Notes ===
% INFO    : Gen at bus 1	: Pg=135.5, Qg=5.0 -> Pg=254.0, Qg=49.0
% INFO    : Gen at bus 2	: Pg=46.0, Qg=3.0 -> Pg=261.0, Qg=-46.0
% INFO    : Gen at bus 5	: Pg=0.0, Qg=0.0 -> Pg=0.0, Qg=32.0
% INFO    : Gen at bus 8	: Pg=0.0, Qg=15.0 -> Pg=0.0, Qg=192.0
% INFO    : Gen at bus 11	: Pg=0.0, Qg=9.0 -> Pg=0.0, Qg=15.0
% INFO    : Gen at bus 13	: Pg=0.0, Qg=9.0 -> Pg=0.0, Qg=-1.0
% INFO    :
% INFO    : === Generator Reactive Capacity Atleast Setpoint Value Notes ===
% INFO    : Gen at bus 1	: Qg 49.0, Qmin 0.0, Qmax 10.0 -> Qmin -58.8, Qmax 58.8
% INFO    : Gen at bus 2	: Qg -46.0, Qmin -40.0, Qmax 46.0 -> Qmin -55.2, Qmax 46.0
% INFO    : Gen at bus 8	: Qg 192.0, Qmin -10.0, Qmax 40.0 -> Qmin -230.4, Qmax 230.4
% INFO    : Gen at bus 11	: Qg 15.0, Qmin -6.0, Qmax 24.0 -> Qmin -18.0, Qmax 24.0
% INFO    :
% INFO    : === Generator Classification Notes ===
% INFO    : SYNC   4   -     0.00
% INFO    : NG     2   -   100.00
% INFO    :
% INFO    : === Generator Active Capacity Stat Model Notes ===
% INFO    : Gen at bus 1 - NG	: Pg=254.0, Pmax=271.0 -> Pmax=351   samples: 5
% INFO    : Gen at bus 2 - NG	: Pg=261.0, Pmax=92.0 -> Pmax=342   samples: 12
% INFO    : Gen at bus 5 - SYNC	: Pg=0.0, Pmax=0.0 -> Pmax=0   samples: 0
% INFO    : Gen at bus 8 - SYNC	: Pg=0.0, Pmax=0.0 -> Pmax=0   samples: 0
% INFO    : Gen at bus 11 - SYNC	: Pg=0.0, Pmax=0.0 -> Pmax=0   samples: 0
% INFO    : Gen at bus 13 - SYNC	: Pg=0.0, Pmax=0.0 -> Pmax=0   samples: 0
% INFO    :
% INFO    : === Generator Active Capacity LB Model Notes ===
% INFO    :
% INFO    : === Generator Reactive Capacity Atleast Max 50 Percent Active Model Notes ===
% INFO    : Gen at bus 1 - NG	: Pmax 351.0, Qmin -58.8, Qmax 58.8 -> Qmin -176.0, Qmax 176.0
% INFO    : Gen at bus 2 - NG	: Pmax 342.0, Qmin -55.2, Qmax 46.0 -> Qmin -171.0, Qmax 171.0
% INFO    :
% INFO    : === Generator Setpoint Replacement Notes ===
% INFO    : Gen at bus 1	: Pg=254.0, Qg=49.0 -> Pg=175.5, Qg=0.0
% INFO    : Gen at bus 1	: Vg=1.0 -> Vg=1.0
% INFO    : Gen at bus 2	: Pg=261.0, Qg=-46.0 -> Pg=171.0, Qg=0.0
% INFO    : Gen at bus 2	: Vg=1.0 -> Vg=1.0
% INFO    : Gen at bus 5	: Pg=0.0, Qg=32.0 -> Pg=0.0, Qg=0.0
% INFO    : Gen at bus 5	: Vg=1.0 -> Vg=1.0
% INFO    : Gen at bus 8	: Pg=0.0, Qg=192.0 -> Pg=0.0, Qg=0.0
% INFO    : Gen at bus 8	: Vg=1.0 -> Vg=1.0
% INFO    : Gen at bus 11	: Pg=0.0, Qg=15.0 -> Pg=0.0, Qg=3.0
% INFO    : Gen at bus 11	: Vg=1.0 -> Vg=1.0
% INFO    : Gen at bus 13	: Pg=0.0, Qg=-1.0 -> Pg=0.0, Qg=9.0
% INFO    : Gen at bus 13	: Vg=1.0 -> Vg=1.0
% INFO    :
% INFO    : === Writing Matpower Case File Notes ===


function talDat = loadTalairachCoordinates;

%loadTalairachCoordinates() Load Tal. coordinates from file.
%
%This function is supposed to prevent multiple hacking of the same coordinates
%instead write to a pure textfile and read them in for each subject.
%The file is assumed to reside at the base directory for the antomies. Hoever deviations
%in file location are posible
%the structure of the text-file is fixed and assumed to be the following:
%x-coord ycoord zcoord descripition-string color
%The file may consist of several lines each specifiying one set of coordinates
%Fields within a line are separated by whitespace(s). The field color is a valid matlab
%colorstring such as 'b' 'r' 'y' etc.
%
% Authors BD and JR 09/18/01

% ugly but conforms with the conventions
rootPath=which(mfilename);
rootPath = fullfile(fileparts(rootPath),'Coords');
pathstr = getPathStrDialog(rootPath,'Choose Talairach-coordinates file','*.txt;*.TXT');

if isempty(pathstr)
    talDat = [];
end

talDat = dlmreadMixedDataType(pathstr,'n1 n2 n3 s4 s5');


classdef OrbitStateEnum < matlab.mixin.SetGet
    %OrbitStateEnum Summary of this class goes here
    %   Detailed explanation goes here

    enumeration
        KeplerianOrbit('Keplerian Orbit','KeplerianOrbitStateModel', ...
                       {'SMA','Eccentricity','Inclination','RAAN','Arg Peri','True Aomaly'}, ...
                       {'km','','deg','deg','deg','deg'}, ...
                       'KeplerianOrbitVariable', ...
                       'Central Body', ...
                       'The body around which this orbit is defined.')
        BodyFixed('Body Fixed Orbit','BodyFixedOrbitStateModel', ...
                  {'Latitude','Longitude','Altitude','Velocity Az','Velocity El','Velocity Mag'}, ...
                  {'degN','degE','km','deg','deg','km/s'}, ...
                  'BodyFixedOrbitVariable', ...
                  'Central Body', ...
                  'The body upon which this body-fixed state is defined.  If launching from the surface, the body being launched from.')
        CR3BP('Primary-centered Circular Restricted 3 Body Problem Orbit','CR3BPOrbitStateModel', ...
                  {'Position (X)','Position (Y)','Position (Z)','Velocity (X)','Velocity (Y)','Velocity (Z)'}, ...
                  {'km','km','km','km/s','km/s','km/s'}, ...
                  'BodyFixedOrbitVariable', ...
                  'Secon. Body', ...
                  'The secondary body in the 3 body rotating frame.  The actual orbit will be defined w.r.t. the parent of this body.  E.G. if you want a Kerbin-Mun rotating frame, select "Mun" here.')
    end

    properties
        name char = ''
        class char = ''
        elemNames(6,1) cell
        unitNames(6,1) cell
        varClass char = '';
        cbLabel char = 'Central Body';
        cbTooltip char = '';
    end

    methods
        function obj = OrbitStateEnum(name,class,elemNames,unitNames,varClass,cbLabel,cbTooltip)
            obj.name = name;
            obj.class = class;
            obj.elemNames = elemNames;
            obj.unitNames = unitNames;
            obj.varClass = varClass;
            obj.cbLabel = cbLabel;
            obj.cbTooltip = cbTooltip;
        end
    end

    methods(Static)
        function listBoxStr = getListBoxStr()
            m = enumeration('OrbitStateEnum');
            listBoxStr = {m.name};
        end

        function [ind, enum] = getIndForName(name)
            m = enumeration('OrbitStateEnum');
            ind = find(ismember({m.name},name),1,'first');
            enum = m(ind);
        end

        function [ind, enum] = getIndForClass(class)
            m = enumeration('OrbitStateEnum');
            ind = find(ismember({m.class},class),1,'first');
            enum = m(ind);
        end
    end
end


% This script file load a data set using fscanf
% The default reads Northern California Hypoellipse Format
%

report_this_filefun(mfilename('fullpath'));
disp('Please make sure the has 88 characters for each line')
disp('and all blanks have been substituted by zeros')

% Lets make sure the file is closed...
safe_fclose(fid);

% reset paramteres
a = []; b = []; n = 0;

if inda == 1
    % initial selection option
    tmin   = 10.0001;
    tmax   = 98.000;
    lonmin = -180.0;
    lonmax =  180.0;
    latmin =  -90.00;
    latmax =  90.0 ;
    Mmin   = -4.0;
    Mmax   = 10.;
    mindep = -10;
    maxdep = 700;

    % call the pre-selection window
    presel
    return
end

% open the file and read 10000 lines at a time
[file1,path1] = uigetfile([ '*.dat'],' Earthquake Datafile');
if length(file1) >1
    fid = fopen([path1 file1],'r') ;;
else
    disp('Data import canceled'); return
end

while  ferror(fid) == ''
    n = n+1;
    % vari name   yr mo da hr mi se lat   la  lon    lo de ma1     ma he   hz
    % variabl #   1  2  3  4  5  6  7      8  9      10 11 12      13 14   15
    % position    2  4  6  8  10 14 16 17  21 24 25  29 34 36 67   69 84   88
    l = fscanf(fid,'%2d%2d%2d%2d%2d%4d%2d%*1c%4d%3d%*1c%4d%5f%2d%*31c%2d%*15c%4d',...
        [14 10000]) ;
    %if ferror(fid) ~= '' ; break; end

    b = [ -l(9,:)-l(10,:)/6000 ; l(7,:)+l(8,:)/6000 ; l(1,:);l(2,:);l(3,:);
        l(13,:)/10;l(11,:)/100;l(4,:);l(5,:); l(14,:)/100;l(12,:)/10];
    b = b';
    l =  b(:,6) >= Mmin & b(:,1) >= lonmin & b(:,1) <= lonmax & ...
        b(:,2) >= latmin & b(:,2) <= latmax & b(:,3) <= tmax  & ...
        b(:,3) >= tmin  & b(:,7) <= maxdep & b(:,7) >= mindep;
    a = [a ; b(l,:)];

    disp([ num2str(n*10000) ' earthquakes scanned, ' num2str(length(a)) ' EQ found'])
    if max(b(:,3)) >  tmax ; break; end

end
ferror(fid)
fclose(fid);

% Convert the third column into time in decimals
if length(a(1,:))== 7
    a.Date = decyear(a(:,3:5));
elseif length(a(1,:))>=9       %if catalog includes hr and minutes
    a.Date = decyear(a(:,[3:5 8 9]));
end

% save the data
[file1,path1] = uiputfile(fullfile(hodi, 'eq_data', '*.mat'), 'Save Earthquake Datafile');
sapa2 = ['save ' path1 file1 ' a'];
if length(file1) > 1; eval(sapa2);end

% call the map window
update(mainmap())


% FLOATREAD - Read matrix from float file ssuming four byte floating point number
%               Can use FSEEK to read an arbitrary (contiguous) submatrix.
%
% Usage:        >> a = floatread(filename,size,'format',offset)
%
% Inputs:
%   filename - name of the file
%   size     - determine the number of float elements to be read and
%              the dimensions of the resulting matrix. If the last element
%              of 'size' is Inf, the size of the last dimension is determined
%              by the file length. If size is 'square,' FLOATREAD attempts
%              to read a square 2-D matrix.
%
% Optional inputs:
%  'format'  - the option FORMAT argument specifies the storage format as
%              defined by FOPEN. Default format ([]) is 'native'.
%  offset    - either the number of first floats to skip from the beginning of the
%              float file, OR a cell array containing the dimensions of the original
%              data matrix and a starting position vector in that data matrix.
%
%              Example: % Read a [3 10] submatrix of a four-dimensional float matrix
%                >> a = floatread('mydata.fdt',[3 10],'native',{[[3 10 4 5],[1,1,3,4]});
%              % Note: The 'size' and 'offset' arguments must be compatible both
%              % with each other and with the size and ordering of the float file.
%
% Author: Sigurd Enghoff, CNL / Salk Institute, La Jolla, 7/1998
%
% See also: FLOATWRITE, FOPEN

% Copyright (C) Sigurd Enghoff, CNL / Salk Institute, La Jolla, 7/1998
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

% 04-26-99  modified by Sigurd Enghoff to handle variable-sized and
%           multi-dimensional data.
% 07-08-99  modified by Sigurd Enghoff, FORMAT argument added.
% 02-08-00  help updated for toolbox inclusion -sm
% 02-14-00  added segment arg -sm
% 08-14-00  added size 'square' option -sm
% 01-25-02  reformated help & license, added links -ad

function A = floatread(fname,Asize,fform,offset)

if nargin<2
  help floatread
  return
end

if ~exist('fform') || isempty(fform) || fform(1)==0
	fform = 'native';
end

if ~exist('offset')
	offset = 0;
end

fid = fopen(fname,'rb',fform);
if fid>0
 if exist('offset')
   if iscell(offset)
     if length(offset) ~= 2
        error('offset must be a positive integer or a 2-item cell array');
     end
     datasize = offset{1};
     startpos = offset{2};
     if length(datasize) ~= length(startpos)
        error('offset must be a positive integer or a 2-item cell array');
     end
     for k=1:length(datasize)
       if startpos(k) < 1 || startpos(k) > datasize(k)
          error('offset must be a positive integer or a 2-item cell array');
       end
     end
     if length(Asize)> length(datasize)
        error('offset must be a positive integer or a 2-item cell array');
     end
     for k=1:length(Asize)-1
         if startpos(k) ~= 1
            error('offset must be a positive integer or a 2-item cell array');
         end
     end
     sizedim = length(Asize);
     if Asize(sizedim) + startpos(sizedim) - 1 > datasize(sizedim)
        error('offset must be a positive integer or a 2-item cell array');
     end
     for k=1:length(Asize)-1
         if Asize(k) ~= datasize(k)
            error('offset must be a positive integer or a 2-item cell array');
         end
     end

     offset = 0;
     jumpfac = 1;
     for k=1:length(startpos)
           offset = offset + jumpfac * (startpos(k)-1);
           jumpfac = jumpfac * datasize(k);
     end

   elseif length(offset) > 1
     error('offset must be a positive integer or a 2-item cell array');
   end

   % perform the fseek() operation
   % -----------------------------
   stts = fseek(fid,4*offset,'bof');

   if stts ~= 0
     error('floatread(): fseek() error.');
     return
   end
 end

% determine what 'square' means
% -----------------------------
 if ischar('Asize')
   if iscell(offset)
         if length(datasize) ~= 2 || datasize(1) ~= datasize(2)
              error('size ''square'' must refer to a square 2-D matrix');
         end
         Asize = [datsize(1) datasize(2)];
   elseif strcmp(Asize,'square')
         fseek(fid,0,'eof'); % go to end of file
         bytes = ftell(fid); % get byte position
         fseek(fid,0,'bof'); % rewind
         bytes = bytes/4; % nfloats
         froot = sqrt(bytes);
         if round(froot)*round(froot) ~= bytes
              error('floatread(): filelength is not square.')
         else
              Asize = [round(froot) round(froot)];
         end
   end
 end
 A = fread(fid,prod(Asize),'float');
else
 error('floatread() fopen() error.');
 return
end

% fprintf('   %d floats read\n',prod(size(A)));

% interpret last element of Asize if 'Inf'
% ----------------------------------------
if Asize(end) == Inf
	Asize = Asize(1:end-1);
	A = reshape(A,[Asize length(A)/prod(Asize)]);
else
	A = reshape(A,Asize);
end

fclose(fid);


classdef ipfHKLKey < ipfColorKey
  % defines an orientation mapping based on a certain inverse pole figure
  %   Detailed explanation goes here

  methods
    function oM = ipfHKLKey(varargin)
      oM = oM@ipfColorKey(varargin{:});
      oM.CS1 = oM.CS1.Laue;

      oM.dirMap = HKLDirectionKey(oM.CS1);
    end

  end
end


function [ cnt, S, bad_idx ] = paramStats( annotation_struct, options, verbose )
%PARAMSTATS Collects statistics about possible positions of each landmark
%point (component)
%   Detailed explanation goes here
%
% INPUT:
%   image      ... array of cells, each cell containes bbox found by detector and filename
%   bw         ... vector [w; h] contains size of base window.
%   components ... matrix of size 2xM, M is count of components [w0 ... wM-1; h0 ... hM-1]. Order of components is important!
%   bw_margin  ... vector [w; h] base window margin in percents of original bbox.
%   image_path ... path to directory containing image database. Must contain subdir /mgt with xml annotations.
%   verbose    ... true for image output with landmarks and components depicted
%
% OUTPUT:
%   cnt     ... count of images that passed test
%   S       ... matrix 4xM [x0_min; y0_min; x0_max; y0_max; ... xM-1_min; yM-1_min; xM-1_max; yM-1_max] bbox for each component
%   bad_idx ... indices to image array of images that does not passed this
%               test
%
% 16-07-10 Michal Uricar
% 10-04-11 Michal Uricar, estimation of S0 fixed (face center intead of nose)
% 12-07-11 Michal Uricar, corners dataset
% 21-03-12 Michal Uricar, LFW annotation in one file

    if (nargin < 3)
        verbose = false;
    end;

    bad_idx = [];

    % count of components
    M = size(options.components, 2);

    cnt = 0;
    S = [inf(2, M); -inf(2, M)];

    % for each image in db
    N = annotation_struct.N;
    for i = 1 : N
        [Iframe, Annotation, I, itmp.bbox, bbox, OrigPoints] = getImageFrame(options, i, annotation_struct);

        % !!! Annotation is empty at i == 578 !!!
        if (isempty(Annotation))
            bad_idx = [bad_idx i];
            continue;
        end;

        Points = prepareS0gt(Annotation.P, options);    % transform nose to the center of face
        Points = Points(:, options.comselect);          % extract relevant points only (name list in options.compnames)
        Points(:, M) = Annotation.P(:, 10);             % copy back original nose position

        %% Check for each component if it fits in normalized frame
        flag = true;
        for j = 1 : M
            if ( ((Points(1, j) - options.components(1, j)/2) < 0) || ((Points(1, j) + options.components(1, j)/2) > options.bw(1)) || ...
                 ((Points(2, j) - options.components(2, j)/2) < 0) || ((Points(2, j) + options.components(2, j)/2) > options.bw(2)) )
                flag = false;
            end;
        end;

        % increase number of valid images if flag is true
        if (flag)
            cnt = cnt + 1;
            fprintf('%.2f%% - Passed: tested image no.%d file %s...\n', i*100/N, i, Annotation.image.filename);

            %% recompute AABB for S
            for j = 1 : M
                bb = [Points(1, j) - options.components(1, j)/2 Points(2, j) - options.components(2, j)/2 ...
                      Points(1, j) + options.components(1, j)/2 Points(2, j) + options.components(2, j)/2 ];
                S(1, j) = min(S(1, j), bb(1));
                S(2, j) = min(S(2, j), bb(2));
                S(3, j) = max(S(3, j), bb(3));
                S(4, j) = max(S(4, j), bb(4));
            end;

        else
            fprintf('%.2f%% - Not passed: tested image no.%d file %s...\n', i*100/N, i, Annotation.image.filename);
            bad_idx = [bad_idx i];
        end;

        %% Visualization
        if (verbose)
            aabb = makeAABB(itmp.bbox);
            aabb2 = makeAABB(bbox);

            % show original image with annotation
            figure(1);
            subplot(2, 2, 1);
            imshow(I, []); hold on;
            % show ground truth points
%             for k = 1 : M
            plot(OrigPoints(1, :), OrigPoints(2, :), 'r.', 'LineWidth', 2, 'MarkerSize', 10);
%             end;
            % show aabb found by detector
            line([aabb(1,:) aabb(1,1)], [aabb(2,:) aabb(2,1)], 'color', 'b');
            line([aabb2(1,:) aabb2(1,1)], [aabb2(2,:) aabb2(2,1)], 'color', 'y');
            hold off;

            % show normalized frame
            subplot(2, 2, 2)
            imshow(Iframe, []); hold on;
            for k = 1 : M
                plot(Points(1, k), Points(2, k), 'r.', 'LineWidth', 2, 'MarkerSize', 10);
                bb = makeAABB([Points(1, k) - options.components(1, k)/2 Points(2, k) - options.components(2, k)/2 ...
                               Points(1, k) + options.components(1, k)/2 Points(2, k) + options.components(2, k)/2 ]);
                line([bb(1,:) bb(1,1)], [bb(2,:) bb(2,1)], 'color', 'y');
            end;
            hold off;

            % show recomputed S also
            if (max(S(1, :)) < inf && min(S(3, :)) > -inf)
                subplot(2, 2, 3)
                imshow(Iframe, []); hold on;
                for k = 1 : M
                    plot(Points(1, k), Points(2, k), 'r.', 'LineWidth', 2, 'MarkerSize', 10);
                    bb = makeAABB(S(:, k));
                    line([bb(1,:) bb(1,1)], [bb(2,:) bb(2,1)], 'color', 'b');
                    bb = makeAABB([Points(1, k) - options.components(1, k)/2 Points(2, k) - options.components(2, k)/2 ...
                                   Points(1, k) + options.components(1, k)/2 Points(2, k) + options.components(2, k)/2 ]);
                    line([bb(1,:) bb(1,1)], [bb(2,:) bb(2,1)], 'color', 'y');
                end;
                hold off;
            end;

%             saveas(gcf, ['./img/' 'bw_' Annotation.image.filename]);
%             close gcf;
        end;
    end;
end


% GET THE 3D TRAJECTORY TRAILS AS A GIF  [ UPDATED ]
function [currentFigure,figureHandle] = GetFigure_isometricGif(SIM,objectIndex,DATA,currentFigure)
% This function generates an animated .gif representing the object
% trajectories over the complete timeseries.

% CONFIGURE THE PLOT ATTRIBUTES
figurePath = strcat(SIM.outputPath,'isometric.gif');
figureHandle = figure('Name','OpenMAS isometric timelapse (GIF)');

% MAXIMISE GRAPH SIZE IN WINDOW
setappdata(figureHandle, 'SubplotDefaultAxesLocation', [0.08, 0.08, 0.90, 0.88]);
set(figureHandle,'Position',DATA.figureProperties.windowSettings);        % [x y width height]
set(figureHandle,'Color',DATA.figureProperties.figureColor);               % Background colour
if DATA.figureProperties.publish
    set(figureHandle,'MenuBar','none');
    set(figureHandle,'ToolBar','none');
    set(figureHandle,'Visible','off');
end
% AXES SETTINGS
ax = axes(figureHandle);

% GET THE SIZE OF THE PLOTTED SET
% The data has already been pre-formatted so that the number of states
% aligns with the number of expected frames in the annimation.
% IMPORT THE OBJECT DATA FROM TEMP FILE
load([SIM.outputPath,SIM.systemFile]);
framesToPlot = size(eval(sprintf('objectID%d',SIM.OBJECTS(1).objectID)),2);   % The variable name in the workspace
F(framesToPlot) = struct('cdata',[],'colormap',[]);

% ax.NextPlot = 'replaceChildren';
inclinationAngle = 62;
viewPoint = -10;
viewRate = 0.05;
for frame = 1:framesToPlot
    hold on;
    % Must be done on a step by step base to get the annimations correct.

    % BUILD THE FRAME
    if frame == 1
        % UPDATE OBJECT HANDLES
        for entity = 1:SIM.totalObjects
            % GET THE OBJECT HANDLE
            objectHandle = objectIndex{SIM.globalIDvector == SIM.OBJECTS(entity).objectID};
            % PULL VARIABLE FROM WORKSPACE
            variableLabel = sprintf('objectID%d',SIM.OBJECTS(entity).objectID); % The variable name in the workspace
            globalStates = eval(variableLabel);                              % Evalutate object states

            % TRACE INITIAL POSITIONS
            traceHandle(entity) = plot3(ax,globalStates(1,frame),globalStates(2,frame),globalStates(3,frame));
            if numel(objectHandle.GEOMETRY.vertices) > 0
                % GET THE GLOBAL POSE AT STEP
                [R_frame] = OMAS_geometry.quaternionToRotationMatrix(globalStates(7:end,frame));
                % BUILD MARKER
                markerHandle(entity) = patch(ax,...
                    'Vertices',objectHandle.GEOMETRY.vertices*R_frame + globalStates(1:3,frame)',...
                    'Faces',objectHandle.GEOMETRY.faces,...
                    'FaceColor',SIM.OBJECTS(entity).colour,...
                    'EdgeColor',DATA.figureProperties.edgeColor,...
                    'EdgeAlpha',DATA.figureProperties.edgeAlpha,...
                    'FaceLighting',DATA.figureProperties.faceLighting,...
                    'FaceAlpha',DATA.figureProperties.faceAlpha,...
                    'LineWidth',DATA.figureProperties.patchLineWidth);             % Patch properties
            else
                % INITIAL MARKER PLOT
                markerHandle(entity) = plot3(ax,globalStates(1,frame),globalStates(2,frame),globalStates(3,frame));
                % ASSIGN MARKER PROPERTIES
                markerHandle(entity).Marker = SIM.OBJECTS(entity).symbol;
                markerHandle(entity).MarkerSize = DATA.figureProperties.markerSize;
                markerHandle(entity).MarkerFaceColor = SIM.OBJECTS(entity).colour;
                markerHandle(entity).MarkerEdgeColor = DATA.figureProperties.markerEdgeColor;
                markerHandle(entity).Color = SIM.OBJECTS(entity).colour;
            end
            % ASSIGN TRACE PROPERTIES
            traceHandle(entity).LineStyle = DATA.figureProperties.lineStyle;
            traceHandle(entity).LineWidth = DATA.figureProperties.lineWidth;
            traceHandle(entity).Color = SIM.OBJECTS(entity).colour;
        end
        % ANNOTATION WITH THE CURRENT TIME
        clockHandle = annotation('textbox',[0.025 0.025 0.15 0.06],'String','Time:','FitBoxToText','off');
        set(clockHandle,...
            'Interpreter',DATA.figureProperties.interpreter,...
            'fontname',DATA.figureProperties.fontName,...
            'FontSize',DATA.figureProperties.axisFontSize,...
            'FontWeight',DATA.figureProperties.fontWeight);
        % Title
        title(ax,...
            sprintf('Object global trajectories over a period of %ss',num2str(SIM.TIME.endTime)),...
            'Interpreter',DATA.figureProperties.interpreter,...
            'fontname',DATA.figureProperties.fontName,...
            'Fontweight',DATA.figureProperties.fontWeight,...
            'FontSize',DATA.figureProperties.titleFontSize,...
            'FontSmoothing','on');
        % X-Label
        xlabel(ax,'x (m)',...
            'Interpreter',DATA.figureProperties.interpreter,...
            'fontname',DATA.figureProperties.fontName,...
            'Fontweight',DATA.figureProperties.fontWeight,...
            'FontSize',DATA.figureProperties.axisFontSize,...
            'FontSmoothing','on');
        % Y-Label
        ylabel(ax,'y (m)',...
            'Interpreter',DATA.figureProperties.interpreter,...
            'fontname',DATA.figureProperties.fontName,...
            'Fontweight',DATA.figureProperties.fontWeight,...
            'FontSize',DATA.figureProperties.axisFontSize,...
            'FontSmoothing','on');
        % Z-Label
        zlabel(ax,'z (m)',...
            'Interpreter',DATA.figureProperties.interpreter,...
            'fontname',DATA.figureProperties.fontName,...
            'Fontweight',DATA.figureProperties.fontWeight,...
            'FontSize',DATA.figureProperties.axisFontSize,...
            'FontSmoothing','on');
        % Axes
        set(ax,...
            'TickLabelInterpreter',DATA.figureProperties.interpreter,...
            'fontname',DATA.figureProperties.fontName,...
            'Fontweight',DATA.figureProperties.fontWeight,...
            'FontSize',DATA.figureProperties.axisFontSize,...
            'FontSmoothing','on',...
            'Color',DATA.figureProperties.axesColor,...
            'GridLineStyle','--',...
            'GridAlpha',0.25,...
            'GridColor','k');

        axisLimit = (DATA.figureProperties.objectMaximalRadii + DATA.figureProperties.maxAbsPosition);
        xlim(ax,[-axisLimit,axisLimit]);
        ylim(ax,[-axisLimit,axisLimit]);
        zlim(ax,[-axisLimit,axisLimit]);
        axis manual;
        % Legend
        legend(markerHandle,DATA.figureProperties.legendEntries,...
            'Location','northeastoutside',...
            'interpreter',DATA.figureProperties.interpreter,...
            'fontname',DATA.figureProperties.fontName);
        view([viewPoint inclinationAngle]);     % Set initial view angle
        grid on; box on; hold off; grid minor;
    else
        % CONTINUED FRAMES
        % FOR EACH PLOT ENTITY
        for entity = 1:SIM.totalObjects
            % GET THE OBJECT HANDLE
            objectHandle = objectIndex{SIM.globalIDvector == SIM.OBJECTS(entity).objectID};
            % PULL VARIABLE FROM WORKSPACE
            variableLabel = sprintf('objectID%d',SIM.OBJECTS(entity).objectID); % The variable name in the workspace
            globalStates = eval(variableLabel);                                 % Evalutate object states
            % CHECK IF UPDATE IS NECESSARY
            if any(isnan(globalStates(:,frame)))                                % Object is static, freeze its position
                continue
            end

            % HANDLE DIFFERENT REPRESENTATIONS
            if numel(objectHandle.GEOMETRY.vertices) > 0
                % GET THE GLOBAL POSE AT STEP
                [R_frame] = OMAS_geometry.quaternionToRotationMatrix(globalStates(7:end,frame));
                % BUILD MARKER
                set(markerHandle(entity),'Vertices',objectHandle.GEOMETRY.vertices*R_frame + globalStates(1:3,frame)');
            else
                % UPDATE MARKER DATA
                set(markerHandle(entity),'XData',globalStates(1,frame));
                set(markerHandle(entity),'YData',globalStates(2,frame));
                set(markerHandle(entity),'ZData',globalStates(3,frame));
            end

            % UPDATE TRACE DATA
            if frame <= DATA.figureProperties.tailLength/SIM.TIME.dt
                % TRANSITIONING PERIOD
                tailTrace = globalStates(1:3,1:frame);                     % All points upto the step position
            elseif (frame - DATA.figureProperties.tailLength/SIM.TIME.dt) > 0
                % IF THE TRAIL IS NOW A SUBSET
                tailTrace = globalStates(1:3,(frame-(DATA.figureProperties.tailLength/SIM.TIME.dt)):frame);        % All points upto the step position
            else
                tailTrace = globalStates(1:3,frame);
            end
            % UPDATE TRACE DATA
            set(traceHandle(entity),'XData', tailTrace(1,:));
            set(traceHandle(entity),'YData', tailTrace(2,:));
            set(traceHandle(entity),'ZData', tailTrace(3,:));
        end
    end
    % UPDATE TIMESTAMP ANNOTATION
    set(clockHandle,'String',sprintf('Time: %ss',num2str(frameTimeVector(frame))));
    % FORCE IMAGE WRITE
    drawnow();

    % COLLECT FRAMES
    F(frame) = getframe(figureHandle);
    im = frame2im(F(frame));
    [imind,cm] = rgb2ind(im,256);

    % APPEND THE FRAMES TO GIF
    if frame == 1
        imwrite(imind,cm,figurePath,'gif','Loopcount',inf,'DelayTime',(1/DATA.figureProperties.fps));
    else
        imwrite(imind,cm,figurePath,'gif','WriteMode','append','DelayTime',(1/DATA.figureProperties.fps));
    end
%     viewPoint = viewPoint + viewRate;
end
% FIGURE COMPLETE
currentFigure = currentFigure + 1;
% CLEAN UP
clearvars -except currentFigure figureHandle
end


function [err, Itrans] = AFNI_IndexChange (Info, Iorig, Direction, DispOrient)
%
%   [err, Itrans] = AFNI_IndexChange (Info, Iorig, Direction, [DispOrient])
%
%Purpose:
%   Change the AFNI Index system between the display's and AFNI's coordinate system
%
%
%Input Parameters:
%   Info: The data structure output from BrikInfo
%   Iorig : anNx3 matrix containing the Ix Iy Iz indices of N points
%   Direction : A string : either 'A2D' or 'D2A' meaning Afni to Display or vice versa
%   DispOrient : The orientation string (or vector) for AFNI's display. This parameter is optional
%    and the defualt is 'RAI", it could be 'LAI' if AFNI's using Left is Left option.
%
%Output Parameters:
%   err : 0 No Problem
%       : 1 Mucho Problems
%   Itrans: if Iorig is specified, Itrans is Iorig in the new coordinate system
%
%
%
%Key Terms:
%
%More Info :
%   Test_AFNI_IndexChange
%
%   see also AFNI_CoordChange
%
%
%     Author : Ziad Saad
%     Date : Fri Sep 8 12:21:01 PDT 2000
%     LBC/NIMH/ National Institutes of Health, Bethesda Maryland

%Define the function name for easy referencing
FuncName = 'AFNI_IndexChange';

%Debug Flag
DBG = 1;

%initailize return variables
err = 1;
Itrans= [];
maplocation = [0 0 0];
mapsign = [0 0 0];

if (nargin == 3),
	DispOrient = [0 3 4]; %that's RAI
end

%Assume we're going from Display to Afni ('D2A)
if (ischar(DispOrient)),
	[err, OrCode] = AFNI_OrientCode (DispOrient);
else
	OrCode = DispOrient;
end

	[err, TrCode] = AFNI_OrientCode (Info.Orientation(:,1)');

%check if that's what is required
if (strmatch(Direction, 'A2D')),
	%we're going from Afni to Display coordinates
		tmp = TrCode;
		TrCode = OrCode;
		OrCode = tmp;
else
	if (~strmatch(Direction, 'D2A')),
		err = ErrEval(FuncName,'Err_Bad Direction string');
		return;
	end
end

%get maplocation and mapsign, automatically from AFNI_CoordChange (no need to rewrite the code here)
	[err,maplocation, mapsign] = AFNI_CoordChange (OrCode, TrCode);

Itrans = Iorig;
if (strmatch(Direction, 'A2D')),
		fprintf ('Doing A2D\n');
		%(1-mapsign(i))./2 is 0 when mapsign(i) = 1 and 1 when mapsign(i) = -1;  This way, the if condition for mapsign(i) can be done away with
		%I left the simple method for the second loop for clarity. i don't think there's much efficiency difference between the two.
	for (i=1:1:3),
		Itrans(:,i) = ( (1-mapsign(i))./2 .* (Info.DATASET_DIMENSIONS(maplocation(i)) - 1) ) + ( mapsign(i) .* Iorig(:,maplocation(i)) );
	end
else
		fprintf ('Doing D2A: \n');
	for (i=1:1:3),
		Itrans(:,i) = Iorig(:,maplocation(i));
		if (mapsign(i) < 0),
			Itrans(:,i) = Info.DATASET_DIMENSIONS((i)) -1 - Itrans(:,i);
		end
	end
end

err = 0;
return;


function test_tutorial_beamformer(datadir)

% MEM 8gb
% WALLTIME 03:30:00
% DEPENDENCY ft_redefinetrial ft_freqanalysis ft_volumesegment ft_prepare_singleshell ft_sourceanalysis ft_prepare_leadfield ft_sourceinterpolate ft_sourceplot ft_volumenormalise

if nargin==0
  % this is where the data should be located
  datadir = dccnpath('/home/common/matlab/fieldtrip/data/ftp/tutorial/beamformer');
end

%load(fullfile(datadir, 'dataFIC.mat'));
load(fullfile(datadir, 'data_all.mat'));
load(fullfile(datadir, 'segmentedmri.mat'));
mri = ft_read_mri(fullfile(datadir, 'Subject01.mri'));

%% Preprocess time windows of interest

cfg = [];
cfg.toilim = [-0.5 0];
dataPre = ft_redefinetrial(cfg, data_all);

cfg.toilim = [0.8 1.3];
dataPost = ft_redefinetrial(cfg, data_all);

%% Cross-spectral density

cfg = [];
cfg.method    = 'mtmfft';
cfg.output    = 'powandcsd';
cfg.tapsmofrq = 4;
cfg.foilim    = [18 18];
freqPre = ft_freqanalysis(cfg, dataPre);

cfg = [];
cfg.method    = 'mtmfft';
cfg.output    = 'powandcsd';
cfg.tapsmofrq = 4;
cfg.foilim    = [18 18];
freqPost = ft_freqanalysis(cfg, dataPost);

%% Compute (or load) the forward model)

%try
  %if ~exist(dccnpath('/home/common/matlab/fieldtrip/data/ftp/tutorial/beamformer/segmentedmri.mat'), 'file')
  cfg = [];
  cfg.write        = 'no';
  [segmentedmri] = ft_volumesegment(cfg, mri);
%catch
%  mri = ft_read_mri(dccnpath('/home/common/matlab/fieldtrip/data/ftp/test/ctf/Subject01.mri'));
%  load(dccnpath('/home/common/matlab/fieldtrip/data/ftp/tutorial/beamformer/segmentedmri.mat'));
%end

%% Prepare head model
cfg = [];
cfg.method = 'singleshell';
vol = ft_prepare_headmodel(cfg, segmentedmri);

%% Prepare leadfield
cfg                 = [];
cfg.grad            = freqPost.grad;
cfg.headmodel       = vol;
cfg.reducerank      = 2;
cfg.channel         = {'MEG','-MLP31', '-MLO12'};
cfg.sourcemodel.resolution = 1;   % use a 3-D grid with a 1 cm resolution
cfg.sourcemodel.unit       = 'cm';
[grid] = ft_prepare_leadfield(cfg);

%% Source analysis without contrasting condition

cfg              = [];
cfg.method       = 'dics';
cfg.frequency    = 18;
cfg.sourcemodel         = grid;
cfg.headmodel    = vol;
cfg.dics.projectnoise = 'yes';
cfg.dics.lambda       = 0;

sourcePost_nocon = ft_sourceanalysis(cfg, freqPost);

%save sourcePost_nocon.mat sourcePost_nocon;

% call ft_volumereslice so that figures appear correct side up
mri = ft_volumereslice([], mri);

% Plot the result
cfg            = [];
cfg.downsample = 2;
cfg.parameter  = 'avg.pow';
sourcePostInt_nocon  = ft_sourceinterpolate(cfg, sourcePost_nocon , mri);

cfg              = [];
cfg.method       = 'slice';
cfg.funparameter = 'avg.pow';
figure
ft_sourceplot(cfg,sourcePostInt_nocon);

%% Compute and plot Neural Activity Index
sourceNAI = sourcePost_nocon;
sourceNAI.avg.pow = sourcePost_nocon.avg.pow ./ sourcePost_nocon.avg.noise;

cfg = [];
cfg.downsample = 2;
cfg.parameter  = 'avg.pow';
sourceNAIInt = ft_sourceinterpolate(cfg, sourceNAI , mri);

cfg = [];
cfg.method        = 'slice';
cfg.funparameter  = 'avg.pow';
cfg.maskparameter = cfg.funparameter;
cfg.funcolorlim   = [4.0 6.2];
cfg.opacitylim    = [4.0 6.2];
cfg.opacitymap    = 'rampup';
figure
ft_sourceplot(cfg, sourceNAIInt);

%% Exercise 4: lead field normalization
cfg                 = [];
cfg.grad            = freqPost.grad;
cfg.headmodel       = vol;
cfg.reducerank      = 2;
cfg.channel         = {'MEG','-MLP31', '-MLO12'};
cfg.sourcemodel.resolution = 1;   % use a 3-D grid with a 1 cm resolution
cfg.sourcemodel.unit       = 'cm';
cfg.normalize       = 'yes';
[gridn] = ft_prepare_leadfield(cfg);

cfg              = [];
cfg.method       = 'dics';
cfg.frequency    = 18;
cfg.sourcemodel         = gridn;
cfg.headmodel    = vol;
cfg.dics.projectnoise = 'yes';
cfg.dics.lambda       = 0;
sourcePostn = ft_sourceanalysis(cfg, freqPost);

cfg            = [];
cfg.downsample = 2;
cfg.parameter  = 'avg.pow';
sourcePostIntn  = ft_sourceinterpolate(cfg, sourcePostn , mri);
cfg              = [];
cfg.method       = 'slice';
cfg.funparameter = 'avg.pow';
cfg.maskparameter = cfg.funparameter;
cfg.funcolorlim   = [.6 1.2]*1e-26;
cfg.opacitylim    = [.6 1.2]*1e-26;
cfg.opacitymap    = 'rampup';
figure
ft_sourceplot(cfg,sourcePostIntn);

%% Source analysis with constrasting condition
dataAll = ft_appenddata([], dataPre, dataPost);

cfg = [];
cfg.method    = 'mtmfft';
cfg.output    = 'powandcsd';
cfg.tapsmofrq = 4;
cfg.foilim    = [18 18];
freqAll = ft_freqanalysis(cfg, dataAll);

cfg              = [];
cfg.method       = 'dics';
cfg.frequency    = 18;
cfg.sourcemodel         = grid;
cfg.headmodel    = vol;
cfg.dics.projectnoise = 'yes';
cfg.dics.lambda       = '5%';
cfg.dics.keepfilter   = 'yes';
cfg.dics.realfilter   = 'yes';
sourceAll = ft_sourceanalysis(cfg, freqAll);

cfg.sourcemodel.filter = sourceAll.avg.filter;
sourcePre_con  = ft_sourceanalysis(cfg, freqPre );
sourcePost_con = ft_sourceanalysis(cfg, freqPost);

%save sourcePre_con sourcePre_con
%save sourcePost_con sourcePost_con

% %% Plot results
% cfg            = [];
% cfg.downsample = 2;
% cfg.parameter  = 'avg.pow';
% sourcePostInt  = ft_sourceinterpolate(cfg, sourcePost , mri);
%
% cfg              = [];
% cfg.method       = 'slice';
% cfg.funparameter = 'avg.pow';
% figure
% ft_sourceplot(cfg,sourcePostInt);
%
% %% Plot Condition contrast

sourceDiff = sourcePost_con;
sourceDiff.avg.pow = (sourcePost_con.avg.pow - sourcePre_con.avg.pow) ./ sourcePre_con.avg.pow;

cfg            = [];
cfg.downsample = 2;
cfg.parameter  = 'avg.pow';
sourceDiffInt  = ft_sourceinterpolate(cfg, sourceDiff , mri);

cfg = [];
cfg.method        = 'slice';
cfg.funparameter  = 'avg.pow';
cfg.maskparameter = cfg.funparameter;
cfg.funcolorlim   = [0 1.2];
cfg.opacitylim    = [0 1.2];
cfg.opacitymap    = 'rampup';
figure
ft_sourceplot(cfg, sourceDiffInt);

%% Exercise 6: regularization
cfg              = [];
cfg.method       = 'dics';
cfg.frequency    = 18;
cfg.sourcemodel         = grid;
cfg.headmodel    = vol;
cfg.dics.projectnoise = 'yes';
cfg.dics.lambda       = '0%';
cfg.dics.keepfilter   = 'yes';
cfg.dics.realfilter   = 'yes';
sourceAll = ft_sourceanalysis(cfg, freqAll);
cfg.sourcemodel.filter = sourceAll.avg.filter;
source0Pre  = ft_sourceanalysis(cfg, freqPre );
source0Post = ft_sourceanalysis(cfg, freqPost);
cfg              = [];
cfg.method       = 'dics';
cfg.frequency    = 18;
cfg.sourcemodel         = grid;
cfg.headmodel    = vol;
cfg.dics.projectnoise = 'yes';
cfg.dics.lambda       = '10%';
cfg.dics.keepfilter   = 'yes';
cfg.dics.realfilter   = 'yes';
sourceAll = ft_sourceanalysis(cfg, freqAll);
cfg.sourcemodel.filter = sourceAll.avg.filter;
source10Pre  = ft_sourceanalysis(cfg, freqPre );
source10Post = ft_sourceanalysis(cfg, freqPost);

source0Diff = source0Post;
source0Diff.avg.pow = (source0Post.avg.pow - source0Pre.avg.pow) ./ source0Pre.avg.pow;
cfg            = [];
cfg.downsample = 2;
cfg.parameter  = 'avg.pow';
source0DiffInt  = ft_sourceinterpolate(cfg, source0Diff , mri);
cfg = [];
cfg.method        = 'slice';
cfg.funparameter  = 'avg.pow';
cfg.maskparameter = cfg.funparameter;
cfg.funcolorlim   = [0 1.2];
cfg.opacitylim    = [0 1.2];
cfg.opacitymap    = 'rampup';
figure
ft_sourceplot(cfg, source0DiffInt);

source10Diff = source10Post;
source10Diff.avg.pow = (source10Post.avg.pow - source10Pre.avg.pow) ./ source10Pre.avg.pow;
cfg            = [];
cfg.downsample = 2;
cfg.parameter  = 'avg.pow';
source10DiffInt  = ft_sourceinterpolate(cfg, source10Diff , mri);
cfg = [];
cfg.method        = 'slice';
cfg.funparameter  = 'avg.pow';
cfg.maskparameter = cfg.funparameter;
cfg.funcolorlim   = [0 1.2];
cfg.opacitylim    = [0 1.2];
cfg.opacitymap    = 'rampup';
figure
ft_sourceplot(cfg, source10DiffInt);

%% Orthogonal cut

cfg = [];
cfg.method        = 'ortho';
cfg.funparameter  = 'avg.pow';
cfg.maskparameter = cfg.funparameter;
cfg.funcolorlim   = [0.0 1.2];
cfg.opacitylim    = [0.0 1.2];
cfg.opacitymap    = 'rampup';
figure
ft_sourceplot(cfg, sourceDiffInt);

%% Template MRI

cfg = [];
cfg.nonlinear     = 'no';
sourceDiffIntNorm = ft_volumenormalise(cfg, sourceDiffInt);

cfg = [];
cfg.method        = 'ortho';
%cfg.interactive   = 'yes';
cfg.funparameter  = 'avg.pow';
cfg.maskparameter = cfg.funparameter;
cfg.funcolorlim   = [0.0 1.2];
cfg.opacitylim    = [0.0 1.2];
cfg.opacitymap    = 'rampup';
figure
ft_sourceplot(cfg, sourceDiffIntNorm);

%% Project to a surface
% cfg = [];
% cfg.nonlinear     = 'no';
% sourceDiffIntNorm = ft_volumenormalise(cfg, sourceDiffInt);

cfg = [];
cfg.method         = 'surface';
cfg.funparameter   = 'avg.pow';
cfg.maskparameter  = cfg.funparameter;
cfg.funcolorlim    = [0.0 1.2];
cfg.funcolormap    = 'jet';
cfg.opacitylim     = [0.0 1.2];
cfg.opacitymap     = 'rampup';
cfg.projmethod     = 'nearest';
cfg.surffile       = 'surface_white_both.mat';
cfg.surfdownsample = 10;
figure
ft_sourceplot(cfg, sourceDiffIntNorm);
view ([90 0])