%% MEEG time-lock searchlight
%
% This example shows MVPA analyses performed on MEEG data.
%
% The input dataset involved a paradigm where a participant saw
% images of six object categories.
%
%
% The code presented here can be adapted for other MEEG analyses, but
% there please note:
% * the current examples do not perform baseline corrections or signal
%   normalizations, which may reduce discriminatory power.
%
% Note: running this code requires FieldTrip.
%
% #   For CoSMoMVPA's copyright information and license terms,   #
% #   see the COPYING file distributed with CoSMoMVPA.           #

%% get timelock data in CoSMoMVPA format

% set configuration
config=cosmo_config();
data_path=fullfile(config.tutorial_data_path,'meg_obj6');

% show dataset information
readme_fn=fullfile(data_path,'README');
cosmo_type(readme_fn);

% reset citation list
cosmo_check_external('-tic');

% load preprocessed data
data_fn=fullfile(data_path,'meg_obj6_s00.mat');
data_tl=load(data_fn);

% Show data_tl
% >@@>
cosmo_disp(data_tl);
% <@@<

%%

% convert to cosmomvpa struct, using cosmo_meeg_dataset
% >@@>
ds=cosmo_meeg_dataset(data_tl);
% <@@<

% show the dataset
% >@@>
cosmo_disp(ds);
% <@@<

%%

% set the targets in ds.sa.targets (trial condition)
% Hint: use the first column from ds.sa.trialinfo
% >@@>
ds.sa.targets=ds.sa.trialinfo(:,1); % 6 categories
% <@@<

% set the chunks in ds.sa.chunks (independent measurements)
% all trials are here considered to be independent, so the chunks
% must all have a different value
% >@@>
nsamples=size(ds.samples,1);
ds.sa.chunks=(1:nsamples)';
% <@@<

% in addition give a label to each trial
index2label={'body','car','face','flower','insect','scene'};
ds.sa.labels=cellfun(@(x)index2label(x),num2cell(ds.sa.targets));

% just to check everything is ok
cosmo_check_dataset(ds);

%% Count number of channels, time points and trials
% >@@>
fprintf('There are %d channels, %d time points and %d trials\n',...
        numel(unique(ds.fa.chan)),numel(unique(ds.fa.time)),...
        size(ds.samples,1));
% <@@<
%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Part I: compute difference between faces and scenes
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% For each time point and sensor; then visualize the results
% for the magnetometer (meg_axial) sensors.

% slice 'ds' twice to get 'ds_face' and 'ds_scene', each with only trials
% from the face and scene categories

% >@@>
ds_face=cosmo_slice(ds,cosmo_match(ds.sa.labels,'face'));
ds_scene=cosmo_slice(ds,cosmo_match(ds.sa.labels,'scene'));
% <@@<

% prepare dataset for output
ds_faceVSscene=cosmo_slice(ds_face,1);
ds_faceVSscene.sa=struct(); % destroy sample attributes

% Compute difference between average of faces versus average of scenes;
% store the result in the samples field of ds_faceVSscene
% >@@>
ds_faceVSscene.samples=mean(ds_face.samples)-mean(ds_scene.samples);
% <@@<

% Convert ds_faceVSscene to a fieldtrip structure and convert
ft_faceVSscene=cosmo_map2meeg(ds_faceVSscene);
%%
% Use FieldTrip to visualize the face versus house contrast
chantype='meg_axial';
layout=cosmo_meeg_find_layout(ds_faceVSscene,'chantype',chantype);

figure();
cfg=struct();
cfg.interactive='yes';
cfg.zlim=[-1 1];
cfg.layout=layout;

% show figure with plots for each sensor
ft_multiplotER(cfg, ft_faceVSscene);
%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Part 2: run searchlight over time
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% set MVPA parameters
fprintf('The input has feature dimensions %s\n', ...
                cosmo_strjoin(ds.a.fdim.labels,', '));

% only select relevant time period and sensors
sensor_posterior_axial={'MEG1631', 'MEG1641', 'MEG1731', 'MEG1841', ...
                        'MEG1911', 'MEG1921', 'MEG1941', 'MEG2231', ...
                        'MEG2311', 'MEG2321', 'MEG2341', 'MEG2431', ...
                        'MEG2441', 'MEG2511', 'MEG2531'};

% define the mask
msk=cosmo_dim_match(ds,'time',@(t) t>=-.1 & t<=.4,...
                        'chan',sensor_posterior_axial);

% first slice the dataset, then use cosmo_dim_prune to avoid using
% non-selected data. Assign the result to ds_sel
%%%% >>> Your code here <<< %%%%
ds_sel_orig=cosmo_slice(ds,msk,2);
cosmo_disp(ds_sel_orig);

ft_orig=cosmo_map2meeg(ds_sel_orig);
%%
ds_sel=cosmo_dim_prune(ds_sel_orig);
cosmo_disp(ds_sel);
ft_sel=cosmo_map2meeg(ds_sel);

%%

% define the neighborhood for time with a time radius of 2 time points,
% and assign to time_nbrhood.
% Hint: use cosmo_interval_neighborhood,

time_nbrhood=cosmo_interval_neighborhood(ds_sel,'time','radius',2);
cosmo_disp(time_nbrhood)

%%

%%%% >>> Your code here <<< %%%%

% Define the measure to be cosmo_crossvalidation_measure,
% and assign to measure
measure=@cosmo_crossvalidation_measure;

%%%% >>> Your code here <<< %%%%

%nsamples=numel(ds_sel.samples);
%rp=cosmo_randperm(nsamples);
%ds_sel.sa.targets=ds_sel.sa.targets(rp);

partitions=cosmo_independent_samples_partitioner(ds_sel,...
                                    'fold_count',5,...
                                    'test_ratio',0.2);

cosmo_disp(partitions)
%%
% Define the partitioning scheme using
% cosmo_independent_samples_partitioner, and assign to partitions.
% Use 'fold_count',5 to use 5 folds,
% and use 'test_ratio',.2 to use 20% of the data for testing (and 80% for
% training) in each fold.

%%%% >>> Your code here <<< %%%%

% Use the LDA classifier and the partitions just defined,
measure_args=struct();
measure_args.partitions=partitions;
measure_args.classifier=@cosmo_classify_lda;

ds_sl=cosmo_searchlight(ds_sel,time_nbrhood,measure,measure_args);

plot(ds_sl.a.fdim.values{1},ds_sl.samples)
xlabel('time');
ylabel('classification accuracy');

%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Part III: channel-time searchlight
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% select limited time period
msk=cosmo_dim_match(ds,'time',@(t) t>=-.1 & t<=.4);

% first slice the dataset using the mask and assign to 'ds_sel'
ds_sel=cosmo_slice(ds,msk,2);

% Now use cosmo_dim_prune to avoid attempts to using
% non-selected data in the searchlight
ds_sel=cosmo_dim_prune(ds_sel);

% Set the seachlight parameters
chan_count=10; % 10 center channels in each searchlight
time_radius=2; % 2*2+1=5 time bins
chan_type='meg_combined_from_planar';

% define the neighborhood for each dimensions
% First, set 'chan_nbrhood' using cosmo_meeg_chan_neighborhood,
% and use the 'chantype' and 'count' parameters to set the channel type
% and the number of sensors in each searchlight.
chan_nbrhood=cosmo_meeg_chan_neighborhood(ds_sel,'chantype',chan_type,...
                                    'count',chan_count);

cosmo_disp(chan_nbrhood);
%%

%%%% >>> Your code here <<< %%%%

% Second, set 'time_nbrhood' using cosmo_interval_neighborhood,
% using the 'time' dimension

time_nbrhood=cosmo_interval_neighborhood(ds_sel,'time','radius',2);

%%%% >>> Your code here <<< %%%%

% cross neighborhoods for chan-time searchlight
% Hint: use cosmo_cross_neighborhood, and use chan_nbrhood and time_nbrhood
% (in that order) in a cell as the second argument
nbrhood=cosmo_cross_neighborhood(ds_sel,{chan_nbrhood,time_nbrhood});

%%%% >>> Your code here <<< %%%%

% print how many neighbors features have on average
nbrhood_nfeatures=cellfun(@numel,nbrhood.neighbors);
fprintf('Features have on average %.1f +/- %.1f neighbors\n', ...
            mean(nbrhood_nfeatures), std(nbrhood_nfeatures));

%%

% set the 'measure' variable to a function handle to the
% split-half correlation measure
measure=@cosmo_correlation_measure;

% Define the partitioning scheme using
% cosmo_independent_samples_partitioner.
% Use 'fold_count',1 to use 1 folds,
% and use 'test_ratio',.5 to use 50% of the data for testing (and 50% for
% training) in the single fold.
partitions=cosmo_independent_samples_partitioner(ds_sel,'fold_count',1,...
                                            'test_ratio',0.5);

%%%% >>> Your code here <<< %%%%
measure_args=struct();
measure_args.partitions=partitions;

%% run searchlight
% run the searchlight using the parameters above, and assign the result
% to a varibale 'ds_sl'

ds_sl=cosmo_searchlight(ds_sel,nbrhood,measure,measure_args);

%%%% >>> Your code here <<< %%%%

%% visualize timeseries results

% deduce layout from output
layout=cosmo_meeg_find_layout(ds_sl);
fprintf('The output uses layout %s\n', layout.name);

% map ds_sl to a FieldTrip structure. Assign the result to 'sl_ft'
sl_ft=cosmo_map2meeg(ds_sl);

%%%% >>> Your code here <<< %%%%

figure();
cfg = [];
cfg.interactive = 'yes';
cfg.zlim=[-1 1];
cfg.layout       = layout;

% show figure with fisher-transformed correlations for each sensor
ft_multiplotER(cfg, sl_ft);

%% visualize topology results
% show figure with topology for 100 before to 400ms after stimulus onset
% in bins of 50 ms
figure();
cfg.xlim=-0.1:0.05:0.4;
ft_topoplotER(cfg, sl_ft);

%% Show citation information
cosmo_check_external('-cite');


function y=ewmacovariance(R1,R2,n,s,lambda)
%
% implemented by ewmaestimatevar function
%
%% Written By Ali Najjar
%
if s==1
    y=R1(n-s)*R2(n-s);
else
    y=((1-lambda)*((R1(n-1))*(R2(n-1))))+(lambda*ewmacovariance(R1,R2,n-1,s-1,lambda));
end
end


clear all;
close all;
clc;
check_yale_faces(4, @ssc_l1, 'ssc_l1');


function measPara = convertToMeasPara( drecksMDH, measPara )
%CONVERTTOMEASPARA convert from drecksMDH 2.0-struct to measPara-struct,
% but measPara-struct now contains just all needed variables
%
% (c) Thomas Kuestner
% ---------------------------------------------------------------------

if(drecksMDH.Seq.Is3D)
    measPara.dimensionSeq = '3D';
else
    measPara.dimensionSeq = '2D';
end
measPara.sliceThickness = drecksMDH.Geo.FOV(3)/drecksMDH.Geo.MatrixSize(3);
measPara.lines = drecksMDH.Geo.MatrixSize(2);
measPara.partitions = drecksMDH.Geo.MatrixSize(3);
measPara.baseResolution = drecksMDH.Geo.MatrixSize(1);
measPara.FOVread = drecksMDH.Geo.FOV(1);
measPara.FOVphase = drecksMDH.Geo.FOV(2);
measPara.sequenceName = drecksMDH.Seq.Sequence;
if(isfield(drecksMDH.Geo,'FFTLength'))
    measPara.ftlenPhase = drecksMDH.Geo.FFTLength(1);
    measPara.ftlenPar = drecksMDH.Geo.FFTLength(2);
else
    measPara.ftlenPhase = [];
    measPara.ftlenPar = [];
end
measPara.imageWidth = [];
measPara.imageHeight = [];

if(isfield(drecksMDH,'Accel') && isfield(drecksMDH.Accel,'EspressoDir'))
    dir_mapping = {'y', 'z', 'off'};
    measPara.ESPReSSoDirection = dir_mapping{drecksMDH.Accel.EspressoDir};
    pfn_mapping = [81, 90, 99, 108, 117; 1, 0.5, 0.625, 0.75, 0.875];
    measPara.ESPReSSo = pfn_mapping(2,pfn_mapping(1,:) == drecksMDH.Accel.EspressoFactor);
else
    measPara.ESPReSSoDirection = 'off';
    measPara.ESPReSSo = 1;
end

if(isfield(drecksMDH,'Wip'))
    if(isfield(drecksMDH.Wip,'SamplingFactor'))
        measPara.CSAcceleration = drecksMDH.Wip.SamplingFactor;
    end
    if(isfield(drecksMDH.Wip,'Phases'))
       	measPara.dim(4) = drecksMDH.Wip.Phases;
    end
    if(isfield(drecksMDH.Wip,'FullySampled'))
        measPara.CSFullySampled = drecksMDH.Wip.FullySampled;
    end
    if(isfield(drecksMDH.Wip,'Mask'))
        switch drecksMDH.Wip.Mask(1:2)
            case '06', measPara.CSSamplingType = 'Poisson';
            case '07', measPara.CSSamplingType = 'Random';
            case '08', measPara.CSSamplingType = 'Gaussian';
        end
        if(length(drecksMDH.Wip.Mask) > 3)
            switch drecksMDH.Wip.Mask(4:5)
                case '01', measPara.CSVDmap = 'None';
                case '02', measPara.CSVDmap = 'Point';
                case '03', measPara.CSVDmap = 'Block';
                case '04', measPara.CSVDmap = 'Ellipse';
                case '05', measPara.CSVDmap = 'Ring';
            end
    %         switch drecksMDH.Wip.Mask(7:8)
    %             case '14', measPara.CSBodyRegion = 'None';
    %             case '15', measPara.CSBodyRegion = 'Head';
    %             case '16', measPara.CSBodyRegion = 'Thorax';
    %             case '17', measPara.CSBodyRegion = 'Abdomen';
    %             case '18', measPara.CSBodyRegion = 'Pelvis';
    %         end
        end
    end
end

if(isfield(drecksMDH.Seq,'Bandwidth'))
    measPara.bandwidthPerPixel = drecksMDH.Seq.Bandwidth;
end

if(isfield(drecksMDH.Geo,'NormSag'))
    if(drecksMDH.Geo.NormSag)
        measPara.orientation    = 'sagittal';
    elseif(drecksMDH.Geo.NormCor)
        measPara.orientation    = 'coronal';
    elseif(drecksMDH.Geo.NormTra)
        measPara.orientation    = 'transversal';
    else
        measPara.orientation = 'rotated';
    end

    % pixel positions
    if(isfield(drecksMDH.Geo,'Shift'))
        measPara.position = drecksMDH.Geo.Shift;
    else
        measPara.position = zeros(1,3);
    end
    measPara.pixelSpacing = [drecksMDH.Geo.FOV(2)/drecksMDH.Geo.MatrixSize(2), drecksMDH.Geo.FOV(1)/drecksMDH.Geo.MatrixSize(1), drecksMDH.Geo.FOV(3)/drecksMDH.Geo.MatrixSize(3)]; % y-x-z/slice
    center = [drecksMDH.Geo.MatrixSize(2)/2, drecksMDH.Geo.MatrixSize(1)/2, drecksMDH.Geo.MatrixSize(3)/2];

    switch measPara.orientation
        case 'sagittal'
            measPara.xPos = measPara.position(1) + ([1:drecksMDH.Geo.MatrixSize(3)].' - center(3)) .* measPara.pixelSpacing(3);
            measPara.yPos = measPara.position(2) + ([1:drecksMDH.Geo.MatrixSize(2)].' - center(1)) .* measPara.pixelSpacing(1);
            measPara.zPos = measPara.position(3) + ([1:drecksMDH.Geo.MatrixSize(1)].' - center(2)) .* measPara.pixelSpacing(2);
        case 'coronal'
            measPara.xPos = measPara.position(1) + ([1:drecksMDH.Geo.MatrixSize(1)].' - center(2)) .* measPara.pixelSpacing(2);
            measPara.yPos = measPara.position(2) + ([1:drecksMDH.Geo.MatrixSize(3)].' - center(3)) .* measPara.pixelSpacing(3);
            measPara.zPos = measPara.position(3) + ([1:drecksMDH.Geo.MatrixSize(2)].' - center(1)) .* measPara.pixelSpacing(1);
        case 'transversal'
            measPara.xPos = measPara.position(1) + ([1:drecksMDH.Geo.MatrixSize(1)].' - center(2)) .* measPara.pixelSpacing(2);
            measPara.yPos = measPara.position(2) + ([1:drecksMDH.Geo.MatrixSize(2)].' - center(1)) .* measPara.pixelSpacing(1);
            measPara.zPos = measPara.position(3) + ([1:drecksMDH.Geo.MatrixSize(3)].' - center(3)) .* measPara.pixelSpacing(3);
        otherwise
            %
    end
end

% correct values
if(~isfield(measPara,'dim'))
    measPara.dim = zeros(1,5);
    measPara.LCall = zeros(1,4);
end
measPara.dim(1) = measPara.lines;
measPara.dim(2) = drecksMDH.Geo.OverSampling(1) * measPara.baseResolution; % due to CS_Trufi prescans
measPara.dim(3) = measPara.partitions;
% if(strcmp(measPara.sequenceName, 'CS_Trufi') && ~isempty(iLC)) % number of kernels (SetLC) = cardiac phases = time domain
%     measPara.dim(4) = double(max(iLC(:,10)) - min(iLC(:,10)) + 1); % SetLC
% end
measPara.LCall(2) = drecksMDH.LC.Averages;
if(measPara.dim(3) <= 1)
    measPara.dimension = '2D';
else
    if(measPara.dim(4) > 1)
        measPara.dimension = '4D';
    else
        measPara.dimension = '3D';
    end
end
measPara.dim(6) = 1;
if(isfield(drecksMDH,'Wip'))
    if(isfield(drecksMDH.Wip,'NSamples') && drecksMDH.Wip.NSamples > 0)
        measPara.dimension = '5D';
        measPara.dim(6) = drecksMDH.Wip.NSamples;
    elseif(isfield(drecksMDH.Wip,'NCardGates') && drecksMDH.Wip.NCardGates > 0)
        measPara.dimension = '5D';
        measPara.dim(6) = drecksMDH.Wip.NCardGates;
    end
end
if(isfield(measPara, 'sequenceName') && strcmp(measPara.sequenceName,'CS_Retro'))
    measPara.CSAcceleration = 2; % something unequal to 1
end

% local variables, just needed for further calculations
FOVphasePercentage = measPara.FOVphase/measPara.FOVread;
phaseOversampling = drecksMDH.Geo.OverSampling(2) - 1;
sliceOversampling = drecksMDH.Geo.OverSampling(3) - 1;

%% oversampling and anisotropy

% OVERSAMPLING PHASE INCORRECT!!!!!
% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

% initialize anisotropic correction (y-x-z/slice-t)
measPara.aniso = [measPara.dim(1), measPara.dim(2), measPara.dim(3), measPara.dim(4), measPara.dim(6)];
% oversampling correction exactly possible => no case switch necessary later
if(~isfield(measPara,'oversampling'))
    measPara.oversampling = cell(2,3);
end
measPara.oversampling{2,2} = true;
measPara.oversampling{2,3} = true;

% readout oversampling
readoutDiff = (drecksMDH.Geo.OverSampling(1) - 1) * measPara.baseResolution;
measPara.oversampling{1,1} = readoutDiff/2+1:measPara.dim(2)-readoutDiff/2;
if(isempty(measPara.imageWidth) || measPara.imageWidth == 0)
    measPara.imageWidth = length(measPara.oversampling{1,1});
end

% correct anisotropy if oversampling correction was done during recon
if(measPara.oversampling{2,1})
    measPara.aniso(2) = length(measPara.oversampling{1,1});
end

% phase anistropy
if(isempty(measPara.ftlenPhase) || measPara.ftlenPhase == 0 || measPara.ftlenPhase ~= round(measPara.baseResolution * FOVphasePercentage * (1+phaseOversampling)))
    measPara.ftlenPhase = round(measPara.baseResolution * FOVphasePercentage * (1+phaseOversampling));
    if(measPara.ftlenPhase > measPara.baseResolution && FOVphasePercentage < 1) % can occur that y>x
        measPara.ftlenPhase = measPara.baseResolution;
    end
end
if(drecksMDH.Geo.PhaseRes(1) ~= 1)
    measPara.aniso(1) = measPara.ftlenPhase;
end
% phase oversampling
if(isempty(measPara.imageHeight) || measPara.imageHeight == 0)
    diffSize = abs(measPara.ftlenPhase - round(FOVphasePercentage * measPara.baseResolution));
    measPara.imageHeight = measPara.ftlenPhase;
else
    diffSize = abs(measPara.imageHeight - round(FOVphasePercentage * measPara.baseResolution));
end
if(mod(diffSize,2) == 0)
    oversamplimits = [round(diffSize/2)+1, round(diffSize/2)];
else
    oversamplimits = [round(diffSize/2)+1, 0];
    oversamplimits(2) = abs(diffSize-(oversamplimits(1)-1));
end
measPara.oversampling{1,2} = oversamplimits(1):(measPara.aniso(1)-oversamplimits(2));

if(strcmp(measPara.dimension,'3D') || strcmp(measPara.dimension,'4D') ||  strcmp(measPara.dimension,'5D'))
    % slice anisotropy
    if(isempty(measPara.ftlenPar) || measPara.ftlenPar == 0 || measPara.ftlenPar ~= round(drecksMDH.Geo.ImagesPerSlab * (1+sliceOversampling)))
        measPara.ftlenPar = round(drecksMDH.Geo.ImagesPerSlab * (1+sliceOversampling));
    end
    if(drecksMDH.Geo.PhaseRes(2) ~= 1)
        measPara.aniso(3) = measPara.ftlenPar;
    end
    % slice oversampling
    diffSize = abs(measPara.ftlenPar - drecksMDH.Geo.ImagesPerSlab);
    if(mod(diffSize,2) == 0)
        oversamplimits = [round(diffSize/2)+1, round(diffSize/2)];
    else
        oversamplimits = [round(diffSize/2)+1, 0];
        oversamplimits(2) = abs(diffSize-(oversamplimits(1)-1));
    end
    measPara.oversampling{1,3} = oversamplimits(1):(measPara.aniso(3)-oversamplimits(2));
%     measPara.imageDepth = measPara.imagesPerSlab;  %% ATTENTION !!!!!!!!!!! depth does not support time yet
else
    measPara.aniso(3) = measPara.LCall(1);
    measPara.oversampling{1,3} = 1:measPara.LCall(1);
%     measPara.imageDepth = measPara.LCall(1);     %% ATTENTION !!!!!!!!!!! depth does not support time yet
end

end


function createSureFitRawData(volPixSize)
% createSureFitRawData([volPixSize])
%
% volPixSize is in mm/pixel (defaults to [240/256 240/256 1.2])
%
% Converts Ifile data into the row-major ordered (8-bit uchar) data
% format requried by SureFit. This script is essentiall the createVAnatomy script
% with the output format modified slightly (in saveSureFitAnat()  -- which was
% saveVAnat())
%
% 00.01.20 RFD
%

if ~exist('volPixSize','var')
   volPixSize = [240/256 240/256 1.2];
   disp(['volPixSize defaulting to [ ' num2str(volPixSize,'%.4f ') ...
         	'].  I hope this is correct!']);
end

volume_pix_size = 1./volPixSize;

[fname, path] = uigetfile('*.*', 'Select one of the I-files...');

% load ifiles
%
disp('Loading I-files...');
img = makeCubeIfiles([path 'I'], 256, [1:124]);

disp('Finding optimal clip values...');
figure(99);
hist(img(:),100);
lowerClip = 0;
upperClip = 500;
answer = inputdlg({'lower clip value: ','upper clip value: '}, ...
   'Set intensity clip values', 1, ...
   {num2str(lowerClip),num2str(upperClip)}, 'on');
if ~isempty(answer)
	lowerClip = str2num(answer{1});
	upperClip = str2num(answer{2});
end
disp(['intensity clip values are: ' num2str(lowerClip) ', ' num2str(upperClip)]);

% Scale image values to be 0-255
% (if intensityClip <= 1, my scaleImage routine will clip the highest 'intensityClip'
% proportion of values, or, if intensityClip > 1, it clips it to the image value
% specified by intensityClip.
%
% I haven't been fully satisfied by just automatically clipping off the top,
% say 2% of intensities (this is what mrInitRet currently does to the inplanes).
% So, lately I've been looking at the histogram and picking intensityClip
% by hand, then viewing the images to see how well it worked.
disp('Clipping intensities...');
img(img<lowerClip) = lowerClip;
img(img>upperClip) = upperClip;
img = img-lowerClip;

% crop the image cube
% (you can skip this if you want, and just do the crop in mrGray)
figure(1);image(squeeze(img2(round(end/2),:,:))./clip.*255);colormap(gray(256));axis image;
figure(2);image(squeeze(img2(:,round(end/2),:))./clip.*255);colormap(gray(256));axis image;
figure(3);image(squeeze(img2(:,:,round(end/2)))./clip.*255);colormap(gray(256));axis image;
img2 = img2(20:200,30:240,1:124);
figure(1);image(squeeze(img(round(end/2),:,:))./clip.*255);colormap(gray(256));axis image;
figure(2);image(squeeze(img(:,round(end/2),:))./clip.*255);colormap(gray(256));axis image;
figure(3);image(squeeze(img(:,:,round(end/2)))./clip.*255);colormap(gray(256));axis image;

disp('Scaling to 0-255...');
img = round(img./upperClip*255);
disp('Original orientation:');
figure(99);
subplot(2,2,1);
image(squeeze(img(round(end/2),:,:)));colormap(gray(256));axis image;axis off;
subplot(2,2,2);
image(squeeze(img(:,round(end/2),:)));colormap(gray(256));axis image;axis off;
subplot(2,2,4);
image(squeeze(img(:,:,round(end/2))));colormap(gray(256));axis image;axis off;

% Reslice the data so that all voxels are cubic.
% The image currently has a field of view (fov) of 240mm in 256 voxels on the x and y axes
% and a fov of 148.800mm in 124 voxels on the z axis.

reslicedImg = resliceVoxels(img, 240, 240, 148.800);

% Reorient the data into the orientation expected by SureFit
% Basically, the data needs to be rotated 90 degrees around the anterior-posterior axis of the brain
% The image data is no 159x256x256

disp('Reorienting data...');

rotImg= zeros(planes,rows,cols);
for index=1:rows
   rotImg(:,index,:) = rot90(squeeze(reslicedImg(:,index,:)),3);
end

disp(['Volume dimensions are now:' int2str(size(rotImg))]);

disp('The reoriented data:');
figure(100);
subplot(2,2,1);
image(squeeze(rotImg(round(end/2),:,:)));colormap(gray(256));axis image;axis off;
subplot(2,2,2);
image(squeeze(rotImg(:,round(end/2),:)));colormap(gray(256));axis image;axis off;
subplot(2,2,4);
image(squeeze(rotImg(:,:,round(end/2))));colormap(gray(256));axis image;axis off;

% Save SureFitAnatomy
%
disp('Saving data in SureFit raw Format...');
path = saveSureFitAnat(rotImg);
save([path 'UnfoldParams'], 'volume_pix_size', 'lowerClip', 'upperClip');
disp(['SureFit raw data format saved to ' path]);
disp(['You should now run "python SUREFit/bin/Raw2Minc "' path size(rotImg)]);

return;

function path = saveSureFitAnat(imgCube, fileName)
% path = saveSureFitAnat(imgCube, [fileName])
% imgCube is a [rows x cols x planes] image array
% It must already be scaled to 0-255!
%
% fileName specifies the output file location (full path!)
% If omitted, then a save-file dialog box appears.
%
% The path to where the anatomy ends up is returned, in
% case you care.
%
%
% See Also: writeVolume, which does the same thing, but takes
% the input data in a different format.
%
% RFD

if ~exist('fileName', 'var')
   fileName = '';
end

% open file for writing (little-endian mode)
if isempty(fileName)
	[fname, path] = uiputfile('sureFitRawData.dat', 'Save SureFit raw data file...');
   fileName = [path fname];
else
   path = fileName;
end

vFile = fopen(fileName,'w','l');
if vFile<1
   while vFile<1;
   disp('Couldn''t open that file- please try saving it somewhere else.');
	[fname, path] = uiputfile('sureFitRawData.dat', 'Save SureFit raw data file...');
   fileName = [path fname];
   vFile = fopen(fileName,'w','l');
	end
end

% SureFit's Raw2Minc doesn't want any header, so nothing is written before the image data.

% Write data
count = fwrite(vFile, imgCube, 'uchar');
fclose(vFile);

return;


function [anal] = er_chopTSeriesMulti3D(view,coords,scans,varargin);
% [anal] = er_chopTSeriesMulti3D(view,[roi],[scans],[options]);
%
% Chop an event-related tSeries according to specified parfiles,
% separately for each voxel in an ROI.
%
% Returns two output structs. results is a struct with
% certain summary statistics across voxels, such as the mean
% amplitudes for each condition and voxel, sems, etc. anal
% is a struct array containing one entry for each voxel. Each
% entry contains fields from er_chopTSeries (type
% help on that function for a list).
%
% Note: this does a minimal analysis only on each voxel, for
% speed purposes, unless the 'fullanal' option is passed in.
% In this case, calculations of SNR, fMRI relative amplitudes,
% and t-tests for significant activation are performed for
% each voxel, which would not otherwise be performed.
% Be warned, however, that the analysis could take twice to four
% times as long.
%
% 08/04 ras.
global dataTYPES;

if ieNotDefined('coords')
    rois = viewGet(view,'rois');
    selRoi = viewGet(view,'selectedroi');
    coords = rois(selRoi).coords;
end

dt = viewGet(view,'curdt');

if ieNotDefined('scans')
    [scans dt] = er_getScanGroup(view);
    view = viewSet(view,'curdt',dt);
end

%%%%% params/defaults %%%%%
barebones = 0;          % if 0, do full analysis; if 1, do minimal analysis
normBsl = 1;            % flag to zero baseline or not
alpha = 0.05;           % threshold for significant activations
bslPeriod = -6:0;       % period to use as baseline in t-tests, in seconds
peakPeriod = 6:12;       % period to look for peaks in t-tests, in seconds
timeWindow = -6:22;     % seconds relative to trial onset to take for each trial
onsetDelta = 0;         % # secs to shift onsets in parfiles, relative to time course
snrConds = [];          % For calculating SNR, which conditions to use (if empty, use all)
waitbarFlag = 0;        % flag to show a graphical mrvWaitbar to show load progress

%%%%% get the parfile info
trials = er_concatParfiles(view,scans);
condNums = unique(trials.cond(trials.cond > 0));
whichconds=condNums;

%%%%% parse the options %%%%%
varargin = unNestCell(varargin);
for i = 1:length(varargin)
    if ischar(varargin{i})
        switch lower(varargin{i})
        case 'barebones', barebones = 1;
        case 'normbsl', normBsl = varargin{i+1};
        case 'alpha', alpha = varargin{i+1};
        case 'peakperiod', peakPeriod = varargin{i+1};
        case 'bslperiod', bslPeriod = varargin{i+1};
        case 'timewindow', timeWindow = varargin{i+1};
        case 'onsetdelta', onsetDelta = varargin{i+1};
        case 'snrconds', snrConds = varargin{i+1};
        case 'whichconds', whichconds = varargin{i+1};
        case 'mrvWaitbar', waitbarFlag = 1;
        otherwise, % ignore
        end
    end
end

%%%%% check if the full analysis option is set
chk = 0;
for i = 1:length(varargin)
    if isequal(lower(varargin{i}),'fullanal')
        chk = 1;
        break;
    end
end
if chk==0
    varargin{end+1} = 'barebones';
end

%%%%% get the tSeries for each voxel / concat across scans
dt = viewGet(view,'curdt');
textstring=sprintf('Loading tSeries from %s datatype scans %d-%d...',dataTYPES(dt).name,min(scans),max(scans));
h = mrvWaitbar(0,textstring);

tSeries = [];
for s = 1:length(scans)
     raw = ~(detrendFlag(view,s));
    subt = getTseriesOneROI(view,coords,scans(s),raw);
    tSeries = [tSeries; subt{1}];
    mrvWaitbar(s/length(scans),h);
end

close(h)

%%%%% run the standard choptSeries analysis on each voxel

nVoxels = size(tSeries,2);
fprintf(1,'num voxels in view %s is %5d \n',view.viewType,nVoxels);

% jl101104 peak peropd 4:12 onset delta 0
% jv062004 onset delta=-4 peakPeriod 6:16
% ras062304 onset delta=0 peakPeriod 6:14-
% kgs080304  peak period 4:14 delta=0
% kgs061504 peak period 4:14 delta  onset=0
% skipped 3 frames adjusted par files;  use mc data
% ras 041702 6:14 offset -6 blocks of 16s
% js061504  4:12 onset 0 very noisy scan did not cover FFA

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% add menus (3): Settings
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
defaults{1} = num2str(timeWindow);
defaults{2} = num2str(bslPeriod);
defaults{3} = num2str(peakPeriod);
defaults{4} = num2str(alpha);
defaults{5} = num2str(onsetDelta);
defaults{6} = num2str(whichconds);
defaults{7} = num2str(normBsl);
defaults{8}='y';
defaults{9}='y';
defaults{10}='n';

prompt{1} = 'Time Window, in seconds (incl. pre-stimulus onset period):';
prompt{2} = 'Baseline Period, in seconds:';
prompt{3} = 'Peak Period, in seconds:';
prompt{4} = 'Alpha for significant activation (peak vs baseline):';
prompt{5} = 'Shift onsets relative to time course, in seconds:';
prompt{6} = 'Which conditions to calculate reliability?';
prompt{7} = 'Normalize all trials during the baseline period? (0 for no, 1 for yes)';
prompt{8}=  'Plot matrix of all voxels amps [y/n]?';
prompt{9}=  'Conduct reliability analysis [y/n]?';
prompt{10}= 'Load tcUI for ROI data [y/n]?';
AddOpts.Resize = 'on';
AddOpts.Interpreter = 'tex';
AddOpts.WindowStyle = 'Normal';
answers = inputdlg(prompt,'Chop tSeries-Multi Settings...',1,defaults,AddOpts);

% exit if cancel is selected
if isempty(answers)
    return;
end

% parse the user responses / defaults
timeWindow = str2num(answers{1});
bslPeriod = str2num(answers{2});
peakPeriod = str2num(answers{3});
alpha = str2num(answers{4});
onsetDelta = str2num(answers{5});
whichconds = str2num(answers{6});
normBsl = str2num(answers{7});

if answers{8}=='y' | answers{8}=='Y'
    plotampsmat=1;
else
    plotampsmat=0;
end

if answers{9}=='y' | answers{9}=='Y'
    reliability=1;
else
    reliability=0;
end
if answers{10}=='y' | answers{10}=='Y'
    tcUI=1;
else
    tcUI=0;
end
roiName=view.ROIs(selRoi).name;

h = mrvWaitbar(0,'Chopping tSeries...');
anal = er_chopTSeries3D(tSeries,trials,roiName,...
              'peakPeriod',peakPeriod,...
              'bslPeriod',bslPeriod,...
              'timeWindow',timeWindow,...
              'alpha',alpha,...
              'onsetDelta',onsetDelta,...
              'whichconds',whichconds,...
              'normBsl',normBsl,...
              'plotampsmat',plotampsmat);
close(h)
% save data
newdir=view.viewType;
cd (newdir)
dataTypedir=getDataTypeName(view);
cd (dataTypedir)

if ~exist('ROI4D')
        mkdir 'ROI4D'
end
cd ..    % newdir
cd ..    % data dir

anal.roiName=view.ROIs(selRoi).name;
whichconds
if reliability
    [rc,pc,rcov, pcov, odd, even]=pattern_analysis(anal.allamps(:,whichconds,:),anal.allampsminusDC(:,whichconds,:),anal.labels(whichconds),anal.roiName);
    anal.pc=pc;
    anal.rc=rc;
    anal.rcov=rcov;
    anal.pcov=pcov;
end

% too long but makes it platform insensitive
cd (newdir)
cd (dataTypedir)
cd ('ROI4D')
filename=view.ROIs(selRoi).name;
eval (['save ' filename ' anal']);
fprintf(1, 'saved anal to %s/%s/ROI4D/%s.mat \n ', newdir,dataTypedir,filename);
cd ..
cd ..
cd ..
if tcUI
    fprintf(1, 'Loading mean ROI timecourse UI..........')
    tc = timeCourseUI(view,view.ROIs(selRoi).name,scans,dt);
end
return


report_this_filefun(mfilename('fullpath'));

% TODO delete this, probably. -CGR
% Now lets plot the color-map of the z-value
%
figure

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

rect = [0.18,  0.10, 0.7, 0.75];
rect1 = rect;

% set values greater tresh = nan
%
re4 = ret;l = r > tresh; re4(l) = zeros(1,length(find(l)))*nan;

% plot image
%
orient portrait
set(gcf,'PaperPosition', [2. 1 7.0 5.0])

l = isnan(re4);

axes('position',rect);hold on

pco1 = pcolor(gx,gy,(re4))
caxis([ 25 150]);
shading interp
axis([ min(gx) max(gx) min(gy) max(gy)]);
axis image;
hold on
h = cool(64);h = [  h]; colormap(h)

set(gca,'Color',[0.9 0.9 0.9])
set(gca,'YTickLabels',[  10 8  6 4  2])

%xlabel('Distance in [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)
%ylabel('depth in [km]','FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)

if exist('maex', 'var')
    pl = plot(maex,-maey,'*y');
    set(pl,'MarkerSize',6,'LineWidth',2)
end
overlay

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

% Create a colobar
%
% h5 = colorbar('horiz');
%set(h5,'Pos',[0.25 0.05 0.5 0.05],...
%'FontWeight','bold','FontSize',ZmapGlobal.Data.fontsz.m)

% Make the figure visible
%
set(gca,'visible','on','FontSize',10,'FontWeight','bold',...
    'FontWeight','normal','LineWidth',1.0,...
    'Box','on','TickDir','out')

axes(h1)


%% t_installSegmentation
%
% Illustrates how to align the inplane volume from an fMRI session to the
% 3D volume anatomy using sample data set <erniePRF>
%
% Dependencies:
%   Remote Data Toolbox
%
% This tutorial is part of a sequence. Run
%   t_initAnatomyFromFreesurfer
%   t_initVistaSession
%   t_alignInplaneToVolume
% prior to running this tutorial.
%
% Summary
%
% - Specify alignment matrix linking inplane anatomy to volume anatomy
% - Save mrSESSION with alignment matrix
%
% Tested 07/21/2016 - MATLAB r2015a, Mac OS 10.11.6
%
%  See also: t_initAnatomyFromFreesurfer t_initVistaSession t_alignInplaneToVolume
%
% Winawer lab (NYU)

%% Start
% Clean start in case we have a vista session open
mrvCleanWorkspace();

% Remember where we are
curdir = pwd();

%% Organize functional data

% Find ernie PRF session in scratch directory
erniePathTemp      = fullfile(vistaRootPath, 'local', 'scratch', 'erniePRF');

if ~exist(erniePathTemp, 'dir')
    help(mfilename)
    error('Please run  pre-requisite tutorials')
end

% Navigate and create a directory
cd(erniePathTemp)

%% Align inplane to t1 and install Gray/white segmentation

% Open a hidden view
vw = initHiddenInplane();

% Segmentation inputs
%   use command line, not dialog
query = false;

%   keep all gray nodes, including those outside functional FOV
keepAllNodes = true;

%   path to class file
filePaths = fullfile('3DAnatomy', 't1_class.nii.gz');

%   number of layers in gray graph along surface (3 layers for 1 mm voxels)
numGrayLayers = 3;

% Do it
installSegmentation(query, keepAllNodes, filePaths, numGrayLayers);

%% Visualize

% open a UI
vw = mrVista;

% Define an ROI that is the entire functional slab
vw = makeGrayROI(vw);
vw = refreshScreen(vw,0);

% add the local variable, vw, to the UI in case you would like to interact
% with the GUI
updateGlobal(vw)

%% Clean up
close(viewGet(vw, 'figure number'));
mrvCleanWorkspace
cd(curdir)


function [OMNISol,bilevelMILPProblem] = OMNI(model, selectedRxnList, options, constrOpt, measOpt, prevSolutions, verbFlag)
%
%% ***********************NOT WORKING**************************************
%

%function [OMNISol,bilevelMILPProblem] = OMNI(model,selectedRxnList,options,constrOpt,prevSolutions,verbFlag,solutionFileNameTmp)

%OMNI Run OMNI in the most general form
%
% OMNI(model,selectedRxnList,options,constrOpt,prevSolutions,verbFlag,solutionFileName)
%
%INPUTS
% model                 Structure containing all necessary variables to
%                       describe a stoichiometric model
%   rxns                  Rxns in the model
%   mets                  Metabolites in the model
%   S                     Stoichiometric matrix (sparse)
%   b                     RHS of Sv = b (usually zeros)
%   c                     Objective coefficients
%   lb                    Lower bounds for fluxes
%   ub                    Upper bounds for fluxes
%   rev                    Reversibility of fluxes
% selectedRxnList       List of reactions that can be knocked-out in OMNI
% options               OMNI options
%   numDel                # of bottlenecks
%   numDelSense           Direction of # of bottleneck constraint (G/E/L)
%   vMax                  Max flux
%   solveOMNI             Solve problem within Matlab
%   createGams            Create GAMS input file
%   gamsFile              GAMS input file name
% constrOpt             Explicitly constrained reaction options
%   rxnList               Reaction list
%   values                Values for constrained reactions
%   sense                 Constraint senses for constrained reactions
%                         (G/E/L)
% measOpt               Measured flux options
%   rxnSel                Names of measured reactions
%   values                Flux values of measured reactions
%   weights               Weights for measured fluxes
%
%OPTIONAL INPUTS
% prevSolutions         Previous solutions
% verbFlag              Verbose flag
% solutionFileName      File name for storing temporary solutions
%
%OUTPUTS
% OMNISol               OMNI solution structure
% bilevelMILPProblem    bi-level MILP problem structure used
%
% Markus Herrgard 3/28/05

% Set these for MILP callbacks
global MILPproblemType;
global selectedRxnIndIrrev;
%global rxnList;
global irrev2rev;
%global solutionFileName;
%global biomassRxnID;
%global OMNIKOrxnList;
%global OMNIObjective;
%global OMNIGrowth;
%global solID;

if (nargin < 5)
    prevSolutions = [];
end
if (nargin < 6)
    verbFlag = false;
end
% if (nargin < 7)
%     solutionFileName = 'OMNISolutions.mat';
% else
%     solutionFileName = solutionFileNameTmp;
% end

% Convert to irreversible rxns
[modelIrrev,matchRev,rev2irrev,irrev2rev] = convertToIrreversible(model);

% Create the index of the previous KO's suggested by OMNI to avoid obtaining the same
% solution again
selPrevSolIrrev = [];
for i = 1:size(prevSolutions,2)
    prevSolRxnList = model.rxns(prevSolutions(:,i)==1);
    selPrevSol = ismember(model.rxns,prevSolRxnList);
    selPrevSolIrrev(:,i) = selPrevSol(irrev2rev);
end

[nMets,nRxns] = size(modelIrrev.S);

% Create matchings for reversible reactions in the set selected for KOs
% This is to ensure that both directions of the reaction are knocked out
selSelectedRxn = ismember(model.rxns,selectedRxnList);
selSelectedRxnIrrev = selSelectedRxn(irrev2rev);
selectedRxnIndIrrev = find(selSelectedRxnIrrev);
cnt = 0;
%prevRxnID = -10;
nSelected = length(selectedRxnIndIrrev);
selRxnCnt = 1;
while selRxnCnt <= nSelected
    rxnID = selectedRxnIndIrrev(selRxnCnt);
    if (matchRev(rxnID)>0)
        cnt = cnt + 1;
        selectedRxnMatch(cnt,1) = selRxnCnt;
        selectedRxnMatch(cnt,2) = selRxnCnt+1;
        selRxnCnt = selRxnCnt + 1;
    end
    selRxnCnt = selRxnCnt + 1;
end

% Set inner constraints for the LP
constrOptIrrev = setConstraintsIrrevModel(constrOpt,model,modelIrrev,rev2irrev);
% constrOptIrrev = model;
% constrOptIrrev = [];

% Set objectives for linear and integer parts
cLinear = zeros(nRxns,1);
cInteger = zeros(sum(selSelectedRxnIrrev),1);

% Set the correct objective coefficient (not necessary for OMNI)
% targetRxnID = find(ismember(model.rxns,options.targetRxn));
% targetRxnIDirrev = rev2irrev{targetRxnID}(1);
% cLinear(targetRxnIDirrev) = 1;

% Set measured reaction in objective
sel_meas_rxn = measOpt.rxnSel';
b_meas_rxn = measOpt.values';
wt_meas_rxn = measOpt.weights';
n_m = length(sel_meas_rxn);

% Create selection vector in the decoupled representation
% This is to ensure that the objective function for measured reversible
% reactions is constructed correctly
sel_m = zeros(nRxns,1);
ord_ir = [];
b_meas_tmp = [];
wt_meas_tmp = [];
for i = 1:n_m
    rxn_name = sel_meas_rxn{i};
    rxn_id = find(strcmp(model.rxns,rxn_name));
    if (~isempty(rxn_id)) % Protect against measured fluxes that are not part of the model
        b_meas_tmp = [b_meas_tmp;b_meas_rxn(i)];
        wt_meas_tmp = [wt_meas_tmp;wt_meas_rxn(i)];
        % Reversible rxns
        if (model.rev(rxn_id))
            rxn_id_ir = rev2irrev{rxn_id}(1);
            sel_m(rxn_id_ir) = 1;
            sel_m(rxn_id_ir+1) = -1;
        else
            % Irrev rxns
            rxn_id_ir = rev2irrev{rxn_id};
            sel_m(rxn_id_ir) = 1;
        end
        % Figure out ordering in decoupled representation
        ord_ir = [ord_ir rxn_id_ir];
    end
end
% Get ordering indices
[tmp,ord_ind] = sort(ord_ir);
% Reorder or create weights
if (sum(wt_meas_rxn) == 0)
    measOpts.weights = ones(n_m,1);
else
    measOpts.weights = wt_meas_tmp(ord_ind);
end
% Reorder measured flux values
measOpts.values = b_meas_tmp(ord_ind);

measOpts.rxnSel = sel_m;

% Create the constraint matrices for the bilevel MILP
bilevelMILPProblem = createBilevelMILPproblem(modelIrrev,cLinear,cInteger,selSelectedRxnIrrev,...
    selectedRxnMatch,constrOptIrrev,measOpts,options,selPrevSolIrrev);

% Initial guess (random)
%bilevelMILPProblem.x0 = round(rand(length(bilevelMILPProblem.c),1));
if isfield(options,'initSolution')
    if (length(options.initSolution) > options.numDel | ~all(ismember(options.initSolution,selectedRxnList)))
        warning('Initial solution not valid - starting from a random initial solution')
        bilevelMILPProblem.x0 = [];
    else
        % Set initial integer solution
        selInitRxn = ismember(model.rxns,options.initSolution);
        selInitRxnIrrev = selInitRxn(irrev2rev);
        initRxnIndIrrev = find(selInitRxnIrrev);
        initIntegerSol = ~ismember(selectedRxnIndIrrev,initRxnIndIrrev);
        selInteger = bilevelMILPProblem.vartype == 'B';
        [nConstr,nVar] = size(bilevelMILPProblem.A);
        bilevelMILPProblem.x0 = nan(nVar,1);
        bilevelMILPProblem.x0(selInteger) = initIntegerSol;

%         LPproblem.b = bilevelMILPProblem.b - bilevelMILPProblem.A(:,selInteger)*initIntegerSol;
%         LPproblem.A = bilevelMILPProblem.A(:,bilevelMILPProblem.vartype == 'C');
%         LPproblem.c = bilevelMILPProblem.c(bilevelMILPProblem.vartype == 'C');
%         LPproblem.lb = bilevelMILPProblem.lb(bilevelMILPProblem.vartype == 'C');
%         LPproblem.ub = bilevelMILPProblem.ub(bilevelMILPProblem.vartype == 'C');
%         LPproblem.osense = -1;
%         LPproblem.csense = bilevelMILPProblem.csense;
%         LPsol = solveCobraLP(LPproblem);
%
%         bilevelMILPProblem.x0(~selInteger) = LPsol.full;
    end
else
    bilevelMILPProblem.x0 = [];
end

% Minimize
bilevelMILPProblem.osense = 1;

if (verbFlag)
    [nConstr,nVar] = size(bilevelMILPProblem.A);
    nInt = length(bilevelMILPProblem.intSolInd);
    fprintf('MILP problem with %d constraints %d integer variables and %d continuous variables\n',...
        nConstr,nInt,nVar);
end

bilevelMILPProblem.model = modelIrrev;

% Set these for CPLEX callbacks
MILPproblemType = 'OMNI';
% rxnList = model.rxns;
% biomassRxnID = find(modelIrrev.c==1);
% solID = 0;
% OMNIObjective = [];
% OMNIGrowth = [];
% OMNIKOrxnList = {};

% Solve problem
if (options.solveOMNI)
    OMNISol = solveCobraMILP(bilevelMILPProblem,'printLevel',0);
    if OMNISol.stat~=0
        if (~isempty(OMNISol.cont))
            OMNISol.fluxes = convertIrrevFluxDistribution(OMNISol.cont(1:length(matchRev)),matchRev);
        end
        if (~isempty(OMNISol.int))
            % Figure out the KO reactions
            OMNIRxnInd = selectedRxnIndIrrev(OMNISol.int < 1e-4);
            OMNISol.kos = model.rxns(unique(irrev2rev(OMNIRxnInd)));

%             %sanity check
%             modelTemp = changeRxnBounds(model,OMNISol.kos,0,'b');
%             solTemp = optimizeCbModel(modelTemp);
%             if abs(solTemp.f - OMNISol.obj) > 1e-4
%                 [OMNISol,bilevelMILPProblem] = OMNI(model, selectedRxnList, options, constrOpt, measOpt, prevSolutions, verbFlag);
%                 previous_solutions(:,end+1) = zeros(length(model.rxns),1);
%             end
        end
    else
        OMNISol.fluxes=[];
        OMNISol.kos={};
    end
else
    OMNISol.rxnList = {};
    OMNISol.fluxes = [];
end


function XY = rl_reward_firepit( type )
%RL_REWARD_FIREPITE
%
%   intput-----------------------------------------------------------------
%
%           o type : string, type of fire pit.
%
%   output-----------------------------------------------------------------
%
%           o XY   : (N x 2)
%
%

XY = [];

if strcmp(type,'central_pit')

    [X,Y] = meshgrid(linspace(3,7,20),linspace(3,7,20));
    XY    = [X(:),Y(:)];

else

end

end


classdef ParamMPCGCBF < handle
    properties
        horizon
        gamma
        P % weight for terminal cost (CLF)
        xWeight
        uWeight
    end
    methods
        function self = ParamMPCGCBF(horizon, gamma, P, x_weight, u_weight)
            self.horizon = horizon;
            self.gamma = gamma;
            self.P = P;
            self.xWeight = x_weight;
            self.uWeight = u_weight;
        end
    end
end


% EEG_TOPOPLOT - plot scalp map
%
% eeg_topoplot( vals, chanlocs, 'key', 'val');
%
% Input:
%   vals     - values, one per channel
%   chanlocs - channel structure, same size as vals
%
% Optional inputs:
%   'colormap'   - colormap. Possible colormaps are 'blueredyellow', ...
%                'yellowredblue', 'bluered' or any Matlab colormap ('cool',
%                'jet', 'hsv', ...). It can also be a text file 'xxx.txt'.
%                The text file must contain 3 columns and idealy 64 rows
%                defining the colors in RGB format.
%   'maplimits'  - can be [min max]. This help defines the color scale for
%                maps.
%   'electrodes' - can be 'on' to show electrode dots, 'off', or
%               'labels' to show electrode labels. Default is 'on'
%   'dotsize'    - size of electrode dots. Default is 5.
%   'shading'    - 'flat','interp'  {default: 'interp'}
%   'exclude'    - labels or indices of electrodes not to be plotted. From the
%                compiled files, these must be entered using underscores
%                for separators (e.g., "cz_pz").
%   'sphspline'  - can be 'on' or 'off'. If 'on' spherical splines are used
%                for interpolation of the scalp map. If 'off' standard
%                planar inverse distance interpolation is used.
%   'shrink'     - shrink electrode positions (default is 0.75 to be able to
%                plot electrode at the head limit if spherical interpolation
%                is set and 0.95 for planar 2-D interpolation).
%
% References for spline interpolation:
%   [1] Perrin, F., Pernier, J., Bertrand, O., & Echallier, J. F.
%       (1989). Spherical splines for scalp potential and current
%       density mapping. Electroencephalography and Clinical
%       Neurophysiology, 72, 184-187
%   [2] Ferree, T. C. (2000). Spline Interpolation of the Scalp EEG.
%       Retrieved March 26, 2006, from
%       www.egi.com/Technotes/SplineInterpolation.pdf
%
% limitation: does not plot anything below the upper part of the head

% Copyright (C) Arnaud Delorme, SCCN, INC, 2010
%
% 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 eeg_topoplot(values, chanlocs, varargin);

g = [];
for index = 1:2:length(varargin)
    g = setfield(g, varargin{index}, varargin{index+1});
end
if ~isfield(g, 'electrodes'), g.electrodes = 'on'; end
if ~isfield(g, 'colormap'),   g.colormap   = jet;  end
if ~isfield(g, 'maplimits'),  g.maplimits  = [];   end
if ~isfield(g, 'headrad'),    g.headrad    = [];   end
if ~isfield(g, 'sphspline'),  g.sphspline  = 'on'; end
if ~isfield(g, 'shading'),    g.shading    = 'interp'; end
if ~isfield(g, 'contour'),    g.contour    = 'on'; end
if ~isfield(g, 'dotsize'),    g.dotsize    = 5;    end
if ~isfield(g, 'mark'),       g.mark       = [];   end
if ~isfield(g, 'exclude'),    g.exclude    = [];   end
if ~isfield(g, 'linewidth'),  g.linewidth  = 2;    end
if ~isfield(g, 'shrink'),     g.shrink     = 1;    end
if ischar(g.dotsize), g.dotsize = str2num(g.dotsize); end
if any(values == 0)
    inds = find(values == 0);
    if ~isempty( [ chanlocs(inds).theta ])
        g.contour = 'off';
        g.sphspline = 'off';
    end
end

% exclude electrodes
% ------------------
if ~isempty(g.exclude)
    chanlocs(g.exclude) = [];
    values(g.exclude)   = [];
end

% find channel coordinates
% ------------------------
emptyvals = cellfun('isempty', { chanlocs.theta });
th = [ chanlocs.theta ];
rd = [ chanlocs.radius ];
[y x] = pol2cart(th/180*pi, rd); x=-x;
x = x*g.shrink;
y = y*g.shrink;
newvalues            = values;
newvalues(emptyvals) = [];
labls = { chanlocs.labels };
labls(emptyvals) = [];

if strcmpi(g.sphspline, 'on')
    % default head radius
    % -------------------
    g.headrad = 0.5;

    % spherical plotting
    % ------------------
    xelec = [ chanlocs.X ];
	yelec = [ chanlocs.Y ];
	zelec = [ chanlocs.Z ];

    dist = sqrt(xelec.^2+yelec.^2+zelec.^2);
	xelec = xelec./dist;
	yelec = yelec./dist;
	zelec = zelec./dist;

    if g.shrink ~= 1
        [th phi rad] = cart2sph(xelec, yelec, zelec);
        phi = (phi-pi/2)*g.shrink+pi/2;
        [xelec, yelec, zelec] = sph2cart(th, phi, rad);
    end;

	[xsph, ysph, zsph, valsph] = spheric_spline(xelec,yelec,zelec,newvalues);
    surf(-ysph/2,xsph/2,zsph/2,double(valsph), 'edgecolor', 'none'); view([0 0 1]);hold on;
    shading(g.shading);
    top = max(abs(valsph(:)))*1000;

    if strcmpi(g.contour, 'on')
    	[c h] = contour3(-ysph/2, xsph/2, valsph+top/10, 5); view([0 0 1]);
        set(h, 'cdata', [], 'edgecolor', 'k')
    end

	% coordinates for electrodes
	% --------------------------
    xelec(find(zelec < 0)) = [];
    yelec(find(zelec < 0)) = [];
    x = yelec/2;
    y = xelec/2;

else
    % default head radius
    % -------------------
    if isempty(g.headrad);
        g.headrad = max(sqrt(x.^2+y.^2));
    end

    % data points for 2-D data plot
    % -----------------------------
    pnts = linspace(0,2*pi,200/0.25*(g.headrad.^2));
    xx = sin(pnts)*g.headrad;
    yy = cos(pnts)*g.headrad;

	% make grid and add circle
	% ------------------------
    gridres = 30;
	coords = linspace(-g.headrad, g.headrad, gridres);
	ay = repmat(coords,  [gridres 1]);
	ax = repmat(coords', [1 gridres]);
	for ind=1:length(xx)
        [tmp closex] = min(abs(xx(ind)-coords));
        [tmp closey] = min(abs(yy(ind)-coords));
        ax(closex,closey) = xx(ind);
        ay(closex,closey) = yy(ind);
	end
	xx2 = sin(pnts)*(g.headrad-0.01);
	yy2 = cos(pnts)*(g.headrad-0.01);
	for ind=1:length(xx)
        [tmp closex] = min(abs(xx2(ind)-coords));
        [tmp closey] = min(abs(yy2(ind)-coords));
        ax(closex,closey) = xx(ind);
        ay(closex,closey) = yy(ind);
	end

	% linear interpolation and removal of values outside circle
	% ---------------------------------------------------------
    a = griddata(x, y, newvalues, -ay, ax, 'v4');
	aradius = sqrt(ax.^2 + ay.^2);
	indoutcircle = find(aradius(:) > g.headrad+0.01);
	a(indoutcircle) = NaN;
	surf(ay, ax, a, 'edgecolor', 'none'); view([0 0 1]); hold on;
    shading(g.shading);
    top = max(values)*1.5;

	% plot level lines
	% ----------------
    if strcmpi(g.contour, 'on')
        [c h] = contour3(ay, ax, a, 5);
        set(h, 'cdata', [], 'edgecolor', 'k')
    end
end

% plot electrodes as dots
% -----------------------
if strcmpi(g.electrodes, 'on') || strcmpi(g.electrodes, 'labels')
    rad = sqrt(x.^2 + y.^2);
    x(find(rad > g.headrad)) = [];
    y(find(rad > g.headrad)) = [];
    plot3( -x, y, ones(size(x))*top, 'k.', 'markersize', g.dotsize);
    for i = g.mark,      plot3( -x(i), y(i), double(top), 'y.', 'markersize', 4*g.dotsize); plot3( -x(i), y(i), double(top), 'r.', 'markersize', 2*g.dotsize); end
    if strcmpi(g.electrodes, 'labels')
        for index = 1:length(x)
            text( -x(index)+0.02, y(index), double(top), labls{index});
        end
    end
else
    % invisible electrode that avoid plotting problem (no surface, only
    % contours)
    plot3( -x, y, -ones(size(x))*top, 'k.', 'markersize', 0.001);
end

% plot dipoles if any
% -------------------
if ~isempty(g.dipole)
    hold on;
    for index = 1:size(g.dipole,1)
        g.dipole(index,:)   = g.dipole(index,:)*0.5;
        g.dipole(index,3:5) = g.dipole(index,3:5)/norm(g.dipole(index,3:end))*0.2;
        if ~any(g.dipole(index,:))
            fprintf('Note: dipole contains 0 - not plotted\n')
        elseif sum(g.dipole(index,3:4).^2) <= 0.00001
            fprintf('Note: dipole is length 0 - not plotted\n')
        elseif sum(g.dipole(index,1:2).^2) > g.headrad
            fprintf('Note: dipole is outside plotting area - not plotted\n')
        else
            hh = plot3( -g.dipole(index, 2), g.dipole(index, 1), top, '.');
            set(hh, 'color', 'k', 'markersize', 30);
            hh = line( -[g.dipole(index, 2) g.dipole(index, 2)+g.dipole(index, 4)]', ...
                [g.dipole(index, 1) g.dipole(index, 1)+g.dipole(index, 3)]',[top top]);
            set(hh, 'color', 'k', 'linewidth', 30/7);
        end
    end
end

% special colormaps
% -----------------
if ischar(g.colormap)
    if ~isempty(strmatch(g.colormap, { 'hsv' 'jet' 'gray' 'hot' 'cool' 'bone' ...
            'copper', 'pink' 'flag' 'prism' }, 'exact'))
    else % read text file
        g.colormap = load('-ascii', g.colormap);
    end
end;
colormap(g.colormap);

if ~isempty(g.maplimits)
    if ~ischar(g.maplimits) && ~isempty(g.maplimits) && ~isnan(g.maplimits(1))
        caxis(g.maplimits);
    end
end

% main circle
% -----------
radiuscircle = 0.5;
pnts   = linspace(0,2*pi,200);
xc     = sin(pnts)*radiuscircle;
yc     = cos(pnts)*radiuscircle;
sf     = 1; % scaling factor
plot3(xc*sf,yc*sf,ones(size(xc))*top, 'k', 'linewidth', g.linewidth); hold on;

% ears & nose
% -----------
rmax  = 0.5;
base  = rmax-.0046;
basex = 0.18*rmax;                   % nose width
tip   = 1.15*rmax;
tiphw = .04*rmax;                    % nose tip half width
tipr  = .01*rmax;                    % nose tip rounding
q = .04; % ear lengthening
EarX  = [.497-.005  .510  .518  .5299 .5419  .54    .547   .532   .510   .489-.005]; % rmax = 0.5
EarY  = [q+.0555 q+.0775 q+.0783 q+.0746 q+.0555 -.0055 -.0932 -.1313 -.1384 -.1199];

plot3(EarX*sf,EarY*sf,ones(size(EarX))*top,'color','k','LineWidth',g.linewidth)    % plot left ear
plot3(-EarX*sf,EarY*sf,ones(size(EarY))*top,'color','k','LineWidth',g.linewidth)   % plot right ear
plot3([basex;tiphw;0;-tiphw;-basex]*sf,[base;tip-tipr;tip;tip-tipr;base]*sf,top*ones(size([basex;tiphw;0;-tiphw;-basex])),'color','k','LineWidth',g.linewidth);

% axis limits
% -----------
axis off;
set(gca, 'ydir', 'normal');
axis equal
ylimtmp = max(g.headrad, 0.58);
ylim([-ylimtmp ylimtmp]);

% ----------------
% spherical spline
% ----------------
function [x, y, z, Res] = spheric_spline( xelec, yelec, zelec, values);

SPHERERES = 40;
[x,y,z] = sphere(SPHERERES);
x(1:(length(x)-1)/2,:) = [];
y(1:(length(x)-1)/2,:) = [];
z(1:(length(x)-1)/2,:) = [];

Gelec = computeg(xelec,yelec,zelec,xelec,yelec,zelec);
Gsph  = computeg(x,y,z,xelec,yelec,zelec);

% equations are
% Gelec*C + C0  = Potential (C unknown)
% Sum(c_i) = 0
% so
%             [c_1]
%      *      [c_2]
%             [c_ ]
%    xelec    [c_n]
% [x x x x x]         [potential_1]
% [x x x x x]         [potential_ ]
% [x x x x x]       = [potential_ ]
% [x x x x x]         [potential_4]
% [1 1 1 1 1]         [0]

% compute solution for parameters C
% ---------------------------------
meanvalues = mean(values);
values = values - meanvalues; % make mean zero
C = pinv([Gelec;ones(1,length(Gelec))]) * [values(:);0];

% apply results
% -------------
Res = zeros(1,size(Gsph,1));
for j = 1:size(Gsph,1)
    Res(j) = sum(C .* Gsph(j,:)');
end
Res = Res + meanvalues;
Res = reshape(Res, size(x));

% compute G function
% ------------------
function g = computeg(x,y,z,xelec,yelec,zelec)

unitmat = ones(length(x(:)),length(xelec));
EI = unitmat - ((repmat(x(:),1,length(xelec)) - repmat(xelec,length(x(:)),1)).^2 +...
                (repmat(y(:),1,length(xelec)) - repmat(yelec,length(x(:)),1)).^2 +...
                (repmat(z(:),1,length(xelec)) - repmat(zelec,length(x(:)),1)).^2)/2;

g = zeros(length(x(:)),length(xelec));
m = 4; % 3 is linear, 4 is best according to Perrin's curve
for n = 1:7
    L = legendre(n,EI);
    g = g + ((2*n+1)/(n^m*(n+1)^m))*squeeze(L(1,:,:));
end
g = g/(4*pi);

% find electrode indices
% ----------------------
function allinds = elecind( str, chanlocs, values );

    findmax = 0;
    findmin = 0;
    if ~iscell(str)
         if strmatch(str, 'max', 'exact'), findmax = 1; end
         if strmatch(str, 'min', 'exact'), findmin = 1; end;
         indunderscore = [ 0 find( str == '_' ) length(str)+1 ];
    else indunderscore = [1:length(str)+1];
    end

    % find maximum or minimum
    % -----------------------
    if findmax, [tmp allinds] = max(values); return; end
    if findmin, [tmp allinds] = min(values); return; end

    % find indices for labels
    % -----------------------
    labels = lower({ chanlocs.labels });
    for i = 1:length(indunderscore)-1
        if ~iscell(str)
             tmpstr = str(indunderscore(i)+1:indunderscore(i+1)-1);
        else tmpstr = str{i};
        end
        tmpind = strmatch(lower(tmpstr), labels, 'exact');
        if isempty(tmpind)
            if str2num(tmpstr) > 0
                tmpind = str2num(tmpstr);
            else
                error(sprintf('Could not find channel "%s"', tmpstr));
            end
        end
        allinds(i) = tmpind;
    end


function proposals = gen_proposals(img, map, resizeRatio, minmaxRF)
    global param
    global globalVar

    %% bw prob map
    f = fspecial('gaussian',[5 5],7);
    map = imfilter(map,f,'same');

    bwmap = map > param.minRegionProb;

    SE1=strel('disk',3);
    bwmap = imerode(bwmap,SE1);
    bwmap = imdilate(bwmap,SE1);
    bwmap = bwmap>0;
    bwmap = imfill(bwmap,'holes');

    %% process each region
    [L, L_num] = bwlabel(bwmap, 8);
    proposals = cell(L_num, 1);
    estimated_orientations = zeros(L_num, 1);
    regions = cell(L_num, 1);
    regionPerims = cell(L_num, 1);
    totalTimeOfGetCompOfRegion = 0;
    totalTimeOfEstimateOrientation = 0;
    totalTimeOfGenProposalsByOrientation = 0;
    for i = 1 : L_num
        regionMap = L == i;

        %% construct regions
        [y, x] = find(regionMap);
        regions{i} = [y, x];

        %% Substruct sub img and sub region map by regions
        regionMinX= min(x);
        regionMaxX = max(x);
        regionMinY = min(y);
        regionMaxY = max(y);
        regionHeight = regionMaxY - regionMinY + 1;
        regionWidth = regionMaxX - regionMinX + 1;

        extendRegionMinX = max(1, regionMinX - regionWidth * 0.005);
        extendRegionMaxX = min(size(img, 2), regionMaxX + regionWidth * 0.005);
        extendRegionMinY = max(1, regionMinY - regionHeight * 0.005);
        extendRegionMaxY = min(size(img, 1), regionMaxY + regionHeight * 0.005);

        subImg = img(extendRegionMinY : extendRegionMaxY, extendRegionMinX : extendRegionMaxX, :);
        subRegionMap = regionMap(extendRegionMinY : extendRegionMaxY, extendRegionMinX : extendRegionMaxX);
        [subY, subX] = find(subRegionMap);
        subRegions = [subY, subX];

        %% Get comp info from subImg
        %comp_infos = normal_mser3(subImg, param.mser_info, resizeRatio, minmaxRF);
        comp_infos = normal_mser(subImg, resizeRatio, minmaxRF, [globalVar.imgName, '_', num2str(i)]);

        %% ---- for debug ----
        if(param.debug)
            boxes = zeros(length(comp_infos), 4);
            for n = 1 : length(comp_infos)
                boxes(n,:) = comp_infos{n}.box;
            end
            show_bbox(subImg, boxes);
        end

        %% construct regionPerims
        subRegionMap = imfill(subRegionMap, 'holes');
        perimMap = bwperim(subRegionMap);
        [y, x] = find(perimMap);
        subRegionPerims = [y, x];

        tic;
        [region_comp_infos] = getCompOfRegion(subImg, subRegions, comp_infos, param.minRegionCompCoveredArea, param.maxRegionCompArea);
        tmpTime = toc;
        totalTimeOfGetCompOfRegion = totalTimeOfGetCompOfRegion + tmpTime;

        %% generate secondary_region_comp_infos
%         [~, secondary_region_comp_idx] = getCompOfRegion(img, regions{i}, comp_infos, param.secondaryMinRegionCompArea);
%         secondary_region_comp_flags = false(length(comp_infos), 1);
%         secondary_region_comp_flags(secondary_region_comp_idx) = true;
%         secondary_region_comp_flags(region_comp_idx) = false;
%         secondary_region_comp_infos = num2cell(comp_infos(secondary_region_comp_flags));

        if(param.debug)
            debug_bbox = zeros(length(region_comp_infos), 4);
            for d_i = 1 : length(region_comp_infos)
                debug_bbox(d_i,:) = region_comp_infos{d_i}.box;
            end
            show_bbox(subImg, debug_bbox);
        end

        if(false && param.debug)
            debug_bbox = zeros(length(secondary_region_comp_infos), 4);
            for d_i = 1 : length(secondary_region_comp_infos)
                debug_bbox(d_i,:) = secondary_region_comp_infos{d_i}.box;
            end
            show_bbox(subImg, debug_bbox);
        end

        tic;
        estimated_orientations(i) = estimateOrientation(subImg, subRegions, region_comp_infos, param.orient_param);
        tmpTime = toc;
        totalTimeOfEstimateOrientation = totalTimeOfEstimateOrientation + tmpTime;

        tic;
        proposals{i} = genProposalsByOrientation(subImg, subRegions, subRegionPerims, estimated_orientations(i), region_comp_infos);
        tmpTime = toc;
        totalTimeOfGenProposalsByOrientation = totalTimeOfGenProposalsByOrientation + tmpTime;

        proposals{i}(:, 1 : 2 : 8) = proposals{i}(:, 1 : 2 : 8) + extendRegionMinX;
        proposals{i}(:, 2 : 2 : 8) = proposals{i}(:, 2 : 2 : 8) + extendRegionMinY;
    end

    if(false)
        fprintf('TotalTime: %.2f, %.2f, %.2f\n', ...
            totalTimeOfGetCompOfRegion, ...
            totalTimeOfEstimateOrientation, ...
            totalTimeOfGenProposalsByOrientation);
    end

    proposals = cell2mat(proposals);
end


function SO3F = rotate_outer(SO3F,varargin)
% rotate ODF
%
% Syntax
%   SO3F = rotate_outer(SO3F,rot)
%
% Input
%  SO3F - @SO3Fun
%  rot  - @rotation
%
% Output
%  SO3F - @SO3FunHandle

SO3F = SO3FunHandle(@(rot) SO3F.eval(rot));

SO3F = rotate_outer(SO3F,varargin{:});


function [sys,x0,str,ts]=NonlinearPD(t,x,u,flag,Beta1,Beta2,Delta,A1,A2,SampleTime)

if flag==0

    sys = [0;1;1;2;0;1;1];
     x0 = [0 ];
    str = [ ];
     ts = [SampleTime 0];

elseif flag==2

    Bili=fal(u(1),A1,Delta);
    Weifen=fal(u(2),A2,Delta);
    sys=Beta1*Bili+Beta2*Weifen;

elseif flag==3
    sys=x;

elseif flag==4
    sys=sys+SampleTime;

else
    sys=[];
end


function data = LoadBinary(filename,varargin)

%LoadBinary - Load data from a multiplexed binary file.
%
%  Reading a subset of the data can be done in two different manners: either
%  by specifying start time and duration (more intuitive), or by indicating
%  the position and size of the subset in terms of number of samples per
%  channel (more accurate).
%
%  USAGE
%
%    data = LoadBinary(filename,<options>)
%
%    filename       file to read
%    <options>      optional list of property-value pairs (see table below)
%
%    =========================================================================
%     Properties    Values
%    -------------------------------------------------------------------------
%     'frequency'   sampling rate (in Hz, default = 20kHz)
%     'start'       position to start reading (in s, default = 0)
%     'duration'    duration to read (in s, default = Inf)
%     'offset'      position to start reading (in samples per channel,
%                   default = 0)
%     'samples'     number of samples (per channel) to read (default = Inf)
%     'nChannels'   number of data channels in the file (default = 1)
%     'channels'    channels to read (default = all)
%     'precision'   sample precision (default = 'int16')
%     'skip'        number of bytes to skip after each value is read
%                   (default = 0)
%     'downsample'  factor by which to downample by (default = 1)
%    =========================================================================

% Copyright (C) 2004-2011 by Michaël Zugaro
%Modified by DLevenstein 2016 to include downsampling
%
% 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.

% Default values
nChannels = 1;
precision = 'int16';
%error('this function is now deprecated, use bz_LoadBinary.m')
%warning(['this function assumes int16 precision, if your file is not int16 use load/resample.m'])
skip = 0;
frequency = 20000;
channels = [];
start = 0;
duration = Inf;
offset = 0;
nSamplesPerChannel = Inf;
time = false;
samples = false;
downsamplefactor = 1;

if nargin < 1 | mod(length(varargin),2) ~= 0,
  error('Incorrect number of parameters (type ''help LoadBinary'' for details).');
end

% Parse options
for i = 1:2:length(varargin),
	if ~ischar(varargin{i}),
		error(['Parameter ' num2str(i+3) ' is not a property (type ''help LoadBinary'' for details).']);
	end
	switch(lower(varargin{i})),
		case 'frequency',
			frequency = varargin{i+1};
			if ~isdscalar(frequency,'>0'),
				error('Incorrect value for property ''frequency'' (type ''help LoadBinary'' for details).');
			end
		case 'start',
			start = varargin{i+1};
			if ~isdscalar(start),
				error('Incorrect value for property ''start'' (type ''help LoadBinary'' for details).');
			end
			if start < 0, start = 0; end
			time = true;
		case 'duration',
			duration = varargin{i+1};
			if ~isdscalar(duration,'>=0'),
				error('Incorrect value for property ''duration'' (type ''help LoadBinary'' for details).');
			end
			time = true;
		case 'offset',
			offset = varargin{i+1};
			if ~isiscalar(offset),
				error('Incorrect value for property ''offset'' (type ''help LoadBinary'' for details).');
			end
			if offset < 0, offset = 0; end
			samples = true;
		case 'samples',
			nSamplesPerChannel = varargin{i+1};
			if ~isdscalar(nSamplesPerChannel,'>=0'),
				error('Incorrect value for property ''samples'' (type ''help LoadBinary'' for details).');
			end
			samples = true;
		case 'nchannels',
			nChannels = varargin{i+1};
			if ~isiscalar(nChannels,'>0'),
				error('Incorrect value for property ''nChannels'' (type ''help LoadBinary'' for details).');
			end
		case 'channels',
			channels = varargin{i+1};
			if ~isivector(channels,'>0'),
				error('Incorrect value for property ''channels'' (type ''help LoadBinary'' for details).');
			end
		case 'precision',
			precision = varargin{i+1};
			if ~isa(precision,'char'),
				error('Incorrect value for property ''precision'' (type ''help LoadBinary'' for details).');
			end
		case 'skip',
			skip = varargin{i+1};
			if ~isiscalar(skip,'>=0'),
				error('Incorrect value for property ''skip'' (type ''help LoadBinary'' for details).');
            end
		case 'downsample',
			downsamplefactor = varargin{i+1};
			if ~isiscalar(downsamplefactor,'>=0'),
				error('Incorrect value for property ''downsample'' (type ''help LoadBinary'' for details).');
			end
		otherwise,
			error(['Unknown property ''' num2str(varargin{i}) ''' (type ''help LoadBinary'' for details).']);
	end
end

% Either start+duration, or offset+size
if time && samples,
	error(['Data subset can be specified either in time or in samples, but not both (type ''help LoadBinary'' for details).']);
end

% By default, load all channels
if isempty(channels),
	channels = 1:nChannels;
end

% Check consistency between channel IDs and number of channels
if any(channels>nChannels),
	error('Cannot load specified channels (listed channel IDs inconsistent with total number of channels).');
end

% Open file
if ~exist(filename),
	error(['File ''' filename ''' not found.']);
end
f = fopen(filename,'r');
if f == -1,
	error(['Cannot read ' filename ' (insufficient access rights?).']);
end

% Size of one data point (in bytes)
sampleSize = 0;
switch precision,
	case {'uchar','unsigned char','schar','signed char','int8','integer*1','uint8','integer*1'},
		sampleSize = 1;
	case {'int16','integer*2','uint16','integer*2'},
		sampleSize = 2;
	case {'int32','integer*4','uint32','integer*4','single','real*4','float32','real*4'},
		sampleSize = 4;
	case {'int64','integer*8','uint64','integer*8','double','real*8','float64','real*8'},
		sampleSize = 8;
end

% Position and number of samples (per channel) of the data subset
if time,
	dataOffset = floor(start*frequency)*nChannels*sampleSize;
	nSamplesPerChannel = floor((duration*frequency));
else
	dataOffset = offset*nChannels*sampleSize;
end

% Position file index for reading
status = fseek(f,dataOffset,'bof');
if status ~= 0,
	fclose(f);
	error('Could not start reading (possible reasons include trying to read past the end of the file).');
end

% Determine total number of samples in file
fileStart = ftell(f);
status = fseek(f,0,'eof');
if status ~= 0,
	fclose(f);
	error('Error reading the data file (possible reasons include trying to read past the end of the file).');
end
fileStop = ftell(f);
% (floor in case all channels do not have the same number of samples)
maxNSamplesPerChannel = floor(((fileStop-fileStart)/nChannels/sampleSize));
frewind(f);
status = fseek(f,dataOffset,'bof');
if status ~= 0,
	fclose(f);
	error('Could not start reading (possible reasons include trying to read past the end of the file).');
end

if isinf(nSamplesPerChannel) || nSamplesPerChannel > maxNSamplesPerChannel,
	nSamplesPerChannel = maxNSamplesPerChannel;
end

if downsamplefactor>1
%     precision = [num2str(nChannels),'*',precision]; % this line is
%     incorrect, the precision variable is a string that does not depend on
%     the number of channels
    skip = nChannels*(downsamplefactor-1)*sampleSize;
    nSamplesPerChannel = floor(nSamplesPerChannel./downsamplefactor);
end

% For large amounts of data, read chunk by chunk
maxSamplesPerChunk = 10000;
nSamples = nSamplesPerChannel*nChannels;
if nSamples <= maxSamplesPerChunk,
	data = LoadChunk(f,nChannels,channels,nSamples/nChannels,precision,skip);
else
	% Determine chunk duration and number of chunks
	nSamplesPerChunk = floor(maxSamplesPerChunk/nChannels)*nChannels;
	nChunks = floor(nSamples/nSamplesPerChunk);
	% Preallocate memory
	data = zeros(nSamplesPerChannel,length(channels),precision);
	% Read all chunks
	i = 1;
	for j = 1:nChunks,
		d = LoadChunk(f,nChannels,channels,nSamplesPerChunk/nChannels,precision,skip);
		[m,n] = size(d);
		if m == 0, break; end
		data(i:i+m-1,:) = d;
		i = i+m;
	end
	% If the data size is not a multiple of the chunk size, read the remainder
	remainder = nSamples - nChunks*nSamplesPerChunk;
	if remainder ~= 0,
		d = LoadChunk(f,nChannels,channels,remainder/nChannels,precision,skip);
		[m,n] = size(d);
		if m ~= 0,
			data(i:i+m-1,:) = d;
		end
	end
end

fclose(f);

% ---------------------------------------------------------------------------------------------------------

function data = LoadChunk(fid,nChannels,channels,nSamples,precision,skip)

if skip ~= 0,
	data = fread(fid,[nChannels nSamples],[num2str(nChannels),'*',precision '=>' precision],skip);
    %data = fread(fid,[nChannels nSamples],[num2str(nChannels),'*',precision],nChannels*skip);
else
	data = fread(fid,[nChannels nSamples],[precision '=>' precision]);
end
data=data';

if isempty(data),
	warning('No data read (trying to read past file end?)');
elseif ~isempty(channels),
	data = data(:,channels);
end


% ------------------------------------------------------------------------
%  Copyright (C)
%  Universitat Politecnica de Catalunya BarcelonaTech (UPC) - Spain
%  University of California Berkeley (UCB) - USA
%
%  Jordi Pont-Tuset <jordi.pont@upc.edu>
%  Pablo Arbelaez <arbelaez@berkeley.edu>
%  June 2014
% ------------------------------------------------------------------------
% This file is part of the MCG package presented in:
%    Arbelaez P, Pont-Tuset J, Barron J, Marques F, Malik J,
%    "Multiscale Combinatorial Grouping,"
%    Computer Vision and Pattern Recognition (CVPR) 2014.
% Please consider citing the paper if you use this code.
% ------------------------------------------------------------------------

% This function defines all parameters to tune in the training of MCG
% params = nyud_params(); %sf_mUCM_multi_3sc_u_4r_12k_params();

%% Compute all points from combining these base hierarchies
% The order of combination is hard-coded, see pareto_learning to change it
% The result will be loaded if already computed
function pareto_chose_point(params, num_regions)
  pareto = pareto_learning(params);

  %% Plot pareto front results

  % Play with the following two number to get the desired point

  % Which measure used to get the Pareto
  pareto_meas = 2;  % Jaccard at class level

  % Which particular point in the curve we choose
  pareto_id = -1;   % Around 14k candidates

  if(pareto_id == -1)
    pareto_id = find( pareto.st{pareto_meas}{params.n_r_cand}.mean_n_masks > num_regions, 1, 'first');
  end

  figure;
  x_limit = 1e6;
  titles{1} = {'Maximum achievable quality',['(Pascal segvoc ' params.gt_set_pareto ')'], 'Jaccard at instance level (Ji)'};
  titles{2} = {'Maximum achievable quality',['(Pascal segvoc ' params.gt_set_pareto ')'], 'Jaccard at class level (Jc)'};
  measures  = {'jaccard_object', 'jaccard_class'};
  colors = {'r','g','b','k','m','c'};
  for jj=1:length(measures)
      subplot(1,2,jj); hold on;

      % Singletons, pairs, and triplets
      % Pareto on the same measure that evaluated
      for ii=1:params.n_r_cand
          plot(pareto.st{jj}{ii}.mean_n_masks,pareto.st{jj}{ii}.(measures{jj}),[colors{ii} '-'])
      end

      for ii=1:params.n_r_cand
          % Pareto on one measure, evaluated on the other
          kk = setdiff([1 2],jj);
          plot(pareto.st{kk}{ii}.mean_n_masks,pareto.st{kk}{ii}.(measures{jj}),[colors{ii} '--'])
      end

      % Plot working point
      tmp = pareto.st{pareto_meas}{params.n_r_cand}.(measures{jj});
      plot(pareto.st{pareto_meas}{params.n_r_cand}.mean_n_masks(pareto_id),tmp(pareto_id),'k*')
      text(70,0.85,{[num2str(pareto.st{pareto_meas}{params.n_r_cand}.mean_n_masks(pareto_id)) ' c/i'],...
                    ['J=' num2str(tmp(pareto_id))]})

      % Make plot nicer
      title(strrep(titles{jj},'_','\_'))
      if (params.n_r_cand==3)
          legend({'Singletons same','Pairs same','Triplets same','Singletons diff','Pairs diff','Triplets diff'},4)
      elseif (params.n_r_cand==4)
          legend({'Singletons same','Pairs same','Triplets same','4-tuples','Singletons diff','Pairs diff','Triplets diff','4-tuples diff'},4)
      end
      grid minor
      grid on
      axis([10,x_limit,0.3,0.9])
      set(gca,'XScale','log')
  end

  %% Once you have found the desired point, save the parameters to file, i.e.,
  % the number of candidates from each hierarchy and for singletons, pairs, etc.
  sel_parameters  = pareto.pars{pareto_meas}{params.n_r_cand}(:,pareto_id);
  sampled_cands = pareto.base_stats{pareto_meas}.n_cands;
  total_cands = 0;
  clear n_cands;
  for ii=1:length(sel_parameters)
      if sel_parameters(ii)==0
          n_cands(ii) = 0; %#ok<*SAGROW>
      else
          n_cands(ii) = sampled_cands(sel_parameters(ii));
          total_cands = total_cands + pareto.base_stats{ii}.mean_n_masks(sel_parameters(ii));
      end
  end
  assert(abs(total_cands-pareto.st{pareto_meas}{params.n_r_cand}.mean_n_masks(pareto_id))<1e-5)
  n_cands = reshape(n_cands,length(params.hiers),params.n_r_cand)';
  n_cands

  save(params.files.pareto_point,'n_cands','pareto_id');
  disp(['Saved: ' params.files.pareto_point])
end
%% Write the curves to file (to put them in the paper)
% out_dir = '/Users/jpont/Publications/2014_CVPR/LaTeX/data/obj_cands/';
%
% % Write up to singletons, pairs, and triplets (w.r.t pareto_meas)
% write_jaccard_to_file(pareto.st{pareto_meas}{1},fullfile(out_dir,[params.gt_set_pareto '_' params.hiers_id '_pareto_singletons.txt']));
% write_jaccard_to_file(pareto.st{pareto_meas}{2},fullfile(out_dir,[params.gt_set_pareto '_' params.hiers_id '_pareto_pairs.txt']));
% write_jaccard_to_file(pareto.st{pareto_meas}{3},fullfile(out_dir,[params.gt_set_pareto '_' params.hiers_id '_pareto_triplets.txt']));
% write_jaccard_to_file(pareto.st{pareto_meas}{4},fullfile(out_dir,[params.gt_set_pareto '_' params.hiers_id '_pareto_4tuples.txt']));
%
% % Write selected pareto point
% % params = sf_mUCM_sub_params('sub1');
% load(params.files.pareto_point)
% fid = fopen(fullfile(out_dir,[params.gt_set_pareto '_' params.hiers_id '_pareto_selected_point.txt']),'w');
% fprintf(fid, 'ncands\tjac_class\tjac_instance\n');
% fprintf(fid, '%d\t%f\t%f\n', [pareto.st{pareto_meas}{4}.mean_n_masks(pareto_id); pareto.st{pareto_meas}{4}.jaccard_class(pareto_id); pareto.st{pareto_meas}{4}.jaccard_object(pareto_id)]);
% fclose(fid);


function test_plotMeanTSeries
%Validate getting plotting the mean TSeries from an INPLANE ROI
%
%  test_plotMeanTSeries()
%
% Tests: meanTSeries, plotMeanTSeries
%
% INPUTS
%  No inputs
%
% RETURNS
%  No returns
%
% Example: test_plotMeanTSeries()
%
% See also MRVTEST
%
% Copyright Stanford team, mrVista, 2011

%% Initialize the key variables and data path
% Data directory (where the mrSession file is located)
dataDir = mrtInstallSampleData('functional','mrBOLD_01');

% This is the validation file
val = mrtGetValididationData('plotMeanTSeriesFromINPLANE');

% These are the items we stored in the validation file
%
% val.detrendDim  = size(d.detrend.frameNumbers);
% val.rawDim      = size(d.raw.frameNumbers);
% val.detrendMn   = mean(d.detrend.tSeries);
% val.detrendMd   = median(d.detrend.tSeries);
% val.detrendMx   = max(d.detrend.tSeries);
% val.detrendMin  = min(d.detrend.tSeries);
% val.rawMn       = mean(d.raw.tSeries);
% val.rawMd       = median(d.raw.tSeries);
% val.rawMx       = max(d.raw.tSeries);
% val.rawMin      = min(d.raw.tSeries);
%
% save(vFile, '-struct', 'val')

%% Retain original directory, change to data directory
curDir = pwd;
cd(dataDir);

% There can be several data types - name the one you want to probe
dataType = 'Original';

% Which scan number from that data type?
scan = 1;

%% Get data structure:
vw = initHiddenInplane(); % Foregoes interface - loads data silently

%% Set dataTYPE:
vw = viewSet(vw, 'Current DataType', dataType); % Data type

%% Load an ROI and coranal
vw = loadROI(vw, 'LV1.mat');

detrend = true;

% open a plot figure
newGraphWin;

% load both raw and detrended tSeries so we can validate both
d.detrend = plotMeanTSeries(vw, scan, [], ~detrend);
d.raw     = plotMeanTSeries(vw, scan, [], detrend);

% close it
closeGraphWin;

%% Go home
cd(curDir)

%% Validate..

% check the number of time points
assertEqual(val.detrendDim, size(d.detrend.frameNumbers));
assertEqual(val.rawDim,     size(d.raw.frameNumbers));

% check detrended t-series
assertElementsAlmostEqual(val.detrendMn,mean(d.detrend.tSeries));
assertElementsAlmostEqual(val.detrendMd,median(d.detrend.tSeries));
assertElementsAlmostEqual(val.detrendMx,max(d.detrend.tSeries));
assertElementsAlmostEqual(val.detrendMin,min(d.detrend.tSeries));

% check raw t-series
assertElementsAlmostEqual(val.rawMn,mean(d.raw.tSeries));
assertElementsAlmostEqual(val.rawMd,median(d.raw.tSeries));
assertElementsAlmostEqual(val.rawMx,max(d.raw.tSeries));
assertElementsAlmostEqual(val.rawMin,min(d.raw.tSeries));

%% Clear workspace

mrvCleanWorkspace;


function [cleanedData, metToKeepSummary] = metsToKeep(dataOrg, metRep, calRelErr, param)
%
% removes the metabolomics measurements from the
% dataOrg table that have low measurement quality based on the relative SD
% of technical replicate sample (RSDqc provided in the metRep variable)
% and/or the average relative error (measured vs actual concentration) of
% the calibration line samples (RE provided in the calRelErr variable)
%
% USAGE:
%   [cleanedData, metToKeepSummary] = metsToKeep(dataOrg, metRep, calRelErr, param)
%
% INPUTS:
%  dataOrg:     A table with original metabolomics data in a long format
%               with information about measured samples, compounds,
%               retention times (RT), area(s), concentrations, etc.
%               the following column is required for the analysis:
%
%                     * .compound - compound (metabolite names) identical
%                                   to the names used in the metRep and
%                                   calRE variables
%  metRep:      A table with quality information based on the dataOrg
%               in a long format (output from mzQuality tool).
%               The following columns are required for the analysis:
%
%                     * .compound - compound (metabolite names) identical
%                                   to the names used in the dataOrg and
%                                   calRE variables
%                     * .RSDqc_* - one or more columns specifying the
%                                  relative standard deviation of the
%                                  repeated measurement of a (quality)
%                                  sample (per batch) per metabolite
%  calRelErr:   A table with quality information about the relative
%               error (RE) of the concentration estimation of the
%               calibration line samples based on the dataOrg
%               in a long format with information about measured samples,
%               compounds, retention times (RT), known concentrations,
%               estimated concentrations, and relative error etc.
%               The following columns are required for the analysis:
%
%                     * .compound - compound (metabolite names) identical
%                                   to the names used in the dataOrg and
%                                   calRE variables
%                     * .RE* - a columns specifying the relative error of
%                              the concentration estimation of the
%                              calibration line samples
%  param.tresholdRSDqc: the treshold value for the relative SD of the repeated
%                       measurement of sample (default = 25 (%); based on
%                       the based on the "Guidelines and considerations for
%                       the use of system suitability and quality control
%                       samples in mass spectrometry assays applied in
%                       untargeted clinical metabolomic studies")
%  param.tresholdCalRE: the treshold value for the relative error of the
%                       concentration estimation of the calibration line
%                       samples (default = 25 (%)
%
% OUTPUTS:
%  cleanedData:         table in the same format as dataOrg without the
%                       metabolites of low quality (above set tresholds)
%  metToKeepSummary:    table in the same format as metRep variable with an
%                       added columns:
%
%                     * .keep -     specifies whether a metabolite is to be
%                                   kept (1) or removed (0) from the further
%                                   analysis
%                     * .REcheck - specifies whether a metabolite passed
%                                   (1) or failed (0) the check based on
%                                   the relative error of the concentration
%                                   estimation of the calibration line sample
%                     * .RSDqcCheck - specifies whether a metabolite passed
%                                     (1) or failed (0) the check based on
%                                     the relative standard deviation of
%                                     the repeated measurement of a (QC) sample
%                     * .sumRE -    shows the average relative error of the
%                                   concentration estimation of the
%                                   calibration line sample per metabolite
%
% EXAMPLE:
%
% NOTE:
%
% Author(s): Agnieszka Wegrzyn (2021)

if exist('param', 'var')
    if isfield(param, "tresholdRSDqc")
        tresholdRSDqc = param.tresholdRSDqc;
    else
        tresholdRSDqc = 25;
    end
    if isfield(param, "tresholdCalRE")
        tresholdCalRE = param.tresholdCalRE;
    else
        tresholdCalRE = 25;
    end
else
    tresholdRSDqc = 25;
    tresholdCalRE = 25;
end

metToKeep = metRep;
calRE = calRelErr;
calRE.RE(isnan(calRE.RE)) = 0;
calRE.RE(isinf(calRE.RE)) = NaN;
metToKeep.REcheck = zeros(length(metToKeep.compound),1);
metToKeep.RSDqcCheck = zeros(length(metToKeep.compound),1);
for i=1:length(metToKeep.compound)
    if sum(ismember(calRE.compound,metToKeep.compound(i))) ~= 0
        avrCalRE = mean(calRE.RE(ismember(calRE.compound,metToKeep.compound(i))),'omitnan');
        sdCalRE = std(calRE.RE(ismember(calRE.compound,metToKeep.compound(i))),'omitnan');
        metToKeep.sumRE(i) = avrCalRE;
        %check if average + 1SD (to account for an outlier) of RE is below the set treshold
        if (avrCalRE + sdCalRE) > tresholdCalRE
            metToKeep.REcheck(i) = 0;
        else
            metToKeep.REcheck(i) = 1;
        end
    else
        metToKeep.sumRE(i) = NaN;
    end
    if all(table2array(metToKeep(i,contains(metToKeep.Properties.VariableNames, 'RSDqc_'))) <= tresholdRSDqc)
        metToKeep.RSDqcCheck(i) = 1;
    else
        metToKeep.RSDqcCheck(i) = 0;
    end
    if metToKeep.RSDqcCheck(i) == 1 && metToKeep.REcheck(i) == 1
        metToKeep.Var1(i) = 1;
    else
        metToKeep.Var1(i) = 0;
    end
end
metToKeepSummary = metToKeep;
metToKeepSummary.Properties.VariableNames(1) = "keep";
cleanedData = dataOrg;
cleanedData(contains(cleanedData.compound,metToKeepSummary.compound(metToKeepSummary.keep == 0)),:)= [];
cleanedData(:,1)= [];
disp(' ')
disp('--------------------------------------------------------------')
disp(['Number of metabolites in the dataset: ' num2str(numel(metToKeepSummary.compound))])
disp(['Number of metabolites left after quality check: ' num2str(sum(metToKeepSummary.keep))])
disp(' ')


function updateScatterPolar(obj, plotIndex)

    %-AXIS INDEX-%
    axIndex = obj.getAxisIndex(obj.State.Plot(plotIndex).AssociatedAxis);

    %-PLOT DATA STRUCTURE- %
    plotData = get(obj.State.Plot(plotIndex).Handle);

    %-CHECK FOR MULTIPLE AXES-%
    [xsource, ysource] = findSourceAxis(obj, axIndex);

    %-ASSOCIATE POLAR-AXES LAYOUT-%
    obj.data{plotIndex}.subplot = sprintf('polar%d', xsource+1);

    %-------------------------------------------------------------------------%

    %-parse plot data-%
    rData = plotData.RData;
    thetaData = rad2deg(plotData.ThetaData);

    thetaData(rData<0) = mod(thetaData(rData<0)+180, 360);
    rData = abs(rData);

    %-------------------------------------------------------------------------%

    %-scatterpolar trace setting-%
    obj.data{plotIndex}.type = 'scatterpolar';
    obj.data{plotIndex}.mode = 'markers';
    obj.data{plotIndex}.visible = strcmp(plotData.Visible,'on');
    obj.data{plotIndex}.name = plotData.DisplayName;

    %-------------------------------------------------------------------------%

    %-set scatterpolar data-%
    obj.data{plotIndex}.r = rData;
    obj.data{plotIndex}.theta = thetaData;

    %-------------------------------------------------------------------------%

    %-trace settings-%
    markerStruct = extractScatterMarker(plotData);

    obj.data{plotIndex}.marker = markerStruct;

    if length(markerStruct.size) == 1
        obj.data{plotIndex}.marker.size = markerStruct.size * 0.2;
    end

    if length(markerStruct.line.color) > 1
        obj.data{plotIndex}.marker.line.color = markerStruct.line.color{1};
    end

    %-------------------------------------------------------------------------%

    %-legend setting-%
    leg = get(plotData.Annotation);
    legInfo = get(leg.LegendInformation);

    switch legInfo.IconDisplayStyle
        case 'on'
            obj.data{plotIndex}.showlegend = true;
        case 'off'
            obj.data{plotIndex}.showlegend = false;
    end

    %-------------------------------------------------------------------------%

    %-set polar axes-%
    updatePolaraxes(obj, plotIndex);

    %-------------------------------------------------------------------------%
end

%-------------------------------------------------------------------------%
%
%-SET POLAR AXIS-%
%
%-------------------------------------------------------------------------%

function updatePolaraxes(obj, plotIndex)

    %-------------------------------------------------------------------------%

    %-AXIS INDEX-%
    axIndex = obj.getAxisIndex(obj.State.Plot(plotIndex).AssociatedAxis);

    %-CHECK FOR MULTIPLE AXES-%
    [xsource, ysource] = findSourceAxis(obj, axIndex);

    %-GET DATA STRUCTURES-%
    plotData = get(obj.State.Plot(plotIndex).Handle);
    axisData = get(plotData.Parent);
    thetaAxis = get(axisData.ThetaAxis);
    rAxis = get(axisData.RAxis);

    %-------------------------------------------------------------------------%

    %-set domain plot-%
    xo = axisData.Position(1);
    yo = axisData.Position(2);
    w = axisData.Position(3);
    h = axisData.Position(4);

    polarAxis.domain.x = min([xo xo + w], 1);
    polarAxis.domain.y = min([yo yo + h], 1);

    %-------------------------------------------------------------------------%

    %-setting angular axis-%
    gridColor = sprintf('rgba(%f,%f,%f,%f)', 255*axisData.GridColor, ...
        axisData.GridAlpha);
    gridWidth = axisData.LineWidth;
    thetaLim = thetaAxis.Limits;

    polarAxis.angularaxis.linecolor = gridColor;
    polarAxis.angularaxis.ticklen = mean(thetaAxis.TickLength);

    if isnumeric(thetaLim)
        polarAxis.angularaxis.range = thetaLim;
    else
        polarAxis.angularaxis.autorange = true;
    end

    if strcmp(axisData.ThetaGrid, 'on')
        polarAxis.angularaxis.gridwidth = gridWidth;
        polarAxis.angularaxis.gridcolor = gridColor;
    end

    %-------------------------------------------------------------------------%

    %-set angular axis label-%
    thetaLabel = thetaAxis.Label;

    polarAxis.angularaxis.title.text = thetaLabel.String;
    polarAxis.radialaxis.title.font.family = matlab2plotlyfont(...
        thetaLabel.FontName);
    polarAxis.radialaxis.title.font.size = thetaLabel.FontSize;
    polarAxis.radialaxis.title.font.color = sprintf('rgb(%f,%f,%f)', ...
        255*thetaLabel.Color);

    %-------------------------------------------------------------------------%

    %-setting radial axis-%
    rLim = rAxis.Limits;

    polarAxis.radialaxis.showline = false;
    polarAxis.radialaxis.angle = axisData.RAxisLocation+6;
    polarAxis.radialaxis.tickangle = 90-rAxis.TickLabelRotation;
    polarAxis.radialaxis.ticklen = mean(rAxis.TickLength);

    if isnumeric(rLim)
        polarAxis.radialaxis.range = rLim;
    else
        polarAxis.radialaxis.autorange = true;
    end

    if strcmp(axisData.RGrid, 'on')
        polarAxis.radialaxis.gridwidth = gridWidth;
        polarAxis.radialaxis.gridcolor = gridColor;
    end

    %-------------------------------------------------------------------------%

    %-set radial axis label-%
    rLabel = thetaAxis.Label;

    polarAxis.angularaxis.title.text = 'label';%rLabel.String;
    polarAxis.angularaxis.title.font.family = matlab2plotlyfont(...
        rLabel.FontName);
    polarAxis.angularaxis.title.font.size = rLabel.FontSize;
    polarAxis.angularaxis.title.font.color = sprintf('rgb(%f,%f,%f)', ...
        255*rLabel.Color);

    %-------------------------------------------------------------------------%

    %-angular tick labels settings-%
    tickValues = axisData.ThetaTick;
    tickLabels = axisData.ThetaTickLabel;
    showTickLabels = true;

    try
        if tickValues(1) == 0 && tickValues(end) == 360
            tickValues = tickValues(1:end-1);
        end
    catch
        tickValues = tickValues;
    end

    if isempty(tickValues)
        showTickLabels = false;
        polarAxis.angularaxis.showticklabels = showTickLabels;
        polarAxis.angularaxis.ticks = '';

    elseif isempty(tickLabels)
        polarAxis.angularaxis.tickvals = tickValues;

    else
        polarAxis.angularaxis.tickvals = tickValues;
        polarAxis.angularaxis.ticktext = tickLabels;

    end

    if showTickLabels
        switch thetaAxis.TickDirection
            case 'in'
                polarAxis.angularaxis.ticks = 'inside';
            case 'out'
                polarAxis.angularaxis.ticks = 'outside';
        end

        %-tick font-%
        polarAxis.angularaxis.tickfont.family = matlab2plotlyfont(...
            thetaAxis.FontName);
        polarAxis.angularaxis.tickfont.size = thetaAxis.FontSize;
        polarAxis.angularaxis.tickfont.color = sprintf('rgb(%f,%f,%f)', ...
            255*thetaAxis.Color);
    end

    %-------------------------------------------------------------------------%

    %-radial tick labels settings-%
    tickValues = axisData.RTick;
    tickLabels = axisData.RTickLabel;
    showTickLabels = true;

    if isempty(tickValues)
        showTickLabels = false;
        polarAxis.radialaxis.showticklabels = showTickLabels;
        polarAxis.radialaxis.ticks = '';

    elseif isempty(tickLabels)
        polarAxis.radialaxis.tickvals = tickValues;

    else
        polarAxis.radialaxis.tickvals = tickValues;
        polarAxis.radialaxis.ticktext = tickLabels;
    end

    if showTickLabels
        switch rAxis.TickDirection
            case 'in'
                polarAxis.radialaxis.ticks = 'inside';
            case 'out'
                polarAxis.radialaxis.ticks = 'outside';
        end

        %-tick font-%
        polarAxis.radialaxis.tickfont.family = matlab2plotlyfont(...
            rAxis.FontName);
        polarAxis.radialaxis.tickfont.size = rAxis.FontSize;
        polarAxis.radialaxis.tickfont.color = sprintf('rgb(%f,%f,%f)', ...
            255*rAxis.Color);
    end

    %-------------------------------------------------------------------------%

    %-set polaraxes to layout-%
    obj.layout = setfield(obj.layout, sprintf('polar%d', xsource+1), polarAxis);

    %-------------------------------------------------------------------------%
end


function f = vis_derived_filter(model, tree)

% AUTORIGHTS
% -------------------------------------------------------
% Copyright (C) 2011-2012 Ross Girshick
%
% This file is part of the voc-releaseX code
% (http://people.cs.uchicago.edu/~rbg/latent/)
% and is available under the terms of an MIT-like license
% provided in COPYING. Please retain this notice and
% COPYING if you use this file (or a portion of it) in
% your project.
% -------------------------------------------------------

conf = voc_config();

% indexes into info from get_detection_trees.cc
% replace with tree_mat_to_struct
N_PARENT      = 1;
N_IS_LEAF     = 2;
N_SYMBOL      = 3;
N_RULE_INDEX  = 4;
N_RHS_INDEX   = 5;
N_X           = 6;
N_Y           = 7;
N_L           = 8;
N_DS          = 9;
N_DX          = 10;
N_DY          = 11;
N_SCORE       = 12;
N_LOSS        = 13;
N_SZ          = 14;

rx = tree(N_X, 1);
ry = tree(N_Y, 1);
rl = tree(N_L, 1);

f = zeros([0 0 conf.features.dim]);
off_x = 0;
off_y = 0;

for i = 2:size(tree,2)
  s = tree(N_SYMBOL, i);
  if model.symbols(s).type == 'T'
    x = off_x + tree(N_X, i) - rx;
    y = off_y + tree(N_Y, i) - ry;
    l = tree(N_L, i) - rl;

    pad = [abs(min(0, [y x])) 0];
    f = padarray(f, pad, 0, 'pre');
    if pad(1) > 0
      off_y = off_y + pad(1);
    end
    if pad(2) > 0
      off_x = off_x + pad(2);
    end

    w = model_get_block(model, model.filters(model.symbols(s).filter));
    wsz = size(w);
    fsz = size(f);
    req_fsz = [off_y + y + wsz(1), off_x + x + wsz(2), wsz(3)];
    pad = max(0, req_fsz - fsz);
    f = padarray(f, pad, 0, 'post');
    f(off_y+1+y:off_y+1+y+wsz(1)-1, off_x+1+x:off_x+1+x+wsz(2)-1, :) = ...
      f(off_y+1+y:off_y+1+y+wsz(1)-1, off_x+1+x:off_x+1+x+wsz(2)-1, :) + w;
  end
end

visualizeHOG(max(0, f));


%1. Load the image, for example
    image        = imread('img.bmp');

%2. Call this function to calculate the quality score:
    qualityscore = SSEQ(image)


function [broadcast_obs,precise_obs]=createObs(TOW,satOrbits)

precise_obs = 0;

index=find(satOrbits(1).TOW==TOW);
PRNlist=[];

for ii=1:32
    if satOrbits(ii).C1(index)~=0 && satOrbits(ii).L1(index)~=0 ...
            &&satOrbits(ii).L2(index)~=0 &&satOrbits(ii).P2(index)~=0
        PRNlist=[PRNlist,ii];
    end
end

broadcast_obs.col.XS=1;
broadcast_obs.col.YS=2;
broadcast_obs.col.ZS=3;
broadcast_obs.col.CorrP=4;
broadcast_obs.col.TOW=5;
broadcast_obs.col.PRN=6;

broadcast_obs.data=zeros(length(PRNlist),5);

for ii=1:length(PRNlist)
    broadcast_obs.data(ii,broadcast_obs.col.XS)=satOrbits(PRNlist(ii)).XS(index);
    broadcast_obs.data(ii,broadcast_obs.col.YS)=satOrbits(PRNlist(ii)).YS(index);
    broadcast_obs.data(ii,broadcast_obs.col.ZS)=satOrbits(PRNlist(ii)).ZS(index);
    broadcast_obs.data(ii,broadcast_obs.col.CorrP)=satOrbits(PRNlist(ii)).CorrP1(index);
    broadcast_obs.data(ii,broadcast_obs.col.PRN)=satOrbits(PRNlist(ii)).PRN;
    broadcast_obs.data(ii,broadcast_obs.col.TOW)=TOW;
end