function [decodedMsgs,epochTimes]=decodeAISPosReports2Mat(NMEAStrings,convert2Metric)
%%DECODEAISPOSREPORTS2MAT Given a matrix of Automatic Identification
%                 System (AIS) messages (or a cell array of AIS messages)
%                 given as National Marine Electronics Association (NMEA)
%                 formatted ASCII text messages, extract position reports
%                 of message types 1, 2, 3, 18, 19, and 27, storing the
%                 information related to ship location, identity, course,
%                 and time in different rows of a matrix, where each
%                 column corresponds to a different report. If a cell
%                 array is passed, then the matrices for decoding each
%                 cell array are placed into corresponding cells on
%                 return. It is also possible to decode timestamps (or
%                 another integer number) appended as a final field on the
%                  messages. The manipulation of matrices rather than
%                 structures is significantly faster in Matlab, which is
%                 why one might prefer this function to decodeAISString
%                 when only simple position reports are needed.
%
%INPUTS: NMEAStrings A character string containing one or more Automatic
%                 Identification System (AIS) messages given as National
%                 Marine Electronics Association (NMEA) formatted ASCII
%                 text. Each message is on its own line. Invalid messages
%                 and messages that are not of types 1, 2, 3, 18, 19, and
%                 27 are skipped.
% convert2Metric  If true, all distance units in the result are converted
%                 to meters, all speed units are converted to meters per
%                 second, and all angles are converted to radians North of
%                 East (the mathematical definition) and angular rates are
%                 converted to radians per second North of East, all
%                 rather than using typical nautical units. The default if
%                 omitted is true.
%
%decodedMsgs A 14XN matrix of the N successfully decoded position reports.
%            The 14 fields that are decoded are stored in the matrix as:
%                     1) The maritime mobile service identity (MMSI)
%                        number of the transmitter that can be used to
%                        identify targets (A 30-bit integer value).
%                     2) Navigation status. An integer indicating what the
%                        ship is doing/ whether it is moving. Possible
%                        valid values are:
%                       *0 = under way using engine
%                       *1 = at anchor
%                       *2 = not under command,
%                       *3 = restricted maneuverability
%                       *4 = constrained by her draught
%                       *5 = moored
%                       *6 = aground
%                       *7 = engaged in fishing
%                       *8 = under way sailing
%                       *9 = reserved for future amendment of
%                          navigational status for ships carrying DG, HS,
%                          or MP, or IMO hazard or pollutant category C,
%                          high speed craft (HSC).
%                       *10 = reserved for future amendment of
%                          navigational status for ships carrying
%                          dangerous goods (DG), harmful substances (HS)
%                          or marine pollutants (MP), or IMO hazard or
%                          pollutant category A, wing in ground (WIG).
%                       *11 = power- driven vessel towing astern
%                              (regional use)
%                       *12 = power-driven vessel pushing ahead or towing
%                              alongside (regional use)
%                       *13 = reserved for future use,
%                       *14 = AIS-SART (active), MOB-AIS, EPIRB-AIS
%                     3) Turn rate. This is limited to +/- 708 degrees per
%                        minute (about +/- .2059 radians per second when
%                        using metric units).
%                     4) Speed over ground in knots up to 102.2 knots, or
%                        52.6 meters per second when using metric units.
%                     5) Position accuracy flag. Possible values are:
%                        1=high (accuracy beter than 10m)
%                        0=low (accuracy worse than 10 meters)
%                     6) Latitude (WGS-84) in degrees North or radians
%                        North when using the metric units option.
%                     7) Longitude (WGS 84) in degrees East or radians
%                        East when using the metric units option.
%                     8) Course over ground (heading) in degrees East of
%                        North or radians North of East when using the
%                        metric units option.
%                     9) True heading in degrees East of North or radians
%                        North of East when using the metric units option.
%                    10) The second number within the universal
%                        coordinated time (UTC) minute when the ship's
%                        transmitter sent the position report. NOTE that
%                        if this is 61 or greater, than this means that the
%                        the positioning system is broken or in dead
%                        reckoning mode, so the return is likely to be
%                        inaccurate. Also, the standard does not properly
%                        account for 61 second minutes when a leapsecond
%                        is added, so it is not clear what will happen
%                        with leapseconds. This field is not used by
%                        message 27. Rather, there is no timestamp and a
%                        position latency indicator is used to indicate
%                        the extend of the delay of the true time of the
%                        position from the broadcast time.
%                    11) Special manoeuvre indicator. This can be
%                        1 = not engaged in special manoeuvre
%                        2 = engaged in special manoeuvre
%                    12) The ID of the message that provided the above
%                        information. This can be
%                        1  Class A position report, scheduled.
%                        2  Class A position report, assigned.
%                        3  Class A position report, when interrogated.
%                        18 Standard class B equipment position report.
%                        19 Extended class B equipment position report.
%                        27 Long-range automatic identification system
%                           broadcast message.
%                    13) A number indicating how many times the message
%                        has been repeated. This ranged from 0 to 3. 3
%                        also indicates that the message should not be
%                        repeated anymore.
%                    14) Position latency. This is only used with message
%                        27. This is 0 or 1. 0 means the position latency
%                        is less than five seconds, one means it is more.
%          epochTimes If this parameter is requested, then the final
%                     numbers after the checklsum (separated by a comma)
%                     are assumed to either be an integer epoch time, or
%                     anything with a comma separating an integer epoch
%                     time at the end. Thus, this tries to decode the
%                     epoch time associated with the message. Note that in
%                     multi-part messages (message 19 can have multiple
%                     parts), the epoch time used is that of the LAST
%                     received part in the sequence. If no time can be
%                     decoded, then
%
%This function relies on libais from
%https://github.com/schwehr/libais
%The library probably does not work on big-endian processors (Intel
%processors are little-endian).
%
%The algorithm can be compiled for use in Matlab using the
%CompileCLibraries function.
%
%The algorithm is run in Matlab using the command format
%decodedMsgs=decodeAISPosReports2Mat(NMEAStrings,convert2Metric);
%or
%[decodedMsgs,epochTimes]=decodeAISPosReports2Mat(NMEAStrings,convert2Metric);
%if timestamps are available
%
%The algorithm is run in Matlab using the command format
%decodedMsgs=decodeAISPosReports2Mat(NMEAStrings,convert2Metric);
%or
%[decodedMsgs,epochTimes]=decodeAISPosReports2Mat(NMEAStrings,convert2Metric);
%if timestamps are available
%
%Example 1:, Decoding a single valid ID=1 string.
% NMEAStrings='!AIVDM,1,1,,A,13HOI:0P0000VOHLCnHQKwvL05Ip,0*23';
% decodedMsgs=decodeAISPosReports2Mat(NMEAStrings,false)
%The decoded message should be:
% decodedMsgs=[227006760;%MMSI
%                      0;%Navigation status (underway)
%                    NaN;%Not used
%                      0;%Turn rate
%                      0;%Speed over ground
%     49.475578308105469;%North latitude
%      0.131380006670952;%East longitude
%     36.700000762939453;%Heading East of North
%                    NaN;%Not used
%                     14;%Seconds within minute when message sent.
%                    NaN;%Not used.
%                      1;%Class A position report, scheduled.
%                      0;%has not ben rebroadcast.
%                    NaN];%Not used.
%
%Example 2: Decoding multiple messages, one valid string of each type of
%message. It is most likely that this would arise from reading the
%messages in from a file, because adding newline characters to strings has
%to be done using the \n newline character to separate the string in
%sprintf rather than just typing them. The AIS19 string consists of two
%parts that are joined.
% NMEAStrings=sprintf('!AIVDM,1,1,,A,13HOI:0P0000VOHLCnHQKwvL05Ip,0*23\n!AIVDM,1,1,,B,284;UGTdP4301>3L;B@Wk3TnU@A1,0*7C\n!AIVDM,1,1,,B,34hoV<5000Jw95`GWokbFTuf0000,0*6C\n!SAVDM,1,1,4,B,B5NU=J000=l0BD6l590EkwuUoP06,0*61\n!AIVDM,2,1,7,B,C5NMbDQl0NNJC7VNuC<v`7NF4T28V@2g0J6F::00000,0*59\n!AIVDM,2,2,7,B,0J70<RRS0,0*30\n!AIVDM,1,1,,B,K815>P8=5EikdUet,0*6B');
% decodedMsgs=decodeAISPosReports2Mat(NMEAStrings,false)
%One will observe that 6 messages are correctly decoded, of types 1, 2, 3,
%18, 19, and 27.
%
%Example 3: Decoding multiple messages, some of them of the wrong type.
%When messages of the wrong type are used, then they are askipped. Here,
%two correct messages are read in as well as one incorrect message in
%between them. The "incorrect" message is of type 26 (not a position report) and is thus ignored.
%Below are four strings, but only two of them contain AIS position reports
% NMEAStrings=sprintf('!AIVDM,1,1,,A,13HOI:0P0000VOHLCnHQKwvL05Ip,0*23\n!AIVDM,1,1,,A,H44cj<0DdvlHhuB222222222220,2*46\n!AIVDM,1,1,,B,284;UGTdP4301>3L;B@Wk3TnU@A1,0*7C');
% decodedMsgs=decodeAISPosReports2Mat(NMEAStrings)
%The results are in metric units.
%
%Example 4: Consider the case where the messages contain some numbers
%after the checksum, which make up the timestamps of the messages.
%This is the same as the previous example, but with fake timestamps
%appended.
% NMEAStrings=sprintf('!AIVDM,1,1,,A,13HOI:0P0000VOHLCnHQKwvL05Ip,0*23,1241827197\n!AIVDM,1,1,,A,H44cj<0DdvlHhuB222222222220,2*46,1241827198\n!AIVDM,1,1,,B,284;UGTdP4301>3L;B@Wk3TnU@A1,0*7C,1241827199');
% [decodedMsgs,epochTimes]=decodeAISPosReports2Mat(NMEAStrings)
%The results are in metric units.
%
%Example 5: Some receivers will append aditional information before the
%timestamp. As long as the timestamp is the last thing in the message,
%then we can still recover it.
% NMEAStrings='!AIVDM,1,1,,A,100WhdhP0nJRdiFFHFvm??v00L12,0*13,raishub,1342569600';
% [decodedMsgs,epochTimes]=decodeAISPosReports2Mat(NMEAStrings)
%The results are in metric units.
%
%November 2015 David F. Crouse, Naval Research Laboratory, Washington D.C.
%(UNCLASSIFIED) DISTRIBUTION STATEMENT A. Approved for public release.

error('This function is only implemented as a mexed C or C++ function. Please run CompileCLibraries.m to compile the function for use.')

end

%LICENSE:
%
%The source code is in the public domain and not licensed or under
%copyright. The information and software may be used freely by the public.
%As required by 17 U.S.C. 403, third parties producing copyrighted works
%consisting predominantly of the material produced by U.S. government
%agencies must provide notice with such work(s) identifying the U.S.
%Government material incorporated and stating that such material is not
%subject to copyright protection.
%
%Derived works shall not identify themselves in a manner that implies an
%endorsement by or an affiliation with the Naval Research Laboratory.
%
%RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE
%SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY THE NAVAL
%RESEARCH LABORATORY FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE ACTIONS
%OF RECIPIENT IN THE USE OF THE SOFTWARE.


clear all;clc;
%  close all;
outputDir = GetOutputDataDir;

%% Init load
hfig = figure;
InitializeAppData(hfig);
ResetDisplayParams(hfig);

%% params
isStimLockRanking = 0; % init
isMotorRanking = 0; % init

for caseflag = 5
    switch caseflag
        case 1 % seeds
            stimrange = [];
            M_clus_range = {[11,2],[12,1]};
            M_clus_name = {'motorseed2','ABN'};
            M_fishrange = {[1:3,5:18],[1:12,14:18]};
            n_reg = length(M_clus_name);

        case 2 % testing
            stimrange = [];
            M_clus_range = {[11,2],[11,3],[11,4]};
            M_clus_name = {'motorseed_v2','motorseed_LRmanual','motorseed_Fwmanual'};
            M_fishrange = {[5:13],[5:13],[5:13]};
            n_reg = length(M_clus_name);

        case 3 % conserved clusters
            stimrange = 1;
            M_clus_range = {[10,1]};
            M_clus_name = {'conservedclus_SLranked'};
            M_fishrange = {1:18};
            n_reg = length(M_clus_name);
            isStimLockRanking = 1;

        case 4 % all Auto0.7 clusters
            stimrange = [];
            M_clus_range = {[6,1]};
            M_clus_name = {'A0.7_def_stimlockrank'};
            M_fishrange = {1:18};
            n_reg = length(M_clus_name);
            isStimLockRanking = 1;

        case 5 % all Auto0.7 clusters
            stimrange = [];
            M_clus_range = {[6,1]};
            M_clus_name = {'A0.7_def_motorrank'};
            M_fishrange = {[1:3,5:18]};
            n_reg = length(M_clus_name);
            isStimLockRanking = 0;
            isMotorRanking = 1;

        case 6 % HBO stripes
            stimrange = 2;
            M_clus_range = {[10,4]};
            M_clus_name = {'HBO_anat'};
%             M_clus_name = {'HBO_OMR_stimlockrank'};
            M_fishrange = {[1:3,5:18]};%{8:18};%{1:18};%
            n_reg = length(M_clus_name);
            isStimLockRanking = 0;%1;
            isMotorRanking = 0;

            P_stimscore = zeros(18,4);

        case 7 % sparse network
            stimrange = 2;
            M_clus_range = {[12,2]};
            M_clus_name = {'sparse_nw'};
            %             M_clus_name = {'HBO_OMR_stimlockrank'};
            M_fishrange = {[1:8]};%{8:18};%{1:18};%
            n_reg = length(M_clus_name);

%                     case 6 % HBO stripes
%             stimrange = 1;
%             M_clus_range = {[10,4]};
%             M_clus_name = {'HBO_PT_stimlockrank'};
%             M_fishrange = {1:18};%{1:18};%{[1:3,5:18]};
%             n_reg = length(M_clus_name);
%             isStimLockRanking = 1;
%
%             P_stimscore = zeros(18,4);
%
%         case 3 % Looming
%             stimrange = 5;
%             M_stimmotorflag = [1,0]; % 1 for stim and 0 for motor
%             M_reg_name = {'Loom_LR','Loom_SwimLR'};
%             M_reg_range =  {[11,12],[1,3]};
%             M_fishrange = {[9:15,17:18],[9:15,17:18]};
%             n_reg = length(M_reg_name);
%
%         case 4 % Dark Flash (black-white)
%             stimrange = 3;
%             M_stimmotorflag = [1,0]; % 1 for stim and 0 for motor
%             M_reg_name = {'DF_BW','DF_SwimLR'};
%             M_reg_range =  {[1,4],[1,3]};
%             M_fishrange = {[12:15,17:18],[12:15,17:18]};
%             n_reg = length(M_reg_name);
    end

    M_fishrange_im = M_fishrange;

    %% Load fish
    range_fish = 1:18;
    IM_full = cell(n_reg,max(range_fish));
    %%
    for i_fish = range_fish
        %% load fish
        if ismember(i_fish,cell2mat(M_fishrange))
            ClusterIDs = [1,1];
            if isempty(stimrange)
                LoadSingleFishDefault(i_fish,hfig,ClusterIDs);
            else
                LoadSingleFishDefault(i_fish,hfig,ClusterIDs,stimrange);
            end
            %         [cIX_load,gIX_load,M,stim,behavior,M_0] = LoadSingleFishDefault(i_fish,hfig,ClusterIDs);
        end

        %% load clusters
        for i_set = 1:n_reg
            range_set = M_fishrange{i_set};
            if ismember(i_fish,range_set)
                ClusterIDs = M_clus_range{i_set};%[12,1];% GetClusterIDs('all');
                [cIX,gIX] = LoadCluster_Direct(i_fish,ClusterIDs(1),ClusterIDs(2));

                % override:
                if caseflag==7
                   gIX = ones(size(cIX));
                end
%                 if caseflag==6
%                     [cIX1,gIX1] = LoadCluster_Direct(i_fish,10,2);
%                     [cIX2,gIX2] = LoadCluster_Direct(i_fish,10,3);
%                     cIX = [cIX1;cIX2];
%                     gIX = [gIX1;5-gIX2];

%                     absIX = getappdata(hfig,'absIX');
%                     name = 'HBO_4stripes';
%                     clusgroupID = 10;
%                     clusIDoverride = 4;
%                     SaveCluster_Direct(cIX,gIX,absIX,i_fish,name,clusgroupID,clusIDoverride);
%                 end

                if isempty(cIX)
                    M_fishrange_im{i_set} = setdiff(M_fishrange_im{i_set} ,i_fish);
                    continue;
                end

                %% [option: ranking]
                if caseflag>=3
                    if isStimLockRanking
                        M = UpdateIndices_Manual(hfig,cIX,gIX);
                        C = FindClustermeans(gIX,M);
                        [~,~,H] = GetTrialAvrLongTrace(hfig,C);
                        [gIX,rankscore] = SortGroupIXbyScore(H,gIX);

                        if caseflag==6
                            P_stimscore(i_fish,:) = H;
                        end
                    elseif isMotorRanking
                        M = UpdateIndices_Manual(hfig,cIX,gIX);
                        C = FindClustermeans(gIX,M);
                        numU = max(gIX);
                       [gIX,rankscore] = RankByMotorReg_Direct(hfig,gIX,numU,C,1);
                    end
                end

                %% make figure

                if caseflag==3 || caseflag==4 || caseflag==6
                    setappdata(hfig,'clrmap_name','hsv_new');
%                 elseif caseflag==6
%                     setappdata(hfig,'clrmap_name','jet');
                else
                    setappdata(hfig,'clrmap_name','hsv_old');
                end

                I = LoadCurrentFishForAnatPlot(hfig,cIX,gIX);
                [h,im_full] = DrawCellsOnAnat(I);

                %% save figure
                close(h);
                IM_full{i_set,i_fish} = im_full;
            end
        end
    end

%     if caseflag==6
%         % save VAR
%         SaveVARtoMat(hfig);
%     end

    %% save as tiff stack
    for i_set = 1:n_reg
        range_im = M_fishrange_im{i_set};
        tiffdir = fullfile(outputDir,[M_clus_name{i_set},'_allfish.tiff']);
        IM = IM_full(i_set,range_im);

        SaveImToTiffStack(IM,tiffdir);
    end

    %% [for later] plot from tiff stack
    isPlotfromtiffstack = 0;

    if isPlotfromtiffstack
        IM_full = cell(n_reg,18);
        for i_set = 1:n_reg
            %% get tiff-stack path
            tiffdir = fullfile(outputDir,[M_clus_name{i_set},'_allfish.tiff']);

            %% load

            for i_fish = 1:18
                im = double(imread(tiffdir,i_fish))./255;
                IM_full{i_set,i_fish} = im(317:1236,1:621,:);
            end
        end
    end

    %% save average tiff image
    for i_set = 1:n_reg;
        range_im = M_fishrange_im{i_set};%[1:3,5:7];%[1:3,5:18];
        cellarray = IM_full(i_set,range_im);

        % adjust params for visualization
        k_scale = 0.5;
        k_contrast = 1;% 1.2;

        [h_anat,im_avr] = AverageAnatPlot(cellarray,k_contrast,k_scale);

        tiffdir = fullfile(outputDir,[M_clus_name{i_set},'_avr.tiff']);
        imwrite(im_avr, tiffdir, 'compression','none','writemode','overwrite');
    end

end


function ph = atlasUndoPhase(atlasParams, ph)
%
%      ph = atlasUndoPhase(atlasParams, ph)
%
% Purpose:
%   Convert the atlas phase data by shifting their phase and scaling the
%   phase range.  The amount of shifting and scaling is stored in the
%   phaseShift/phaseScale fields.  I am not sure why this code is used at
%   all.  I think we should be using shiftPhase instead and this is left
%   over from version 1.0.  I am trying to get rid of it -- BW
%
% HISTORY:
% 2003.08.29 RFD (bob@white.stanford.edu) got tired of duplicating this
% code, so here's a simple function.

warning('atlasUndoPhase is obsolete.')

% Checking.
if(length(atlasParams) ~= length(ph) | length(atlasParams(1).phaseShift) ~= size(ph{1},3))
    warning('atlasParams and ph should have the same number of scans and slices!');
end

%  Create a scaled and shifted version of the atlas parameters.
for(scan=1:length(atlasParams))
    for(slice=1:length(atlasParams(scan).phaseShift))
        ph{scan}(:,:,slice) = mod((squeeze(ph{scan}(:,:,slice)) ...
            - atlasParams(scan).phaseShift(slice)) / atlasParams(scan).phaseScale(slice), 2*pi);
    end
end

return;


function out = rdivide( dividend, divisor )
%RDIVIDE for nested cells
%
% (c) Thomas Kuestner
% ---------------------------------------------------------------------

% determine input types
inType = {class(dividend), class(divisor)};
if(strcmp(inType{1},'TRAFO') && strcmp(inType{2},'TRAFO'))
    [outA, idx] = flattenCellMatrix(dividend.data);
    [outB, idxB] = flattenCellMatrix(divisor.data);
    meta = dividend.meta;
    meta_b = divisor.meta;
    clear 'dividend' 'divisor'

    % idx must be consistent
    if(~isempty(idx) && ~isempty(idxB) && ~all(cellfun(@(x,y) isequal(x,y), idx, idxB)))
        error('TRAFO::rdivide: Nested cells must have the same size');
    end
    if(iscell(meta) && iscell(meta_b))
        if(~isempty(meta) && ~isempty(meta_b))
            if(iscell(meta{1}) && iscell(meta_b{1}))
                if(~all(cellfun(@(x,y) isequal(x,y), flattenCellMatrix(meta), flattenCellMatrix(meta_b))))
                    error('TRAFO::rdivide: Unequal reconstruction information');
                end
            else
                if(~all(cellfun(@(x,y) isequal(x,y), meta, meta_b)))
                    error('TRAFO::rdivide: Unequal reconstruction information');
                end
            end
        end
    else
        if ~isequal(meta, meta_b)
            error('TRAFO::rdivide: Unequal reconstruction information');
        end
    end
    out = cellfun(@(x,y) x./y, outA, outB, 'UniformOutput', false);

elseif(strcmp(inType{1},'TRAFO')) % assume divisor is double/uint/int
    [out, idx] = flattenCellMatrix(dividend.data);
    meta = dividend.meta;
    clear 'dividend'

    out = cellfun(@(x) x./divisor, out, 'UniformOutput', false);

elseif(strcmp(inType{2},'TRAFO'))
    [out, idx] = flattenCellMatrix(divisor.data);
    meta = divisor.meta;
    clear 'divisor'

    out = cellfun(@(x) dividend./x, out, 'UniformOutput', false);

else
    error('TRAFO::rdivide: Impossible constellation!');
end

out = reconFlatCellMatrix(out,idx);
out = TRAFO(out,meta); % return TRAFO object again without modifying input

end


clc;
close all;
clear;

mDir = fileparts(mfilename('fullpath'));
cd(mDir);
addpath(genpath('../'));

%% Params:

exp = 'ALL_4_SEGS'; % Select which configuration to use: 'JUST_LAB_SEG', 'ALL_4_SEGS'
calcInLog=false; %false (for linear vus), true (for logarithmic vus)

%Change these paths:
originalVOCDirectory = TOFILL; %Top directory of VOC 2007 dataset
parsedVOCDir = TOFILL; %Directory where parsed VOC07 will be stored

%VOC params:

imgListDir= 'complete_test_set.txt'; %File with ids of the 4952 images of the test set

params.includeBoxesWithClasses={'aeroplane', 'bicycle','boat','bottle','bus','chair','diningtable','horse','motorbike','person','pottedplant','sofa','train','tvmonitor'};
params.omitImagesWithClasses={'bird','car','cat','cow','dog','sheep'};
params.considerDifficult=true;

nMaximumWindows = 10000;
evalParams.nWindows = unique(round(logspace(0, log10(nMaximumWindows), 100)));
evalParams.ious = 0 : 0.05 : 1;

if(strcmp(exp, 'ALL_4_SEGS'))
  configFile = '../config/rp_4segs.mat';
  proposalsDir = [mDir '/tmp_prop_dir'];
elseif(strcmp(exp, 'JUST_LAB_SEG'))
  configFile = '../config/rp.mat';
  proposalsDir = [mDir '/tmp_prop_dir_lab'];
else
  assert(false);
end
resultDirs={proposalsDir};

%% Parse VOC2007 data:

AdaptVOC2007Data(originalVOCDirectory,imgListDir,parsedVOCDir,params);

%% Compute proposals and individual detection rates:

ComputeProposals(parsedVOCDir, proposalsDir, configFile, evalParams);

%% Aggregate detection rates:

AggregateDRs(proposalsDir, parsedVOCDir, evalParams);

%% Compute Volume Under Surface:

nWindowsRange=[0 10000];
iouRange=[0.5 1];

nResults=numel(resultDirs);
drs=[];
for k=1:nResults
  data=load([resultDirs{k} '/aggregated_drs/drs.mat']);

  [cropped,legendStr]=CropEvaluations({data}, nWindowsRange, iouRange,{''});

  data=cropped{1};

  if(exist('ious','var'))
    assert( all(ious==data.ious));
  else
    ious=data.ious;
    nIous=length(ious);
  end

  if(exist('nWindows','var'))
    assert(all(nWindows==data.nWindows));
  else
    nWindows=data.nWindows;
    nnWindows=length(nWindows);
  end

  assert( ~exist('iNWindows','var') && ~exist('iIous','var'));

  drs=cat(3,drs,data.drs);
end

if(calcInLog)
  nWindows=log10(nWindows);
end

maxDrs=max(drs,[],3);
volumes=[];
maxVolume=trapz(ious, trapz(nWindows, maxDrs));
for k=1:nResults
  assert(all(all(maxDrs>=drs(:,:,k))));
  volumes=[ volumes, trapz(ious, trapz(nWindows, drs(:,:,k)))];
end

%Worse point computation
worsePoint=[];
for k=1:nResults
  worsePoint=[worsePoint, -max(max(maxDrs-drs(:,:,k)))];
end

perVolumes = volumes./((nWindows(end)-nWindows(1))*(ious(end)-ious(1)));

assert(all(perVolumes)>=0 && all(perVolumes)<=1);

volumeRatios=volumes/maxVolume;
[~, ids]=sort(volumeRatios,'descend');

volumeRatios=volumeRatios(ids);
worsePoint=worsePoint(ids);
perVolumes=perVolumes(ids);
assert(issorted(flipdim(perVolumes,2)));
for k=1:nResults
  fName=resultDirs{ids(k)};
  if(fName(end)=='/')
    fName=fName(1:(end-1));
  end
  [~,name,~]=fileparts(fName);
  disp('############################################################################');
  disp([ 'Volume Under Surface (VUS):' num2str(perVolumes(k))]);
end

%% Display DR curve:

selIou = 0.5;
semilogx(data.nWindows, data.drs(:, find(data.ious==selIou)), 'LineWidth', 3, 'Color', 'r');
ylim([0, 1]);
ylabel('Detection Rate');
xlabel('Number of proposals')
axis square;


% ----------------------------------------------------------------------------
% function hfssAssignMaster(fid, Name, ObjName, iUStart, iUEnd, Units,
%                               [ReverseV])
%
% Description :
% -------------
% Creates the necessary VB Script to assign a Master Boundary to a given Object.
%
% Parameters :
% ------------
% fid     - file identifier of the HFSS script file.
% Name    - name of the master boundary (appears under 'Boundaries' in HFSS).
% ObjName - name of the (sheet-like) object to which the master boundary is to
%           be assigned.
% iUStart - (vector) starting point of the U vector. Specify as
%           [x, y, z].
% iUEnd   - (vector) ending point of the U vector. Specify as
%           [x, y, z].
% Units   - specify as 'meter', 'in', 'cm' (defined in HFSS).
% [ReverseV] - (boolean, optional) reverses vector V (defaults to
%                true if the U vector points +y, and to false elsewise)
% Example :
% ---------
% fid = fopen('myantenna.vbs', 'wt');
% ...
% hfssAssignMaster(fid, 'Master', 'Sheet', [-width/2, 0, 0], ...
%	                 [width/2, 0, 0], 'meter', false);
%
% ----------------------------------------------------------------------------

% ----------------------------------------------------------------------------
% CHANGELOG
%
% 20-May-2013: *Initial release.
% ----------------------------------------------------------------------------

% ----------------------------------------------------------------------------
% Written by Pablo Alcon Garcia
% pabloalcongarcia@gmail.com / palcon@tsc.uniovi.es
% 20 May 2013
% ----------------------------------------------------------------------------
function hfssAssignMaster(fid, Name, ObjName, iUStart, iUEnd, Units, ReverseV)

% arguments processor.
if (nargin < 6)
	error('Insufficient # of arguments !');
elseif (nargin < 7)
    if iUEnd(2)~=iUStart(2)
        ReverseV = true;
    else
        ReverseV = false;
    end
end

if ReverseV
    ReverseV = 'true';
else
    ReverseV = 'false';
end

% Preamble.
fprintf(fid, '\n');
fprintf(fid, 'Set oModule = oDesign.GetModule("BoundarySetup")\n');

% Parameters
fprintf(fid, 'oModule.AssignMaster _\n');
fprintf(fid, 'Array("NAME:%s", _\n', Name);
fprintf(fid, '\t"Objects:=", Array("%s"), _\n', ObjName);
fprintf(fid, '\tArray("NAME:CoordSysVector", "Origin:=", _\n');
fprintf(fid, '\t\tArray("%f%s", "%f%s", "%f%s"), _\n', ...
        iUStart(1), Units, iUStart(2), Units, iUStart(3), Units);
fprintf(fid, '\t\t"UPos:=", Array("%f%s", "%f%s", "%f%s") _\n', ...
        iUEnd(1), Units, iUEnd(2), Units, iUEnd(3), Units);
fprintf(fid, '\t\t), _\n');
fprintf(fid, '\t"ReverseV:=", %s _\n',ReverseV);
fprintf(fid, '\t)\n');