function [flow_out, time_shifted_points_out] = em1_flow_with_prior(...
    events, ...
    feature_pos, ...
    prev_shifted_points, ...
    prev_shifted_weights, ...
    flow_init, ...
    params, ...
    fig)
%EM1_FLOW_WITH_PRIOR Estimates optical flow for an event feature.
%
% EM1_FLOW_WITH_PRIOR estimates the optical flow of a set of events
% combined to form a 'feature'. This EM step uses the time shifted points
% from the previous iteration as a template, as in:
% Alex Zihao Zhu, Nikolay Atanasov and Kostas Daniilidis.
% "Event-based Visual Inertial Odometry",
% IEEE International Conference on Computer Vision and Pattern Recognition (CVPR), 2017.
%
% Syntax:  [flow_out, time_shifted_points_out] = EM1_FLOW_WITH_PRIOR(...
%            events, ...
%            feature_pos, ...
%            prev_shifted_points, ...
%            prev_shifted_weights, ...
%            flow_init, ...
%            params, ...
%            fig)
%
% Inputs:
%    events               - 4xN, each column is (x,y,t,p).
%    feature_pos          - 2x1, pixel position of the feature.
%    prev_shifted_points  - 2xM, time shifted points from the previous
%                           iteration, used as a template.
%    prev_shifted_weights - 1xM, weights for each shifted point.
%    flow_init            - 2x1, initialization for the flow.
%    params               - parameters, defined in get_params().
%    fig                  - figure handle for plotting.
%
% Outputs:
%    flow_out                - 2x1, estimated flow.
%    time_shifted_points_out - 2xN, input events in the feature window
%                              shifted by the flow [x; y] + dt * flow.
%
% See also GET_PARAMS
%
% Author: Alex Zihao Zhu, University of Pennsylvania
% Email: alexzhu(at)seas.upenn.edu
% Copyright 2018 University of Pennsylvania
% Alex Zihao Zhu, Nikolay Atanasov, Kostas Daniilidis
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, CONTRIBUTORS, AND THE
% TRUSTEES OF THE UNIVERSITY OF PENNSYLVANIA "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 OWNER, CONTRIBUTORS OR THE TRUSTEES OF
% THE UNIVERSITY OF PENNSYLVANIA 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.

%% Initialization
flow = flow_init;
prev_flow = flow;
% Estimated flow
flow_out = [nan; nan];
% Estimated canonical events
time_shifted_points_out = [];
delta_flows = zeros(params.em1_params.max_iters, 1);
num_iter = 0;
scatter_plot_handle = [];
event_window = [];

target_time = events(3, 1);

centered_events = events;
centered_events(1:2, :) = bsxfun(@minus, events(1:2, :), feature_pos);

kdtree = KDTreeSearcher(...
    prev_shifted_points' / (sqrt(2) * params.em1_params.sigma), ...
    'Distance', 'euclidean');

if params.debug
    set(0, 'CurrentFigure', fig)
    subplot(2,1,2)
    if ~isempty(prev_shifted_points)
        scatter(prev_shifted_points(1, :), prev_shifted_points(2, :), prev_shifted_weights * 10, 'b.')
    end
end

%% Main EM Loop
while true
    if num_iter > params.em1_params.max_iters
        return
    end

    time_shifted_points = centered_events(1:2,:) + ...
        bsxfun(@times, flow,(target_time-centered_events(3,:)));

    if isempty(event_window)
        event_window = ...
            time_shifted_points(1, :) >= -params.window_size/2 &...
            time_shifted_points(2, :) >= -params.window_size/2 & ...
            time_shifted_points(1, :) <= params.window_size/2 & ...
            time_shifted_points(2, :) <= params.window_size/2;

        n_in_window = sum(event_window);
        if n_in_window < params.min_events_for_em
            return
        end

        centered_events = centered_events(:, event_window);
        time_shifted_points = time_shifted_points(:, event_window);

        weights = zeros(size(prev_shifted_points, 2), size(time_shifted_points, 2));
    end

    [neighbors_cell, distances_cell] = rangesearch(...
        kdtree, ...
        time_shifted_points' / (sqrt(2) * params.em1_params.sigma), ...
        params.em1_params.max_distance);

    distancesstacked = cell2mat(cellfun(...
        @transpose, distances_cell, 'UniformOutput', false))';

    if isempty(distancesstacked)
        return
    end

    % NOTE: 'length' is not the same as @length
    num_neighbors = cellfun('length', neighbors_cell);
    prev_correspondences = cell2mat(cellfun(...
        @transpose, neighbors_cell, 'UniformOutput', false))';
    curr_correspondences = repelem(1:size(time_shifted_points, 2), num_neighbors);

    % It's cheaper to multiply to 0 to reset the weights matrix than to
    % reinitialize it using zeros.
    weightsstacked = exp(-distancesstacked);
    weights = weights * 0;

    valid_inds = sub2indc(...
        curr_correspondences, ...
        prev_correspondences, ...
        size(weights));

    weights(valid_inds) = weightsstacked;
    weights = bsxfun(@times, prev_shifted_weights, weights);
    weights_sum = sum(weights, 1);
    valid_weights = weights_sum > 0;
    weights = bsxfun(@rdivide, weights, weights_sum + 1e-10);

    % Simultaneously minimize over flow and translation
    weighted_prior_points = prev_shifted_points * weights;
    weighted_prior_points = weighted_prior_points(:, valid_weights);

    valid_centered_events = centered_events(:, valid_weights);
    dx = weighted_prior_points(1:2, :) - valid_centered_events(1:2, :);
    dt = target_time - valid_centered_events(3, :);

    flow = (dx*dt') / (dt*dt');

    %% Calculate change in flow, plot debug information.
    if (norm(flow - prev_flow) < params.em1_params.min_err)
        break;
    end

    delta_flows(num_iter+1) = norm(flow - prev_flow);
    prev_flow = flow;

    if params.debug
        set(0, 'CurrentFigure', fig)
        subplot(2,1,1)
        plot(delta_flows(delta_flows > 0),'b')
        title('EM1 with prior change in flow (convergence criterion)')
        xlim([0 params.em1_params.max_iters])

        subplot(2,1,2)
        if (~isempty(scatter_plot_handle))
            delete(scatter_plot_handle)
        end

        if ~isempty(prev_shifted_points)
            hold on
        end

        scatter_plot_handle = scatter(time_shifted_points(1, :), time_shifted_points(2, :),'r.');
        hold off
        axis equal
        axis([-params.window_size/2-5 params.window_size/2+5 -params.window_size/2-5 params.window_size/2+5])
        axis ij

        title('EM1 with prior time shifted events')
        pause(0.01)
    end

    num_iter = num_iter + 1;
end

if params.debug
    pause(0.5)
end

flow_out = flow;

dt = events(3, end) - events(3, 1);
centered_events = bsxfun(@minus, events(1:2, :), feature_pos + flow * dt);
time_shifted_points = centered_events(1:2, :) + ...
    bsxfun(@times, flow, (events(3, end) - events(3,:)));

% Make the window a little bigger.
window_size = round(params.window_size * 1.5);

event_window = time_shifted_points(1, :) >= -window_size/2 & ...
    time_shifted_points(2, :) >= -window_size/2 & ...
    time_shifted_points(1, :) <= window_size/2 & ...
    time_shifted_points(2, :) <= window_size/2;

time_shifted_points_out = time_shifted_points(:, event_window);
end


function planC = uniformizeScanSupInf(planC, tMin, tMax, optS, hBar)
%"uniformizeScanSupInf"
%    Creates the superior and inferior scan arrays so that they
%   are uniform, consistent with the rest of the scan array.
%
%Latest modifications:
% 16 Aug 02, V H Clark, first version.
% 09 Apr 03, JOD, added hBar to input parameter list.
% 18 Feb 05, JRA, Added support for multiple scans.
%
%Usage:
%   function planC = uniformizeScanSupInf(planC, tMin, tMax, optS, hBar)

indexS = planC{end};

for scanNum=1:length(planC{indexS.scan})
    scanStruct = planC{indexS.scan}(scanNum);

	uniformScanInfo = planC{indexS.scan}(scanNum).uniformScanInfo;
	sliceNumSup = uniformScanInfo.sliceNumSup; %superior slice number of original CT scan still being used
	sliceNumInf = uniformScanInfo.sliceNumInf; %inferior slice number of original CT scan still being used
	uniformSliceThickness = uniformScanInfo.sliceThickness;
	scanArray = planC{indexS.scan}(scanNum).scanArray;
	scanInfo = planC{indexS.scan}(scanNum).scanInfo;

	[scanArraySup, scanArrayInf, uniformScanFirstZValue] = uniformizeScanEnds(scanStruct, sliceNumSup, sliceNumInf, uniformSliceThickness, tMin, tMax, optS, hBar);

	uniformScanInfo.firstZValue = uniformScanFirstZValue;
	uniformScanInfo.supInfScansCreated = 1;

	planC{indexS.scan}(scanNum).scanArraySuperior = scanArraySup;
	planC{indexS.scan}(scanNum).scanArrayInferior = scanArrayInf;

	planC{indexS.scan}(scanNum).uniformScanInfo = uniformScanInfo;
end


function Ma = timesv(M,a);
%function Ma = timesv(M,a);
%
% Multiplies a by M:
% a(:,:,i) = M*a(:,:,i)
%
% See also FILTER.

dima = size(a,1);
I = eye(dima);
Ma = armafilterv(a,I,M);


classdef EventDeltaVExpendedConstraint < AbstractConstraint
    %EventDeltaVConstraint Summary of this class goes here
    %   Detailed explanation goes here

    properties
        normFact = 1;
        event LaunchVehicleEvent
        eventNode(1,1) ConstraintStateComparisonNodeEnum = ConstraintStateComparisonNodeEnum.FinalState;

        lb(1,1) double = 0;
        ub(1,1) double = 0;

        evalType(1,1) ConstraintEvalTypeEnum = ConstraintEvalTypeEnum.FixedBounds;
        stateCompType(1,1) ConstraintStateComparisonTypeEnum = ConstraintStateComparisonTypeEnum.Equals;
        stateCompEvent LaunchVehicleEvent
        stateCompNode(1,1) ConstraintStateComparisonNodeEnum = ConstraintStateComparisonNodeEnum.FinalState;
    end

    methods
        function obj = EventDeltaVExpendedConstraint(event, lb, ub)
            obj.event = event;
            obj.lb = lb;
            obj.ub = ub;

            obj.id = rand();
        end

        function [lb, ub] = getBounds(obj)
            lb = obj.lb;
            ub = obj.ub;
        end

        function [c, ceq, value, lwrBnd, uprBnd, type, eventNum, valueStateComp] = evalConstraint(obj, stateLog, celBodyData)
            type = obj.getConstraintType();

            deltaVExpended = EventDeltaVExpendedConstraint.computeTotalDeltaV(stateLog, obj.event);
            value = deltaVExpended;

            if(obj.evalType == ConstraintEvalTypeEnum.StateComparison)
                valueStateComp = EventDeltaVExpendedConstraint.computeTotalDeltaV(stateLog, obj.stateCompEvent);

            else
                valueStateComp = NaN;
            end

            [c, ceq] = obj.computeCAndCeqValues(value, valueStateComp);

            lwrBnd = obj.lb;
            uprBnd = obj.ub;

            eventNum = obj.event.getEventNum();
        end

        function sF = getScaleFactor(obj)
            sF = obj.normFact;
        end

        function setScaleFactor(obj, sF)
            obj.normFact = sF;
        end

        function tf = usesStage(obj, stage)
            tf = false;
        end

        function tf = usesEngine(obj, engine)
            tf = false;
        end

        function tf = usesTank(obj, tank)
            tf = false;
        end

        function tf = usesEngineToTankConn(obj, engineToTank)
            tf = false;
        end

        function tf = usesEvent(obj, event)
            tf = obj.event == event;
            if(obj.evalType == ConstraintEvalTypeEnum.StateComparison)
                tf = tf || obj.stateCompEvent == event;
            end
        end

        function tf = usesStopwatch(obj, stopwatch)
            tf = false;
        end

        function tf = usesExtremum(obj, extremum)
            tf = false;
        end

        function tf = canUseSparseOutput(obj)
            tf = false;
        end

        function event = getConstraintEvent(obj)
            event = obj.event;
        end

        function type = getConstraintType(obj)
            type = 'Event Delta-V Expended';
        end

        function [unit, lbLim, ubLim, usesLbUb, usesCelBody, usesRefSc] = getConstraintStaticDetails(obj)
            unit = 'km/s';
            lbLim = 0;
            ubLim = Inf;
            usesLbUb = true;
            usesCelBody = false;
            usesRefSc = false;
        end

        function addConstraintTf = openEditConstraintUI(obj, lvdData)
%             addConstraintTf = lvd_EditGenericMAConstraintGUI(obj, lvdData);

            output = AppDesignerGUIOutput({false});
            lvd_EditGenericMAConstraintGUI_App(obj, lvdData, output);
            addConstraintTf = output.output{1};
        end
    end

    methods(Static, Access=private)
        function deltaVExpended = computeTotalDeltaV(stateLog, event)
            subStateLog = stateLog.getAllStateLogEntriesForEvent(event);

            if(length(subStateLog) > 1)
                g0 = getG0();
                deltaVExpended = 0;

                for(i=1:length(subStateLog)-1) %#ok<NO4LP>
                    stateLogEntry1 = subStateLog(i);
                    stateLogEntry2 = subStateLog(i+1);

                    ut = stateLogEntry1.time;
                    rVect = stateLogEntry1.position;
                    vVect = stateLogEntry1.velocity;

                    bodyInfo = stateLogEntry1.centralBody;
                    tankStates = stateLogEntry1.getAllActiveTankStates();
                    stageStates = stateLogEntry1.stageStates;
                    lvState = stateLogEntry1.lvState;

                    dryMass = stateLogEntry1.getTotalVehicleDryMass();
                    tankStatesMasses = [tankStates.tankMass]';

                    throttleModel = stateLogEntry1.throttleModel;
                    steeringModel = stateLogEntry1.steeringModel;

                    altitude = norm(rVect) - bodyInfo.radius;
                    pressure = getPressureAtAltitude(bodyInfo, altitude);

                    powerStorageStates = stateLogEntry1.getAllActivePwrStorageStates();
                    storageSoCs = NaN(size(powerStorageStates));
                    for(j=1:length(powerStorageStates))
                        storageSoCs(j) = powerStorageStates(j).getStateOfCharge();
                    end

                    throttle = throttleModel.getThrottleAtTime(ut, rVect, vVect, tankStatesMasses, dryMass, stageStates, lvState, tankStates, bodyInfo, storageSoCs, powerStorageStates);

                    [tankMDots, totalThrust, ~] = LaunchVehicleStateLogEntry.getTankMassFlowRatesDueToEngines(tankStates, tankStatesMasses, stageStates, throttle, lvState, pressure, ut, rVect, vVect, bodyInfo, steeringModel, storageSoCs, powerStorageStates, []);

                    if(abs(sum(tankMDots)) > 0)
                        tankMDotsKgS = tankMDots * 1000;
                        totalMDotKgS = sum(tankMDotsKgS); %should be negative
                        totalThrustN = totalThrust * 1000;
                        effIsp = totalThrustN / (getG0() * abs(totalMDotKgS)); %sec

                        totalMass1 = dryMass + stateLogEntry1.getTotalVehiclePropMass();
                        totalMass2 = dryMass + stateLogEntry2.getTotalVehiclePropMass();

                        if(totalMass1 > totalMass2 && stateLogEntry1.time < stateLogEntry2.time)
                            deltaVExpended = deltaVExpended + (g0 * effIsp * log(totalMass1 / totalMass2))/1000; %need to convert to km/s
                        end
                    end
                end
            else
                deltaVExpended = 0;
            end
        end
    end

    methods(Static)
        function constraint = getDefaultConstraint(~, ~)
            constraint = EventDeltaVExpendedConstraint(LaunchVehicleEvent.empty(1,0),0,0);
        end
    end
end


% Li, Hui and Wu, Xiao-Jun and Durrani, Tariq S. Infrared and Visible Image Fusion with ResNet and zero-phase component analysis
% Infrared Physics & Technology, v102, 2019.
% ResNet50 + ZCA & norm(l1, l2, nuclear)

clear all
clc

addpath(genpath('D:\develop\matconvnet\matlab\')); % matconvnet path
% load the pre-trained model - ResNet-50
model_path = './models/';
% http://www.vlfeat.org/matconvnet/pretrained/
net_ = load([model_path, 'imagenet-resnet-50-dag.mat']);
net = dagnn.DagNN.loadobj(net_);
net.mode = 'test';
%% remove layers - ResNet50
% Conv5 - res5cx
for i = 173:175
    net.removeLayer(net.layers(173).name);
end
net_res5cx = net;
% Conv4 - res4fx
net = dagnn.DagNN.loadobj(net_);
net.mode = 'test';
for i = 141:175
    net.removeLayer(net.layers(141).name);
end
net_res4fx = net;

%% Start
n = 20; % number of sourc image
time = zeros(n,1);

% testing dataset
test_path_ir = './IV_images/IR/';
fileFolder_ir=fullfile(test_path_ir);
dirOutput_ir =dir(fullfile(fileFolder_ir,'*'));
num_ir = length(dirOutput_ir);

test_path_vis = replace(test_path_ir, '/IR/', '/VIS/');
fileFolder_vis=fullfile(test_path_vis);
dirOutput_vis =dir(fullfile(fileFolder_vis,'*'));

for i=3:num_ir
    index = i;
    disp(num2str(index));

    % infrared and visible images
    path1 = [test_path_ir,dirOutput_ir(i).name]; % IR image
    path2 = [test_path_vis,dirOutput_vis(i).name]; % VIS image

    % block - 5*5
    % l1 norm
    fuse_path5 = ['./fused_iv/fused_resnet_zca_',dirOutput_ir(i).name];

    image1 = imread(path1);
    image2 = imread(path2);
    image1 = im2double(image1);
    image2 = im2double(image2);

    tic;
    %% Extract features, run the net - ResNet50
    disp('ResNet');
    if size(image1, 3)<3
        I1 = make_3c(image1);
    end
    if size(image2, 3)<3
        I2 = make_3c(image2);
    end
    I1 = single(I1) ; % note: 255 range
    I2 = single(I2) ; % note: 255 range

    % I1
    disp('run the ResNet - I1');
    net_res4fx.eval({'data', I1}) ;
    output4_1 = net_res4fx.vars(net_res4fx.getVarIndex('res4fx')).value ;
    net_res5cx.eval({'data', I1}) ;
    output5_1 = net_res5cx.vars(net_res5cx.getVarIndex('res5cx')).value ;
    % I2
    disp('run the ResNet - I2');
    net_res4fx.eval({'data', I2}) ;
    output4_2 = net_res4fx.vars(net_res4fx.getVarIndex('res4fx')).value ;
    net_res5cx.eval({'data', I2}) ;
    output5_2 = net_res5cx.vars(net_res5cx.getVarIndex('res5cx')).value ;

    %% extract features - ZCA & l1-norm operation
    disp('extract features(whitening operation) - I1');
    feature4_1 = whitening_norm(output4_1);
    feature5_1 = whitening_norm(output5_1);
    disp('extract features(whitening operation) - I2');
    feature4_2 = whitening_norm(output4_2);
    feature5_2 = whitening_norm(output5_2);

    %% fusion strategy - resize to original size and soft-max
    disp('fusion strategy(weighting)');
    % output4 - 1024
    [F_relu4, weight4_a, weight4_b] = fusion_strategy(feature4_1, feature4_2, image1, image2);
    % output5 - 2048
    [F_relu5, weight5_a, weight5_b] = fusion_strategy(feature5_1, feature5_2, image1, image2);
    time(i) = toc;

%     imwrite(F_relu4,fuse_path4,'png');
    imwrite(F_relu5,fuse_path5,'png');
end


%% triangleRayIntersection
% Below is a demonstration of the features of the |triangleRayIntersection| function

%%
clear; close all; clc;

%% Syntax
% |[V_intersect,L_intersect,T] = triangleRayIntersection (V_ori,R,V,F,optStruct);|

%% Description
% UNDOCUMENTED
%% Examples
%
%%
%
% <<gibbVerySmall.gif>>
%
% _*GIBBON*_
% <www.gibboncode.org>
%
% _Kevin Mattheus Moerman_, <gibbon.toolbox@gmail.com>
%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function domisfit(catalog,sig,plu,az,phi,R)
    % domisfit calculates the misfit for each EQ to a given stress tensor orientation.
    % The actual calculation is done using a call to a fortran program.
    %
    % Stefan Wiemer 07/95

    ZG=ZmapGlobal.Data; % used by get_zmap_globals

    global mi mif1 mif2 newcat2 mi2
    global cumu2
    report_this_filefun();

    hodis = fullfile(ZG.hodi, 'external');
    cd(hodis);

    % prepare the focal; mechnism in Gephard format ...
    tmp = [catalog(:,10:12) ];
    tmp(tmp(:,2) >89.999,2) = 89.;

    try
        save data.inp tmp -ascii
    catch ME
        error_handler(ME, ['Error - could not save file ' ZmapGlobal.Data.Directories.output 'data.inp - permission?']);
    end

    infi =  'data.inp';
    outfi = 'tmpin.dat';
    fid = fopen('inmifi.dat','w');
    fprintf(fid,'%s\n',infi);
    fprintf(fid,'%s\n',outfi);
    fclose(fid);

    delete(outfi)

    [status, result] = system('datasetupDD < inmifi.dat');

    fid = ('tmpin.dat');
    format = '%f%f%f%f%f';
    %[d1, d2, d3, d4, d5] = textread(fid,format,'headerlines',1);
    C = textscan(fid,format,'HeaderLines',1); %Problem: "Errorlines" cause crashes.
    dall=[C{:}];

    %dall = [d1, d2, d3, d4, d5];
    save tmpin.dat dall -ascii

    infi = 'tmpin.dat';
    outfi = 'tmpout.dat';

    fid = fopen('inmifi.dat','w');

    fprintf(fid,'%s\n',infi);
    fprintf(fid,'%s\n',outfi);
    fprintf(fid,'%2.0f\n',sig);
    fprintf(fid,'%6.2f\n',plu);
    fprintf(fid,'%6.2f\n',az);
    fprintf(fid,'%6.2f\n',phi);
    fprintf(fid,'%3.2f\n',R);
    le = catalog.Count;
    fprintf(fid,'%6i\n',le);

    fclose(fid);
    try
        delete outfi
    catch ME
        warning(ME.message);
    end

    comm = 'testfm < inmifi.dat'
    [status,result]=system(comm)
    try
        % CGR: it looks like the format will be:
        % line 1: ndata kdata  [where ndata is # of data, kdata is # of fault planes]
        % lines 2-end : az1 dip1 az2 dip2 wt
        % load('tmpout.dat')
        s=importdata('../external/tmpout.dat', ' ', 1);

        headernumbers=str2num(s.textdata{1});
        nData=headernumbers(1);
        kData=headernumbers(2);

        mi = s.data; % probably as [az1, dip1, az2, dip2, wt ; ...]
    catch ME
        warning(ME.message)
    end

    % mi = tmpout; % mi gets results from the fortran progarm

    misfitAngle=mi(:,2);

    mif1=findobj('Type','Figure','-and','Name','Misfit Map');

    if isempty(mif1)
        mif1 = figure_w_normalized_uicontrolunits( ...
            'Name','Misfit Map',...
            'NumberTitle','off', ...
            'backingstore','on',...
            'NextPlot','add', ...
            'Visible','off', ...
            'Position',position_in_current_monitor(ZG.map_len(1), ZG.map_len(2)));

        create_my_menu_1();

        labelList=['Size | Size + Thickness | Size +Thickness +color  '];
        labelPos = [0.2 0.93 0.35 0.05];
        hndl2=uicontrol(...
            'Style','popup',...
            'Units','normalized',...
            'Position',labelPos,...
            'String',labelList,...
            'BackgroundColor',[0.7 0.7 0.7]',...
            'callback',@callbackfun_005);

        decimationList=['1 | 1/2 | 1/3 | 1/4 | 1/5 | 1/6| 1/7| 1/8 | 1/9 | 1/10'];
        labelPos = [0.9 0.93 0.10 0.05];
        uicontrol(...
            'Style','popup',...
            'Units','normalized',...
            'Position',labelPos,...
            'Value',4,...
            'String',decimationList,...
            'BackgroundColor',[0.7 0.7 0.7]',...
            'callback',@store_decimation_cb);

        uicontrol(...
            'Style','pushbutton',...
            'Units','normalized',...
            'Position',[0.9 0.6 0.08 0.08],...
            'String','X-sec',...
            'callback',@callbackfun_007);
        set(gca,'NextPlot','add')
        %end killed
        uicontrol(...
            'Style','pushbutton',...
            'Units','normalized',...
            'Position',[0.9 0.7 0.08 0.08],...
            'String','Map',...
            'callback',@callbackfun_008);
        set(gca,'NextPlot','add')
    end

    figure(mif1)

    plotmima(4, mi)

    mif2=findobj('Type','Figure','-and','Name','Misfit ');

    if isempty(mif2)
        mif2 = figure_w_normalized_uicontrolunits( ...
            'Name','Misfit ',...
            'NumberTitle','off', ...
            'backingstore','on',...
            'NextPlot','add', ...
            'Visible','off', ...
            'Position',position_in_current_monitor(ZG.map_len(1), ZG.map_len(2)));

        create_my_menu_2();
        listFields={'Longitude','Latitude','Time','Magnitude','Depth','Strike','Default'};
        labelPos = [0.7 0.9 0.25 0.08];
        hFieldChoice=uicontrol(...
            'Style','popup',...
            'Units','normalized',...
            'Position',labelPos,...
            'String',listFields,...
            'BackgroundColor',[0.7 0.7 0.7]',...
            'callback',@callbackfun_012);
        set(gca,'NextPlot','add')
    end

    figure(mif2)
    delete(findobj(mif2,'Type','axes'));

    plotmi(listFields{1}, catalog, mi)

    %% ui functions
    function create_my_menu_1() %TODO rename to something more intelligent
        add_menu_divider();    %
        omp2= uimenu('Label','Tools');
        uimenu(omp2,'label','Misfit-Magnitude',...
            'MenuSelectedFcn',@cb_misfitmag);
        uimenu(omp2,'label','Misfit-Depth',...
            'MenuSelectedFcn',@cb_misfitdep);
        uimenu(omp2,'label','Earthquake-Depth',...
            'MenuSelectedFcn',@cb_eqdep);
        uimenu(omp2,'label','Earthquake-Strike',...
            'MenuSelectedFcn',@cb_eqstrike);
        %
    end

    function create_my_menu_2() %TODO rename to something more intelligent
        add_menu_divider();
        omp1= uimenu('Label','Tools');
        uimenu(omp1,'label','Save sorted catalog',...
            'MenuSelectedFcn',@callbackfun_009);
        uimenu(omp1,'label','AS Function',...
            'MenuSelectedFcn',@cb_astmisfit);
        uimenu(omp1,'label','Compare',...
            'MenuSelectedFcn',@cb_comparemisfit);
    end

    %% callback functions
    function cb_misfitmag(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        mi_ma(misfitAngle);
    end

    function cb_misfitdep(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        mi_dep(misfitAngle);
    end

    function cb_eqdep(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        eq_dep(misfitAngle);
    end

    function cb_eqstrike(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        earthquake_strike();
    end

    function callbackfun_005(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        in2=hndl2.Value;
        plotmima(in2, mi);
    end

    function store_decimation_cb(mysrc,myevt)
        global oneOfHowManyPopupIdx
        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        in3=mysrc.Value;
        oneOfHowManyPopupIdx=in3;
        in2=hndl2.Value;
        plotmima(in2, mi) ;
    end

    function callbackfun_007(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        var1 = 3;
        plotmimac(mi, inde); % No idea what inde is or where it comes from
    end

    function callbackfun_008(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        var1 = 1;
        mifigrid(var1,mi);
    end

    function callbackfun_009(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        save_sortpere;
    end

    function cb_astmisfit(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        ast_misfit();
    end

    function cb_comparemisfit(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        compare_misfit();
    end

    function callbackfun_012(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        in2=hFieldChoice.Value;
        plotmi(listfields{in2}, catalog, mi);
    end

end

function earthquake_strike()
    % plot the earthquake number along the strike on the map view
    %	August 1995 by Zhong Lu

    ZG=ZmapGlobal.Data; % used by get_zmap_globals
    report_this_filefun();
    myFigName='Earthquake Number Map';
    mif55=findobj('Type','Figure','-and','Name',myFigName);

    if isempty(mif55)
        mif55 = figure_w_normalized_uicontrolunits( ...
            'Name',myFigName,...
            'NumberTitle','off', ...
            'backingstore','on',...
            'NextPlot','add', ...
            'Visible','off', ...
            'Position',position_in_current_monitor(ZG.map_len(1), ZG.map_len(2)));
    end
    figure(mif55)

    set(gca,'NextPlot','add')

    tt = newcat2;
    [ts,ti] = sort(tt(:,15));
    tt = tt(ti(:,1),:);

    for i = 1:length(tt)
        pt = plot(tt(i,1),tt(i,2),'o');
        set(gca,'NextPlot','add')
    end

end

function eq_dep(misfitAngle)
    %  earthquake_depth
    % August 95 by Zhong Lu

    ZG=ZmapGlobal.Data; % used by get_zmap_globals

    report_this_filefun();
    myFigName='Depth vs Earthquake Number';

    mif66=findobj('Type','Figure','-and','Name',myFigName);

    if isempty(mif66)
        mif66 = figure_w_normalized_uicontrolunits( ...
            'Name',myFigName,...
            'NumberTitle','off', ...
            'backingstore','on',...
            'NextPlot','add', ...
            'Visible','off', ...
            'Position',position_in_current_monitor(ZG.map_len(1), ZG.map_len(2)));
    end
    figure(mif66)
    set(gca,'NextPlot','add')

    x = [1:length(mmi)]';
    [ss,ssi]=sort(catalog.Depth);
    plot(x,ss,'go');

    grid on

    ylabel('Depth of Earthquake','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m);
    xlabel('Earthquake Number','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m);
    set(gca,'NextPlot','replace');
end

function mi_dep(misfitAngle)
    %  misfit_magnitude
    % August 95 by Zhong Lu

    ZG=ZmapGlobal.Data; % used by get_zmap_globals

    report_this_filefun();

    mif77=findobj('Type','Figure','-and','Name','Misfit as a Function of Depth');

    if isempty(mif77)
        mif77 = figure_w_normalized_uicontrolunits( ...
            'Name','Misfit as a Function of Depth',...
            'NumberTitle','off', ...
            'backingstore','on',...
            'NextPlot','add', ...
            'Visible','off', ...
            'Position',position_in_current_monitor(ZG.map_len(1), ZG.map_len(2)));

        set(gca,'NextPlot','add')

    end
    figure_w_normalized_uicontrolunits(mif77)
    set(gca,'NextPlot','add')

    plot(catalog.Depth,misfitAngle,'go');

    grid
    %set(gca,'box','on',...
    %        'SortMethod','childorder','TickDir','out','FontWeight',...
    %        'bold','FontSize',ZmapGlobal.Data.fontsz.m,'Linewidth',1.2);

    xlabel('Depth of Earthquake','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m);
    ylabel('Misfit Angle ','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m);
    set(gca,'NextPlot','replace');
end

function mi_ma(misfitAngle)
    %  misfit_magnitude
    % August 95 by Zhong Lu

    ZG=ZmapGlobal.Data; % used by get_zmap_globals

    report_this_filefun();

    mif88=findobj('Type','Figure','-and','Name','Misfit as a Function of Magnitude');

    if isempty(mif88)
        mif88 = figure_w_normalized_uicontrolunits( ...
            'Name','Misfit as a Function of Magnitude',...
            'NumberTitle','off', ...
            'backingstore','on',...
            'NextPlot','add', ...
            'Visible','off', ...
            'Position',position_in_current_monitor(ZG.map_len(1), ZG.map_len(2)));

        set(gca,'NextPlot','add')

    end
    figure(mif88)
    set(gca,'NextPlot','add')

    plot(catalog.Magnitude,misfitAngle,'go');

    grid
    %set(gca,'box','on',...
    %        'SortMethod','childorder','TickDir','out','FontWeight',...
    %        'bold','FontSize',ZmapGlobal.Data.fontsz.m,'Linewidth',1.2);

    xlabel('Magnitude of Earthquake','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m);
    ylabel('Misfit Angle ','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m);
    set(gca,'NextPlot','replace');
end

function ast_misfit()
    %  ast_misfit calculates A as(t) value for a cumulative number curve and displayed in the plot.
    %

    ZG=ZmapGlobal.Data; % used by get_zmap_globals

    report_this_filefun();

    dat(:,2)=mi2(:,2);
    dat(:,1)=[1:length(mi2(:,1))]';
    cumu = dat(:,2);
    xt = dat(:,1);
    cumu2 = cumsum(cumu);

    %  winlen_days is the cutoff at the beginning and end of the analyses
    %  to avoid spikes at the end
    winlen_days = 5;

    %
    % calculate mean and z value
    ncu = length(xt);
    as = zeros(1,ncu);

    t0b = dat(1,1);
    n = length(dat(:,1));
    teb = dat(n,1);
    tdiff = ncu;

    for i = winlen_days+1:tdiff-winlen_days
        mean1 = mean(cumu(1:i));
        mean2 = mean(cumu(i+1:ncu));
        var1 = cov(cumu(1:i));
        var2 = cov(cumu(i+1:ncu));
        as(i) = (mean1 - mean2)/(sqrt(var1/i+var2/(tdiff-i)));
    end     % for i

    %  Plot the as(t)
    %clf
    figure;
    orient landscape
    % orient tall
    rect = [0.1,  0.10, 0.8, 0.7];
    axes('position',rect);
    yyaxis('left')
    plot(xt,as);
    yyaxis('right')
    plot(xt,cumu2);
    xlabel('Event');
    ylabel('z-value');
    grid

    set(gca,'NextPlot','add');

    %  show option from here
    %
    uicontrol('Units','normal','Position',[.9 .86 .10 .05],'String','Close', 'callback',@(~,~)close())

    str2 = 'AS of Earthquake Number';
    title(str2);
end

function compare_misfit()
    % Compare is used to compare the significance of two segments
    % in the plot of cumulative misfit as a function of earthquake number.
    %  --- Zhong Lu, June 1994.
    %
    % turned into function by Celso G Reyes 2017

    ZG=ZmapGlobal.Data; % used by get_zmap_globals

    report_this_filefun();

    dat(:,2)=mi2(:,2);
    dat(:,1)=[1:length(mi2(:,1))]';
    cumu = dat(:,2);
    xt = dat(:,1);
    cumu2 = cumsum(cumu);

    set(gca,'NextPlot','add');
    ZG.bin_dur = days(0.5);
    par2 = 1.0;
    choice = input('type 1 to select range with cursor, 2 to input event numbers  ');
    if choice == 1
        t1 = [];
        t1 = ginput(1);
        t1(1)=round(t1(1));
        t1p = [  t1 ; t1(1) t1(2)-ZG.bin_dur];
        plot(t1p(:,1),t1p(:,2),'r');
        text( t1(1),t1(2)-par2,['t1: ', num2str(t1p(1))] );

        t2 = [];
        t2 = ginput(1);
        t2(1)=round(t2(1));
        t2p = [  t2 ; t2(1) t2(2)-ZG.bin_dur];
        plot(t2p(:,1),t2p(:,2),'r');
        text( t2(1),t2(2)-par2,['t2: ', num2str(t2p(1))] );

        t3 = [];
        t3 = ginput(1);
        t3(1)=round(t3(1));
        t3p = [  t3 ; t3(1) t3(2)+ZG.bin_dur];
        plot(t3p(:,1),t3p(:,2),'r');
        text( t3(1),t3(2)+par2,['t3: ', num2str(t3p(1))] );

        t4 = [];
        t4 = ginput(1);
        t4(1)=round(t4(1));
        t4p = [  t4 ; t4(1) t4(2)+ZG.bin_dur];
        plot(t4p(:,1),t4p(:,2),'r');
        text( t4(1),t4(2)+par2,['t4: ', num2str(t4p(1))] );
    else
        %tmp = 't1(1),t2(1),t3(1),t4(1)';
        t1(1) = str2double(input('type the 1st event number, then return    ','s'));
        t2(1) = str2double(input('type the 2nd event number, then return    ','s'));
        t3(1) = str2double(input('type the 3rd event number, then return    ','s'));
        t4(1) = str2double(input('type the last event number, then return    ','s'));
    end  % if
    set(gca,'NextPlot','add');

    mean1 = mean(cumu(t1(1):t2(1)));
    mean2 = mean(cumu(t3(1):t4(1)));
    var1  = cov(cumu(t1(1):t2(1)));
    var2  = cov(cumu(t3(1):t4(1)));
    zvalue = (mean1 - mean2)/(sqrt(var1/(t2(1)-t1(1)+1)+var2/(t4(1)-t3(1)+1)))

    if abs(zvalue) >= 2.58 %99%
        S = sprintf('Significant at 99%% ');
        disp(S);
    elseif abs(zvalue) >= 1.96 %95%
        S = sprintf('Significant at 95%% ');
        disp(S);
    elseif abs(zvalue) >= 1.64 %90%
        S = sprintf('Significant at 90%% ');
        disp(S);
    elseif abs(zvalue) >= 1.44 %85%
        S = sprintf('Significant at 85%% ');
        disp(S);
    else
        S = sprintf('May Significant below 85%% ');
        disp(S);
    end % if

    % use the t-test
    tvalue=(mean1 - mean2) * sqrt(t2(1)-t1(1)+t4(1)-t3(1)) / sqrt((t2(1)-t1(1)) * var1+(t4(1)-t3(1))*var2) / sqrt(1.0/(t2(1)-t1(1)+1)+1.0/(t4(1)-t3(1)+1))

    N=t2(1)-t1(1)+t4(1)-t3(1)
    disp('N=n1+n2-2');

end

function plotmima(var1, mi)
    report_this_filefun();

    ZG=ZmapGlobal.Data;
    global mif1
    global oneOfHowManyPopupIdx

    sc = oneOfHowManyPopupIdx;
    angMisfit = mi(:,2)+1; % added 1 because it's used as sizes
    figure(mif1) %TODO figure out where mif1 comes from
    delete(findobj(mif1,'Type','axes'));
    rect = [0.15,  0.20, 0.75, 0.65];
    axes('position',rect)
    watchon

    if var1 == 1

        for i = 1:catalog.Count
            pl =  plot(catalog.Longitude(i),catalog.Latitude(i),'ro');
            set(gca,'NextPlot','add')
            set(pl,'MarkerSize',angMisfit(i)/sc)
        end

    elseif var1 == 2

        for i = 1:catalog.Count
            pl =  plot(catalog.Longitude(i),catalog.Latitude(i),'bx');
            set(gca,'NextPlot','add')
            set(pl,'MarkerSize',angMisfit(i)/sc,'LineWidth',angMisfit(i)/sc)
        end

    elseif var1 == 3

        for i = 1:catalog.Count
            pl =  plot(catalog.Longitude(i),catalog.Latitude(i),'bx');
            set(gca,'NextPlot','add')
            c = angMisfit(i)/max(angMisfit);
            set(pl,'MarkerSize',angMisfit(i)/sc,'LineWidth',angMisfit(i)/sc,'Color',[ c c c ] )
        end

    elseif var1 == 4
        pl =  plot(catalog.Longitude,catalog.Latitude,'bx');
    end

    set(gca,'NextPlot','add')
    %axis([ s2_west s1_east s4_south s3_north])
    %zmap_update_displays();

    xlabel('Longitude [deg]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
    ylabel('Latitude [deg]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
    strib = 'Misfit Map ';
    title(strib,'FontWeight','bold',...
        'FontSize',ZmapGlobal.Data.fontsz.m,'Color','k')

    set(gca,'Color',color_bg);
    set(gca,'box','on',...
        'SortMethod','childorder','TickDir','out','FontWeight',...
        'bold','FontSize',ZmapGlobal.Data.fontsz.m,'Linewidth',1.2)
    watchoff
end

function plotmimac(mi,inde)

    % TODO maybe move into domisfit

    ZG=ZmapGlobal.Data; % used by get_zmap_globals

    report_this_filefun();

    global mif2 mif1
    global oneOfHowManyPopupIdx

    %var1 = 4;
    sc = oneOfHowManyPopupIdx;
    figure(UNK) % FIXME: really? this figure? unsure
    delete(findobj(UNK,'Type','axes'));
    rect = [0.15,  0.20, 0.75, 0.65];
    axes('position',rect)
    watchon

    % check if cross-section exists
    figNumber=findobj('Type','Figure','-and','Name','Cross -Section');

    if isempty(figNumber)
        errordlg('Please create a cross-section first, then rerun the last selection');
        nlammap
        return
    end

    % check if cross-section is still current
    if max(mi(:,1)) > length(mi(:,1))
        errordlg('Please rerun the cross-section first, then rerun the last selection');
        nlammap
        return
    end

    mic = mi(inde,:);
    le = size(newa,2); %FIXME where does newa come from? ZG.newa? input parameter?  Needs to be treated like a ZmapCatalog

    if var1 == 1
        for i = 1:length(newa(:,6))
            pl =  plot(newa(i,le),-newa(i,7),'ro');
            set(gca,'NextPlot','add')
            set(pl,'MarkerSize',mic(i,2)/sc)
        end

    elseif var1 == 2

        for i = 1:length(newa(:,6))
            pl =  plot(newa(i,le),-newa(i,7),'bx');
            set(gca,'NextPlot','add')
            set(pl,'MarkerSize',mic(i,2)/sc,'LineWidth',mic(i,2)/sc)
        end

    elseif var1 == 3

        for i = 1:length(newa(:,6))
            pl =  plot(newa(i,le),-newa(i,7),'bx');
            set(gca,'NextPlot','add')
            c = mic(i,2)/max(mic(:,2));
            %c = newa(i,15)*10;
            set(pl,'MarkerSize',mic(i,2)/sc+3,'LineWidth',mic(i,2)/sc+0.5,'Color',[ c c c ] )
        end

    elseif var1 == 4

        g = jet;
        for i = 1:length(newa(:,6))
            pl =  plot(newa(i,le),-newa(i,7),'bx');
            set(gca,'NextPlot','add')
            c = floor(mic(i,2)/max(mic(:,2))*63+1);
            set(pl,'MarkerSize',4,'LineWidth',2,'Color',[ g(c,:) ] )
        end
        colorbar
        colormap(jet)
    end

    if exist('maex', 'var')
        set(gca,'NextPlot','add')
        pl = plot(maex,-maey,'*m');
        set(pl,'MarkerSize',8,'LineWidth',2)
    end

    if exist('maex', 'var')
        set(gca,'NextPlot','add')
        pl = plot(maex,-maey,'*m');
        set(pl,'MarkerSize',8,'LineWidth',2)
    end

    xlabel('Distance [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
    ylabel('Depth [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
    strib = [  'Misfit '];
    title(strib,'FontWeight','bold',...
        'FontSize',ZmapGlobal.Data.fontsz.m,'Color','k')

    set(gca,'Color',color_bg);
    set(gca,'box','on',...
        'SortMethod','childorder','TickDir','out','FontWeight',...
        'bold','FontSize',ZmapGlobal.Data.fontsz.m,'Linewidth',1.2)
    uicontrol(...
        'Style','pushbutton',...
        'Units','normalized',...
        'Position',[0.9 0.7 0.08 0.08],...
        'String','Grid',...
        'callback',@(~,~)mificrgr(mi,inde));

    uicontrol(...
        'Style','pushbutton',...
        'Units','normalized',...
        'Position',[0.9 0.6 0.08 0.08],...
        'String','Sel EQ',...
        'callback',@cb_pickinv);

    watchoff

    function cb_pickinv(~,~)
        newa2=crosssel(newa);
        ZG.newt2=newa2;
        ZG.newcat=newa2;
        ctp=CumTimePlot(ZG.newt2);
        ctp.plot();
    end
end

function newcat2=plotmi(var1, newcat2, mi)
    %plot misfit (?)
    % TODO make this work with the new catalogs
    report_this_filefun();

    global  mif2 mif1
    global tmp % REALLY? global tmp?  "tmp" is 1:nEvents
    % cumu2 mi2
    figNumber=findobj('Type','Figure','-and','Name','Misfit ');
    figure(figNumber);
    delete(findobj(figNumber,'Type','axes'));
    rect = [0.15,  0.15, 0.75, 0.65];
    axes('position',rect)
    ax=gca;
    nEvents=newcat2.Count;
    tmp=1:nEvents;
    sixSlices=round(0 : nEvents/5 : nEvents);
    sixSlices(1)=1;

    var2=var1;

    misfitAngle = mi(:,2);
    X = 1:nEvents;
    xtitle=sprintf('Number of Eqs (sorted by %s)',lower(var1));
    switch (var1)
        case {'Longitude','Latitude','Magnitude','Depth'}
            % plot_by_lon(); %by lon
            plot_by_field(var1);
        case 'Time'
            plot_by_time(); % by date
        case 'Strike'
            plot_by_strike(); % along strike
        case 'Default'
            option_7(); %unsorted
        otherwise
            error('unknown choice for plotmi');
    end

    grid('on')
    set(ax,'Color',color_bg);
    set(ax,'box','on',...
        'SortMethod','childorder','TickDir','out','FontWeight',...
        'bold','FontSize',ZmapGlobal.Data.fontsz.m,'Linewidth',1.2)
    ylabel('Cumulative Misfit ','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m);
    xlabel(xtitle,'FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)

    if var1 ~= "Default"
        set(gca,'NextPlot','add')
        for i=1:6
            plot(ax,tmp(sixSlices(i)),cumu2(sixSlices(i)),'xr');
            str=['  ',num2str(newcat2(sixSlices(i),var2))];
            te=text(tmp(sixSlices(i)),cumu2(sixSlices(i)),str);
            set(te,'FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.s)
        end
    else

    end

    function plot_by_field(name)
        % assumes that misfit matrix (mi) has same number of rows as
        % number of earthquakes in catalog
        [~,is] = sort(newcat2.(name));
        newcat2.sort(name); % sort the catalog itself by this field

        cumu2=cumsum(misfitAngle(is));
        plot(1:nEvents , cumu2 , 'o');
        xtitle=sprintf('Number of Eqs (sorted by %s)',lower(name));
    end

    function plot_by_time()
        [~,is] = sort(newcat2.Date);
        newcat2.sort(Date);
        cumu2=cumsum(misfitAngle(is));
        pl = plot(tmp,cumu2,'o');
        xtitle='Number of Eqs (sorted by time)';
    end

    function plot_by_strike()
        % [~,is] = sort(newcat2(:,15));
        [~,is] = sort(newcat2(:,end));
        newa2 = newcat2.subset(is) ;
        cumu2=cumsum(misfitAngle(is));
        pl = plot(newa2(:,16)-18.6,cumu2,'o');
        xtitle='Number of Eqs (sorted along strike)';
        var2=15;
    end

    function option_7()
        mi2 = mi ;
        cumu2=cumsum(mi2(:,2));
        pl = plot(tmp,cumu2,'o');
        xtitle='Number of Eqs ';
    end
end

function mifigrid(var1,mi)

    % This function creates a grid with spacing dx, dy (in degrees)
    % The size is selected interactively in an input window.
    % The relative quiescence will be calculated for every grid point
    % for a specific time and plotted in a Seismolap-Quiescence map
    %
    % turned into function by Celso G Reyes 2017
    %
    %MIFIGRID(var1,mi)
    %
    % Alexander Allmann

    ZG=ZmapGlobal.Data; % used by get_zmap_globals

    report_this_filefun();

    global  ni me1 va1
    global a h1 map dx dy Mmin lap1 seismap
    global normlap1 normlap2 mif1 mifmap

    if var1==1

        %input window
        %
        %default parameters
        dx= .5;                      %grid spacing east-west
        dy= .5;                      %grid spacing north-south
        % ldx=100;                     %side length of interaction zone in km (for seislap)
        % tlap=300;                    %interaction time in days (for seislap)
        Mmin=3;                      %minimum magnitude

        %create a input window
        figure_w_normalized_uicontrolunits(...
            'Name','Grid Input Parameter',...
            'NumberTitle','off', ...
            'NextPlot','new', ...
            'units','points',...
            'Visible','off', ...
            'Position',[ ZG.welcome_pos + [200, -200], 450, 250]);
        axis off

        %create a dialog box for the input
        freq_field1=uicontrol('Style','edit',...
            'Position',[.60 .36 .15 .08],...
            'Units','normalized','String',num2str(dx),...
            'callback',@callbackfun_001);

        freq_field2=uicontrol('Style','edit',...
            'Position',[.60 .27 .15 .08],...
            'Units','normalized','String',num2str(dy),...
            'callback',@callbackfun_002);

        freq_field3=uicontrol('Style','edit',...
            'Position',[.60 .48 .15 .08],...
            'Units','normalized','String',num2str(ni),...
            'callback',@callbackfun_003);

        close_button=uicontrol('Style','Pushbutton',...
            'Position',[.70 .05 .15 .12 ],...
            'Units','normalized', 'Callback', @callbackfun_004,'String','Cancel');

        go_button1=uicontrol('Style','Pushbutton',...
            'Position',[.20 .05 .15 .12 ],...
            'Units','normalized',...
            'callback',@callbackfun_005,...
            'String','Go');

        txt4 = text(...
            'Position',[0.50 0.74 0 ],...
            'FontSize',ZmapGlobal.Data.fontsz.l ,...
            'FontWeight','bold',...
            'String',' Grid Parameter');
        txt5 = text(...
            'Position',[0. 0.35 0 ],...
            'FontSize',ZmapGlobal.Data.fontsz.m ,...
            'FontWeight','bold',...
            'String','Spacing in x (dx) in deg:');

        txt6 = text(...
            'Position',[0. 0.25 0 ],...
            'FontSize',ZmapGlobal.Data.fontsz.m ,...
            'FontWeight','bold',...
            'String','Spacing in y (dy) in deg:');

        txt2 = text(...
            'Position',[0. 0.5 0 ],...
            'FontSize',ZmapGlobal.Data.fontsz.m ,...
            'FontWeight','bold',...
            'String',' # of EQ Ni:');

        set(gcf,'visible','on');
        watchoff

    elseif var1==2           %area selection

        figure(map);
        set(gca,'NextPlot','add')
        ax=findobj(gcf,'Tag','mainmap_ax');
        [x,y, mouse_points_overlay] = select_polygon(ax);

        %figure_w_normalized_uicontrolunits(mif1)

        plos2 = plot(x,y,'b-');        % plot outline
        sum3 = 0.;
        pause(0.3)

        %create a rectangular grid
        xvect=[min(x):dx:max(x)];
        yvect=[min(y):dy:max(y)];
        tmpgri=zeros((length(xvect)*length(yvect)),2);
        n=0;
        for i=1:length(xvect)
            for j=1:length(yvect)
                n=n+1;
                tmpgri(n,:)=[xvect(i) yvect(j)];
            end
        end
        %extract all gridpoints in chosen polygon
        XI=tmpgri(:,1);
        YI=tmpgri(:,2);
        ll = polygon_filter(x,y, XI, YI, 'inside');
        %grid points in polygon
        newgri=tmpgri(ll,:);

        % Plot all grid points
        gcf
        plot(newgri(:,1),newgri(:,2),'+k')
        drawnow

        if length(xvect) < 2  ||  length(yvect) < 2
            errordlg('Selection too small! (not a matrix)');
            return
        end

        %calculate lap1(relative quiescence) at every grid point
        %
        ZG.newcat=a;                   %ZG.newcat is only a local variable
        bcat=ZG.newcat;

        me1=zeros(length(newgri(:,1)),1);
        va1=zeros(length(newgri(:,1)),1);

        wai = waitbar(0,' Please Wait ...  ');
        set(wai,'NumberTitle','off','Name','Makegrid - Percent completed');
        drawnow

        for i= 1:length(me1)   %all eqs which are in spacewindow in east-west direction
            l = sqrt(((ZG.newcat.Longitude-newgri(i,1))*cosd(newgri(i,2))*111).^2 +...
                ((ZG.newcat.Latitude-newgri(i,2))*111).^2) ;
            [s,is] = sort(l);
            b = ZG.newcat.subset(is) ;       % re-orders matrix to agree row-wise
            mi2 = mi(is(:,1),2);    % take first ni points
            mi2 = mi2(1:ni);
            me1(i) = mean(mi2);
            va1(i) = std(mi2);
            if rem(i,20)==0;  waitbar(i/length(me1));end

        end

        close(wai)
        %make a color map
        % Find out if figure already exists
        %
        mifmap=findobj('Type','Figure','-and','Name','Misfit-Map 2');

        % Set up the Seismicity Map window Enviroment
        %
        if isempty(mifmap)
            mifmap = figure_w_normalized_uicontrolunits( ...
                'Name','Misfit-Map 2',...
                'NumberTitle','off', ...
                'NextPlot','replace', ...
                'backingstore','on',...
                'Visible','off', ...
                'Position',[ 600 400 500 650]);
            % make menu bar

            set(gca,'NextPlot','add')
        end
        figure(mifmap)
        delete(findobj(mifmap,'Type','axes'));

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

        %minimum and maximum of normlap2 for automatic scaling
        ZG.maxc = max(normlap2);
        ZG.minc = min(normlap2);

        %construct a matrix for the color plot
        normlap1=ones(length(tmpgri(:,1)),1);
        normlap2=nan(length(tmpgri(:,1)),1)
        normlap3=nan(length(tmpgri(:,1)),1)
        normlap1(ll)=me1;
        normlap2(ll)=normlap1(ll);
        normlap1(ll)=va1;
        normlap3(ll)=normlap1(ll);

        normlap2=reshape(normlap2,length(yvect),length(xvect));
        normlap3=reshape(normlap3,length(yvect),length(xvect));

        %plot color image
        orient tall
        memifig2

        return

        rect = [0.25,  0.60, 0.7, 0.35];
        axes('position',rect)
        set(gca,'NextPlot','add')
        pco1 = pcolor(xvect,yvect,normlap2);
        shading interp
        colormap(jet)
        axis([ s2_west s1_east s4_south s3_north])
        set(gca,'NextPlot','add')
        colorbar
        overlay
        title('Mean of the Misfit','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
        xlabel('Longitude [deg]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
        ylabel('Latitude [deg]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)

        set(gca,'visible','on','FontSize',ZmapGlobal.Data.fontsz.m,'FontWeight','bold',...
            'FontWeight','bold','LineWidth',1.5,...
            'Box','on','TickDir','out')

        rect = [0.25,  0.10, 0.7, 0.35];
        axes('position',rect)
        set(gca,'NextPlot','add')
        pco1 = pcolor(xvect,yvect,normlap3);
        axis([ s2_west s1_east s4_south s3_north])
        set(gca,'NextPlot','add')
        shading interp
        colormap(jet)
        set(gca,'NextPlot','add')
        colorbar
        title(' Variance of the Misfit','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
        xlabel('Longitude [deg]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
        ylabel('Latitude [deg]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)

        set(gca,'visible','on','FontSize',ZmapGlobal.Data.fontsz.m,'FontWeight','bold',...
            'FontWeight','bold','LineWidth',1.5,...
            'Box','on','TickDir','out')

        overlay
        memifig2
    end

    function callbackfun_001(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        dx=str2double(freq_field1.String);
        freq_field1.String=num2str(dx);
    end

    function callbackfun_002(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        dy=str2double(freq_field2.String);
        freq_field2.String=num2str(dy);
    end

    function callbackfun_003(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        ni=str2double(freq_field3.String);
        freq_field3.String=num2str(ni);
    end

    function callbackfun_004(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        close;

    end

    function callbackfun_005(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        close;
        var1 = 2;
        mifigrid(var1, mi);
    end

end

function memifig2()
    % Misfitmap 2 (?)

    ZG=ZmapGlobal.Data; % used by get_zmap_globals
    report_this_filefun();

    %input window
    %
    %default parameters

    %make a color map
    % Find out if figure already exists
    %
    mifmap=findobj('Type','Figure','-and','Name','Misfit-Map 2');

    % Set up the Seismicity Map window Enviroment
    %
    if isempty(mifmap)
        mifmap = figure_w_normalized_uicontrolunits( ...
            'Name','Misfit-Map 2',...
            'NumberTitle','off', ...
            'NextPlot','replace', ...
            'backingstore','on',...
            'Visible','off', ...
            'Position',[ 600 400 500 350]);
        % make menu bar
        set(gca,'NextPlot','add')
    end

    figure(mifmap);
    delete(findobj(mifmap,'Type','axes'));

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

    %minimum and maximum of normlap2 for automatic scaling
    ZG.maxc = max(normlap2);
    ZG.minc = min(normlap2);

    %construct a matrix for the color plot
    normlap1=ones(length(tmpgri(:,1)),1);
    normlap2=nan(length(tmpgri(:,1)),1)
    normlap3=nan(length(tmpgri(:,1)),1)
    normlap1(ll)=me1;
    normlap2(ll)=normlap1(ll);
    normlap1(ll)=va1;
    normlap3(ll)=normlap1(ll);

    normlap2=reshape(normlap2,length(yvect),length(xvect));
    normlap3=reshape(normlap3,length(yvect),length(xvect));

    %plot color image
    orient tall
    gx = xvect; gy = yvect;

    set(gca,'NextPlot','add')
    pco1 = pcolor(xvect,yvect,normlap2);
    shading interp
    colormap(flipud(jet(10)));
    axis([ min(gx) max(gx) min(gy) max(gy)])
    axis image

    set(gca,'NextPlot','add')
    h5 = colorbar('vert');
    set(h5,'Pos',[0.82 0.46 0.02 0.20],...
        'FontSize',12)

    if exist('maex', 'var')
        set(gca,'NextPlot','add')
        pl = plot(maex,-maey,'*k');
        set(pl,'MarkerSize',6,'LineWidth',2)
    end

    overlay
    title(['Mean of the Misfit (' num2str(sig) '/' num2str(az)  '/' num2str(plu) '/' num2str(phi) '/' num2str(R) ')'] ,'FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.s)
    xlabel('Longitude in [deg]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.s)
    ylabel('latitude in [deg]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.s)

    set(gca,'visible','on','FontSize',ZmapGlobal.Data.fontsz.s,'FontWeight','bold',...
        'FontWeight','bold','LineWidth',1.5,...
        'Box','on','TickDir','out')
end

function mificrgr( mi, inde)
    % This function creates a grid with spacing dx, dy (in degrees)
    % The size is selected interactively in an input window.
    % The relative quiescence will be calculated for every grid point
    % for a specific time and plotted in a Seismolap-Quiescence map
    %  Alexander Allmann
    %
    % turned into function by Celso G Reyes 2017

    %global freq_field1 freq_field2 freq_field3 freq_field4 freq_field5
    %global freq_field6 ni me1 va1
    %global h1 map dx dy Mmin lap1 seismap
    %global normlap1 normlap2 mif1 mifmap

    ZG=ZmapGlobal.Data; % used by get_zmap_globals

    report_this_filefun();

    %input window
    %
    %default parameters
    dx= .5;                      %grid spacing east-west
    dy= .5;                      %grid spacing north-south
    %ldx=100;                     %side length of interaction zone in km (for seislap)
    %tlap=300;                    %interaction time in days (for seislap)
    Mmin=3;                      %minimum magnitude
    ni=100; % number of events

    %create a input window
    fig=figure_w_normalized_uicontrolunits(...
        'Name','Grid Input Parameter',...
        'NumberTitle','off', ...
        'NextPlot','new', ...
        'units','points',...
        'Visible','off', ...
        'MenuBar','none',...
        'Position',[ ZG.welcome_pos + [200, -200], 700, 250]);
    axis off

    gridOpts = ZG.gridopt;
    esp = EventSelectionParameters('NumClosestEvents',ni);
    selOpts = EventSelectionChoice(fig,'evsel',esp);

    close_button=uicontrol('Style','Pushbutton',...
        'Position',[.70 .05 .15 .12 ],...
        'Units','normalized', 'Callback', @callbackfun_cancel,'String','Cancel');

    go_button1=uicontrol('Style','Pushbutton',...
        'Position',[.20 .05 .15 .12 ],...
        'Units','normalized',...
        'callback',@callbackfun_go,...
        'String','Go');

    set(gcf,'visible','on');
    watchoff

    function my_calculate()

        xsec_h=xsec_fig();

        if isempty(xsec_h) % best guess at figure handle variable
            nlammap
        else
            figure(xsec_h);
        end

        set(gca,'NextPlot','add')
        ax=findobj(gcf,'Tag','mainmap_ax');
        [x,y, mouse_points_overlay] = select_polygon(ax);

        figure(xsec_h)

        plos2 = plot(x,y,'b-');        % plot outline
        sum3 = 0.;
        pause(0.3)

        %create a rectangular grid
        xvect=[min(x):dx:max(x)];
        yvect=[min(y):dy:max(y)];
        tmpgri=zeros((length(xvect)*length(yvect)),2);
        n=0;
        for i=1:length(xvect)
            for j=1:length(yvect)
                n=n+1;
                tmpgri(n,:)=[xvect(i) yvect(j)];
            end
        end
        %extract all gridpoints in chosen polygon
        XI=tmpgri(:,1);
        YI=tmpgri(:,2);

        ll = polygon_filter(x,y, XI, YI, 'inside');
        %grid points in polygon
        newgri=tmpgri(ll,:);

        % Plot all grid points
        gcf
        plot(newgri(:,1),newgri(:,2),'+k')
        drawnow

        if length(xvect) < 2  ||  length(yvect) < 2
            errordlg('Selection too small! (not a matrix)');
            return
        end

        %
        ZG.newcat=a;                   %ZG.newcat is only a local variable
        bcat=ZG.newcat;

        me1=zeros(length(newgri(:,1)),1);
        va1=zeros(length(newgri(:,1)),1);
        mic = mi(inde,:);

        wai = waitbar(0,' Please Wait ...  ');
        set(wai,'NumberTitle','off','Name','Makegrid - Percent completed');
        drawnow

        for i= 1:length(me1)   %all eqs which are in spacewindow in east-west direction
            x = newgri(i,1);y = newgri(i,2);

            l = sqrt(((xsecx' - x)).^2 + ((xsecy + y)).^2) ;
            [s,is] = sort(l);
            b = ZG.newcat.subset(is) ;       % re-orders matrix to agree row-wise
            mi2 = mic(is(:,1),2);    % take first ni points
            mi2 = mi2(1:ni);
            me1(i) = mean(mi2);
            va1(i) = std(mi2);
            if rem(i,20)==0;  waitbar(i/length(me1));end
        end

        close(wai)
        %make a color map
        % Find out if figure already exists
        %
        mifmap=findobj('Type','Figure','-and','Name','Misfit-Map 2');

        % Set up the Seismicity Map window Enviroment
        %
        if isempty(mifmap)
            mifmap = figure_w_normalized_uicontrolunits( ...
                'Name','Misfit-Map 2',...
                'NumberTitle','off', ...
                'NextPlot','replace', ...
                'backingstore','on',...
                'Visible','off', ...
                'Position',[ 600 400 500 650]);
            % make menu bar

            set(gca,'NextPlot','add')
        end

        figure(mifmap);
        delete(findobj(mifmap,'Type','axes'));

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

        %minimum and maximum of normlap2 for automatic scaling
        ZG.maxc = max(normlap2);
        ZG.minc = min(normlap2);

        %construct a matrix for the color plot
        normlap1=ones(length(tmpgri(:,1)),1);
        normlap2=nan(length(tmpgri(:,1)),1)
        normlap3=nan(length(tmpgri(:,1)),1)
        normlap1(ll)=me1;
        normlap2(ll)=normlap1(ll);
        normlap1(ll)=va1;
        normlap3(ll)=normlap1(ll);

        normlap2=reshape(normlap2,length(yvect),length(xvect));
        normlap3=reshape(normlap3,length(yvect),length(xvect));

        %plot color image
        orient tall
        gx = xvect;
        gy = yvect;
        memifig

        return

        rect = [0.25,  0.60, 0.7, 0.35];
        axes('position',rect)
        set(gca,'NextPlot','add')
        pco1 = pcolor(xvect,yvect,normlap2);
        shading interp
        colormap(jet)
        %axis([ s2_west s1_east s4_south s3_north])
        axis([ min(gx) max(gx) min(gy) max(gy)])
        axis image

        set(gca,'NextPlot','add')
        colorbar
        if exist('maex', 'var')
            set(gca,'NextPlot','add')
            pl = plot(maex,-maey,'*m');
            set(pl,'MarkerSize',8,'LineWidth',2)
        end

        %overlay
        title('Mean of the Misfit','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
        xlabel('Distance in [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
        ylabel('Depth in [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)

        set(gca,'visible','on','FontSize',ZmapGlobal.Data.fontsz.m,'FontWeight','bold',...
            'FontWeight','bold','LineWidth',1.5,...
            'Box','on','TickDir','out')

        rect = [0.25,  0.10, 0.7, 0.35];
        axes('position',rect)
        set(gca,'NextPlot','add')
        pco1 = pcolor(xvect,yvect,normlap3);
        axis([ min(gx) max(gx) min(gy) max(gy)])
        axis image

        if exist('maex', 'var')
            set(gca,'NextPlot','add')
            pl = plot(maex,-maey,'*w');
            set(pl,'MarkerSize',8,'LineWidth',2)
        end

        set(gca,'NextPlot','add')
        shading interp
        colormap(jet)
        set(gca,'NextPlot','add')
        colorbar
        title(' Variance of the Misfit','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
        xlabel('Distance in [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
        ylabel('Depth in [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)

        set(gca,'visible','on','FontSize',ZmapGlobal.Data.fontsz.m,'FontWeight','bold',...
            'FontWeight','bold','LineWidth',1.5,...
            'Box','on','TickDir','out')

    end

    function callbackfun_cancel(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        close;

    end

    function callbackfun_go(mysrc,myevt)

        callback_tracker(mysrc,myevt,mfilename('fullpath'));
        dx=gridOpts.dx;
        dy=gridOpts.dy;
        ni=selOpts.ni;
        delete(selOpts);
        close;
        my_calculate();
    end

end

function memifig()
    % turned into function by Celso G Reyes 2017

    ZG=ZmapGlobal.Data; % used by get_zmap_globals
    report_this_filefun();

    %input window
    %
    %default parameters

    %make a color map
    % Find out if figure already exists
    %
    mifmap=findobj('Type','Figure','-and','Name','Misfit-Map 2');

    % Set up the Seismicity Map window Enviroment
    %
    if isempty(mifmap)
        mifmap = figure_w_normalized_uicontrolunits( ...
            'Name','Misfit-Map 2',...
            'NumberTitle','off', ...
            'NextPlot','replace', ...
            'backingstore','on',...
            'Visible','off', ...
            'Position',[ 600 400 500 350]);
        % make menu bar

        set(gca,'NextPlot','add')
    end
    figure(mifmap);
    delete(findobj(mifmap,'Type','axes'));

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

    %minimum and maximum of normlap2 for automatic scaling
    ZG.maxc = max(normlap2);
    ZG.minc = min(normlap2);

    %construct a matrix for the color plot
    normlap1=ones(length(tmpgri(:,1)),1);
    normlap2=nan(length(tmpgri(:,1)),1)
    normlap3=nan(length(tmpgri(:,1)),1)
    normlap1(ll)=me1;
    normlap2(ll)=normlap1(ll);
    normlap1(ll)=va1;
    normlap3(ll)=normlap1(ll);

    normlap2=reshape(normlap2,length(yvect),length(xvect));
    normlap3=reshape(normlap3,length(yvect),length(xvect));

    %plot color image
    orient tall
    gx = xvect; gy = yvect;

    set(gca,'NextPlot','add')
    pco1 = pcolor(xvect,yvect,normlap2);
    shading interp
    colormap( flipud(jet(64)) );
    axis([ min(gx) max(gx) min(gy) max(gy)])
    axis image

    set(gca,'NextPlot','add')
    h5 = colorbar('vert');
    set(h5,'Pos',[0.82 0.46 0.03 0.10],...
        'FontSize',2)

    if exist('maex', 'var')
        set(gca,'NextPlot','add')
        pl = plot(maex,-maey,'*w');
        set(pl,'MarkerSize',6,'LineWidth',1)
    end

    %overlay
    title('Mean of the Misfit','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.s)
    xlabel('Distance in [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.s)
    ylabel('Depth in [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.s)

    set(gca,'visible','on','FontSize',ZmapGlobal.Data.fontsz.s,'FontWeight','bold',...
        'FontWeight','bold','LineWidth',1.5,...
        'Box','on','TickDir','out')
end


function o = cat(dr,varargin)
% Concatenate file_array objects.  The result is a non-simple object
% that can no longer be reshaped.
% _______________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging

%
% $Id: cat.m 1143 2008-02-07 19:33:33Z spm $

if dr>32 || dr<0, error('Unknown command option.'); end;
dr   = max(round(dr),1);
d    = ones(nargin-1,16);
tmp  = {};
dpos = 0;
for i=1:nargin-1,
    vi = varargin{i};
    if strcmp(class(vi),'file_array')
        sz                = size(vi);
        d(i,1:length(sz)) = sz;
        svi               = struct(vi);
        svi               = svi(:);
        for j=1:length(svi(:)),
            if length(svi(j).pos)<dr
                svi(j).pos((length(svi(j).pos)+1):dr) = 1;
            end
            svi(j).pos(dr)= svi(j).pos(dr) + dpos;
        end;
        dpos              = dpos + d(i,dr);
        tmp{i}            = svi;
    else
        error(['Conversion to file_array from ' class(vi) ' is not possible.']);
    end;
end;
if any(diff(d(:,[1:(dr-1) (dr+1):end]),1,1))
    error('All matrices on a row in the bracketed expression must have the same number of rows.');
else
    o = vertcat(tmp{:});
    o = class(o,'file_array');
end;


function [scores, blocks] = readscorestats(inffile, model)

% [scores, blocks] = readscorestats(inffile, model)
%
% Read a score statistics file and parse it into labels, total scores,
% unique flags, and block scores.

fid = fopen(inffile, 'rb');
num = fread(fid, 1, 'int32');
scores = zeros(num, 1);
blocks = zeros(num, model.numblocks);
for i = 1:num
  tmp = fread(fid, model.numblocks+1, 'double');
  scores(i) = tmp(1);
  blocks(i,:) = tmp(2:end);
end
fclose(fid);


function [X,Y,T,options,A,R2_pca,pca_opt,features] = preproc4hmm(X,Y,T,options)
% Prepare data to run TUDA
% 1. check parameters, including the type of classifier (regression is default)
% 2. Format X and Y accordingly to the classifier
% 3. Sets up state to be sequential , if asked
% 4. Preprocesses the data, including embedding

if length(size(X))==3 % 1st dim, time; 2nd dim, trials; 3rd dim, channels
    X = reshape(X,[size(X,1)*size(X,2), size(X,3)]);
end

N = length(T);
p = size(X,2);

if any(isnan(Y(:))), error('NaN found in Y'); end
if ~isfield(options,'Y_is_continuous') %ie not discrete
    options.Y_is_continuous = length(unique(Y(:))) > 50;
end

if size(X,1) ~= sum(T), error('Dimension of X not correct'); end
if size(Y,1) < size(Y,2); Y = Y'; end
if (size(Y,1) ~= sum(T)) && (size(Y,1) ~= length(T))
    error('Dimension of Y not correct');
end
q = size(Y,2);

if ~isfield(options,'K'), error('K needs to be specified'); end
if isfield(options,'downsample') && options.downsample
   error('Downsampling is not currently an option')
end
if isfield(options,'filter') && ~isempty(options.filter) && ~isfield(options,'Fs')
   error('You must specify options.Fs if you are to filter the data')
end

% options relative to the regression setting
if ~isfield(options,'classifier'), options.classifier = ''; end
% if empty, it is meant to be used with a continuous response
if ~isfield(options,'Nfeatures'), Nfeatures = p;
else, Nfeatures = options.Nfeatures; end
if ~isfield(options,'standardise'), standardise = 0;
else, standardise = options.standardise; end % otherwise it's done per trial
if ~isfield(options,'onpower'), onpower = 0;
else, onpower = options.onpower; end
if ~isfield(options,'embeddedlags'), embeddedlags = 0;
else, embeddedlags = options.embeddedlags; end
if ~isfield(options,'filter'), filter = [];
else, filter = options.filter; end
if ~isfield(options,'detrend'), detrend = 0;
else, detrend = options.detrend; end
% econ_embed saves memory at the expense of speed, when pca is applied
if ~isfield(options,'econ_embed'), econ_embed = 0;
else, econ_embed = options.econ_embed; end
if ~isfield(options,'parallel_trials'), parallel_trials = all(T==T(1)) & length(T)>1;
else, parallel_trials = options.parallel_trials; end
if ~isfield(options,'acrosstrial_constrained'), options.acrosstrial_constrained = 0; end

if ~isfield(options,'pca'), pca_opt = 0;
else, pca_opt = options.pca; end
if ~isfield(options,'A'), A = [];
else, A = options.A; end
if isfield(options,'downsample') && options.downsample~=0
    warning('Downsampling is not possible for TUDA')
end
if ~isfield(options,'encodemodel')
    options.encodemodel = false;
end
%options relative to classification models:
if ~isempty(options.classifier) || options.encodemodel
    if strcmp(options.classifier,'logistic')
        %set default options for logistic regression classification:
        options.distribution = 'logistic';
        demeanstim = false;
        %determine if multinomial or binomial:
        vals = unique(Y(:));
        if length(vals) == 2
            if all((vals == 0) | (vals == 1))
                Y = 2*(Y)-1;
            elseif q==1 && all((vals == 1) | (vals == 2))
                Y(Y==2) = -1;
            elseif any((vals ~= -1) & (vals ~= 1))
                error('Format of Y incorrect for classification tasks');
            end
        elseif length(vals) > 2 && q == 1
            % Y entered as categorical format
            fprintf(['\nFitting multinomial logistic classifier with classes ',int2str(vals'), '\n']);
            Y = convertToMultinomial(Y);
        elseif length(vals) == 3
            if any((vals ~= -1) & (vals ~= 1) & (vals ~= 0))
                error('Format of Y incorrect for classification tasks');
            end
        end
        options.logisticYdim=size(Y,2);
        if ~isfield(options,'balancedata')
            options.balancedata = 0;
        else
            options.balancedata = options.balancedata;
        end
        if ~isfield(options,'intercept'), options.intercept = 0; end
        if options.intercept
           X = [X,ones(size(X,1),1)];
        end
        options = rmfield(options,'intercept');
        if ~isfield(options,'sequential')
            options.sequential = 1;
        end
        if ~isfield(options,'inittype')
            if options.sequential ~= 0
                options.inittype = 'sequential';
            else
                options.inittype = 'HMM-MAR';
            end
        end
        add_noise = 0;
        if ~isfield(options,'cyc'), options.cyc = 1; end
   elseif strcmp(options.classifier,'LDA') || options.encodemodel
       % set default options for LDA model:
       options.distribution = 'Gaussian';
       demeanstim = false;
        if ~isfield(options,'intercept'), options.intercept = 1; end
        if options.intercept
            if size(Y,2)==1 && all((Y==0) + (Y==1))
                Y = [ones(size(Y,1),1),Y==1];
            else
                Y = [ones(size(Y,1),1),Y];
            end
            q = size(Y,2);
        end
        if ~isfield(options,'covtype')
            options.covtype = 'sharedfull';
        end
        options=rmfield(options,'intercept');
        if ~isfield(options,'sequential')
            options.sequential = 1;
        end
        if ~isfield(options,'inittype')
            if options.sequential ~= 0
                options.inittype = 'sequential';
            else
                options.inittype = 'HMM-MAR';
            end
        end
        options.add_noise = 0;
        add_noise = 0;
    elseif strcmp(options.classifier,'SVM') || strcmp(options.classifier,'SVM_rbf') || ...
            strcmp(options.classifier,'KNN') || ...
            strcmp(options.classifier,'decisiontree')
        add_noise = 0;
        demeanstim = false;
        options.sequential = 0;
    elseif strcmp(options.classifier,'regression')
        options.distribution = 'Gaussian';
        demeanstim = false;
        %determine if multinomial or binomial:
        vals = unique(Y(:));
        if length(vals) == 2 && q == 1
            if all((vals == 0) | (vals == 1))
                Y = 2*(Y)-1;
            elseif any((vals ~= -1) & (vals ~= 1))
                error('Format of Y incorrect for classification tasks');
            end
            c1 = sum(Y==-1); c2 = sum(Y==1); c12 = length(Y);
            Y(Y==-1) = - c12 / c1;  Y(Y==+1) = c12 / c2;
        elseif length(vals) > 2 && q == 1
            Ytmp = Y;
            Y = zeros(size(Y,1),length(vals));
            for jj = 1:length(vals), Y(Ytmp==vals(jj),jj) = 1; end
            q = length(vals);
        elseif q > 1
            if any((vals ~= 0) & (vals ~= 1))
                error('Format of Y incorrect for classification tasks');
            end
        end
        add_noise = ~options.Y_is_continuous;
        if ~isfield(options,'sequential')
            options.sequential = 1;
        end
        if ~isfield(options,'inittype')
            if options.sequential ~= 0
                options.inittype = 'sequential';
            else
                options.inittype = 'HMM-MAR';
            end
        end
    end

else % Standard regression problem

    options.distribution = 'Gaussian'; %default for all non-classification models
    demeanstim = true;
    if ~isfield(options,'add_noise'), add_noise = 0;
    else, add_noise = options.add_noise;
    end
    if ~isfield(options,'sequential')
        options.sequential = 1;
    end
    if ~isfield(options,'inittype')
        if options.sequential ~= 0
            options.inittype = 'fixedsequential';
        else
            options.inittype = 'HMM-MAR';
        end
    end
    if ~isfield(options,'intercept'), options.intercept = 0; end
    if options.intercept
       X = [X,ones(size(X,1),1)];
    end
    options = rmfield(options,'intercept');
    if ~isfield(options,'cyc'), options.cyc = 1; end
end

if ~isfield(options,'cyc'), options.cyc = 25; end
if ~isfield(options,'logisticYdim'), options.logisticYdim = 0; end

% Set up states to be a a sequence
if isfield(options,'sequential') && options.sequential ~= 0
    options.Pistructure = zeros(1,options.K);
    options.Pistructure(1:abs(options.sequential)) = 1;
    options.Pistructure = logical(options.Pistructure);
    options.Pstructure = logical(eye(options.K));
    for k = 1:abs(options.sequential)
        options.Pstructure = options.Pstructure + diag(ones(options.K-k,1),k);
    end
    if options.sequential < 0
        for k = 1:abs(options.sequential)
            options.Pstructure = options.Pstructure + diag(ones(options.K-k,1),-k);
        end
    end
end

% Options relative to constraints in the trans prob mat
if ~isfield(options,'K'), error('K was not specified'); end
if ~isfield(options,'Pstructure')
    options.Pstructure = true(options.K);
end
if ~isfield(options,'Pistructure')
    options.Pistructure = true(1,options.K);
end

options.parallel_trials = parallel_trials;
if ~isfield(options,'tudamonitoring'), options.tudamonitoring = 0; end
if ~isfield(options,'plotGamma'), options.plotGamma = 0; end

if parallel_trials && ~all(T==T(1))
    error('parallel_trials can be used only when all trials have equal length');
end
if options.tudamonitoring && ~all(T==T(1))
    error('tudamonitoring can be used only when all trials have equal length');
end

% options relative to the HMM
if ~isfield(options,'distribution'),options.distribution='Gaussian';end
if options.logisticYdim>0
    options.distribution = 'logistic';
end
if strcmp(options.distribution,'logistic')
    options.covtype = '';
end
if ~isfield(options,'covtype') && strcmp(options.distribution,'Gaussian')
    options.covtype = 'shareddiag';
end
if ~isfield(options,'inittype'), options.inittype = 'HMM-MAR'; end

options.order = 1;
options.zeromean = 1;
options.embeddedlags = 0; % it is done here
options.pca = 0; % it is done here
options.standardise = 0; % it is done here
options.onpower = 0; % it is done here
options.detrend = 0; % it is done here
options.filter = []; % it is done here
options.downsample = 0; % it is done here
options.dropstates = 0;

if isfield(options,'econ_embed'), options = rmfield(options,'econ_embed'); end
if isfield(options,'Nfeatures'), options = rmfield(options,'Nfeatures'); end
if isfield(options,'demeanstim'), options = rmfield(options,'demeanstim'); end
% Set a high prior for the initial probabilities because otherwise the
% model is biased to have the first time point of each trial to be assigned
% to just one state.
if ~isfield(options,'PriorWeightingPi'), options.PriorWeightingPi = length(T)/20; end
if ~isfield(options,'DirichletDiag'), options.DirichletDiag = 100; end

do_embedding = length(embeddedlags)>1;
do_pca = ~isempty(A) || length(pca_opt)>1 || (pca_opt>0 && pca_opt<(p*length(embeddedlags)));
do_pls = isfield(options,'pls');

if ~do_embedding && econ_embed
    econ_embed = 0;
end
if do_embedding && ~do_pca && econ_embed
    warning('It only makes sense to use econ_embed when using pca')
    econ_embed = 0;
end

emforw = max(max(embeddedlags),0);
emback = max(-min(embeddedlags),0);

if size(Y,1) == N % one value for the entire trial
    %Y = reshape(repmat(reshape(Y,[1 N q]),[ttrial 1 1]),[N*ttrial q]);
    Ytmp = Y;
    Y = zeros(sum(T),q);
    for n = 1:N
        Y(sum(T(1:n-1)) + (1:T(n)),:) = repmat(Ytmp(n,:),T(n),1);
    end; clear Ytmp
end

if q == 1 && length(unique(Y))==2
    if ismember(0,unique(Y)) || all(unique(Y)>0) && ~strcmp(options.distribution,'logistic')
        warning('Seems this is binary classification, transforming stimulus to have elements (-1,+1)')
        if islogical(Y);Y=1*Y;end
        v = unique(Y);
        Y(Y==v(1)) = -1; Y(Y==v(2)) = +1;
        if options.logisticYdim==0
            Y = Y - mean(Y);
        end
    end
end

if demeanstim
    % Demean stimulus
    Y = bsxfun(@minus,Y,mean(Y));
end
% Add noise, to avoid numerical problems
if add_noise > 0
    if add_noise == 1
        Y = Y + 1e-5 * randn(size(Y)) .* repmat(std(Y),size(Y,1),1);
    else
        Y = Y + add_noise * randn(size(Y)) .* repmat(std(Y),size(Y,1),1);
    end
end
% Standardise data
if standardise && N > 1
   warning(['You have set standardise=1, so each channel and trial will be standardized. ' ...
       'This will probably result in a loss of information in terms of how each stimulus is processed'])
   X = standardisedata(X,T,standardise);
end

% Filtering
if ~isempty(filter)
    data = filterdata(X,T,options.Fs,filter);
end
% Detrend data
if detrend
    X = detrenddata(X,T);
end

% adjust dimension of Y according to embedding
if do_embedding
    Ttmp = T-emforw-emback;
    Ytmp = Y;
    Y = zeros(sum(Ttmp),q);
    for n = 1:N
        Y(sum(Ttmp(1:n-1)) + (1:Ttmp(n)),:) = ...
            Ytmp(sum(T(1:n-1)) + (1+emforw:T(n)-emback) ,:);
    end; clear Ytmp Ttmp
end

% feature selection
if Nfeatures < p && Nfeatures > 0
    me = sum((repmat(mean(Y),size(Y,1),1) - Y).^2);
    C = zeros(p,1);
    for j=1:p
        if onpower
            x = rawsignal2power(X(:,j),T);
        else
            x = X(:,j);
        end
        if do_embedding
            x = embeddata(x,T,embeddedlags);
        end
        b = (x' * x) \ (x' * Y);
        e = sum((x * b - Y).^2);
        C(j) = sum(1 - e ./ me);
    end
    [~,features] = sort(C,1,'descend');
    features = features(1:Nfeatures);
    X = X(:,features);
    p = Nfeatures;
else
    features = 1:p;
end

% Hilbert envelope
if onpower
    X = rawsignal2power(X,T);
end

% do embedding + PCA
R2_pca = [];
if econ_embed

    % build gram matrix subject by subject
    for n = 1:N
        t = (1:T(n)) + sum(T(1:n-1));
        if do_embedding
            Xn = embeddata(X(t,:),T(n),embeddedlags);
        else
            Xn = X(t,:);
        end
        Xn = Xn - repmat(mean(Xn),size(Xn,1),1); % must center
        if n==1, C = zeros(size(Xn,2)); end
        C = C + Xn' * Xn;
    end

    % do SVD
    if isempty(A)
        [A,e,~] = svd(C);
        e = diag(e);
        e = cumsum(e)/sum(e);
        p = num_comp_pca(e,pca_opt);
        A = A(:,1:p);
        R2_pca = e(p);
    else
        R2_pca = []; p = size(A,2);
    end
    % eigendecompose subject by subject
    Xtmp = X; Ttmp = T;
    T = T-emforw-emback;
    X = zeros(sum(T),p);
    for n = 1:N
        t = (1:T(n)) + sum(T(1:n-1));
        ttmp = (1:Ttmp(n)) + sum(Ttmp(1:n-1));
        if do_embedding
            Xn = embeddata(Xtmp(ttmp,:),Ttmp(n),embeddedlags);
        else
            Xn = Xtmp(ttmp,:);
        end
        Xn = Xn - repmat(mean(Xn),size(Xn,1),1); % must center
        X(t,:) = Xn * A;
    end

else

    if do_embedding
        [X,T] = embeddata(X,T,embeddedlags);
        msg = '(embedded)';
    else
        msg = '';
    end
    if do_pca
        if isempty(A)
            [A,X,e] = pca(X);
            e = cumsum(e)/sum(e);
            p = num_comp_pca(e,pca_opt);
            R2_pca = e(p);
            X = X(:,1:p);
            A = A(:,1:p);
            fprintf('Working in PCA %s space, with %d components. \n',msg,p)
        else
            X = bsxfun(@minus,X,mean(X));
            X = X * A;
        end
    else
        R2_pca = 1;
    end
    if do_pls
        [X,A] = PLSdimreduce(X,Y,T,options.pls);
        options = rmfield(options,'pls');
    end
end

end

function ncomp = num_comp_pca(e,d)

if length(d)==1 && d<1
    ncomp = find(e>d,1);
elseif length(d)==1 && d>=1
    ncomp = d;
elseif length(d)==2 || (length(d)==3 && d(3)==1)
    ncomp = min(find(e>d(1),1),d(2));
elseif length(d)==3 && d(3)==2
    ncomp = max(find(e>d(1),1),d(2));
else
    error('pca parameters are wrongly specified')
end

end


function vid_bic = interp_bicubic(vid_l, upscale)

N = length(vid_l);

for i = 1: N
    vid_bic{i} = imresize(vid_l{i}, upscale, 'bicubic');
    %vid_bic{i} = imresize(vid_l{i}, upscale, 'nearest');
end


% STD_READTOPO - returns the scalp map of a specified ICA component, assumed
%                  to have been saved in a Matlab file, [dataset_name].icatopo,
%                  in the same directory as the dataset file. If this file does
%                  not exist, use STD_TOPO to create it, else a pre-clustering
%                  function that calls it: POP_PRECLUST or EEG_PRECLUST.
% Usage:
%   >> [grid, y, x ] = std_readtopo(ALLEEG, setindx, component);
%   >> [grid, y, x ] = std_readtopo(ALLEEG, setindx, component, transform, mode);
%
% Inputs:
%   ALLEEG     - vector of EEG datasets (can also be one EEG set).
%                must contain the dataset of interest (see 'setindx' below).
%   setindx    - [integer] an index of an EEG dataset in the ALLEEG
%                structure, for which to get the component ERP.
%   component  - [integer] index of the component for which the scalp map
%                grid should be returned.
%   transform  - ['none'!'laplacian'|'gradient'] transform scalp map to
%                laplacian or gradient map. Default is 'none'.
%   mode       - ['2dmap'|'preclust'] return either a 2-D array for direct
%                plotting ('2dmap') or an array formatted for preclustering
%                with all the NaN values removed (ncomps x points). Default
%                is '2dmap' for 1 component and 'preclust' for several.
%
% Outputs:
%   grid      - square scalp-map color-value grid for the requested ICA component
%               in the specified dataset, an interpolated Cartesian grid as output
%               by TOPOPLOT.
%   y         - y-axis values for the interpolated grid
%   x         - x-axis values of the interpolated grid
%
%  See also  STD_TOPO, STD_PRECLUST
%
% Authors: Arnaud Delorme, Hilit Serby, SCCN, INC, UCSD, February, 2005

% Copyright (C) Hilit Serby, SCCN, INC, UCSD, October 11, 2004, hilit@sccn.ucsd.edu
%
% 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.

function [X, yi, xi ] = std_readtopo(ALLEEG, abset, comps, option, mode)

X = [];
yi = [];
xi = [];
if nargin < 4
    option = 'none';
end
if nargin < 5
    mode = '2Dmap';
end
filename = correctfile(fullfile( ALLEEG(abset).filepath,[ ALLEEG(abset).filename(1:end-3) 'icatopo']),ALLEEG(abset).filepath);
tmpfile  = which(filename);
if ~isempty(tmpfile), filename = tmpfile; end

% 061411, 2:51pm
% Modified by Joaquin
% while getfield(dir(filename), 'bytes') < 1000
i = 1;
while getfield(dir(filename), 'bytes') < 5000
    topo = load( '-mat', filename);
    filename = correctfile(topo.file, ALLEEG(abset).filepath);
    tmpfile  = which(filename);
    if ~isempty(tmpfile), filename = tmpfile; end
    if(i>100)
        error('too many attempts to find valid icatopo');
    end
    i = i+1;
end

for k = 1:length(comps)

    if length(comps) < 3
        lastwarn('', '');
        try
            topo = load( '-mat', filename, ...
                         [ 'comp' int2str(comps(k)) '_grid'], ...
                         [ 'comp' int2str(comps(k)) '_x'], ...
                         [ 'comp' int2str(comps(k)) '_y'] );
        catch
            error( [ 'Cannot read file ''' filename '''' ]);
        end
        [~, warnId] = lastwarn();
        if ~isempty(warnId)
            error( 'Cannot find component %d in file %s', comps(k),  filename );
        end
    elseif k == 1
        try
            topo = load( '-mat', filename);
        catch
            error([ 'Missing scalp topography file - also necessary for ERP polarity' 10 'Try recomputing scalp topographies for components' ]);
        end
    end

    try
        tmp =  getfield(topo, [ 'comp' int2str(comps(k)) '_grid' ]);
    catch
        error([ 'Empty scalp topography file - also necessary for ERP polarity' 10 'Try recomputing scalp topographies for components' ]);
    end

    if strcmpi(option, 'gradient')
        [tmpx, tmpy]  = gradient(tmp); % Gradient
        tmp        = tmpx;
        tmp(:,:,2) = tmpy;
    elseif strcmpi(option, 'laplacian')
        tmp = del2(tmp); % Laplacian
    end

    if length(comps) > 1 || strcmpi(mode, 'preclust')
        tmp = tmp(find(~isnan(tmp))); % remove NaN for more than 1 component
    end
    if k == 1
        X = zeros([ length(comps) size(tmp) ]) ;
    end
    X(k,:,:,:) =  tmp;
    if k == 1
        yi   = getfield(topo, [ 'comp' int2str(comps(k)) '_y']);
        xi   = getfield(topo, [ 'comp' int2str(comps(k)) '_x']);
    end
end
X = squeeze(X);

return;

function filename = correctfile(filename, datasetpath)
    comp = computer;
    if filename(2) == ':' && ~strcmpi(comp(1:2), 'PC')
        filename = [filesep filename(4:end) ];
        filename(find(filename == '\')) = filesep;
    end

    if ~exist(filename)
        [tmpp tmpf ext] = fileparts(filename);
        if exist([tmpf ext])
            filename = [tmpf ext];
        else
            [tmpp2 tmpp1] = fileparts(tmpp);
            if exist(fullfile(tmpp1, [ tmpf ext ]))
                filename = fullfile(tmpp1, [ tmpf ext ]);
            else
                filename = fullfile(datasetpath, [ tmpf ext ]);
                if ~exist(filename)
                    error([ 'Cannot load file ''' [ tmpf ext ] '''' 10 'Go back and recompute the data file.' 10 'Note that plotting ICA component ERPs require' 10 'to precompute ICA topographies (see tutorial)']);
                end
            end
        end
    end;